mirror of
https://github.com/anope/anope.git
synced 2026-07-08 10:23:14 +02:00
Change extensible keys to require explicitly having a type defined for it. Completely modularize more features like bs_kick, entrymsg, log, mode, etc. Move fantasy to its own module. Move greet to its own module.
This commit is contained in:
+60
-20
@@ -99,13 +99,6 @@ module
|
||||
*/
|
||||
#smartjoin = yes
|
||||
|
||||
/*
|
||||
* Defines the prefixes for fantasy commands in channels. One of these characters will have to be prepended
|
||||
* to all fantasy commands. If you choose "!", for example, fantasy commands will be "!kick",
|
||||
* "!op", etc. This directive is optional, if left out, the default fantasy character is "!".
|
||||
*/
|
||||
#fantasycharacter = "!."
|
||||
|
||||
/*
|
||||
* Modes to set on service bots when they join channels, comment this out for no modes
|
||||
*
|
||||
@@ -137,13 +130,17 @@ command { service = "BotServ"; name = "HELP"; command = "generic/help"; }
|
||||
/*
|
||||
* bs_assign
|
||||
*
|
||||
* Provides the commands botserv/assign and botserv/unassign.
|
||||
* Provides the commands:
|
||||
* botserv/assign - Used to assign BotServ bots to channels
|
||||
* botserv/unassign - Used to unassign BotServ bots
|
||||
* botserv/set/nobot - Used to prohibit channels from being assigned BotServ bots.
|
||||
*
|
||||
* Used for assigning and unassigning bots to channels.
|
||||
*/
|
||||
module { name = "bs_assign" }
|
||||
command { service = "BotServ"; name = "ASSIGN"; command = "botserv/assign"; }
|
||||
command { service = "BotServ"; name = "UNASSIGN"; command = "botserv/unassign"; }
|
||||
command { service = "BotServ"; name = "SET NOBOT"; command = "botserv/set/nobot"; permission = "botserv/set/nobot"; }
|
||||
|
||||
/*
|
||||
* bs_autoassign
|
||||
@@ -240,6 +237,8 @@ command { service = "BotServ"; name = "INFO"; command = "botserv/info"; }
|
||||
* botserv/kick/repeat - Configures BotServ's repeat kicker.
|
||||
* botserv/kick/reverses - Configures BotServ's reverse kicker.
|
||||
* botserv/kick/underlines - Configures BotServ's reverse kicker.
|
||||
* botserv/set/dontkickops - Used for preventing BotServ from kicking channel operators.
|
||||
* botserv/set/dontkickvoices - Used for preventing BotServ from kicking voices.
|
||||
*
|
||||
* Used for configuring what bots should kick for.
|
||||
*/
|
||||
@@ -275,29 +274,70 @@ command { service = "BotServ"; name = "KICK REPEAT"; command = "botserv/kick/rep
|
||||
command { service = "BotServ"; name = "KICK REVERSES"; command = "botserv/kick/reverses"; }
|
||||
command { service = "BotServ"; name = "KICK UNDERLINES"; command = "botserv/kick/underlines"; }
|
||||
|
||||
command { service = "BotServ"; name = "SET DONTKICKOPS"; command = "botserv/set/dontkickops"; }
|
||||
command { service = "BotServ"; name = "SET DONTKICKVOICES"; command = "botserv/set/dontkickvoices"; }
|
||||
|
||||
/*
|
||||
* bs_set
|
||||
*
|
||||
* Provides the commands:
|
||||
* botserv/set/dontkickops - Used for preventing BotServ from kicking channel operators.
|
||||
* botserv/set/dontkickvoices - Used for preventing BotServ from kicking voices.
|
||||
* botserv/set/fantasy - Used for enabling or disabling BotServ's fantasist commands.
|
||||
* botserv/set/greet - Used for enabling or disabling BotServ's greet messages in a channel.
|
||||
* botserv/set/nobot - Used to prohibit specific channels from being assigned BotServ bots.
|
||||
* botserv/set/private - Used to prohibit specific BotServ bots from being assigned to channels.
|
||||
*
|
||||
* Used for setting options such as kickers and fantasy replies.
|
||||
*/
|
||||
module { name = "bs_set" }
|
||||
command { service = "BotServ"; name = "SET"; command = "botserv/set"; }
|
||||
command { service = "BotServ"; name = "SET BANEXPIRE"; command = "botserv/set/banexpire"; }
|
||||
command { service = "BotServ"; name = "SET DONTKICKOPS"; command = "botserv/set/dontkickops"; }
|
||||
command { service = "BotServ"; name = "SET DONTKICKVOICES"; command = "botserv/set/dontkickvoices"; }
|
||||
command { service = "BotServ"; name = "SET FANTASY"; command = "botserv/set/fantasy"; }
|
||||
command { service = "BotServ"; name = "SET GREET"; command = "botserv/set/greet"; }
|
||||
command { service = "BotServ"; name = "SET NOBOT"; command = "botserv/set/nobot"; permission = "botserv/set/nobot"; }
|
||||
command { service = "BotServ"; name = "SET PRIVATE"; command = "botserv/set/private"; permission = "botserv/set/private"; }
|
||||
|
||||
/*
|
||||
* greet
|
||||
*
|
||||
* Provides the commands:
|
||||
* botserv/set/greet - Used for enabling or disabling BotServ's greet messages in a channel.
|
||||
* nickserv/set/greet, nickserv/saset/greet - Used for changing a users greet message, which is displayed when they enter channels.
|
||||
*/
|
||||
module { name = "greet" }
|
||||
command { service = "BotServ"; name = "SET GREET"; command = "botserv/set/greet"; }
|
||||
command { service = "NickServ"; name = "SET GREET"; command = "nickserv/set/greet"; }
|
||||
command { service = "NickServ"; name = "SASET GREET"; command = "nickserv/saset/greet"; permission = "nickserv/saset/greet"; }
|
||||
|
||||
/*
|
||||
* GREET privilege.
|
||||
*
|
||||
* Used by 'greet'.
|
||||
*
|
||||
* Users with this privilege have their greet shown when they join channels.
|
||||
*/
|
||||
privilege
|
||||
{
|
||||
name = "GREET"
|
||||
rank = 40
|
||||
level = 5
|
||||
flag = "g"
|
||||
xop = "AOP"
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fantasy
|
||||
*
|
||||
* Allows 'fantaisist' commands to be used in channels.
|
||||
*
|
||||
* Provides the commands:
|
||||
* botserv/set/fantasy - Used for enabling or disabling BotServ's fantasist commands.
|
||||
*/
|
||||
module
|
||||
{
|
||||
name = "fantasy"
|
||||
|
||||
/*
|
||||
* Defines the prefixes for fantasy commands in channels. One of these characters will have to be prepended
|
||||
* to all fantasy commands. If you choose "!", for example, fantasy commands will be "!kick",
|
||||
* "!op", etc. This directive is optional, if left out, the default fantasy character is "!".
|
||||
*/
|
||||
#fantasycharacter = "!."
|
||||
}
|
||||
command { service = "BotServ"; name = "SET FANTASY"; command = "botserv/set/fantasy"; }
|
||||
|
||||
/*
|
||||
* Fantasy commands
|
||||
*
|
||||
|
||||
+28
-42
@@ -74,9 +74,9 @@ module
|
||||
* - keeptopic: Retain topic when the channel is not in use
|
||||
* - peace: Disallow users from kicking or removing modes from others who are of the same
|
||||
* access level or superior
|
||||
* - private: Hide the channel from ChanServ's LIST command
|
||||
* - cs_private: Hide the channel from ChanServ's LIST command
|
||||
* - restricted: Kick/ban users who are restricted from the channel
|
||||
* - secure: Enable channel security, requiring the user to be identified with NickServ in
|
||||
* - cs_secure: Enable channel security, requiring the user to be identified with NickServ in
|
||||
* order to be considered for being on the access list of the channel
|
||||
* - secureops: Only allow operator status to be given if the user is on the access list
|
||||
* - securefounder: Only allow the real founder of the channel to drop the channel, change it's
|
||||
@@ -89,10 +89,10 @@ module
|
||||
* - noautoop: Disables autoop on the channel
|
||||
* - none: No defaults
|
||||
*
|
||||
* This directive is optional, if left blank, the options will default to keeptopic, secure, securefounder,
|
||||
* This directive is optional, if left blank, the options will default to keeptopic, cs_secure, securefounder,
|
||||
* and signkick. If you really want no defaults, use "none" by itself as the option.
|
||||
*/
|
||||
defaults = "keeptopic peace secure securefounder signkick"
|
||||
defaults = "keeptopic peace cs_secure securefounder signkick"
|
||||
|
||||
/*
|
||||
* The maximum number of channels which may be registered to a single nickname.
|
||||
@@ -110,18 +110,6 @@ module
|
||||
*/
|
||||
expire = 14d
|
||||
|
||||
/*
|
||||
* The default ban type for newly registered channels.
|
||||
*
|
||||
* defbantype can be:
|
||||
*
|
||||
* 0: ban in the form of *!user@host
|
||||
* 1: ban in the form of *!*user@host
|
||||
* 2: ban in the form of *!*@host
|
||||
* 3: ban in the form of *!*user@*.domain
|
||||
*/
|
||||
defbantype = 2
|
||||
|
||||
/*
|
||||
* The maximum number of entries on a channel's access list.
|
||||
*/
|
||||
@@ -423,22 +411,6 @@ privilege
|
||||
xop = "AOP"
|
||||
}
|
||||
|
||||
/*
|
||||
* GREET privilege.
|
||||
*
|
||||
* Used by botserv/main.
|
||||
*
|
||||
* Users with this permission get their greet shown on join.
|
||||
*/
|
||||
privilege
|
||||
{
|
||||
name = "GREET"
|
||||
rank = 40
|
||||
level = 5
|
||||
flag = "g"
|
||||
xop = "AOP"
|
||||
}
|
||||
|
||||
/*
|
||||
* HALFOP privilege.
|
||||
*
|
||||
@@ -983,9 +955,9 @@ command { service = "ChanServ"; name = "KICK"; command = "chanserv/kick"; }
|
||||
/*
|
||||
* cs_list
|
||||
*
|
||||
* Provides the command chanserv/list.
|
||||
*
|
||||
* Used for retrieving and searching the registered channel list.
|
||||
* Provides the commands:
|
||||
* chanserv/list - Used for retrieving and searching the registered channel list.
|
||||
* chanserv/set/private - Used for setting whether channels should show up in chanserv/list.
|
||||
*/
|
||||
module
|
||||
{
|
||||
@@ -998,6 +970,7 @@ module
|
||||
}
|
||||
|
||||
command { service = "ChanServ"; name = "LIST"; command = "chanserv/list"; permission = "chanserv/list"; group = "chanserv/admin"; }
|
||||
command { service = "ChanServ"; name = "SET PRIVATE"; command = "chanserv/set/private"; }
|
||||
|
||||
/*
|
||||
* cs_log
|
||||
@@ -1057,10 +1030,8 @@ cs_seen
|
||||
* chanserv/set/bantype - Used for controlling what format of bans are placed on channels.
|
||||
* chanserv/set/description - Used for changing channels descriptions.
|
||||
* chanserv/set/founder - Used for changing a channel's founder.
|
||||
* chanserv/set/keeptopic - Used for configuring if ChanServ is to restore the channel topic when a channel is created.
|
||||
* chanserv/set/peace - Used for configuring if users are able to kick other users with higher access than them.
|
||||
* chanserv/set/persist - Used for setting whether ChanServ should stay in channels after the last user leaves.
|
||||
* chanserv/set/private - Used for setting whether channels should show up in chanserv/list.
|
||||
* chanserv/set/restricted - Used for setting whether users not on a channel's access list can join.
|
||||
* chanserv/set/secure - Used for setting whether users who are recognized for accounts should have their access in channels.
|
||||
* chanserv/set/securefounder - Used for setting whether users with founder level access in channels have true founder or not.
|
||||
@@ -1071,7 +1042,22 @@ cs_seen
|
||||
*
|
||||
* This is a dummy command to provide a help wrapper for the various SET commands.
|
||||
*/
|
||||
module { name = "cs_set" }
|
||||
module
|
||||
{
|
||||
name = "cs_set"
|
||||
|
||||
/*
|
||||
* The default ban type for newly registered channels.
|
||||
*
|
||||
* defbantype can be:
|
||||
*
|
||||
* 0: ban in the form of *!user@host
|
||||
* 1: ban in the form of *!*user@host
|
||||
* 2: ban in the form of *!*@host
|
||||
* 3: ban in the form of *!*user@*.domain
|
||||
*/
|
||||
defbantype = 2
|
||||
}
|
||||
|
||||
command { service = "ChanServ"; name = "SET"; command = "chanserv/set"; group = "chanserv/management"; }
|
||||
command { service = "ChanServ"; name = "SET AUTOOP"; command = "chanserv/set/autoop"; }
|
||||
@@ -1079,10 +1065,8 @@ command { service = "ChanServ"; name = "SET BANTYPE"; command = "chanserv/set/ba
|
||||
command { service = "ChanServ"; name = "SET DESCRIPTION"; command = "chanserv/set/description"; }
|
||||
command { service = "ChanServ"; name = "SET DESC"; command = "chanserv/set/description"; }
|
||||
command { service = "ChanServ"; name = "SET FOUNDER"; command = "chanserv/set/founder"; }
|
||||
command { service = "ChanServ"; name = "SET KEEPTOPIC"; command = "chanserv/set/keeptopic"; }
|
||||
command { service = "ChanServ"; name = "SET PEACE"; command = "chanserv/set/peace"; }
|
||||
command { service = "ChanServ"; name = "SET PERSIST"; command = "chanserv/set/persist"; }
|
||||
command { service = "ChanServ"; name = "SET PRIVATE"; command = "chanserv/set/private"; }
|
||||
command { service = "ChanServ"; name = "SET RESTRICTED"; command = "chanserv/set/restricted"; }
|
||||
command { service = "ChanServ"; name = "SET SECURE"; command = "chanserv/set/secure"; }
|
||||
command { service = "ChanServ"; name = "SET SECUREFOUNDER"; command = "chanserv/set/securefounder"; }
|
||||
@@ -1149,12 +1133,14 @@ command { service = "ChanServ"; name = "SYNC"; command = "chanserv/sync"; group
|
||||
/*
|
||||
* cs_topic
|
||||
*
|
||||
* Provides the command chanserv/topic.
|
||||
* Provides the commands:
|
||||
* chanserv/topic - Used for changing the channel topic. Useful in conjunction with chanserv/set/topiclock.
|
||||
* chanserv/set/keeptopic - Used for configuring if ChanServ is to restore the channel topic when a channel is created.
|
||||
*
|
||||
* Used for changing the channel topic. Useful in conjunction with chanserv/set/topiclock.
|
||||
*/
|
||||
module { name = "cs_topic" }
|
||||
command { service = "ChanServ"; name = "TOPIC"; command = "chanserv/topic"; group = "chanserv/management"; }
|
||||
command { service = "ChanServ"; name = "SET KEEPTOPIC"; command = "chanserv/set/keeptopic"; }
|
||||
|
||||
/*
|
||||
* cs_unban
|
||||
|
||||
@@ -1109,6 +1109,7 @@ mail
|
||||
* [DEPRECATED] db_plain
|
||||
*
|
||||
* This is the flatfile database format from Anope-1.9.2 to Anope-1.9.5.
|
||||
* This module only loads this database, and will NOT save it.
|
||||
* To convert from this format, load both this and db_flatfile. Be sure to name db_flatfile's
|
||||
* target database to something else. Start Anope then shut down so the new database will be written.
|
||||
* Then unload this and restart Anope, loading from the new database.
|
||||
|
||||
+23
-31
@@ -94,9 +94,9 @@ module
|
||||
* - killprotect: Kill nick if not identified within 60 seconds
|
||||
* - kill_quick: Kill nick if not identified within 20 seconds, this one overrides the above
|
||||
* option and the above must be specified with this one
|
||||
* - secure: Enable nickname security, requiring the nick's password before any operations
|
||||
* - ns_secure: Enable nickname security, requiring the nick's password before any operations
|
||||
* can be done on it
|
||||
* - private: Hide the nick from NickServ's LIST command
|
||||
* - ns_private: Hide the nick from NickServ's LIST command
|
||||
* - hide_email: Hide's the nick's e-mail address from NickServ's INFO command
|
||||
* - hide_mask: Hide's the nick's last or current user@host from NickServ's INFO command
|
||||
* - hide_quit: Hide's the nick's last quit message
|
||||
@@ -106,10 +106,10 @@ module
|
||||
* - msg: Services messages will be sent as PRIVMSGs instead of NOTICEs, requires
|
||||
* options:useprivmsg to be enabled as well
|
||||
*
|
||||
* This directive is optional, if left blank, the options will default to secure, memo_signon, and
|
||||
* This directive is optional, if left blank, the options will default to ns_secure, memo_signon, and
|
||||
* memo_receive. If you really want no defaults, use "none" by itself as the option.
|
||||
*/
|
||||
defaults = "secure private hide_email hide_mask memo_signon memo_receive autoop"
|
||||
defaults = "ns_secure ns_private hide_email hide_mask memo_signon memo_receive autoop"
|
||||
|
||||
/*
|
||||
* The minimum length of time between consecutive uses of NickServ's REGISTER command. This
|
||||
@@ -124,14 +124,6 @@ module
|
||||
*/
|
||||
expire = 21d
|
||||
|
||||
/*
|
||||
* The length of time a user using an unconfirmed account has
|
||||
* before the account will be released for general use again.
|
||||
*
|
||||
* This directive is only required if the e-mail registration option is enabled.
|
||||
*/
|
||||
#unconfirmedexpire = 1d
|
||||
|
||||
/*
|
||||
* Prevents the use of the ACCESS (excluding the LIST subcommand), DROP, FORBID, SUSPEND,
|
||||
* GETPASS and SET PASSWORD commands by services operators on other services operators.
|
||||
@@ -350,19 +342,24 @@ command { service = "NickServ"; name = "IDENTIFY"; command = "nickserv/identify"
|
||||
/*
|
||||
* ns_info
|
||||
*
|
||||
* Provides the command nickserv/info.
|
||||
* Provides the commands:
|
||||
* nickserv/info. - Used for gathering information about an account.
|
||||
* nickserv/set/hide, nickserv/saset/hide - Used for configuring which options are publically shown in nickserv/info.
|
||||
*
|
||||
* Used for gathering information about an account.
|
||||
*/
|
||||
module { name = "ns_info" }
|
||||
command { service = "NickServ"; name = "INFO"; command = "nickserv/info"; }
|
||||
|
||||
command { service = "NickServ"; name = "SET HIDE"; command = "nickserv/set/hide"; }
|
||||
command { service = "NickServ"; name = "SASET HIDE"; command = "nickserv/saset/hide"; permission = "nickserv/saset/hide"; }
|
||||
|
||||
/*
|
||||
* ns_list
|
||||
*
|
||||
* Provides the command nickserv/list.
|
||||
* Provides the commands:
|
||||
* nickserv/list - Used for retrieving and searching the registered account list.
|
||||
* nickserv/set/private, nickserv/saset/private - Used for configuring whether or a users account shows up in nickserv/list.
|
||||
*
|
||||
* Used for retrieving and searching the registered account list.
|
||||
*/
|
||||
module
|
||||
{
|
||||
@@ -375,6 +372,9 @@ module
|
||||
}
|
||||
command { service = "NickServ"; name = "LIST"; command = "nickserv/list"; group = "nickserv/admin"; }
|
||||
|
||||
command { service = "NickServ"; name = "SET PRIVATE"; command = "nickserv/set/private"; }
|
||||
command { service = "NickServ"; name = "SASET PRIVATE"; command = "nickserv/saset/private"; permission = "nickserv/saset/private"; }
|
||||
|
||||
/*
|
||||
* ns_logout
|
||||
*
|
||||
@@ -441,6 +441,12 @@ module
|
||||
* This directive is optional.
|
||||
*/
|
||||
#nickregdelay = 30s
|
||||
|
||||
/*
|
||||
* The length of time a user using an unconfirmed account has
|
||||
* before the account will be released for general use again.
|
||||
*/
|
||||
#unconfirmedexpire = 1d
|
||||
}
|
||||
|
||||
command { service = "NickServ"; name = "CONFIRM"; command = "nickserv/confirm"; }
|
||||
@@ -465,17 +471,12 @@ command { service = "NickServ"; name = "RESETPASS"; command = "nickserv/resetpas
|
||||
* nickserv/set/autoop, nickserv/saset/autoop - Determines whether or not modes are automatically set users when joining a channel.
|
||||
* nickserv/set/display, nickserv/saset/display - Used for setting a users display name.
|
||||
* nickserv/set/email, nickserv/saset/email - Used for setting a users email address.
|
||||
* nickserv/set/greet, nickserv/saset/greet - Used for changing a users greet message, which is displayed when they enter channels.
|
||||
* nicksrev/set/hide, nickserv/saset/hide - Used for configuring which options are publically shown in nickserv/info for users account.
|
||||
* nickserv/set/kill, nickserv/saset/kill - Used for configuring nickname protection.
|
||||
* nickserv/set/language, nickserv/saset/language - Used for configuring what language services use.
|
||||
* nickserv/set/message, nickserv/saset/message - Used to configure how services send messages to you.
|
||||
* nickserv/set/password, nickserv/saset/password - Used for changing a users greet password.
|
||||
* nickserv/set/private, nickserv/saset/private - Used for configuring whether or a users account shows up in nickserv/list.
|
||||
* nickserv/set/password, nickserv/saset/password - Used for changing a users password.
|
||||
* nickserv/set/secure, nickserv/saset/secure - Used for configuring whether a user can identify by simply being recognized by nickserv/access.
|
||||
* nickserv/saset/noexpire - Used for configuring noexpire, which prevents nicks from expiring.
|
||||
*
|
||||
* This is a dummy command to provide a help wrapper for the various SET and SASET commands.
|
||||
*/
|
||||
module
|
||||
{
|
||||
@@ -502,12 +503,6 @@ command { service = "NickServ"; name = "SASET DISPLAY"; command = "nickserv/sase
|
||||
command { service = "NickServ"; name = "SET EMAIL"; command = "nickserv/set/email"; }
|
||||
command { service = "NickServ"; name = "SASET EMAIL"; command = "nickserv/saset/email"; permission = "nickserv/saset/email"; }
|
||||
|
||||
command { service = "NickServ"; name = "SET GREET"; command = "nickserv/set/greet"; }
|
||||
command { service = "NickServ"; name = "SASET GREET"; command = "nickserv/saset/greet"; permission = "nickserv/saset/greet"; }
|
||||
|
||||
command { service = "NickServ"; name = "SET HIDE"; command = "nickserv/set/hide"; }
|
||||
command { service = "NickServ"; name = "SASET HIDE"; command = "nickserv/saset/hide"; permission = "nickserv/saset/hide"; }
|
||||
|
||||
command { service = "NickServ"; name = "SET KILL"; command = "nickserv/set/kill"; }
|
||||
command { service = "NickServ"; name = "SASET KILL"; command = "nickserv/saset/kill"; permission = "nickserv/saset/kill"; }
|
||||
|
||||
@@ -520,9 +515,6 @@ command { service = "NickServ"; name = "SASET MESSAGE"; command = "nickserv/sase
|
||||
command { service = "NickServ"; name = "SET PASSWORD"; command = "nickserv/set/password"; }
|
||||
command { service = "NickServ"; name = "SASET PASSWORD"; command = "nickserv/saset/password"; permission = "nickserv/saset/password"; }
|
||||
|
||||
command { service = "NickServ"; name = "SET PRIVATE"; command = "nickserv/set/private"; }
|
||||
command { service = "NickServ"; name = "SASET PRIVATE"; command = "nickserv/saset/private"; permission = "nickserv/saset/private"; }
|
||||
|
||||
command { service = "NickServ"; name = "SET SECURE"; command = "nickserv/set/secure"; }
|
||||
command { service = "NickServ"; name = "SASET SECURE"; command = "nickserv/saset/secure"; permission = "nickserv/saset/secure"; }
|
||||
|
||||
|
||||
@@ -27,15 +27,6 @@ extern CoreExport Serialize::Checker<nickcore_map> NickCoreList;
|
||||
|
||||
/* A registered nickname.
|
||||
* It matters that Base is here before Extensible (it is inherited by Serializable)
|
||||
*
|
||||
* Possible flags:
|
||||
* NO_EXPIRE - Nick never expires
|
||||
* HELD - This nick is being held after a kill by an enforcer client
|
||||
* or is being SVSHeld.
|
||||
* COLLIDED - We are taking over this nick, either by SVSNICK or KILL
|
||||
* and are waiting for the confirmation of either of these actions to
|
||||
* proceed. This is checked in NickAlias::OnCancel
|
||||
*
|
||||
*/
|
||||
class CoreExport NickAlias : public Serializable, public Extensible
|
||||
{
|
||||
@@ -112,26 +103,6 @@ class CoreExport NickAlias : public Serializable, public Extensible
|
||||
/* A registered account. Each account must have a NickAlias with the same nick as the
|
||||
* account's display.
|
||||
* It matters that Base is here before Extensible (it is inherited by Serializable)
|
||||
*
|
||||
* Possible flags:
|
||||
* KILLPROTECT - Kill other users who try to take this nick
|
||||
* SECURE - Don't recognize unless identified
|
||||
* MSG - Use PRIVMSG instead of notice
|
||||
* MEMO_HARDMAX - Don't allow user to change memo limit
|
||||
* MEMO_SIGNON - Notify of memos at signon and unaway
|
||||
* MEMO_RECEIEVE - Notify of new memos when sent
|
||||
* PRIVATE - Don't show in LIST to non-servadmins
|
||||
* HIDE_EMAIL - Don't show email in INFO
|
||||
* HIDE_MASK - Don't show last seen address in INFO
|
||||
* HIDE_QUIT - Don't show last quit message in INFO
|
||||
* KILL_QUICK - Kill quicker
|
||||
* KILL_IMMED - Kill immediately
|
||||
* MEMO_MAIL - User gets email on memo
|
||||
* HIDE_STATUS - Don't show services access status
|
||||
* SUSPEND - Nickname is suspended
|
||||
* AUTOOP - Autoop nickname in channels
|
||||
* UNCONFIRMED - Account has not had email address confirmed
|
||||
* STATS - ChanStats is enabled for this user
|
||||
*/
|
||||
class CoreExport NickCore : public Serializable, public Extensible
|
||||
{
|
||||
@@ -143,15 +114,11 @@ class CoreExport NickCore : public Serializable, public Extensible
|
||||
/* User password in form of hashm:data */
|
||||
Anope::string pass;
|
||||
Anope::string email;
|
||||
/* Greet associated with the account, sometimes sent when the user joins a channel */
|
||||
Anope::string greet;
|
||||
/* Locale name of the language of the user. Empty means default language */
|
||||
Anope::string language;
|
||||
/* Access list, contains user@host masks of users who get certain privileges based
|
||||
* on if NI_SECURE is set and what (if any) kill protection is enabled. */
|
||||
std::vector<Anope::string> access;
|
||||
/* SSL certificate list. Users who have a matching certificate may be automatically logged in */
|
||||
std::vector<Anope::string> cert;
|
||||
MemoInfo memos;
|
||||
|
||||
/* Nicknames registered that are grouped to this account.
|
||||
@@ -242,46 +209,6 @@ class CoreExport NickCore : public Serializable, public Extensible
|
||||
*/
|
||||
bool IsOnAccess(const User *u) const;
|
||||
|
||||
/** 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) const;
|
||||
|
||||
/** 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();
|
||||
|
||||
/** Finds an account
|
||||
* @param nick The account name to find
|
||||
* @return The account, if it exists
|
||||
|
||||
@@ -48,6 +48,8 @@ class CoreExport Channel : public Base, public Extensible
|
||||
time_t creation_time;
|
||||
/* If the channel has just been created in a netjoin */
|
||||
bool syncing;
|
||||
/* Is configured in the conf as a channel bots should be in */
|
||||
bool botchannel;
|
||||
|
||||
/* Users in the channel */
|
||||
typedef std::map<User *, ChanUserContainer *> ChanUserList;
|
||||
|
||||
@@ -32,7 +32,6 @@ class InfoFormatter;
|
||||
class IRCDProto;
|
||||
class ListenSocket;
|
||||
class Log;
|
||||
class LogInfo;
|
||||
class Memo;
|
||||
class MessageSource;
|
||||
class Module;
|
||||
|
||||
+213
-80
@@ -12,109 +12,242 @@
|
||||
|
||||
#include "anope.h"
|
||||
#include "serialize.h"
|
||||
#include "service.h"
|
||||
#include "logger.h"
|
||||
|
||||
/* All items added to Extensible must inherit from this.
|
||||
*/
|
||||
class CoreExport ExtensibleItem
|
||||
class Extensible;
|
||||
|
||||
class CoreExport ExtensibleBase : public Service
|
||||
{
|
||||
protected:
|
||||
std::map<Extensible *, void *> items;
|
||||
|
||||
ExtensibleBase(Module *m, const Anope::string &n);
|
||||
~ExtensibleBase();
|
||||
|
||||
public:
|
||||
virtual ~ExtensibleItem() { }
|
||||
virtual void Unset(Extensible *obj) = 0;
|
||||
|
||||
virtual const Anope::string *Serialize() { return NULL; }
|
||||
/* called when an object we are keep track of is serializing */
|
||||
virtual void ExtensibleSerialize(const Extensible *, const Serializable *, Serialize::Data &) const { }
|
||||
virtual void ExtensibleUnserialize(Extensible *, Serializable *, Serialize::Data &) { }
|
||||
};
|
||||
|
||||
/** Common class used to Extensible::Extend as it inherits from both ExtensibleItem
|
||||
* and whatever basic object you're trying to store.
|
||||
* Eg, obj->Extend(key, new ExtensibleItemClass<Anope::string>(value));
|
||||
*/
|
||||
template<typename T> struct CoreExport ExtensibleItemClass : T, ExtensibleItem
|
||||
{
|
||||
ExtensibleItemClass(const T& t) : T(t) { }
|
||||
};
|
||||
|
||||
/* Used to attach metadata to this object that is automatically saved
|
||||
* when the object is saved (assuming the object's Serialize method
|
||||
* correcly calls Extensible::ExtensibleSerialize).
|
||||
*/
|
||||
struct CoreExport ExtensibleMetadata : ExtensibleItemClass<Anope::string>
|
||||
{
|
||||
ExtensibleMetadata(const Anope::string &t) : ExtensibleItemClass<Anope::string>(t) { }
|
||||
|
||||
const Anope::string *Serialize() anope_override { return this; }
|
||||
};
|
||||
|
||||
/* Used to attach arbitrary objects to this object using unique keys */
|
||||
class CoreExport Extensible
|
||||
{
|
||||
private:
|
||||
typedef std::map<Anope::string, ExtensibleItem *> extensible_map;
|
||||
extensible_map *extension_items;
|
||||
|
||||
public:
|
||||
/** Default constructor
|
||||
*/
|
||||
Extensible();
|
||||
std::set<ExtensibleBase *> extension_items;
|
||||
|
||||
/** Destructor, deletes all of the extensible items in this object
|
||||
* then clears the map
|
||||
*/
|
||||
virtual ~Extensible();
|
||||
|
||||
/** Extend an Extensible class.
|
||||
*
|
||||
* @param key The key parameter is an arbitary string which identifies the extension data
|
||||
* @param p This parameter is a pointer to an ExtensibleItem or ExtensibleItemBase derived class
|
||||
*
|
||||
* You must provide a key to store the data as via the parameter 'key'.
|
||||
* The data will be inserted into the map. If the data already exists, it will be overwritten.
|
||||
*/
|
||||
void Extend(const Anope::string &key, ExtensibleItem *p = NULL);
|
||||
template<typename T> T* GetExt(const Anope::string &name) const;
|
||||
bool HasExt(const Anope::string &name) const;
|
||||
|
||||
void ExtendMetadata(const Anope::string &key, const Anope::string &value = "");
|
||||
template<typename T> T* Extend(const Anope::string &name, const T &what);
|
||||
template<typename T> T* Extend(const Anope::string &name);
|
||||
template<typename T> T* Require(const Anope::string &name);
|
||||
template<typename T> void Shrink(const Anope::string &name);
|
||||
|
||||
/** Shrink an Extensible class.
|
||||
*
|
||||
* @param key The key parameter is an arbitary string which identifies the extension data
|
||||
*
|
||||
* You must provide a key name. The given key name will be removed from the classes data. If
|
||||
* you provide a nonexistent key (case is important) then the function will return false.
|
||||
* @return Returns true on success.
|
||||
*/
|
||||
bool Shrink(const Anope::string &key);
|
||||
static void ExtensibleSerialize(const Extensible *, const Serializable *, Serialize::Data &data);
|
||||
static void ExtensibleUnserialize(Extensible *, Serializable *, Serialize::Data &data);
|
||||
};
|
||||
|
||||
/** Get an extension item.
|
||||
*
|
||||
* @param key The key parameter is an arbitary string which identifies the extension data
|
||||
* @return The item found
|
||||
*/
|
||||
template<typename T> T GetExt(const Anope::string &key) const
|
||||
template<typename T>
|
||||
class BaseExtensibleItem : public ExtensibleBase
|
||||
{
|
||||
protected:
|
||||
virtual T *Create(Extensible *) = 0;
|
||||
|
||||
public:
|
||||
BaseExtensibleItem(Module *m, const Anope::string &n) : ExtensibleBase(m, n) { }
|
||||
|
||||
~BaseExtensibleItem()
|
||||
{
|
||||
if (this->extension_items)
|
||||
for (std::map<Extensible *, void *>::iterator it = items.begin(); it != items.end(); ++it)
|
||||
{
|
||||
extensible_map::const_iterator it = this->extension_items->find(key);
|
||||
if (it != this->extension_items->end())
|
||||
return anope_dynamic_static_cast<T>(it->second);
|
||||
}
|
||||
T *value = static_cast<T *>(it->second);
|
||||
|
||||
items.erase(it->first);
|
||||
it->first->extension_items.erase(this);
|
||||
delete value;
|
||||
}
|
||||
}
|
||||
|
||||
T* Set(Extensible *obj, const T &value)
|
||||
{
|
||||
T* t = Set(obj);
|
||||
*t = value;
|
||||
return t;
|
||||
}
|
||||
|
||||
T* Set(Extensible *obj)
|
||||
{
|
||||
T* t = Create(obj);
|
||||
Unset(obj);
|
||||
items[obj] = t;
|
||||
obj->extension_items.insert(this);
|
||||
return t;
|
||||
}
|
||||
|
||||
void Unset(Extensible *obj) anope_override
|
||||
{
|
||||
T *value = Get(obj);
|
||||
items.erase(obj);
|
||||
obj->extension_items.erase(this);
|
||||
delete value;
|
||||
}
|
||||
|
||||
T* Get(const Extensible *obj) const
|
||||
{
|
||||
std::map<Extensible *, void *>::const_iterator it = items.find(const_cast<Extensible *>(obj));
|
||||
if (it != items.end())
|
||||
return static_cast<T *>(it->second);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Check if an extension item exists.
|
||||
*
|
||||
* @param key The key parameter is an arbitary string which identifies the extension data
|
||||
* @return True if the item was found.
|
||||
*/
|
||||
bool HasExt(const Anope::string &key) const;
|
||||
bool HasExt(const Extensible *obj) const
|
||||
{
|
||||
return items.find(const_cast<Extensible *>(obj)) != items.end();
|
||||
}
|
||||
|
||||
/** Get a list of all extension items names.
|
||||
* @param list A deque of strings to receive the list
|
||||
* @return This function writes a list of all extension items stored
|
||||
* in this object by name into the given deque and returns void.
|
||||
*/
|
||||
void GetExtList(std::deque<Anope::string> &list) const;
|
||||
T* Require(Extensible *obj)
|
||||
{
|
||||
T* t = Get(obj);
|
||||
if (t)
|
||||
return t;
|
||||
|
||||
void ExtensibleSerialize(Serialize::Data &data) const;
|
||||
void ExtensibleUnserialize(Serialize::Data &data);
|
||||
return Set(obj);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class ExtensibleItem : public BaseExtensibleItem<T>
|
||||
{
|
||||
protected:
|
||||
T* Create(Extensible *obj) anope_override
|
||||
{
|
||||
return new T(obj);
|
||||
}
|
||||
public:
|
||||
ExtensibleItem(Module *m, const Anope::string &n) : BaseExtensibleItem<T>(m, n) { }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class PrimitiveExtensibleItem : public BaseExtensibleItem<T>
|
||||
{
|
||||
protected:
|
||||
T* Create(Extensible *obj) anope_override
|
||||
{
|
||||
return new T();
|
||||
}
|
||||
public:
|
||||
PrimitiveExtensibleItem(Module *m, const Anope::string &n) : BaseExtensibleItem<T>(m, n) { }
|
||||
};
|
||||
|
||||
template<>
|
||||
class PrimitiveExtensibleItem<bool> : public BaseExtensibleItem<bool>
|
||||
{
|
||||
protected:
|
||||
bool* Create(Extensible *) anope_override
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
public:
|
||||
PrimitiveExtensibleItem(Module *m, const Anope::string &n) : BaseExtensibleItem<bool>(m, n) { }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class SerializableExtensibleItem : public PrimitiveExtensibleItem<T>
|
||||
{
|
||||
public:
|
||||
SerializableExtensibleItem(Module *m, const Anope::string &n) : PrimitiveExtensibleItem<T>(m, n) { }
|
||||
|
||||
void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override
|
||||
{
|
||||
T* t = this->Get(e);
|
||||
data[this->name] << *t;
|
||||
}
|
||||
|
||||
void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override
|
||||
{
|
||||
T* t = this->Require(e);
|
||||
data[this->name] >> *t;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class SerializableExtensibleItem<bool> : public PrimitiveExtensibleItem<bool>
|
||||
{
|
||||
public:
|
||||
SerializableExtensibleItem(Module *m, const Anope::string &n) : PrimitiveExtensibleItem<bool>(m, n) { }
|
||||
|
||||
void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override
|
||||
{
|
||||
data[this->name] << true;
|
||||
}
|
||||
|
||||
void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override
|
||||
{
|
||||
bool b;
|
||||
data[this->name] >> b;
|
||||
if (b)
|
||||
this->Set(e);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ExtensibleRef : ServiceReference<BaseExtensibleItem<T> >
|
||||
{
|
||||
ExtensibleRef(const Anope::string &n) : ServiceReference<BaseExtensibleItem<T> >("Extensible", n) { }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
T* Extensible::GetExt(const Anope::string &name) const
|
||||
{
|
||||
ExtensibleRef<T> ref(name);
|
||||
if (ref)
|
||||
return ref->Get(this);
|
||||
|
||||
Log(LOG_DEBUG) << "GetExt for nonexistent type " << name << " on " << static_cast<const void *>(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* Extensible::Extend(const Anope::string &name, const T &what)
|
||||
{
|
||||
T* t = Extend<T>(name);
|
||||
*t = what;
|
||||
return t;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* Extensible::Extend(const Anope::string &name)
|
||||
{
|
||||
ExtensibleRef<T> ref(name);
|
||||
if (ref)
|
||||
return ref->Set(this);
|
||||
|
||||
Log(LOG_DEBUG) << "Extend for nonexistent type " << name << " on " << static_cast<void *>(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* Extensible::Require(const Anope::string &name)
|
||||
{
|
||||
if (HasExt(name))
|
||||
return GetExt<T>(name);
|
||||
else
|
||||
return Extend<T>(name);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Extensible::Shrink(const Anope::string &name)
|
||||
{
|
||||
ExtensibleRef<T> ref(name);
|
||||
if (ref)
|
||||
ref->Unset(this);
|
||||
else
|
||||
Log(LOG_DEBUG) << "Shrink for nonexistent type " << name << " on " << static_cast<void *>(this);
|
||||
}
|
||||
|
||||
#endif // EXTENSIBLE_H
|
||||
|
||||
@@ -87,6 +87,7 @@ class CoreExport InfoFormatter
|
||||
InfoFormatter(NickCore *nc);
|
||||
void Process(std::vector<Anope::string> &);
|
||||
Anope::string &operator[](const Anope::string &key);
|
||||
void AddOption(const Anope::string &opt);
|
||||
};
|
||||
|
||||
#endif // LISTS_H
|
||||
|
||||
+18
-5
@@ -626,9 +626,10 @@ class CoreExport Module : public Extensible
|
||||
virtual void OnLevelChange(CommandSource &source, ChannelInfo *ci, const Anope::string &priv, int16_t what) { throw NotImplementedException(); }
|
||||
|
||||
/** Called right before a channel is dropped
|
||||
* @param source The user dropping the channel
|
||||
* @param ci The channel
|
||||
*/
|
||||
virtual void OnChanDrop(ChannelInfo *ci) { throw NotImplementedException(); }
|
||||
virtual EventReturn OnChanDrop(CommandSource &source, ChannelInfo *ci) { throw NotImplementedException(); }
|
||||
|
||||
/** Called when a channel is registered
|
||||
* @param ci The channel
|
||||
@@ -823,6 +824,10 @@ class CoreExport Module : public Extensible
|
||||
*/
|
||||
virtual void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) { throw NotImplementedException(); }
|
||||
|
||||
/** Called when a user uses botserv/info on a bot or channel.
|
||||
*/
|
||||
virtual void OnBotInfo(CommandSource &source, BotInfo *bi, ChannelInfo *ci, InfoFormatter &info) { throw NotImplementedException(); }
|
||||
|
||||
/** Check whether a username and password is correct
|
||||
* @param u The user trying to identify, if applicable.
|
||||
* @param req The login request
|
||||
@@ -887,20 +892,20 @@ class CoreExport Module : public Extensible
|
||||
/** Called when a mode is set on a channel
|
||||
* @param c The channel
|
||||
* @param setter The user or server that is setting the mode
|
||||
* @param mname The mode name
|
||||
* @param mode The mode
|
||||
* @param param The mode param, if there is one
|
||||
* @return EVENT_STOP to make mlock/secureops etc checks not happen
|
||||
*/
|
||||
virtual EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, const Anope::string &mname, const Anope::string ¶m) { throw NotImplementedException(); }
|
||||
virtual EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) { throw NotImplementedException(); }
|
||||
|
||||
/** Called when a mode is unset on a channel
|
||||
* @param c The channel
|
||||
* @param setter The user or server that is unsetting the mode
|
||||
* @param mname The mode name
|
||||
* @param mode The mode
|
||||
* @param param The mode param, if there is one
|
||||
* @return EVENT_STOP to make mlock/secureops etc checks not happen
|
||||
*/
|
||||
virtual EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, const Anope::string &mname, const Anope::string ¶m) { throw NotImplementedException(); }
|
||||
virtual EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) { throw NotImplementedException(); }
|
||||
|
||||
/** Called when a mode is set on a user
|
||||
* @param u The user
|
||||
@@ -1053,6 +1058,14 @@ class CoreExport Module : public Extensible
|
||||
* channels, etc.
|
||||
*/
|
||||
virtual void OnExpireTick() { throw NotImplementedException(); }
|
||||
|
||||
/** Called when a nick is validated. That is, to determine if a user is permissted
|
||||
* to be on the given nick.
|
||||
* @param u The user
|
||||
* @param na The nick they are on
|
||||
* @return EVENT_STOP to force the user off of the nick
|
||||
*/
|
||||
virtual EventReturn OnNickValidate(User *u, NickAlias *na) { throw NotImplementedException(); }
|
||||
};
|
||||
|
||||
/** Used to manage modules.
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/* BotServ core functions
|
||||
*
|
||||
* (C) 2003-2013 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
*
|
||||
* Based on the original code of Epona by Lara.
|
||||
* Based on the original code of Services by Andy Church.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/** Flags for badwords
|
||||
*/
|
||||
enum BadWordType
|
||||
{
|
||||
/* Always kicks if the word is said */
|
||||
BW_ANY,
|
||||
/* User must way the entire word */
|
||||
BW_SINGLE,
|
||||
/* The word has to start with the badword */
|
||||
BW_START,
|
||||
/* The word has to end with the badword */
|
||||
BW_END
|
||||
};
|
||||
|
||||
/* Structure used to contain bad words. */
|
||||
struct BadWord
|
||||
{
|
||||
Anope::string chan;
|
||||
Anope::string word;
|
||||
BadWordType type;
|
||||
|
||||
protected:
|
||||
BadWord() { }
|
||||
};
|
||||
|
||||
struct BadWords
|
||||
{
|
||||
/** Add a badword to the badword list
|
||||
* @param word The badword
|
||||
* @param type The type (SINGLE START END)
|
||||
* @return The badword
|
||||
*/
|
||||
virtual BadWord* AddBadWord(const Anope::string &word, BadWordType type) = 0;
|
||||
|
||||
/** Get a badword structure by index
|
||||
* @param index The index
|
||||
* @return The badword
|
||||
*/
|
||||
virtual BadWord* GetBadWord(unsigned index) const = 0;
|
||||
|
||||
/** Get how many badwords are on this channel
|
||||
* @return The number of badwords in the vector
|
||||
*/
|
||||
virtual unsigned GetBadWordCount() const = 0;
|
||||
|
||||
/** Remove a badword
|
||||
* @param index The index of the badword
|
||||
*/
|
||||
virtual void EraseBadWord(unsigned index) = 0;
|
||||
|
||||
/** Clear all badwords from the channel
|
||||
*/
|
||||
virtual void ClearBadWords() = 0;
|
||||
|
||||
virtual void Check() = 0;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/* BotServ core functions
|
||||
*
|
||||
* (C) 2003-2013 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
*
|
||||
* Based on the original code of Epona by Lara.
|
||||
* Based on the original code of Services by Andy Church.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/* Indices for TTB (Times To Ban) */
|
||||
enum
|
||||
{
|
||||
TTB_BOLDS,
|
||||
TTB_COLORS,
|
||||
TTB_REVERSES,
|
||||
TTB_UNDERLINES,
|
||||
TTB_BADWORDS,
|
||||
TTB_CAPS,
|
||||
TTB_FLOOD,
|
||||
TTB_REPEAT,
|
||||
TTB_ITALICS,
|
||||
TTB_AMSGS,
|
||||
TTB_SIZE
|
||||
};
|
||||
|
||||
struct KickerData
|
||||
{
|
||||
bool amsgs, badwords, bolds, caps, colors, flood, italics, repeat, reverses, underlines;
|
||||
int16_t ttb[TTB_SIZE]; /* Times to ban for each kicker */
|
||||
int16_t capsmin, capspercent; /* For CAPS kicker */
|
||||
int16_t floodlines, floodsecs; /* For FLOOD kicker */
|
||||
int16_t repeattimes; /* For REPEAT kicker */
|
||||
|
||||
bool dontkickops, dontkickvoices;
|
||||
|
||||
protected:
|
||||
KickerData() { }
|
||||
|
||||
public:
|
||||
virtual void Check(ChannelInfo *ci) = 0;
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2013 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
*
|
||||
* Based on the original code of Epona by Lara.
|
||||
* Based on the original code of Services by Andy Church.
|
||||
*/
|
||||
|
||||
struct LogSetting
|
||||
{
|
||||
Anope::string chan;
|
||||
/* Our service name of the command */
|
||||
Anope::string service_name;
|
||||
/* The name of the client the command is on */
|
||||
Anope::string command_service;
|
||||
/* Name of the command to the user, can have spaces */
|
||||
Anope::string command_name;
|
||||
Anope::string method, extra;
|
||||
Anope::string creator;
|
||||
time_t created;
|
||||
|
||||
protected:
|
||||
LogSetting() { }
|
||||
};
|
||||
|
||||
struct LogSettings : Serialize::Checker<std::vector<LogSetting *> >
|
||||
{
|
||||
typedef std::vector<LogSetting *>::iterator iterator;
|
||||
|
||||
protected:
|
||||
LogSettings() : Serialize::Checker<std::vector<LogSetting *> >("LogSetting")
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual LogSetting *Create() = 0;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2013 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
*
|
||||
* Based on the original code of Epona by Lara.
|
||||
* Based on the original code of Services by Andy Church.
|
||||
*/
|
||||
|
||||
struct ModeLock
|
||||
{
|
||||
Anope::string ci;
|
||||
bool set;
|
||||
Anope::string name;
|
||||
Anope::string param;
|
||||
Anope::string setter;
|
||||
time_t created;
|
||||
|
||||
protected:
|
||||
ModeLock() { }
|
||||
};
|
||||
|
||||
struct ModeLocks
|
||||
{
|
||||
typedef std::vector<ModeLock *> ModeList;
|
||||
|
||||
/** Check if a mode is mlocked
|
||||
* @param mode The mode
|
||||
* @param An optional param
|
||||
* @param status True to check mlock on, false for mlock off
|
||||
* @return true on success, false on fail
|
||||
*/
|
||||
virtual bool HasMLock(ChannelMode *mode, const Anope::string ¶m, bool status) const = 0;
|
||||
|
||||
/** Set a mlock
|
||||
* @param mode The mode
|
||||
* @param status True for mlock on, false for mlock off
|
||||
* @param param An optional param arg for + mlocked modes
|
||||
* @param setter Who is setting the mlock
|
||||
* @param created When the mlock was created
|
||||
* @return true on success, false on failure (module blocking)
|
||||
*/
|
||||
virtual bool SetMLock(ChannelMode *mode, bool status, const Anope::string ¶m = "", Anope::string setter = "", time_t created = Anope::CurTime) = 0;
|
||||
|
||||
/** Remove a mlock
|
||||
* @param mode The mode
|
||||
* @param status True for mlock on, false for mlock off
|
||||
* @param param The param of the mode, required if it is a list or status mode
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
virtual bool RemoveMLock(ChannelMode *mode, bool status, const Anope::string ¶m = "") = 0;
|
||||
|
||||
virtual void RemoveMLock(ModeLock *mlock) = 0;
|
||||
|
||||
/** Clear all mlocks on the channel
|
||||
*/
|
||||
virtual void ClearMLock() = 0;
|
||||
|
||||
/** Get all of the mlocks for this channel
|
||||
* @return The mlocks
|
||||
*/
|
||||
virtual const ModeList &GetMLock() const = 0;
|
||||
|
||||
/** Get a list of mode locks on a channel
|
||||
* @param name The mode name to get a list of
|
||||
* @return a list of mlocks for the given mode
|
||||
*/
|
||||
virtual std::list<ModeLock *> GetModeLockList(const Anope::string &name) = 0;
|
||||
|
||||
/** Get details for a specific mlock
|
||||
* @param mname The mode name
|
||||
* @param An optional param to match with
|
||||
* @return The MLock, if any
|
||||
*/
|
||||
virtual const ModeLock *GetMLock(const Anope::string &mname, const Anope::string ¶m = "") = 0;
|
||||
|
||||
/** Get the current mode locks as a string
|
||||
* @param complete True to show mlock parameters aswell
|
||||
* @return A string of mode locks, eg: +nrt
|
||||
*/
|
||||
virtual Anope::string GetMLockAsString(bool complete) const = 0;
|
||||
|
||||
virtual void Check() = 0;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2013 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
*
|
||||
* Based on the original code of Epona by Lara.
|
||||
* Based on the original code of Services by Andy Church.
|
||||
*/
|
||||
|
||||
struct CSSuspendInfo
|
||||
{
|
||||
Anope::string chan, by, reason;
|
||||
time_t time, expires;
|
||||
|
||||
protected:
|
||||
CSSuspendInfo() { }
|
||||
};
|
||||
@@ -0,0 +1,61 @@
|
||||
/* NickServ core functions
|
||||
*
|
||||
* (C) 2003-2013 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
*
|
||||
* Based on the original code of Epona by Lara.
|
||||
* Based on the original code of Services by Andy Church.
|
||||
*/
|
||||
|
||||
struct NSCertList
|
||||
{
|
||||
protected:
|
||||
NSCertList() { }
|
||||
public:
|
||||
|
||||
/** Add an entry to the nick's certificate list
|
||||
*
|
||||
* @param entry The fingerprint to add to the cert list
|
||||
*
|
||||
* Adds a new entry into the cert list.
|
||||
*/
|
||||
virtual void AddCert(const Anope::string &entry) = 0;
|
||||
|
||||
/** Get an entry from the nick's cert list by index
|
||||
*
|
||||
* @param entry Index in the certificaate list vector to retrieve
|
||||
* @return The fingerprint entry of the given index if within bounds, an empty string if the vector is empty or the index is out of bounds
|
||||
*
|
||||
* Retrieves an entry from the certificate list corresponding to the given index.
|
||||
*/
|
||||
virtual Anope::string GetCert(unsigned entry) const = 0;
|
||||
|
||||
virtual unsigned GetCertCount() const = 0;
|
||||
|
||||
/** Find an entry in the nick's cert list
|
||||
*
|
||||
* @param entry The fingerprint to search for
|
||||
* @return True if the fingerprint is found in the cert list, false otherwise
|
||||
*
|
||||
* Search for an fingerprint within the cert list.
|
||||
*/
|
||||
virtual bool FindCert(const Anope::string &entry) const = 0;
|
||||
|
||||
/** Erase a fingerprint from the nick's certificate list
|
||||
*
|
||||
* @param entry The fingerprint to remove
|
||||
*
|
||||
* Removes the specified fingerprint from the cert list.
|
||||
*/
|
||||
virtual void EraseCert(const Anope::string &entry) = 0;
|
||||
|
||||
/** Clears the entire nick's cert list
|
||||
*
|
||||
* Deletes all the memory allocated in the certificate list vector and then clears the vector.
|
||||
*/
|
||||
virtual void ClearCert() = 0;
|
||||
|
||||
virtual void Check() = 0;
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
/* NickServ core functions
|
||||
*
|
||||
* (C) 2003-2013 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
*
|
||||
* Based on the original code of Epona by Lara.
|
||||
* Based on the original code of Services by Andy Church.
|
||||
*/
|
||||
|
||||
struct NSSuspendInfo
|
||||
{
|
||||
Anope::string nick, by, reason;
|
||||
time_t when, expires;
|
||||
|
||||
protected:
|
||||
NSSuspendInfo() { }
|
||||
};
|
||||
+1
-205
@@ -22,49 +22,6 @@ typedef Anope::hash_map<ChannelInfo *> registered_channel_map;
|
||||
|
||||
extern CoreExport Serialize::Checker<registered_channel_map> RegisteredChannelList;
|
||||
|
||||
/* Indices for TTB (Times To Ban) */
|
||||
enum
|
||||
{
|
||||
TTB_BOLDS,
|
||||
TTB_COLORS,
|
||||
TTB_REVERSES,
|
||||
TTB_UNDERLINES,
|
||||
TTB_BADWORDS,
|
||||
TTB_CAPS,
|
||||
TTB_FLOOD,
|
||||
TTB_REPEAT,
|
||||
TTB_ITALICS,
|
||||
TTB_AMSGS,
|
||||
TTB_SIZE
|
||||
};
|
||||
|
||||
/** Flags for badwords
|
||||
*/
|
||||
enum BadWordType
|
||||
{
|
||||
/* Always kicks if the word is said */
|
||||
BW_ANY,
|
||||
/* User must way the entire word */
|
||||
BW_SINGLE,
|
||||
/* The word has to start with the badword */
|
||||
BW_START,
|
||||
/* The word has to end with the badword */
|
||||
BW_END
|
||||
};
|
||||
|
||||
/* Structure used to contain bad words. */
|
||||
struct CoreExport BadWord : Serializable
|
||||
{
|
||||
Serialize::Reference<ChannelInfo> ci;
|
||||
Anope::string word;
|
||||
BadWordType type;
|
||||
|
||||
BadWord();
|
||||
~BadWord();
|
||||
void Serialize(Serialize::Data &data) const anope_override;
|
||||
static Serializable* Unserialize(Serializable *obj, Serialize::Data &);
|
||||
};
|
||||
|
||||
/* AutoKick data. */
|
||||
class CoreExport AutoKick : public Serializable
|
||||
{
|
||||
@@ -86,74 +43,7 @@ class CoreExport AutoKick : public Serializable
|
||||
static Serializable* Unserialize(Serializable *obj, Serialize::Data &);
|
||||
};
|
||||
|
||||
struct CoreExport ModeLock : Serializable
|
||||
{
|
||||
public:
|
||||
Serialize::Reference<ChannelInfo> ci;
|
||||
bool set;
|
||||
Anope::string name;
|
||||
Anope::string param;
|
||||
Anope::string setter;
|
||||
time_t created;
|
||||
|
||||
ModeLock(ChannelInfo *ch, bool s, const Anope::string &n, const Anope::string &p, const Anope::string &se = "", time_t c = Anope::CurTime);
|
||||
~ModeLock();
|
||||
|
||||
void Serialize(Serialize::Data &data) const anope_override;
|
||||
static Serializable* Unserialize(Serializable *obj, Serialize::Data &);
|
||||
};
|
||||
|
||||
struct CoreExport LogSetting : Serializable
|
||||
{
|
||||
Serialize::Reference<ChannelInfo> ci;
|
||||
/* Our service name of the command */
|
||||
Anope::string service_name;
|
||||
/* The name of the client the command is on */
|
||||
Anope::string command_service;
|
||||
/* Name of the command to the user, can have spaces */
|
||||
Anope::string command_name;
|
||||
Anope::string method, extra;
|
||||
Anope::string creator;
|
||||
time_t created;
|
||||
|
||||
LogSetting() : Serializable("LogSetting") { }
|
||||
void Serialize(Serialize::Data &data) const anope_override;
|
||||
static Serializable* Unserialize(Serializable *obj, Serialize::Data &);
|
||||
};
|
||||
|
||||
/* It matters that Base is here before Extensible (it is inherited by Serializable)
|
||||
*
|
||||
* Possible flags:
|
||||
* TOPICLOCK - Topic can only be changed by TOPIC SET
|
||||
* RESTRICTED - Only users on the access list may join
|
||||
* PEACE - Don't allow ChanServ and BotServ commands to do bad things to users with higher access levels
|
||||
* SECURE - Don't allow any privileges
|
||||
* NO_EXPIRE - Channel does not expire
|
||||
* MEMO_HARDMAX - Channel memo limit may not be changed
|
||||
* SECUREFOUNDER - Stricter control of channel founder status
|
||||
* SIGNKICK - Sign kicks with the user who did the kick
|
||||
* SIGNKICK_LEVEL - Sign kicks if level is < than the one defined by the SIGNKICK level
|
||||
* SUSPENDED - Channel is suepended
|
||||
* PERSIST - Channel still exists when empited (perm channel mode or leaving a botserv bot).
|
||||
* STATS - Chanstats are enabled
|
||||
* NOAUTOOP - If set users are not auto given any status on join
|
||||
*
|
||||
* BotServ flags:
|
||||
* BS_DONTKICKOPS - BotServ won't kick ops
|
||||
* BS_DONTKICKVOICES - BotServ won't kick voices
|
||||
* BS_FANTASY - BotServ bot accepts fantasy commands
|
||||
* BS_GREET - BotServ should show greets
|
||||
* BS_NOBOT - BotServ bots are not allowed to be in this channel
|
||||
* BS_KICK_BOLDS - BotServ kicks for bolds
|
||||
* BS_KICK_COLORS - BotServ kicks for colors
|
||||
* BS_KICK_REVERSES - BotServ kicks for reverses
|
||||
* BS_KICK_UNDERLINES - BotServ kicks for underlines
|
||||
* BS_KICK_BADWORD - BotServ kicks for badwords
|
||||
* BS_KICK_CAPS - BotServ kicks for caps
|
||||
* BS_KICK_FLOOD - BotServ kicks for flood
|
||||
* BS_KICK_REPEAT - BotServ kicks for repeating
|
||||
* BS_KICK_ITALICS - BotServ kicks for italics
|
||||
* BS_KICK_AMSGS - BotServ kicks for amsgs
|
||||
*/
|
||||
class CoreExport ChannelInfo : public Serializable, public Extensible
|
||||
{
|
||||
@@ -162,17 +52,11 @@ class CoreExport ChannelInfo : public Serializable, public Extensible
|
||||
Serialize::Reference<NickCore> successor; /* Who gets the channel if the founder nick is dropped or expires */
|
||||
Serialize::Checker<std::vector<ChanAccess *> > access; /* List of authorized users */
|
||||
Serialize::Checker<std::vector<AutoKick *> > akick; /* List of users to kickban */
|
||||
Serialize::Checker<std::vector<BadWord *> > badwords; /* List of badwords */
|
||||
Anope::map<int16_t> levels;
|
||||
|
||||
public:
|
||||
friend class ChanAccess;
|
||||
friend class AutoKick;
|
||||
friend struct BadWord;
|
||||
|
||||
typedef std::multimap<Anope::string, ModeLock *> ModeList;
|
||||
Serialize::Checker<ModeList> mode_locks;
|
||||
Serialize::Checker<std::vector<LogSetting *> > log_settings;
|
||||
|
||||
Anope::string name; /* Channel name */
|
||||
Anope::string desc;
|
||||
@@ -192,11 +76,6 @@ class CoreExport ChannelInfo : public Serializable, public Extensible
|
||||
|
||||
/* For BotServ */
|
||||
Serialize::Reference<BotInfo> bi; /* Bot used on this channel */
|
||||
int16_t ttb[TTB_SIZE]; /* Times to ban for each kicker */
|
||||
|
||||
int16_t capsmin, capspercent; /* For CAPS kicker */
|
||||
int16_t floodlines, floodsecs; /* For FLOOD kicker */
|
||||
int16_t repeattimes; /* For REPEAT kicker */
|
||||
|
||||
time_t banexpire; /* Time bans expire in */
|
||||
|
||||
@@ -206,7 +85,7 @@ class CoreExport ChannelInfo : public Serializable, public Extensible
|
||||
ChannelInfo(const Anope::string &chname);
|
||||
|
||||
/** Copy constructor
|
||||
* @param ci The ChannelInfo to copy settings to
|
||||
* @param ci The ChannelInfo to copy settings from
|
||||
*/
|
||||
ChannelInfo(const ChannelInfo &ci);
|
||||
|
||||
@@ -310,89 +189,6 @@ class CoreExport ChannelInfo : public Serializable, public Extensible
|
||||
*/
|
||||
void ClearAkick();
|
||||
|
||||
/** Add a badword to the badword list
|
||||
* @param word The badword
|
||||
* @param type The type (SINGLE START END)
|
||||
* @return The badword
|
||||
*/
|
||||
BadWord* AddBadWord(const Anope::string &word, BadWordType type);
|
||||
|
||||
/** Get a badword structure by index
|
||||
* @param index The index
|
||||
* @return The badword
|
||||
*/
|
||||
BadWord* GetBadWord(unsigned index) const;
|
||||
|
||||
/** Get how many badwords are on this channel
|
||||
* @return The number of badwords in the vector
|
||||
*/
|
||||
unsigned GetBadWordCount() const;
|
||||
|
||||
/** Remove a badword
|
||||
* @param index The index of the badword
|
||||
*/
|
||||
void EraseBadWord(unsigned index);
|
||||
|
||||
/** Clear all badwords from the channel
|
||||
*/
|
||||
void ClearBadWords();
|
||||
|
||||
/** Check if a mode is mlocked
|
||||
* @param mode The mode
|
||||
* @param An optional param
|
||||
* @param status True to check mlock on, false for mlock off
|
||||
* @return true on success, false on fail
|
||||
*/
|
||||
bool HasMLock(ChannelMode *mode, const Anope::string ¶m, bool status) const;
|
||||
|
||||
/** Set a mlock
|
||||
* @param mode The mode
|
||||
* @param status True for mlock on, false for mlock off
|
||||
* @param param An optional param arg for + mlocked modes
|
||||
* @param setter Who is setting the mlock
|
||||
* @param created When the mlock was created
|
||||
* @return true on success, false on failure (module blocking)
|
||||
*/
|
||||
bool SetMLock(ChannelMode *mode, bool status, const Anope::string ¶m = "", Anope::string setter = "", time_t created = Anope::CurTime);
|
||||
|
||||
/** Remove a mlock
|
||||
* @param mode The mode
|
||||
* @param status True for mlock on, false for mlock off
|
||||
* @param param The param of the mode, required if it is a list or status mode
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
bool RemoveMLock(ChannelMode *mode, bool status, const Anope::string ¶m = "");
|
||||
|
||||
void RemoveMLock(ModeLock *mlock);
|
||||
|
||||
/** Clear all mlocks on the channel
|
||||
*/
|
||||
void ClearMLock();
|
||||
|
||||
/** Get all of the mlocks for this channel
|
||||
* @return The mlocks
|
||||
*/
|
||||
const ModeList &GetMLock() const;
|
||||
|
||||
/** 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
|
||||
*/
|
||||
std::pair<ModeList::iterator, ModeList::iterator> GetModeList(const Anope::string &name);
|
||||
|
||||
/** Get details for a specific mlock
|
||||
* @param mname The mode name
|
||||
* @param An optional param to match with
|
||||
* @return The MLock, if any
|
||||
*/
|
||||
const ModeLock *GetMLock(const Anope::string &mname, const Anope::string ¶m = "");
|
||||
|
||||
/** Get the current mode locks as a string
|
||||
* @param complete True to show mlock parameters aswell
|
||||
* @return A string of mode locks, eg: +nrt
|
||||
*/
|
||||
Anope::string GetMLockAsString(bool complete) const;
|
||||
|
||||
/** Get the level for a privilege
|
||||
* @param priv The privilege name
|
||||
* @return the level
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
|
||||
#include "services.h"
|
||||
#include "anope.h"
|
||||
#include "modules.h"
|
||||
#include "base.h"
|
||||
|
||||
/** Anything that inherits from this class can be referred to
|
||||
* using ServiceReference. Any interfaces provided by modules,
|
||||
|
||||
@@ -145,14 +145,69 @@ class CommandBSUnassign : public Command
|
||||
}
|
||||
};
|
||||
|
||||
class CommandBSSetNoBot : public Command
|
||||
{
|
||||
public:
|
||||
CommandBSSetNoBot(Module *creator, const Anope::string &sname = "botserv/set/nobot") : Command(creator, sname, 2, 2)
|
||||
{
|
||||
this->SetDesc(_("Prevent a bot from being assigned to a channel"));
|
||||
this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
ChannelInfo *ci = ChannelInfo::Find(params[0]);
|
||||
const Anope::string &value = params[1];
|
||||
|
||||
if (ci == NULL)
|
||||
{
|
||||
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.equals_ci("ON"))
|
||||
{
|
||||
Log(LOG_ADMIN, source, this, ci) << "to enable nobot";
|
||||
|
||||
ci->Extend<bool>("BS_NOBOT");
|
||||
if (ci->bi)
|
||||
ci->bi->UnAssign(source.GetUser(), ci);
|
||||
source.Reply(_("No-bot mode is now \002on\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else if (value.equals_ci("OFF"))
|
||||
{
|
||||
Log(LOG_ADMIN, source, this, ci) << "to disable nobot";
|
||||
|
||||
ci->Shrink<bool>("BS_NOBOT");
|
||||
source.Reply(_("No-bot mode is now \002off\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, source.command);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(_(" \n"
|
||||
"This option makes a channel be unassignable. If a bot\n"
|
||||
"is already assigned to the channel, it is unassigned\n"
|
||||
"automatically when you enable the option."));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class BSAssign : public Module
|
||||
{
|
||||
ExtensibleItem<bool> nobot;
|
||||
|
||||
CommandBSAssign commandbsassign;
|
||||
CommandBSUnassign commandbsunassign;
|
||||
CommandBSSetNoBot commandbssetnobot;
|
||||
|
||||
public:
|
||||
BSAssign(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
commandbsassign(this), commandbsunassign(this)
|
||||
nobot(this, "BS_NOBOT"),
|
||||
commandbsassign(this), commandbsunassign(this), commandbssetnobot(this)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -163,7 +218,7 @@ class BSAssign : public Module
|
||||
return;
|
||||
|
||||
AccessGroup access = c->ci->AccessFor(source);
|
||||
if (c->ci->HasExt("BS_NOBOT") || (!access.HasPriv("ASSIGN") && !source->HasPriv("botserv/administration")))
|
||||
if (nobot.HasExt(c->ci) || (!access.HasPriv("ASSIGN") && !source->HasPriv("botserv/administration")))
|
||||
{
|
||||
targ->SendMessage(bi, ACCESS_DENIED);
|
||||
return;
|
||||
@@ -184,6 +239,12 @@ class BSAssign : public Module
|
||||
bi->Assign(source, c->ci);
|
||||
targ->SendMessage(bi, _("Bot \002%s\002 has been assigned to %s."), bi->nick.c_str(), c->name.c_str());
|
||||
}
|
||||
|
||||
void OnBotInfo(CommandSource &source, BotInfo *bi, ChannelInfo *ci, InfoFormatter &info) anope_override
|
||||
{
|
||||
if (nobot.HasExt(ci))
|
||||
info.AddOption(_("No bot"));
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_INIT(BSAssign)
|
||||
|
||||
@@ -10,11 +10,132 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/bs_badwords.h"
|
||||
|
||||
struct BadWordImpl : BadWord, Serializable
|
||||
{
|
||||
BadWordImpl() : Serializable("BadWord") { }
|
||||
~BadWordImpl();
|
||||
|
||||
void Serialize(Serialize::Data &data) const anope_override
|
||||
{
|
||||
data["ci"] << this->chan;
|
||||
data["word"] << this->word;
|
||||
data.SetType("type", Serialize::Data::DT_INT); data["type"] << this->type;
|
||||
}
|
||||
|
||||
static Serializable* Unserialize(Serializable *obj, Serialize::Data &);
|
||||
};
|
||||
|
||||
struct BadWordsImpl : BadWords
|
||||
{
|
||||
Serialize::Reference<ChannelInfo> ci;
|
||||
typedef std::vector<BadWordImpl *> list;
|
||||
Serialize::Checker<list> badwords;
|
||||
|
||||
BadWordsImpl(Extensible *obj) : ci(anope_dynamic_static_cast<ChannelInfo *>(obj)), badwords("BadWord") { }
|
||||
|
||||
BadWord* AddBadWord(const Anope::string &word, BadWordType type) anope_override
|
||||
{
|
||||
BadWordImpl *bw = new BadWordImpl();
|
||||
bw->chan = ci->name;
|
||||
bw->word = word;
|
||||
bw->type = type;
|
||||
|
||||
this->badwords->push_back(bw);
|
||||
|
||||
FOREACH_MOD(OnBadWordAdd, (ci, bw));
|
||||
|
||||
return bw;
|
||||
}
|
||||
|
||||
BadWord* GetBadWord(unsigned index) const anope_override
|
||||
{
|
||||
if (this->badwords->empty() || index >= this->badwords->size())
|
||||
return NULL;
|
||||
|
||||
BadWordImpl *bw = (*this->badwords)[index];
|
||||
bw->QueueUpdate();
|
||||
return bw;
|
||||
}
|
||||
|
||||
unsigned GetBadWordCount() const anope_override
|
||||
{
|
||||
return this->badwords->size();
|
||||
}
|
||||
|
||||
void EraseBadWord(unsigned index) anope_override
|
||||
{
|
||||
if (this->badwords->empty() || index >= this->badwords->size())
|
||||
return;
|
||||
|
||||
FOREACH_MOD(OnBadWordDel, (ci, (*this->badwords)[index]));
|
||||
|
||||
delete this->badwords->at(index);
|
||||
}
|
||||
|
||||
void ClearBadWords() anope_override
|
||||
{
|
||||
while (!this->badwords->empty())
|
||||
delete this->badwords->back();
|
||||
}
|
||||
|
||||
void Check() anope_override
|
||||
{
|
||||
if (this->badwords->empty())
|
||||
ci->Shrink<BadWords>("badwords");
|
||||
}
|
||||
};
|
||||
|
||||
BadWordImpl::~BadWordImpl()
|
||||
{
|
||||
ChannelInfo *ci = ChannelInfo::Find(chan);
|
||||
if (ci)
|
||||
{
|
||||
BadWordsImpl *badwords = ci->GetExt<BadWordsImpl>("badwords");
|
||||
if (badwords)
|
||||
{
|
||||
BadWordsImpl::list::iterator it = std::find(badwords->badwords->begin(), badwords->badwords->end(), this);
|
||||
if (it != badwords->badwords->end())
|
||||
badwords->badwords->erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Serializable* BadWordImpl::Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
{
|
||||
Anope::string sci, sword;
|
||||
|
||||
data["ci"] >> sci;
|
||||
data["word"] >> sword;
|
||||
|
||||
ChannelInfo *ci = ChannelInfo::Find(sci);
|
||||
if (!ci)
|
||||
return NULL;
|
||||
|
||||
unsigned int n;
|
||||
data["type"] >> n;
|
||||
|
||||
BadWordImpl *bw;
|
||||
if (obj)
|
||||
bw = anope_dynamic_static_cast<BadWordImpl *>(obj);
|
||||
else
|
||||
bw = new BadWordImpl();
|
||||
bw->chan = sci;
|
||||
bw->word = sword;
|
||||
bw->type = static_cast<BadWordType>(n);
|
||||
|
||||
BadWordsImpl *bws = ci->Require<BadWordsImpl>("badwords");
|
||||
bws->badwords->push_back(bw);
|
||||
|
||||
return bw;
|
||||
}
|
||||
|
||||
class BadwordsDelCallback : public NumberList
|
||||
{
|
||||
CommandSource &source;
|
||||
ChannelInfo *ci;
|
||||
BadWords *bw;
|
||||
Command *c;
|
||||
unsigned deleted;
|
||||
bool override;
|
||||
@@ -23,6 +144,7 @@ class BadwordsDelCallback : public NumberList
|
||||
{
|
||||
if (!source.AccessFor(ci).HasPriv("BADWORDS") && source.HasPriv("botserv/administration"))
|
||||
this->override = true;
|
||||
bw = ci->Require<BadWords>("badwords");
|
||||
}
|
||||
|
||||
~BadwordsDelCallback()
|
||||
@@ -37,12 +159,12 @@ class BadwordsDelCallback : public NumberList
|
||||
|
||||
void HandleNumber(unsigned Number) anope_override
|
||||
{
|
||||
if (!Number || Number > ci->GetBadWordCount())
|
||||
if (!bw || !Number || Number > bw->GetBadWordCount())
|
||||
return;
|
||||
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, c, ci) << "DEL " << ci->GetBadWord(Number - 1)->word;
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, c, ci) << "DEL " << bw->GetBadWord(Number - 1)->word;
|
||||
++deleted;
|
||||
ci->EraseBadWord(Number - 1);
|
||||
bw->EraseBadWord(Number - 1);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -54,10 +176,11 @@ class CommandBSBadwords : public Command
|
||||
bool override = !source.AccessFor(ci).HasPriv("BADWORDS");
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "LIST";
|
||||
ListFormatter list;
|
||||
BadWords *bw = ci->GetExt<BadWords>("badwords");
|
||||
|
||||
list.AddColumn("Number").AddColumn("Word").AddColumn("Type");
|
||||
|
||||
if (!ci->GetBadWordCount())
|
||||
if (!bw || !bw->GetBadWordCount())
|
||||
{
|
||||
source.Reply(_("%s bad words list is empty."), ci->name.c_str());
|
||||
return;
|
||||
@@ -68,40 +191,41 @@ class CommandBSBadwords : public Command
|
||||
{
|
||||
ListFormatter &list;
|
||||
ChannelInfo *ci;
|
||||
BadWords *bw;
|
||||
public:
|
||||
BadwordsListCallback(ListFormatter &_list, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), list(_list), ci(_ci)
|
||||
BadwordsListCallback(ListFormatter &_list, ChannelInfo *_ci, BadWords *_bw, const Anope::string &numlist) : NumberList(numlist, false), list(_list), ci(_ci), bw(_bw)
|
||||
{
|
||||
}
|
||||
|
||||
void HandleNumber(unsigned Number) anope_override
|
||||
{
|
||||
if (!Number || Number > ci->GetBadWordCount())
|
||||
if (!Number || Number > bw->GetBadWordCount())
|
||||
return;
|
||||
|
||||
const BadWord *bw = ci->GetBadWord(Number - 1);
|
||||
const BadWord *b = bw->GetBadWord(Number - 1);
|
||||
ListFormatter::ListEntry entry;
|
||||
entry["Number"] = stringify(Number);
|
||||
entry["Word"] = bw->word;
|
||||
entry["Type"] = bw->type == BW_SINGLE ? "(SINGLE)" : (bw->type == BW_START ? "(START)" : (bw->type == BW_END ? "(END)" : ""));
|
||||
entry["Word"] = b->word;
|
||||
entry["Type"] = b->type == BW_SINGLE ? "(SINGLE)" : (b->type == BW_START ? "(START)" : (b->type == BW_END ? "(END)" : ""));
|
||||
this->list.AddEntry(entry);
|
||||
}
|
||||
}
|
||||
nl_list(list, ci, word);
|
||||
nl_list(list, ci, bw, word);
|
||||
nl_list.Process();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned i = 0, end = ci->GetBadWordCount(); i < end; ++i)
|
||||
for (unsigned i = 0, end = bw->GetBadWordCount(); i < end; ++i)
|
||||
{
|
||||
const BadWord *bw = ci->GetBadWord(i);
|
||||
const BadWord *b = bw->GetBadWord(i);
|
||||
|
||||
if (!word.empty() && !Anope::Match(bw->word, word))
|
||||
if (!word.empty() && !Anope::Match(b->word, word))
|
||||
continue;
|
||||
|
||||
ListFormatter::ListEntry entry;
|
||||
entry["Number"] = stringify(i + 1);
|
||||
entry["Word"] = bw->word;
|
||||
entry["Type"] = bw->type == BW_SINGLE ? "(SINGLE)" : (bw->type == BW_START ? "(START)" : (bw->type == BW_END ? "(END)" : ""));
|
||||
entry["Word"] = b->word;
|
||||
entry["Type"] = b->type == BW_SINGLE ? "(SINGLE)" : (b->type == BW_START ? "(START)" : (b->type == BW_END ? "(END)" : ""));
|
||||
list.AddEntry(entry);
|
||||
}
|
||||
}
|
||||
@@ -127,6 +251,7 @@ class CommandBSBadwords : public Command
|
||||
size_t pos = word.rfind(' ');
|
||||
BadWordType bwtype = BW_ANY;
|
||||
Anope::string realword = word;
|
||||
BadWords *badwords = ci->Require<BadWords>("badwords");
|
||||
|
||||
if (pos != Anope::string::npos)
|
||||
{
|
||||
@@ -144,7 +269,7 @@ class CommandBSBadwords : public Command
|
||||
}
|
||||
|
||||
unsigned badwordsmax = Config->GetModule(this->module)->Get<unsigned>("badwordsmax");
|
||||
if (ci->GetBadWordCount() >= badwordsmax)
|
||||
if (badwords->GetBadWordCount() >= badwordsmax)
|
||||
{
|
||||
source.Reply(_("Sorry, you can only have %d bad words entries on a channel."), badwordsmax);
|
||||
return;
|
||||
@@ -152,9 +277,9 @@ class CommandBSBadwords : public Command
|
||||
|
||||
bool casesensitive = Config->GetModule("botserv")->Get<bool>("casesensitive");
|
||||
|
||||
for (unsigned i = 0, end = ci->GetBadWordCount(); i < end; ++i)
|
||||
for (unsigned i = 0, end = badwords->GetBadWordCount(); i < end; ++i)
|
||||
{
|
||||
const BadWord *bw = ci->GetBadWord(i);
|
||||
const BadWord *bw = badwords->GetBadWord(i);
|
||||
|
||||
if ((casesensitive && realword.equals_cs(bw->word)) || (!casesensitive && realword.equals_ci(bw->word)))
|
||||
{
|
||||
@@ -165,13 +290,21 @@ class CommandBSBadwords : public Command
|
||||
|
||||
bool override = !source.AccessFor(ci).HasPriv("BADWORDS");
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "ADD " << realword;
|
||||
ci->AddBadWord(realword, bwtype);
|
||||
badwords->AddBadWord(realword, bwtype);
|
||||
|
||||
source.Reply(_("\002%s\002 added to %s bad words list."), realword.c_str(), ci->name.c_str());
|
||||
}
|
||||
|
||||
void DoDelete(CommandSource &source, ChannelInfo *ci, const Anope::string &word)
|
||||
{
|
||||
BadWords *badwords = ci->GetExt<BadWords>("badwords");
|
||||
|
||||
if (!badwords || !badwords->GetBadWordCount())
|
||||
{
|
||||
source.Reply(_("%s bad words list is empty."), ci->name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
/* Special case: is it a number/list? Only do search if it isn't. */
|
||||
if (!word.empty() && isdigit(word[0]) && word.find_first_not_of("1234567890,-") == Anope::string::npos)
|
||||
{
|
||||
@@ -183,9 +316,9 @@ class CommandBSBadwords : public Command
|
||||
unsigned i, end;
|
||||
const BadWord *badword;
|
||||
|
||||
for (i = 0, end = ci->GetBadWordCount(); i < end; ++i)
|
||||
for (i = 0, end = badwords->GetBadWordCount(); i < end; ++i)
|
||||
{
|
||||
badword = ci->GetBadWord(i);
|
||||
badword = badwords->GetBadWord(i);
|
||||
|
||||
if (word.equals_ci(badword->word))
|
||||
break;
|
||||
@@ -202,10 +335,10 @@ class CommandBSBadwords : public Command
|
||||
|
||||
source.Reply(_("\002%s\002 deleted from %s bad words list."), badword->word.c_str(), ci->name.c_str());
|
||||
|
||||
ci->EraseBadWord(i);
|
||||
badwords->EraseBadWord(i);
|
||||
}
|
||||
|
||||
return;
|
||||
badwords->Check();
|
||||
}
|
||||
|
||||
void DoClear(CommandSource &source, ChannelInfo *ci)
|
||||
@@ -213,7 +346,9 @@ class CommandBSBadwords : public Command
|
||||
bool override = !source.AccessFor(ci).HasPriv("BADWORDS");
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "CLEAR";
|
||||
|
||||
ci->ClearBadWords();
|
||||
BadWords *badwords = ci->GetExt<BadWords>("badwords");
|
||||
if (badwords)
|
||||
badwords->ClearBadWords();
|
||||
source.Reply(_("Bad words list is now empty."));
|
||||
}
|
||||
|
||||
@@ -309,10 +444,12 @@ class CommandBSBadwords : public Command
|
||||
class BSBadwords : public Module
|
||||
{
|
||||
CommandBSBadwords commandbsbadwords;
|
||||
ExtensibleItem<BadWordsImpl> badwords;
|
||||
Serialize::Type badword_type;
|
||||
|
||||
public:
|
||||
BSBadwords(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
commandbsbadwords(this)
|
||||
commandbsbadwords(this), badwords(this, "badwords"), badword_type("BadWord", BadWordImpl::Unserialize)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
@@ -36,16 +36,6 @@ class CommandBSInfo : public Command
|
||||
buffers.push_back(buf);
|
||||
}
|
||||
|
||||
void CheckOptStr(Anope::string &buf, const Anope::string &flag, const char *option, Extensible *flags, const NickCore *nc)
|
||||
{
|
||||
if (flags->HasExt(flag))
|
||||
{
|
||||
if (!buf.empty())
|
||||
buf += ", ";
|
||||
buf += Language::Translate(nc, option);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
CommandBSInfo(Module *creator) : Command(creator, "botserv/info", 1, 1)
|
||||
{
|
||||
@@ -57,8 +47,8 @@ class CommandBSInfo : public Command
|
||||
{
|
||||
const Anope::string &query = params[0];
|
||||
|
||||
const BotInfo *bi = BotInfo::Find(query, true);
|
||||
ChannelInfo *ci;
|
||||
BotInfo *bi = BotInfo::Find(query, true);
|
||||
ChannelInfo *ci = ChannelInfo::Find(query);
|
||||
InfoFormatter info(source.nc);
|
||||
|
||||
if (bi)
|
||||
@@ -70,6 +60,8 @@ class CommandBSInfo : public Command
|
||||
info[_("Options")] = bi->oper_only ? _("Private") : _("None");
|
||||
info[_("Used on")] = stringify(bi->GetChannelCount()) + " channel(s)";
|
||||
|
||||
FOREACH_MOD(OnBotInfo, (source, bi, ci, info));
|
||||
|
||||
std::vector<Anope::string> replies;
|
||||
info.Process(replies);
|
||||
|
||||
@@ -85,7 +77,7 @@ class CommandBSInfo : public Command
|
||||
}
|
||||
|
||||
}
|
||||
else if ((ci = ChannelInfo::Find(query)))
|
||||
else if (ci)
|
||||
{
|
||||
if (!source.AccessFor(ci).HasPriv("INFO") && !source.HasPriv("botserv/administration"))
|
||||
{
|
||||
@@ -99,114 +91,7 @@ class CommandBSInfo : public Command
|
||||
Anope::string enabled = Language::Translate(source.nc, _("Enabled"));
|
||||
Anope::string disabled = Language::Translate(source.nc, _("Disabled"));
|
||||
|
||||
if (ci->HasExt("BS_KICK_BADWORDS"))
|
||||
{
|
||||
if (ci->ttb[TTB_BADWORDS])
|
||||
info[_("Bad words kicker")] = Anope::printf("%s (%d kick(s) to ban)", enabled.c_str(), ci->ttb[TTB_BADWORDS]);
|
||||
else
|
||||
info[_("Bad words kicker")] = enabled;
|
||||
}
|
||||
else
|
||||
info[_("Bad words kicker")] = disabled;
|
||||
|
||||
if (ci->HasExt("BS_KICK_BOLDS"))
|
||||
{
|
||||
if (ci->ttb[TTB_BOLDS])
|
||||
info[_("Bolds kicker")] = Anope::printf("%s (%d kick(s) to ban)", enabled.c_str(), ci->ttb[TTB_BOLDS]);
|
||||
else
|
||||
info[_("Bolds kicker")] = enabled;
|
||||
}
|
||||
else
|
||||
info[_("Bolds kicker")] = disabled;
|
||||
|
||||
if (ci->HasExt("BS_KICK_CAPS"))
|
||||
{
|
||||
if (ci->ttb[TTB_CAPS])
|
||||
info[_("Caps kicker")] = Anope::printf(_("%s (%d kick(s) to ban; minimum %d/%d%%"), enabled.c_str(), ci->ttb[TTB_CAPS], ci->capsmin, ci->capspercent);
|
||||
else
|
||||
info[_("Caps kicker")] = Anope::printf(_("%s (minimum %d/%d%%)"), enabled.c_str(), ci->capsmin, ci->capspercent);
|
||||
}
|
||||
else
|
||||
info[_("Caps kicker")] = disabled;
|
||||
|
||||
if (ci->HasExt("BS_KICK_COLORS"))
|
||||
{
|
||||
if (ci->ttb[TTB_COLORS])
|
||||
info[_("Colors kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), ci->ttb[TTB_COLORS]);
|
||||
else
|
||||
info[_("Colors kicker")] = enabled;
|
||||
}
|
||||
else
|
||||
info[_("Colors kicker")] = disabled;
|
||||
|
||||
if (ci->HasExt("BS_KICK_FLOOD"))
|
||||
{
|
||||
if (ci->ttb[TTB_FLOOD])
|
||||
info[_("Flood kicker")] = Anope::printf(_("%s (%d kick(s) to ban; %d lines in %ds"), enabled.c_str(), ci->ttb[TTB_FLOOD], ci->floodlines, ci->floodsecs);
|
||||
else
|
||||
info[_("Flood kicker")] = Anope::printf(_("%s (%d lines in %ds)"), enabled.c_str(), ci->floodlines, ci->floodsecs);
|
||||
}
|
||||
else
|
||||
info[_("Flood kicker")] = disabled;
|
||||
|
||||
if (ci->HasExt("BS_KICK_REPEAT"))
|
||||
{
|
||||
if (ci->ttb[TTB_REPEAT])
|
||||
info[_("Repeat kicker")] = Anope::printf(_("%s (%d kick(s) to ban; %d times)"), enabled.c_str(), ci->ttb[TTB_REPEAT], ci->repeattimes);
|
||||
else
|
||||
info[_("Repeat kicker")] = Anope::printf(_("%s (%d times)"), enabled.c_str(), ci->repeattimes);
|
||||
}
|
||||
else
|
||||
info[_("Repeat kicker")] = disabled;
|
||||
|
||||
if (ci->HasExt("BS_KICK_REVERSES"))
|
||||
{
|
||||
if (ci->ttb[TTB_REVERSES])
|
||||
info[_("Reverses kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), ci->ttb[TTB_REVERSES]);
|
||||
else
|
||||
info[_("Reverses kicker")] = enabled;
|
||||
}
|
||||
else
|
||||
info[_("Reverses kicker")] = disabled;
|
||||
|
||||
if (ci->HasExt("BS_KICK_UNDERLINES"))
|
||||
{
|
||||
if (ci->ttb[TTB_UNDERLINES])
|
||||
info[_("Underlines kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), ci->ttb[TTB_UNDERLINES]);
|
||||
else
|
||||
info[_("Underlines kicker")] = enabled;
|
||||
}
|
||||
else
|
||||
info[_("Underlines kicker")] = disabled;
|
||||
|
||||
if (ci->HasExt("BS_KICK_ITALICS"))
|
||||
{
|
||||
if (ci->ttb[TTB_ITALICS])
|
||||
info[_("Italics kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), ci->ttb[TTB_ITALICS]);
|
||||
else
|
||||
info[_("Italics kicker")] = enabled;
|
||||
}
|
||||
else
|
||||
info[_("Italics kicker")] = disabled;
|
||||
|
||||
if (ci->HasExt("BS_KICK_AMSGS"))
|
||||
{
|
||||
if (ci->ttb[TTB_AMSGS])
|
||||
info[_("AMSG kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), ci->ttb[TTB_AMSGS]);
|
||||
else
|
||||
info[_("AMSG kicker")] = enabled;
|
||||
}
|
||||
else
|
||||
info[_("AMSG kicker")] = disabled;
|
||||
|
||||
Anope::string flags;
|
||||
CheckOptStr(flags, "BS_DONTKICKOPS", _("Ops protection"), ci, source.nc);
|
||||
CheckOptStr(flags, "BS_DONTKICKVOICES", _("Voices protection"), ci, source.nc);
|
||||
CheckOptStr(flags, "BS_FANTASY", _("Fantasy"), ci, source.nc);
|
||||
CheckOptStr(flags, "BS_GREET", _("Greet"), ci, source.nc);
|
||||
CheckOptStr(flags, "BS_NOBOT", _("No bot"), ci, source.nc);
|
||||
|
||||
info[_("Options")] = flags.empty() ? _("None") : flags;
|
||||
FOREACH_MOD(OnBotInfo, (source, bi, ci, info));
|
||||
|
||||
std::vector<Anope::string> replies;
|
||||
info.Process(replies);
|
||||
|
||||
+496
-127
File diff suppressed because it is too large
Load Diff
+2
-315
@@ -127,314 +127,6 @@ class CommandBSSetBanExpire : public Command
|
||||
}
|
||||
};
|
||||
|
||||
class CommandBSSetDontKickOps : public Command
|
||||
{
|
||||
public:
|
||||
CommandBSSetDontKickOps(Module *creator, const Anope::string &sname = "botserv/set/dontkickops") : Command(creator, sname, 2, 2)
|
||||
{
|
||||
this->SetDesc(_("To protect ops against bot kicks"));
|
||||
this->SetSyntax(_("\037channel\037 {ON | OFF}"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
ChannelInfo *ci = ChannelInfo::Find(params[0]);
|
||||
if (ci == NULL)
|
||||
{
|
||||
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
AccessGroup access = source.AccessFor(ci);
|
||||
if (!source.HasPriv("botserv/administration") && !access.HasPriv("SET"))
|
||||
{
|
||||
source.Reply(ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Anope::ReadOnly)
|
||||
{
|
||||
source.Reply(_("Sorry, bot option setting is temporarily disabled."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (params[1].equals_ci("ON"))
|
||||
{
|
||||
bool override = !access.HasPriv("SET");
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable dontkickops";
|
||||
|
||||
ci->ExtendMetadata("BS_DONTKICKOPS");
|
||||
source.Reply(_("Bot \002won't kick ops\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else if (params[1].equals_ci("OFF"))
|
||||
{
|
||||
bool override = !access.HasPriv("SET");
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable dontkickops";
|
||||
|
||||
ci->Shrink("BS_DONTKICKOPS");
|
||||
source.Reply(_("Bot \002will kick ops\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, source.command);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(_(" \n"
|
||||
"Enables or disables \002ops protection\002 mode on a channel.\n"
|
||||
"When it is enabled, ops won't be kicked by the bot\n"
|
||||
"even if they don't match the NOKICK level."));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandBSSetDontKickVoices : public Command
|
||||
{
|
||||
public:
|
||||
CommandBSSetDontKickVoices(Module *creator, const Anope::string &sname = "botserv/set/dontkickvoices") : Command(creator, sname, 2, 2)
|
||||
{
|
||||
this->SetDesc(_("To protect voices against bot kicks"));
|
||||
this->SetSyntax(_("\037channel\037 {ON | OFF}"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
ChannelInfo *ci = ChannelInfo::Find(params[0]);
|
||||
if (ci == NULL)
|
||||
{
|
||||
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
AccessGroup access = source.AccessFor(ci);
|
||||
if (!source.HasPriv("botserv/administration") && !access.HasPriv("SET"))
|
||||
{
|
||||
source.Reply(ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Anope::ReadOnly)
|
||||
{
|
||||
source.Reply(_("Sorry, bot option setting is temporarily disabled."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (params[1].equals_ci("ON"))
|
||||
{
|
||||
bool override = !access.HasPriv("SET");
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable dontkickvoices";
|
||||
|
||||
ci->ExtendMetadata("BS_DONTKICKVOICES");
|
||||
source.Reply(_("Bot \002won't kick voices\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else if (params[1].equals_ci("OFF"))
|
||||
{
|
||||
bool override = !access.HasPriv("SET");
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable dontkickvoices";
|
||||
|
||||
ci->Shrink("BS_DONTKICKVOICES");
|
||||
source.Reply(_("Bot \002will kick voices\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, source.command);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(_(" \n"
|
||||
"Enables or disables \002voices protection\002 mode on a channel.\n"
|
||||
"When it is enabled, voices won't be kicked by the bot\n"
|
||||
"even if they don't match the NOKICK level."));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandBSSetFantasy : public Command
|
||||
{
|
||||
public:
|
||||
CommandBSSetFantasy(Module *creator, const Anope::string &sname = "botserv/set/fantasy") : Command(creator, sname, 2, 2)
|
||||
{
|
||||
this->SetDesc(_("Enable fantaisist commands"));
|
||||
this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
ChannelInfo *ci = ChannelInfo::Find(params[0]);
|
||||
const Anope::string &value = params[1];
|
||||
|
||||
if (ci == NULL)
|
||||
{
|
||||
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!source.HasPriv("botserv/administration") && !source.AccessFor(ci).HasPriv("SET"))
|
||||
{
|
||||
source.Reply(ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Anope::ReadOnly)
|
||||
{
|
||||
source.Reply(_("Sorry, bot option setting is temporarily disabled."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.equals_ci("ON"))
|
||||
{
|
||||
bool override = !source.AccessFor(ci).HasPriv("SET");
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable fantasy";
|
||||
|
||||
ci->ExtendMetadata("BS_FANTASY");
|
||||
source.Reply(_("Fantasy mode is now \002on\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else if (value.equals_ci("OFF"))
|
||||
{
|
||||
bool override = !source.AccessFor(ci).HasPriv("SET");
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable fantasy";
|
||||
|
||||
ci->Shrink("BS_FANTASY");
|
||||
source.Reply(_("Fantasy mode is now \002off\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, source.command);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(_(" \n"
|
||||
"Enables or disables \002fantasy\002 mode on a channel.\n"
|
||||
"When it is enabled, users will be able to use\n"
|
||||
"fantasy commands on a channel when prefixed\n"
|
||||
"with one of the following fantasy characters: \002%s\002\n"
|
||||
" \n"
|
||||
"Note that users wanting to use fantaisist\n"
|
||||
"commands MUST have enough access for both\n"
|
||||
"the FANTASIA and the command they are executing."),
|
||||
Config->GetModule("botserv")->Get<const Anope::string>("fantasycharacter", "!").c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandBSSetGreet : public Command
|
||||
{
|
||||
public:
|
||||
CommandBSSetGreet(Module *creator, const Anope::string &sname = "botserv/set/greet") : Command(creator, sname, 2, 2)
|
||||
{
|
||||
this->SetDesc(_("Enable greet messages"));
|
||||
this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
ChannelInfo *ci = ChannelInfo::Find(params[0]);
|
||||
const Anope::string &value = params[1];
|
||||
|
||||
if (ci == NULL)
|
||||
{
|
||||
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!source.HasPriv("botserv/administration") && !source.AccessFor(ci).HasPriv("SET"))
|
||||
{
|
||||
source.Reply(ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Anope::ReadOnly)
|
||||
{
|
||||
source.Reply(_("Sorry, bot option setting is temporarily disabled."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.equals_ci("ON"))
|
||||
{
|
||||
bool override = !source.AccessFor(ci).HasPriv("SET");
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable greets";
|
||||
|
||||
ci->ExtendMetadata("BS_GREET");
|
||||
source.Reply(_("Greet mode is now \002on\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else if (value.equals_ci("OFF"))
|
||||
{
|
||||
bool override = !source.AccessFor(ci).HasPriv("SET");
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable greets";
|
||||
|
||||
ci->Shrink("BS_GREET");
|
||||
source.Reply(_("Greet mode is now \002off\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, source.command);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(_(" \n"
|
||||
"Enables or disables \002greet\002 mode on a channel.\n"
|
||||
"When it is enabled, the bot will display greet\n"
|
||||
"messages of users joining the channel, provided\n"
|
||||
"they have enough access to the channel."));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandBSSetNoBot : public Command
|
||||
{
|
||||
public:
|
||||
CommandBSSetNoBot(Module *creator, const Anope::string &sname = "botserv/set/nobot") : Command(creator, sname, 2, 2)
|
||||
{
|
||||
this->SetDesc(_("Prevent a bot from being assigned to a channel"));
|
||||
this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
ChannelInfo *ci = ChannelInfo::Find(params[0]);
|
||||
const Anope::string &value = params[1];
|
||||
|
||||
if (ci == NULL)
|
||||
{
|
||||
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.equals_ci("ON"))
|
||||
{
|
||||
Log(LOG_ADMIN, source, this, ci) << "to enable nobot";
|
||||
|
||||
ci->ExtendMetadata("BS_NOBOT");
|
||||
if (ci->bi)
|
||||
ci->bi->UnAssign(source.GetUser(), ci);
|
||||
source.Reply(_("No-bot mode is now \002on\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else if (value.equals_ci("OFF"))
|
||||
{
|
||||
Log(LOG_ADMIN, source, this, ci) << "to disable nobot";
|
||||
|
||||
ci->Shrink("BS_NOBOT");
|
||||
source.Reply(_("No-bot mode is now \002off\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, source.command);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(_(" \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."));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandBSSetPrivate : public Command
|
||||
{
|
||||
public:
|
||||
@@ -483,17 +175,12 @@ class BSSet : public Module
|
||||
{
|
||||
CommandBSSet commandbsset;
|
||||
CommandBSSetBanExpire commandbssetbanexpire;
|
||||
CommandBSSetDontKickOps commandbssetdontkickops;
|
||||
CommandBSSetDontKickVoices commandbssetdontkickvoices;
|
||||
CommandBSSetFantasy commandbssetfantasy;
|
||||
CommandBSSetGreet commandbssetgreet;
|
||||
CommandBSSetNoBot commandbssetnobot;
|
||||
CommandBSSetPrivate commandbssetprivate;
|
||||
|
||||
public:
|
||||
BSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
commandbsset(this), commandbssetbanexpire(this), commandbssetdontkickops(this), commandbssetdontkickvoices(this),
|
||||
commandbssetfantasy(this), commandbssetgreet(this), commandbssetnobot(this), commandbssetprivate(this)
|
||||
commandbsset(this), commandbssetbanexpire(this),
|
||||
commandbssetprivate(this)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ class CommandCSAKick : public Command
|
||||
const NickAlias *na = NickAlias::Find(mask);
|
||||
NickCore *nc = NULL;
|
||||
const AutoKick *akick;
|
||||
|
||||
unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200");
|
||||
|
||||
if (reason.length() > reasonmax)
|
||||
reason = reason.substr(0, reasonmax);
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/bs_badwords.h"
|
||||
|
||||
class CommandCSClone : public Command
|
||||
{
|
||||
@@ -125,12 +126,16 @@ public:
|
||||
}
|
||||
else if (what.equals_ci("BADWORDS"))
|
||||
{
|
||||
target_ci->ClearBadWords();
|
||||
for (unsigned i = 0; i < ci->GetBadWordCount(); ++i)
|
||||
{
|
||||
const BadWord *bw = ci->GetBadWord(i);
|
||||
target_ci->AddBadWord(bw->word, bw->type);
|
||||
}
|
||||
BadWords *target_badwords = target_ci->GetExt<BadWords>("badwords"),
|
||||
*badwords = ci->Require<BadWords>("badwords");
|
||||
if (target_badwords)
|
||||
target_badwords->ClearBadWords();
|
||||
if (badwords)
|
||||
for (unsigned i = 0; i < badwords->GetBadWordCount(); ++i)
|
||||
{
|
||||
const BadWord *bw = badwords->GetBadWord(i);
|
||||
target_badwords->AddBadWord(bw->word, bw->type);
|
||||
}
|
||||
|
||||
source.Reply(_("All badword entries from \002%s\002 have been cloned to \002%s\002."), channel.c_str(), target.c_str());
|
||||
}
|
||||
@@ -141,8 +146,6 @@ public:
|
||||
}
|
||||
|
||||
Log(LOG_COMMAND, source, this, ci) << "to clone " << (what.empty() ? "everything from it" : what) << " to " << target_ci->name;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
|
||||
|
||||
@@ -37,23 +37,20 @@ class CommandCSDrop : public Command
|
||||
return;
|
||||
}
|
||||
|
||||
if (ci->HasExt("SUSPENDED") && !source.HasCommand("chanserv/drop"))
|
||||
{
|
||||
source.Reply(CHAN_X_SUSPENDED, chan.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")) && !source.HasCommand("chanserv/drop"))
|
||||
{
|
||||
source.Reply(ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
EventReturn MOD_RESULT;
|
||||
FOREACH_RESULT(OnChanDrop, MOD_RESULT, (source, ci));
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
return;
|
||||
|
||||
bool override = (ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER"));
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "(founder was: " << (ci->GetFounder() ? ci->GetFounder()->display : "none") << ")";
|
||||
|
||||
FOREACH_MOD(OnChanDrop, (ci));
|
||||
|
||||
Reference<Channel> c = ci->c;
|
||||
delete ci;
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ class CommandCSEnforce : public Command
|
||||
* if it's off.
|
||||
*/
|
||||
bool hadsecureops = ci->HasExt("SECUREOPS");
|
||||
ci->ExtendMetadata("SECUREOPS");
|
||||
ci->Extend<bool>("SECUREOPS");
|
||||
|
||||
for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
|
||||
{
|
||||
@@ -37,7 +37,7 @@ class CommandCSEnforce : public Command
|
||||
}
|
||||
|
||||
if (!hadsecureops)
|
||||
ci->Shrink("SECUREOPS");
|
||||
ci->Shrink<bool>("SECUREOPS");
|
||||
|
||||
source.Reply(_("Secureops enforced on %s."), ci->name.c_str());
|
||||
}
|
||||
|
||||
@@ -37,9 +37,9 @@ struct EntryMsg : Serializable
|
||||
static Serializable* Unserialize(Serializable *obj, Serialize::Data &data);
|
||||
};
|
||||
|
||||
struct EntryMessageList : Serialize::Checker<std::vector<EntryMsg *> >, ExtensibleItem
|
||||
struct EntryMessageList : Serialize::Checker<std::vector<EntryMsg *> >
|
||||
{
|
||||
EntryMessageList() : Serialize::Checker<std::vector<EntryMsg *> >("EntryMsg") { }
|
||||
EntryMessageList(Extensible *) : Serialize::Checker<std::vector<EntryMsg *> >("EntryMsg") { }
|
||||
|
||||
~EntryMessageList()
|
||||
{
|
||||
@@ -71,12 +71,9 @@ Serializable* EntryMsg::Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
return msg;
|
||||
}
|
||||
|
||||
EntryMessageList *messages = ci->GetExt<EntryMessageList *>("cs_entrymsg");
|
||||
EntryMessageList *messages = ci->GetExt<EntryMessageList>("entrymsg");
|
||||
if (messages == NULL)
|
||||
{
|
||||
messages = new EntryMessageList();
|
||||
ci->Extend("cs_entrymsg", messages);
|
||||
}
|
||||
messages = ci->Extend<EntryMessageList>("entrymsg");
|
||||
|
||||
data["when"] >> swhen;
|
||||
|
||||
@@ -90,12 +87,9 @@ class CommandEntryMessage : public Command
|
||||
private:
|
||||
void DoList(CommandSource &source, ChannelInfo *ci)
|
||||
{
|
||||
EntryMessageList *messages = ci->GetExt<EntryMessageList *>("cs_entrymsg");
|
||||
EntryMessageList *messages = ci->GetExt<EntryMessageList>("entrymsg");
|
||||
if (messages == NULL)
|
||||
{
|
||||
messages = new EntryMessageList();
|
||||
ci->Extend("cs_entrymsg", messages);
|
||||
}
|
||||
messages = ci->Extend<EntryMessageList>("entrymsg");
|
||||
|
||||
if ((*messages)->empty())
|
||||
{
|
||||
@@ -129,12 +123,9 @@ class CommandEntryMessage : public Command
|
||||
|
||||
void DoAdd(CommandSource &source, ChannelInfo *ci, const Anope::string &message)
|
||||
{
|
||||
EntryMessageList *messages = ci->GetExt<EntryMessageList *>("cs_entrymsg");
|
||||
EntryMessageList *messages = ci->GetExt<EntryMessageList>("entrymsg");
|
||||
if (messages == NULL)
|
||||
{
|
||||
messages = new EntryMessageList();
|
||||
ci->Extend("cs_entrymsg", messages);
|
||||
}
|
||||
messages = ci->Extend<EntryMessageList>("entrymsg");
|
||||
|
||||
if ((*messages)->size() >= Config->GetModule(this->owner)->Get<unsigned>("maxentries"))
|
||||
source.Reply(_("The entry message list for \002%s\002 is full."), ci->name.c_str());
|
||||
@@ -148,12 +139,9 @@ class CommandEntryMessage : public Command
|
||||
|
||||
void DoDel(CommandSource &source, ChannelInfo *ci, const Anope::string &message)
|
||||
{
|
||||
EntryMessageList *messages = ci->GetExt<EntryMessageList *>("cs_entrymsg");
|
||||
EntryMessageList *messages = ci->GetExt<EntryMessageList>("entrymsg");
|
||||
if (messages == NULL)
|
||||
{
|
||||
messages = new EntryMessageList();
|
||||
ci->Extend("cs_entrymsg", messages);
|
||||
}
|
||||
messages = ci->Extend<EntryMessageList>("entrymsg");
|
||||
|
||||
if (!message.is_pos_number_only())
|
||||
source.Reply(("Entry message \002%s\002 not found on channel \002%s\002."), message.c_str(), ci->name.c_str());
|
||||
@@ -169,7 +157,7 @@ class CommandEntryMessage : public Command
|
||||
delete (*messages)->at(i - 1);
|
||||
(*messages)->erase((*messages)->begin() + i - 1);
|
||||
if ((*messages)->empty())
|
||||
ci->Shrink("cs_entrymsg");
|
||||
ci->Shrink<EntryMessageList>("entrymsg");
|
||||
Log(source.IsFounder(ci) ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove a message";
|
||||
source.Reply(_("Entry message \002%i\002 for \002%s\002 deleted."), i, ci->name.c_str());
|
||||
}
|
||||
@@ -185,14 +173,7 @@ class CommandEntryMessage : public Command
|
||||
|
||||
void DoClear(CommandSource &source, ChannelInfo *ci)
|
||||
{
|
||||
EntryMessageList *messages = ci->GetExt<EntryMessageList *>("cs_entrymsg");
|
||||
if (messages != NULL)
|
||||
{
|
||||
for (unsigned i = 0; i < (*messages)->size(); ++i)
|
||||
delete (*messages)->at(i);
|
||||
(*messages)->clear();
|
||||
ci->Shrink("cs_entrymsg");
|
||||
}
|
||||
ci->Shrink<EntryMessageList>("entrymsg");
|
||||
|
||||
Log(source.IsFounder(ci) ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove all messages";
|
||||
source.Reply(_("Entry messages for \002%s\002 have been cleared."), ci->name.c_str());
|
||||
@@ -267,9 +248,10 @@ class CSEntryMessage : public Module
|
||||
{
|
||||
Serialize::Type entrymsg_type;
|
||||
CommandEntryMessage commandentrymsg;
|
||||
ExtensibleItem<EntryMessageList> eml;
|
||||
|
||||
public:
|
||||
CSEntryMessage(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), entrymsg_type("EntryMsg", EntryMsg::Unserialize), commandentrymsg(this)
|
||||
CSEntryMessage(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), entrymsg_type("EntryMsg", EntryMsg::Unserialize), commandentrymsg(this), eml(this, "entrymsg")
|
||||
{
|
||||
|
||||
}
|
||||
@@ -278,7 +260,7 @@ class CSEntryMessage : public Module
|
||||
{
|
||||
if (u && c && c->ci && u->server->IsSynced())
|
||||
{
|
||||
EntryMessageList *messages = c->ci->GetExt<EntryMessageList *>("cs_entrymsg");
|
||||
EntryMessageList *messages = c->ci->GetExt<EntryMessageList>("entrymsg");
|
||||
|
||||
if (messages != NULL)
|
||||
for (unsigned i = 0; i < (*messages)->size(); ++i)
|
||||
|
||||
@@ -13,17 +13,6 @@
|
||||
|
||||
class CommandCSInfo : public Command
|
||||
{
|
||||
void CheckOptStr(Anope::string &buf, const Anope::string &opt, const char *str, const ChannelInfo *ci, const NickCore *nc)
|
||||
{
|
||||
if (ci->HasExt(opt))
|
||||
{
|
||||
if (!buf.empty())
|
||||
buf += ", ";
|
||||
|
||||
buf += Language::Translate(nc, str);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
CommandCSInfo(Module *creator) : Command(creator, "chanserv/info", 1, 2)
|
||||
{
|
||||
@@ -66,43 +55,9 @@ class CommandCSInfo : public Command
|
||||
info["Registered"] = Anope::strftime(ci->time_registered);
|
||||
info["Last used"] = Anope::strftime(ci->last_used);
|
||||
|
||||
const ModeLock *secret = ci->GetMLock("SECRET");
|
||||
if (!ci->last_topic.empty() && (show_all || ((!secret || secret->set == false) && (!ci->c || !ci->c->HasMode("SECRET")))))
|
||||
{
|
||||
info["Last topic"] = ci->last_topic;
|
||||
info["Topic set by"] = ci->last_topic_setter;
|
||||
}
|
||||
|
||||
if (show_all)
|
||||
{
|
||||
info["Ban type"] = stringify(ci->bantype);
|
||||
|
||||
Anope::string optbuf;
|
||||
CheckOptStr(optbuf, "KEEPTOPIC", _("Topic Retention"), ci, nc);
|
||||
CheckOptStr(optbuf, "PEACE", _("Peace"), ci, nc);
|
||||
CheckOptStr(optbuf, "PRIVATE", _("Private"), ci, nc);
|
||||
CheckOptStr(optbuf, "RESTRICTED", _("Restricted Access"), ci, nc);
|
||||
CheckOptStr(optbuf, "SECURE", _("Secure"), ci, nc);
|
||||
CheckOptStr(optbuf, "SECUREFOUNDER", _("Secure Founder"), ci, nc);
|
||||
CheckOptStr(optbuf, "SECUREOPS", _("Secure Ops"), ci, nc);
|
||||
if (ci->HasExt("SIGNKICK"))
|
||||
CheckOptStr(optbuf, "SIGNKICK", _("Signed kicks"), ci, nc);
|
||||
else
|
||||
CheckOptStr(optbuf, "SIGNKICK_LEVEL", _("Signed kicks"), ci, nc);
|
||||
CheckOptStr(optbuf, "TOPICLOCK", _("Topic Lock"), ci, nc);
|
||||
CheckOptStr(optbuf, "PERSIST", _("Persistent"), ci, nc);
|
||||
CheckOptStr(optbuf, "NO_EXPIRE", _("No expire"), ci, nc);
|
||||
CheckOptStr(optbuf, "STATS", _("Chanstats"), ci, nc);
|
||||
|
||||
info["Options"] = optbuf.empty() ? _("None") : optbuf;
|
||||
|
||||
const Anope::string &ml = ci->GetMLockAsString(true);
|
||||
if (!ml.empty())
|
||||
info["Mode lock"] = ml;
|
||||
|
||||
time_t chanserv_expire = Config->GetModule("chanserv")->Get<time_t>("expire", "14d");
|
||||
if (!ci->HasExt("NO_EXPIRE") && chanserv_expire && !Anope::NoExpire)
|
||||
info["Expires on"] = Anope::strftime(ci->last_used + chanserv_expire);
|
||||
}
|
||||
|
||||
FOREACH_MOD(OnChanInfo, (source, ci, info, show_all));
|
||||
|
||||
@@ -81,11 +81,11 @@ class CommandCSList : public Command
|
||||
{
|
||||
const ChannelInfo *ci = it->second;
|
||||
|
||||
if (!is_servadmin && (ci->HasExt("PRIVATE") || ci->HasExt("SUSPENDED")))
|
||||
if (!is_servadmin && (ci->HasExt("CS_PRIVATE") || ci->HasExt("SUSPENDED")))
|
||||
continue;
|
||||
else if (suspended && !ci->HasExt("SUSPENDED"))
|
||||
continue;
|
||||
else if (channoexpire && !ci->HasExt("NO_EXPIRE"))
|
||||
else if (channoexpire && !ci->HasExt("CS_NO_EXPIRE"))
|
||||
continue;
|
||||
|
||||
if (pattern.equals_ci(ci->name) || ci->name.equals_ci(spattern) || Anope::Match(ci->name, pattern, false, true) || Anope::Match(ci->name, spattern, false, true))
|
||||
@@ -93,7 +93,7 @@ class CommandCSList : public Command
|
||||
if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nchans <= listmax)
|
||||
{
|
||||
bool isnoexpire = false;
|
||||
if (is_servadmin && (ci->HasExt("NO_EXPIRE")))
|
||||
if (is_servadmin && (ci->HasExt("CS_NO_EXPIRE")))
|
||||
isnoexpire = true;
|
||||
|
||||
ListFormatter::ListEntry entry;
|
||||
@@ -159,14 +159,89 @@ class CommandCSList : public Command
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSSetPrivate : public Command
|
||||
{
|
||||
public:
|
||||
CommandCSSetPrivate(Module *creator, const Anope::string &cname = "chanserv/set/private") : Command(creator, cname, 2, 2)
|
||||
{
|
||||
this->SetDesc(_("Hide channel from the LIST command"));
|
||||
this->SetSyntax(_("\037channel\037 {ON | OFF}"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
ChannelInfo *ci = ChannelInfo::Find(params[0]);
|
||||
if (ci == NULL)
|
||||
{
|
||||
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
EventReturn MOD_RESULT;
|
||||
FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
return;
|
||||
|
||||
if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
|
||||
{
|
||||
source.Reply(ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (params[1].equals_ci("ON"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable private";
|
||||
ci->Extend<bool>("CS_PRIVATE");
|
||||
source.Reply(_("Private option for %s is now \002on\002."), ci->name.c_str());
|
||||
}
|
||||
else if (params[1].equals_ci("OFF"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable private";
|
||||
ci->Shrink<bool>("CS_PRIVATE");
|
||||
source.Reply(_("Private option for %s is now \002off\002."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, "PRIVATE");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_("Enables or disables the \002private\002 option for a channel."));
|
||||
|
||||
BotInfo *bi;
|
||||
Anope::string cmd;
|
||||
if (Command::FindCommandFromService("chanserv/list", bi, cmd))
|
||||
source.Reply(_("When \002private\002 is set, the channel will not appear in\n"
|
||||
"%s's %s command."), bi->nick.c_str(), cmd.c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CSList : public Module
|
||||
{
|
||||
CommandCSList commandcslist;
|
||||
CommandCSSetPrivate commandcssetprivate;
|
||||
|
||||
SerializableExtensibleItem<bool> priv;
|
||||
|
||||
public:
|
||||
CSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcslist(this)
|
||||
CSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
commandcslist(this), commandcssetprivate(this), priv(this, "CS_PRIVATE")
|
||||
{
|
||||
}
|
||||
|
||||
void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_all) anope_override
|
||||
{
|
||||
if (!show_all)
|
||||
return;
|
||||
|
||||
if (priv.HasExt(ci))
|
||||
info.AddOption(_("Private"));
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_INIT(CSList)
|
||||
|
||||
+102
-24
@@ -10,6 +10,77 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/cs_log.h"
|
||||
|
||||
struct LogSettingImpl : LogSetting, Serializable
|
||||
{
|
||||
LogSettingImpl() : Serializable("LogSetting")
|
||||
{
|
||||
}
|
||||
|
||||
~LogSettingImpl()
|
||||
{
|
||||
ChannelInfo *ci = ChannelInfo::Find(chan);
|
||||
if (ci)
|
||||
{
|
||||
LogSettings *ls = ci->Require<LogSettings>("logsettings");
|
||||
LogSettings::iterator it = std::find((*ls)->begin(), (*ls)->end(), this);
|
||||
if (it != (*ls)->end())
|
||||
(*ls)->erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void Serialize(Serialize::Data &data) const anope_override
|
||||
{
|
||||
data["ci"] << chan;
|
||||
data["service_name"] << service_name;
|
||||
data["command_service"] << command_service;
|
||||
data["command_name"] << command_name;
|
||||
data["method"] << method;
|
||||
data["extra"] << extra;
|
||||
data["creator"] << creator;
|
||||
data.SetType("created", Serialize::Data::DT_INT); data["created"] << created;
|
||||
}
|
||||
|
||||
static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
{
|
||||
Anope::string sci;
|
||||
data["ci"] >> sci;
|
||||
|
||||
ChannelInfo *ci = ChannelInfo::Find(sci);
|
||||
if (ci == NULL)
|
||||
return NULL;
|
||||
|
||||
LogSetting *ls;
|
||||
if (obj)
|
||||
ls = anope_dynamic_static_cast<LogSettingImpl *>(obj);
|
||||
else
|
||||
{
|
||||
LogSettings *lsettings = ci->Require<LogSettings>("logsettings");
|
||||
ls = new LogSettingImpl();
|
||||
(*lsettings)->push_back(ls);
|
||||
}
|
||||
|
||||
ls->chan = ci->name;
|
||||
data["service_name"] >> ls->service_name;
|
||||
data["command_service"] >> ls->command_service;
|
||||
data["command_name"] >> ls->command_name;
|
||||
data["method"] >> ls->method;
|
||||
data["extra"] >> ls->extra;
|
||||
data["creator"] >> ls->creator;
|
||||
data["created"] >> ls->created;
|
||||
}
|
||||
};
|
||||
|
||||
struct LogSettingsImpl : LogSettings
|
||||
{
|
||||
LogSettingsImpl(Extensible *) { }
|
||||
|
||||
LogSetting *Create() anope_override
|
||||
{
|
||||
return new LogSettingImpl();
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSLog : public Command
|
||||
{
|
||||
@@ -32,16 +103,17 @@ public:
|
||||
source.Reply(ACCESS_DENIED);
|
||||
else if (params.size() == 1)
|
||||
{
|
||||
if (ci->log_settings->empty())
|
||||
LogSettings *ls = ci->Require<LogSettings>("logsettings");
|
||||
if (!ls || (*ls)->empty())
|
||||
source.Reply(_("There currently are no logging configurations for %s."), ci->name.c_str());
|
||||
else
|
||||
{
|
||||
ListFormatter list;
|
||||
list.AddColumn("Number").AddColumn("Service").AddColumn("Command").AddColumn("Method").AddColumn("");
|
||||
|
||||
for (unsigned i = 0; i < ci->log_settings->size(); ++i)
|
||||
for (unsigned i = 0; i < (*ls)->size(); ++i)
|
||||
{
|
||||
const LogSetting *log = ci->log_settings->at(i);
|
||||
const LogSetting *log = (*ls)->at(i);
|
||||
|
||||
ListFormatter::ListEntry entry;
|
||||
entry["Number"] = stringify(i + 1);
|
||||
@@ -63,6 +135,7 @@ public:
|
||||
}
|
||||
else if (params.size() > 2)
|
||||
{
|
||||
LogSettings *ls = ci->Require<LogSettings>("logsettings");
|
||||
const Anope::string &command = params[1];
|
||||
const Anope::string &method = params[2];
|
||||
const Anope::string &extra = params.size() > 3 ? params[3] : "";
|
||||
@@ -106,16 +179,15 @@ public:
|
||||
|
||||
bool override = !source.AccessFor(ci).HasPriv("SET");
|
||||
|
||||
for (unsigned i = ci->log_settings->size(); i > 0; --i)
|
||||
for (unsigned i = (*ls)->size(); i > 0; --i)
|
||||
{
|
||||
LogSetting *log = ci->log_settings->at(i - 1);
|
||||
LogSetting *log = (*ls)->at(i - 1);
|
||||
|
||||
if (log->service_name == bi->commands[command_name].name && log->method.equals_ci(method))
|
||||
{
|
||||
if (log->extra == extra)
|
||||
{
|
||||
delete log;
|
||||
ci->log_settings->erase(ci->log_settings->begin() + i - 1);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to remove logging for " << command << " with method " << method << (extra == "" ? "" : " ") << extra;
|
||||
source.Reply(_("Logging for command %s on %s with log method %s%s%s has been removed."), command_name.c_str(), bi->nick.c_str(), method.c_str(), extra.empty() ? "" : " ", extra.empty() ? "" : extra.c_str());
|
||||
}
|
||||
@@ -129,8 +201,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
LogSetting *log = new LogSetting();
|
||||
log->ci = ci;
|
||||
LogSetting *log = new LogSettingImpl();
|
||||
log->chan = ci->name;
|
||||
log->service_name = bi->commands[command_name].name;
|
||||
log->command_service = bi->nick;
|
||||
log->command_name = command_name;
|
||||
@@ -139,7 +211,8 @@ public:
|
||||
log->created = Anope::CurTime;
|
||||
log->creator = source.GetNick();
|
||||
|
||||
ci->log_settings->push_back(log);
|
||||
(*ls)->push_back(log);
|
||||
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to log " << command << " with method " << method << (extra == "" ? "" : " ") << extra;
|
||||
|
||||
source.Reply(_("Logging is now active for command %s on %s, using log method %s%s%s."), command_name.c_str(), bi->nick.c_str(), method.c_str(), extra.empty() ? "" : " ", extra.empty() ? "" : extra.c_str());
|
||||
@@ -180,10 +253,13 @@ class CSLog : public Module
|
||||
{
|
||||
ServiceReference<MemoServService> MSService;
|
||||
CommandCSLog commandcslog;
|
||||
ExtensibleItem<LogSettingsImpl> logsettings;
|
||||
Serialize::Type logsetting_type;
|
||||
|
||||
public:
|
||||
CSLog(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
MSService("MemoServService", "MemoServ"), commandcslog(this)
|
||||
MSService("MemoServService", "MemoServ"), commandcslog(this), logsettings(this, "logsettings"),
|
||||
logsetting_type("LogSetting", LogSettingImpl::Unserialize)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -193,25 +269,27 @@ class CSLog : public Module
|
||||
if (l->type != LOG_COMMAND || l->u == NULL || l->c == NULL || l->ci == NULL || !Me || !Me->IsSynced())
|
||||
return;
|
||||
|
||||
for (unsigned i = l->ci->log_settings->size(); i > 0; --i)
|
||||
{
|
||||
const LogSetting *log = l->ci->log_settings->at(i - 1);
|
||||
|
||||
if (log->service_name == l->c->name)
|
||||
LogSettings *ls = logsettings.Get(l->ci);
|
||||
if (ls)
|
||||
for (unsigned i = 0; i < (*ls)->size(); ++i)
|
||||
{
|
||||
Anope::string buffer = l->u->nick + " used " + log->command_name + " " + l->buf.str();
|
||||
const LogSetting *log = (*ls)->at(i);
|
||||
|
||||
if (log->method.equals_ci("MESSAGE") && l->ci->c && l->ci->bi && l->ci->c->FindUser(l->ci->bi) != NULL)
|
||||
if (log->service_name == l->c->name)
|
||||
{
|
||||
IRCD->SendPrivmsg(l->ci->bi, log->extra + l->ci->c->name, "%s", buffer.c_str());
|
||||
l->ci->bi->lastmsg = Anope::CurTime;
|
||||
Anope::string buffer = l->u->nick + " used " + log->command_name + " " + l->buf.str();
|
||||
|
||||
if (log->method.equals_ci("MESSAGE") && l->ci->c && l->ci->bi && l->ci->c->FindUser(l->ci->bi) != NULL)
|
||||
{
|
||||
IRCD->SendPrivmsg(l->ci->bi, log->extra + l->ci->c->name, "%s", buffer.c_str());
|
||||
l->ci->bi->lastmsg = Anope::CurTime;
|
||||
}
|
||||
else if (log->method.equals_ci("NOTICE") && l->ci->c && l->ci->bi && l->ci->c->FindUser(l->ci->bi) != NULL)
|
||||
IRCD->SendNotice(l->ci->bi, log->extra + l->ci->c->name, "%s", buffer.c_str());
|
||||
else if (log->method.equals_ci("MEMO") && MSService && l->ci->WhoSends() != NULL)
|
||||
MSService->Send(l->ci->WhoSends()->nick, l->ci->name, buffer, true);
|
||||
}
|
||||
else if (log->method.equals_ci("NOTICE") && l->ci->c && l->ci->bi && l->ci->c->FindUser(l->ci->bi) != NULL)
|
||||
IRCD->SendNotice(l->ci->bi, log->extra + l->ci->c->name, "%s", buffer.c_str());
|
||||
else if (log->method.equals_ci("MEMO") && MSService && l->ci->WhoSends() != NULL)
|
||||
MSService->Send(l->ci->WhoSends()->nick, l->ci->name, buffer, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+354
-14
@@ -10,6 +10,234 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/cs_mode.h"
|
||||
|
||||
struct ModeLockImpl : ModeLock, Serializable
|
||||
{
|
||||
ModeLockImpl() : Serializable("ModeLock")
|
||||
{
|
||||
}
|
||||
|
||||
~ModeLockImpl()
|
||||
{
|
||||
ChannelInfo *chan = ChannelInfo::Find(ci);
|
||||
if (chan)
|
||||
{
|
||||
ModeLocks *ml = chan->GetExt<ModeLocks>("modelocks");
|
||||
if (ml)
|
||||
ml->RemoveMLock(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Serialize(Serialize::Data &data) const anope_override;
|
||||
static Serializable* Unserialize(Serializable *obj, Serialize::Data &data);
|
||||
};
|
||||
|
||||
struct ModeLocksImpl : ModeLocks
|
||||
{
|
||||
Serialize::Reference<ChannelInfo> ci;
|
||||
Serialize::Checker<ModeList> mlocks;
|
||||
|
||||
ModeLocksImpl(Extensible *obj) : ci(anope_dynamic_static_cast<ChannelInfo *>(obj)), mlocks("ModeLock")
|
||||
{
|
||||
}
|
||||
|
||||
bool HasMLock(ChannelMode *mode, const Anope::string ¶m, bool status) const anope_override
|
||||
{
|
||||
if (!mode)
|
||||
return false;
|
||||
|
||||
for (ModeList::const_iterator it = this->mlocks->begin(); it != this->mlocks->end(); ++it)
|
||||
{
|
||||
const ModeLock *ml = *it;
|
||||
|
||||
if (ml->name == mode->name && ml->set == status && ml->param == param)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SetMLock(ChannelMode *mode, bool status, const Anope::string ¶m, Anope::string setter, time_t created = Anope::CurTime) anope_override
|
||||
{
|
||||
if (!mode)
|
||||
return false;
|
||||
|
||||
RemoveMLock(mode, status, param);
|
||||
|
||||
if (setter.empty())
|
||||
setter = ci->GetFounder() ? ci->GetFounder()->display : "Unknown";
|
||||
|
||||
ModeLock *ml = new ModeLockImpl();
|
||||
ml->ci = ci->name;
|
||||
ml->set = status;
|
||||
ml->name = mode->name;
|
||||
ml->param = param;
|
||||
ml->setter = setter;
|
||||
ml->created = created;
|
||||
|
||||
EventReturn MOD_RESULT;
|
||||
FOREACH_RESULT(OnMLock, MOD_RESULT, (this->ci, ml));
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
{
|
||||
delete ml;
|
||||
return false;
|
||||
}
|
||||
|
||||
this->mlocks->push_back(ml);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RemoveMLock(ChannelMode *mode, bool status, const Anope::string ¶m = "") anope_override
|
||||
{
|
||||
if (!mode)
|
||||
return false;
|
||||
|
||||
for (ModeList::iterator it = this->mlocks->begin(); it != this->mlocks->end(); ++it)
|
||||
{
|
||||
ModeLock *m = *it;
|
||||
|
||||
if (m->name == mode->name)
|
||||
{
|
||||
// For list or status modes, we must check the parameter
|
||||
if (mode->type == MODE_LIST || mode->type == MODE_STATUS)
|
||||
if (m->param != param)
|
||||
continue;
|
||||
|
||||
EventReturn MOD_RESULT;
|
||||
FOREACH_RESULT(OnUnMLock, MOD_RESULT, (this->ci, m));
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
break;
|
||||
|
||||
delete m;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void RemoveMLock(ModeLock *mlock) anope_override
|
||||
{
|
||||
ModeList::iterator it = std::find(this->mlocks->begin(), this->mlocks->end(), mlock);
|
||||
if (it != this->mlocks->end())
|
||||
this->mlocks->erase(it);
|
||||
}
|
||||
|
||||
void ClearMLock() anope_override
|
||||
{
|
||||
ModeList ml;
|
||||
this->mlocks->swap(ml);
|
||||
for (unsigned i = 0; i < ml.size(); ++i)
|
||||
delete ml[i];
|
||||
}
|
||||
|
||||
const ModeList &GetMLock() const anope_override
|
||||
{
|
||||
return this->mlocks;
|
||||
}
|
||||
|
||||
std::list<ModeLock *> GetModeLockList(const Anope::string &name) anope_override
|
||||
{
|
||||
std::list<ModeLock *> mlist;
|
||||
for (ModeList::const_iterator it = this->mlocks->begin(); it != this->mlocks->end(); ++it)
|
||||
{
|
||||
ModeLock *m = *it;
|
||||
if (m->name == name)
|
||||
mlist.push_back(m);
|
||||
}
|
||||
return mlist;
|
||||
}
|
||||
|
||||
const ModeLock *GetMLock(const Anope::string &mname, const Anope::string ¶m = "") anope_override
|
||||
{
|
||||
for (ModeList::const_iterator it = this->mlocks->begin(); it != this->mlocks->end(); ++it)
|
||||
{
|
||||
ModeLock *m = *it;
|
||||
|
||||
if (m->name == mname && m->param == param)
|
||||
return m;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Anope::string GetMLockAsString(bool complete) const anope_override
|
||||
{
|
||||
Anope::string pos = "+", neg = "-", params;
|
||||
|
||||
for (ModeList::const_iterator it = this->mlocks->begin(); it != this->mlocks->end(); ++it)
|
||||
{
|
||||
const ModeLock *ml = *it;
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name);
|
||||
|
||||
if (!cm || cm->type == MODE_LIST || cm->type == MODE_STATUS)
|
||||
continue;
|
||||
|
||||
if (ml->set)
|
||||
pos += cm->mchar;
|
||||
else
|
||||
neg += cm->mchar;
|
||||
|
||||
if (complete && ml->set && !ml->param.empty() && cm->type == MODE_PARAM)
|
||||
params += " " + ml->param;
|
||||
}
|
||||
|
||||
if (pos.length() == 1)
|
||||
pos.clear();
|
||||
if (neg.length() == 1)
|
||||
neg.clear();
|
||||
|
||||
return pos + neg + params;
|
||||
}
|
||||
|
||||
void Check() anope_override
|
||||
{
|
||||
if (this->mlocks->empty())
|
||||
ci->Shrink<ModeLocks>("modelocks");
|
||||
}
|
||||
};
|
||||
|
||||
void ModeLockImpl::Serialize(Serialize::Data &data) const
|
||||
{
|
||||
data["ci"] << this->ci;
|
||||
data["set"] << this->set;
|
||||
data["name"] << this->name;
|
||||
data["param"] << this->param;
|
||||
data["setter"] << this->setter;
|
||||
data.SetType("created", Serialize::Data::DT_INT); data["created"] << this->created;
|
||||
}
|
||||
|
||||
Serializable* ModeLockImpl::Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
{
|
||||
Anope::string sci;
|
||||
|
||||
data["ci"] >> sci;
|
||||
|
||||
ChannelInfo *ci = ChannelInfo::Find(sci);
|
||||
if (!ci)
|
||||
return NULL;
|
||||
|
||||
ModeLockImpl *ml;
|
||||
if (obj)
|
||||
ml = anope_dynamic_static_cast<ModeLockImpl *>(obj);
|
||||
else
|
||||
{
|
||||
ml = new ModeLockImpl();
|
||||
ml->ci = ci->name;
|
||||
}
|
||||
|
||||
data["set"] >> ml->set;
|
||||
data["created"] >> ml->created;
|
||||
data["setter"] >> ml->setter;
|
||||
data["name"] >> ml->name;
|
||||
data["param"] >> ml->param;
|
||||
|
||||
if (!obj)
|
||||
ci->Require<ModeLocksImpl>("modelocks")->mlocks->push_back(ml);
|
||||
|
||||
return ml;
|
||||
}
|
||||
|
||||
class CommandCSMode : public Command
|
||||
{
|
||||
@@ -28,21 +256,20 @@ class CommandCSMode : public Command
|
||||
const Anope::string ¶m = params.size() > 3 ? params[3] : "";
|
||||
|
||||
bool override = !source.AccessFor(ci).HasPriv("MODE");
|
||||
ModeLocks *modelocks = ci->Require<ModeLocks>("modelocks");
|
||||
|
||||
if ((subcommand.equals_ci("ADD") || subcommand.equals_ci("SET")) && !param.empty())
|
||||
{
|
||||
/* If setting, remove the existing locks */
|
||||
if (subcommand.equals_ci("SET"))
|
||||
{
|
||||
const ChannelInfo::ModeList &mlocks = ci->GetMLock();
|
||||
for (ChannelInfo::ModeList::const_iterator it = mlocks.begin(), it_next; it != mlocks.end(); it = it_next)
|
||||
const ModeLocks::ModeList mlocks = modelocks->GetMLock();
|
||||
for (ModeLocks::ModeList::const_iterator it = mlocks.begin(); it != mlocks.end(); ++it)
|
||||
{
|
||||
const ModeLock *ml = it->second;
|
||||
const ModeLock *ml = *it;
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name);
|
||||
it_next = it;
|
||||
++it_next;
|
||||
if (cm && cm->CanSet(source.GetUser()))
|
||||
ci->RemoveMLock(cm, ml->set, ml->param);
|
||||
modelocks->RemoveMLock(cm, ml->set, ml->param);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +313,7 @@ class CommandCSMode : public Command
|
||||
source.Reply(_("List for mode %c is full."), cm->mchar);
|
||||
else
|
||||
{
|
||||
ci->SetMLock(cm, adding, mode_param, source.GetNick());
|
||||
modelocks->SetMLock(cm, adding, mode_param, source.GetNick());
|
||||
|
||||
if (adding)
|
||||
{
|
||||
@@ -110,8 +337,8 @@ class CommandCSMode : public Command
|
||||
neg.clear();
|
||||
Anope::string reply = pos + neg + pos_params + neg_params;
|
||||
|
||||
source.Reply(_("%s locked on %s."), ci->GetMLockAsString(true).c_str(), ci->name.c_str());
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to lock " << ci->GetMLockAsString(true);
|
||||
source.Reply(_("%s locked on %s."), modelocks->GetMLockAsString(true).c_str(), ci->name.c_str());
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to lock " << modelocks->GetMLockAsString(true);
|
||||
|
||||
if (ci->c)
|
||||
ci->c->CheckModes();
|
||||
@@ -154,7 +381,7 @@ class CommandCSMode : public Command
|
||||
source.Reply(_("Missing parameter for mode %c."), cm->mchar);
|
||||
else
|
||||
{
|
||||
if (ci->RemoveMLock(cm, adding, mode_param))
|
||||
if (modelocks->RemoveMLock(cm, adding, mode_param))
|
||||
{
|
||||
if (!mode_param.empty())
|
||||
mode_param = " " + mode_param;
|
||||
@@ -169,7 +396,7 @@ class CommandCSMode : public Command
|
||||
}
|
||||
else if (subcommand.equals_ci("LIST"))
|
||||
{
|
||||
const ChannelInfo::ModeList &mlocks = ci->GetMLock();
|
||||
const ModeLocks::ModeList mlocks = modelocks->GetMLock();
|
||||
if (mlocks.empty())
|
||||
{
|
||||
source.Reply(_("Channel %s has no mode locks."), ci->name.c_str());
|
||||
@@ -179,9 +406,9 @@ class CommandCSMode : public Command
|
||||
ListFormatter list;
|
||||
list.AddColumn("Mode").AddColumn("Param").AddColumn("Creator").AddColumn("Created");
|
||||
|
||||
for (ChannelInfo::ModeList::const_iterator it = mlocks.begin(), it_end = mlocks.end(); it != it_end; ++it)
|
||||
for (ModeLocks::ModeList::const_iterator it = mlocks.begin(), it_end = mlocks.end(); it != it_end; ++it)
|
||||
{
|
||||
const ModeLock *ml = it->second;
|
||||
const ModeLock *ml = *it;
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name);
|
||||
if (!cm)
|
||||
continue;
|
||||
@@ -481,13 +708,126 @@ class CommandCSMode : public Command
|
||||
class CSMode : public Module
|
||||
{
|
||||
CommandCSMode commandcsmode;
|
||||
ExtensibleItem<ModeLocksImpl> modelocks;
|
||||
Serialize::Type modelocks_type;
|
||||
|
||||
public:
|
||||
CSMode(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
commandcsmode(this)
|
||||
commandcsmode(this), modelocks(this, "modelocks"), modelocks_type("ModeLock", ModeLockImpl::Unserialize)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
EventReturn OnCheckModes(Channel *c) anope_override
|
||||
{
|
||||
if (!c->ci)
|
||||
return EVENT_CONTINUE;
|
||||
|
||||
ModeLocks *ml = modelocks.Get(c->ci);
|
||||
if (ml)
|
||||
for (ModeLocks::ModeList::const_iterator it = ml->GetMLock().begin(), it_end = ml->GetMLock().end(); it != it_end; ++it)
|
||||
{
|
||||
const ModeLock *ml = *it;
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name);
|
||||
if (!cm)
|
||||
continue;
|
||||
|
||||
if (cm->type == MODE_REGULAR)
|
||||
{
|
||||
if (!c->HasMode(cm->name) && ml->set)
|
||||
c->SetMode(NULL, cm);
|
||||
else if (c->HasMode(cm->name) && !ml->set)
|
||||
c->RemoveMode(NULL, cm);
|
||||
}
|
||||
else if (cm->type == MODE_PARAM)
|
||||
{
|
||||
/* If the channel doesnt have the mode, or it does and it isn't set correctly */
|
||||
if (ml->set)
|
||||
{
|
||||
Anope::string param;
|
||||
c->GetParam(cm->name, param);
|
||||
|
||||
if (!c->HasMode(cm->name) || (!param.empty() && !ml->param.empty() && !param.equals_cs(ml->param)))
|
||||
c->SetMode(NULL, cm, ml->param);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c->HasMode(cm->name))
|
||||
c->RemoveMode(NULL, cm);
|
||||
}
|
||||
|
||||
}
|
||||
else if (cm->type == MODE_LIST)
|
||||
{
|
||||
if (ml->set)
|
||||
c->SetMode(NULL, cm, ml->param);
|
||||
else
|
||||
c->RemoveMode(NULL, cm, ml->param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) anope_override
|
||||
{
|
||||
if (!c->ci)
|
||||
return EVENT_CONTINUE;
|
||||
|
||||
ModeLocks *ml = modelocks.Get(c->ci);
|
||||
if (!ml)
|
||||
return EVENT_CONTINUE;
|
||||
|
||||
if (ml->HasMLock(mode, param, false))
|
||||
c->RemoveMode(c->ci->WhoSends(), mode, param);
|
||||
}
|
||||
|
||||
EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) anope_override
|
||||
{
|
||||
if (!c->ci)
|
||||
return EVENT_CONTINUE;
|
||||
|
||||
ModeLocks *ml = modelocks.Get(c->ci);
|
||||
if (!ml)
|
||||
return EVENT_CONTINUE;
|
||||
|
||||
if (ml->HasMLock(mode, param, true))
|
||||
c->SetMode(c->ci->WhoSends(), mode, param);
|
||||
}
|
||||
|
||||
void OnCreateChan(ChannelInfo *ci) anope_override
|
||||
{
|
||||
ModeLocks *ml = modelocks.Require(ci);
|
||||
Anope::string modes;
|
||||
spacesepstream sep(Config->GetModule(this)->Get<const Anope::string>("mlock", "+nrt"));
|
||||
if (sep.GetToken(modes))
|
||||
{
|
||||
bool add = true;
|
||||
for (unsigned i = 0; i < modes.length(); ++i)
|
||||
{
|
||||
if (modes[i] == '+')
|
||||
add = true;
|
||||
else if (modes[i] == '-')
|
||||
add = false;
|
||||
else
|
||||
{
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
|
||||
Anope::string param;
|
||||
if (cm && (cm->type == MODE_REGULAR || sep.GetToken(param)))
|
||||
ml->SetMLock(cm, add, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
ml->Check();
|
||||
}
|
||||
|
||||
void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_hidden) anope_override
|
||||
{
|
||||
if (!show_hidden)
|
||||
return;
|
||||
|
||||
ModeLocks *ml = modelocks.Get(ci);
|
||||
if (ml)
|
||||
info[_("Mode lock")] = ml->GetMLockAsString(true);
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_INIT(CSMode)
|
||||
|
||||
@@ -95,7 +95,7 @@ static bool ShouldHide(const Anope::string &channel, User *u)
|
||||
|
||||
if (targetchan && targetchan->HasMode("SECRET"))
|
||||
return true;
|
||||
else if (targetchan_ci && targetchan_ci->HasExt("PRIVATE"))
|
||||
else if (targetchan_ci && targetchan_ci->HasExt("CS_PRIVATE"))
|
||||
return true;
|
||||
else if (u && u->HasMode("PRIV"))
|
||||
return true;
|
||||
|
||||
+98
-165
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/cs_mode.h"
|
||||
|
||||
class CommandCSSet : public Command
|
||||
{
|
||||
@@ -86,13 +87,13 @@ class CommandCSSetAutoOp : public Command
|
||||
if (params[1].equals_ci("ON"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable autoop";
|
||||
ci->Shrink("NOAUTOOP");
|
||||
ci->Shrink<bool>("NOAUTOOP");
|
||||
source.Reply(_("Services will now automatically give modes to users in \002%s\002."), ci->name.c_str());
|
||||
}
|
||||
else if (params[1].equals_ci("OFF"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable autoop";
|
||||
ci->ExtendMetadata("NOAUTOOP");
|
||||
ci->Extend<bool>("NOAUTOOP");
|
||||
source.Reply(_("Services will no longer automatically give modes to users in \002%s\002."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
@@ -203,14 +204,14 @@ class CommandCSSetChanstats : public Command
|
||||
|
||||
if (params[1].equals_ci("ON"))
|
||||
{
|
||||
ci->ExtendMetadata("STATS");
|
||||
ci->Extend<bool>("CS_STATS");
|
||||
source.Reply(_("Chanstats statistics are now enabled for this channel."));
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable chanstats";
|
||||
}
|
||||
else if (params[1].equals_ci("OFF"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable chanstats";
|
||||
ci->Shrink("STATS");
|
||||
ci->Shrink<bool>("CS_STATS");
|
||||
source.Reply(_("Chanstats statistics are now disabled for this channel."));
|
||||
}
|
||||
else
|
||||
@@ -344,64 +345,6 @@ class CommandCSSetFounder : public Command
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSSetKeepTopic : public Command
|
||||
{
|
||||
public:
|
||||
CommandCSSetKeepTopic(Module *creator, const Anope::string &cname = "chanserv/set/keeptopic") : Command(creator, cname, 2, 2)
|
||||
{
|
||||
this->SetDesc(_("Retain topic when channel is not in use"));
|
||||
this->SetSyntax(_("\037channel\037 {ON | OFF}"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
ChannelInfo *ci = ChannelInfo::Find(params[0]);
|
||||
if (ci == NULL)
|
||||
{
|
||||
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
EventReturn MOD_RESULT;
|
||||
FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
return;
|
||||
|
||||
if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
|
||||
{
|
||||
source.Reply(ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (params[1].equals_ci("ON"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable keeptopic";
|
||||
ci->ExtendMetadata("KEEPTOPIC");
|
||||
source.Reply(_("Topic retention option for %s is now \002on\002."), ci->name.c_str());
|
||||
}
|
||||
else if (params[1].equals_ci("OFF"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable keeptopic";
|
||||
ci->Shrink("KEEPTOPIC");
|
||||
source.Reply(_("Topic retention option for %s is now \002off\002."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, "KEEPTOPIC");
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_("Enables or disables the \002topic retention\002 option for a\n"
|
||||
"channel. When \002%s\002 is set, the topic for the\n"
|
||||
"channel will be remembered by %s even after the\n"
|
||||
"last user leaves the channel, and will be restored the\n"
|
||||
"next time the channel is created."), this->name.c_str(), source.service->nick.c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSSetPeace : public Command
|
||||
{
|
||||
public:
|
||||
@@ -433,13 +376,13 @@ class CommandCSSetPeace : public Command
|
||||
if (params[1].equals_ci("ON"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable peace";
|
||||
ci->ExtendMetadata("PEACE");
|
||||
ci->Extend<bool>("PEACE");
|
||||
source.Reply(_("Peace option for %s is now \002on\002."), ci->name.c_str());
|
||||
}
|
||||
else if (params[1].equals_ci("OFF"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable peace";
|
||||
ci->Shrink("PEACE");
|
||||
ci->Shrink<bool>("PEACE");
|
||||
source.Reply(_("Peace option for %s is now \002off\002."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
@@ -495,7 +438,7 @@ class CommandCSSetPersist : public Command
|
||||
{
|
||||
if (!ci->HasExt("PERSIST"))
|
||||
{
|
||||
ci->ExtendMetadata("PERSIST");
|
||||
ci->Extend<bool>("PERSIST");
|
||||
|
||||
/* Channel doesn't exist, create it */
|
||||
if (!ci->c)
|
||||
@@ -535,7 +478,9 @@ class CommandCSSetPersist : public Command
|
||||
if (ci->c && !ci->c->HasMode("PERM"))
|
||||
ci->c->SetMode(NULL, cm);
|
||||
/* Add it to the channels mlock */
|
||||
ci->SetMLock(cm, true);
|
||||
ModeLocks *ml = ci->Require<ModeLocks>("modelocks");
|
||||
if (ml)
|
||||
ml->SetMLock(cm, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,7 +491,7 @@ class CommandCSSetPersist : public Command
|
||||
{
|
||||
if (ci->HasExt("PERSIST"))
|
||||
{
|
||||
ci->Shrink("PERSIST");
|
||||
ci->Shrink<bool>("PERSIST");
|
||||
|
||||
/* Unset perm mode */
|
||||
if (cm)
|
||||
@@ -554,7 +499,9 @@ class CommandCSSetPersist : public Command
|
||||
if (ci->c && ci->c->HasMode("PERM"))
|
||||
ci->c->RemoveMode(NULL, cm);
|
||||
/* Remove from mlock */
|
||||
ci->RemoveMLock(cm, true);
|
||||
ModeLocks *ml = ci->GetExt<ModeLocks>("modelocks");
|
||||
if (ml)
|
||||
ml->RemoveMLock(cm, true);
|
||||
}
|
||||
|
||||
/* No channel mode, no BotServ, but using ChanServ as the botserv bot
|
||||
@@ -608,68 +555,6 @@ class CommandCSSetPersist : public Command
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSSetPrivate : public Command
|
||||
{
|
||||
public:
|
||||
CommandCSSetPrivate(Module *creator, const Anope::string &cname = "chanserv/set/private") : Command(creator, cname, 2, 2)
|
||||
{
|
||||
this->SetDesc(_("Hide channel from the LIST command"));
|
||||
this->SetSyntax(_("\037channel\037 {ON | OFF}"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
ChannelInfo *ci = ChannelInfo::Find(params[0]);
|
||||
if (ci == NULL)
|
||||
{
|
||||
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
EventReturn MOD_RESULT;
|
||||
FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
return;
|
||||
|
||||
if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
|
||||
{
|
||||
source.Reply(ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (params[1].equals_ci("ON"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable private";
|
||||
ci->ExtendMetadata("PRIVATE");
|
||||
source.Reply(_("Private option for %s is now \002on\002."), ci->name.c_str());
|
||||
}
|
||||
else if (params[1].equals_ci("OFF"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable private";
|
||||
ci->Shrink("PRIVATE");
|
||||
source.Reply(_("Private option for %s is now \002off\002."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, "PRIVATE");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_("Enables or disables the \002private\002 option for a channel."));
|
||||
|
||||
BotInfo *bi;
|
||||
Anope::string cmd;
|
||||
if (Command::FindCommandFromService("chanserv/list", bi, cmd))
|
||||
source.Reply(_("When \002private\002 is set, the channel will not appear in\n"
|
||||
"%s's %s command."), bi->nick.c_str(), cmd.c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSSetRestricted : public Command
|
||||
{
|
||||
public:
|
||||
@@ -702,13 +587,13 @@ class CommandCSSetRestricted : public Command
|
||||
if (params[1].equals_ci("ON"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable restricted";
|
||||
ci->ExtendMetadata("RESTRICTED");
|
||||
ci->Extend<bool>("RESTRICTED");
|
||||
source.Reply(_("Restricted access option for %s is now \002on\002."), ci->name.c_str());
|
||||
}
|
||||
else if (params[1].equals_ci("OFF"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable restricted";
|
||||
ci->Shrink("RESTRICTED");
|
||||
ci->Shrink<bool>("RESTRICTED");
|
||||
source.Reply(_("Restricted access option for %s is now \002off\002."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
@@ -758,13 +643,13 @@ class CommandCSSetSecure : public Command
|
||||
if (params[1].equals_ci("ON"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable secure";
|
||||
ci->ExtendMetadata("SECURE");
|
||||
ci->Extend<bool>("CS_SECURE");
|
||||
source.Reply(_("Secure option for %s is now \002on\002."), ci->name.c_str());
|
||||
}
|
||||
else if (params[1].equals_ci("OFF"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable secure";
|
||||
ci->Shrink("SECURE");
|
||||
ci->Shrink<bool>("CS_SECURE");
|
||||
source.Reply(_("Secure option for %s is now \002off\002."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
@@ -816,13 +701,13 @@ class CommandCSSetSecureFounder : public Command
|
||||
if (params[1].equals_ci("ON"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable secure founder";
|
||||
ci->ExtendMetadata("SECUREFOUNDER");
|
||||
ci->Extend<bool>("SECUREFOUNDER");
|
||||
source.Reply(_("Secure founder option for %s is now \002on\002."), ci->name.c_str());
|
||||
}
|
||||
else if (params[1].equals_ci("OFF"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable secure founder";
|
||||
ci->Shrink("SECUREFOUNDER");
|
||||
ci->Shrink<bool>("SECUREFOUNDER");
|
||||
source.Reply(_("Secure founder option for %s is now \002off\002."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
@@ -874,13 +759,13 @@ class CommandCSSetSecureOps : public Command
|
||||
if (params[1].equals_ci("ON"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable secure ops";
|
||||
ci->ExtendMetadata("SECUREOPS");
|
||||
ci->Extend<bool>("SECUREOPS");
|
||||
source.Reply(_("Secure ops option for %s is now \002on\002."), ci->name.c_str());
|
||||
}
|
||||
else if (params[1].equals_ci("OFF"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable secure ops";
|
||||
ci->Shrink("SECUREOPS");
|
||||
ci->Shrink<bool>("SECUREOPS");
|
||||
source.Reply(_("Secure ops option for %s is now \002off\002."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
@@ -904,7 +789,7 @@ class CommandCSSetSignKick : public Command
|
||||
CommandCSSetSignKick(Module *creator, const Anope::string &cname = "chanserv/set/signkick") : Command(creator, cname, 2, 2)
|
||||
{
|
||||
this->SetDesc(_("Sign kicks that are done with the KICK command"));
|
||||
this->SetSyntax(_("\037channel\037 SIGNKICK {ON | LEVEL | OFF}"));
|
||||
this->SetSyntax(_("\037channel\037 {ON | LEVEL | OFF}"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
@@ -929,23 +814,23 @@ class CommandCSSetSignKick : public Command
|
||||
|
||||
if (params[1].equals_ci("ON"))
|
||||
{
|
||||
ci->ExtendMetadata("SIGNKICK");
|
||||
ci->Shrink("SIGNKICK_LEVEL");
|
||||
ci->Extend<bool>("SIGNKICK");
|
||||
ci->Shrink<bool>("SIGNKICK_LEVEL");
|
||||
source.Reply(_("Signed kick option for %s is now \002on\002."), ci->name.c_str());
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable sign kick";
|
||||
}
|
||||
else if (params[1].equals_ci("LEVEL"))
|
||||
{
|
||||
ci->ExtendMetadata("SIGNKICK_LEVEL");
|
||||
ci->Shrink("SIGNKICK");
|
||||
ci->Extend<bool>("SIGNKICK_LEVEL");
|
||||
ci->Shrink<bool>("SIGNKICK");
|
||||
source.Reply(_("Signed kick option for %s is now \002on\002, but depends of the\n"
|
||||
"level of the user that is using the command."), ci->name.c_str());
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable sign kick level";
|
||||
}
|
||||
else if (params[1].equals_ci("OFF"))
|
||||
{
|
||||
ci->Shrink("SIGNKICK");
|
||||
ci->Shrink("SIGNKICK_LEVEL");
|
||||
ci->Shrink<bool>("SIGNKICK");
|
||||
ci->Shrink<bool>("SIGNKICK_LEVEL");
|
||||
source.Reply(_("Signed kick option for %s is now \002off\002."), ci->name.c_str());
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable sign kick";
|
||||
}
|
||||
@@ -1075,13 +960,13 @@ class CommandCSSetNoexpire : public Command
|
||||
if (params[1].equals_ci("ON"))
|
||||
{
|
||||
Log(LOG_ADMIN, source, this, ci) << "to enable noexpire";
|
||||
ci->ExtendMetadata("NO_EXPIRE");
|
||||
ci->Extend<bool>("CS_NO_EXPIRE");
|
||||
source.Reply(_("Channel %s \002will not\002 expire."), ci->name.c_str());
|
||||
}
|
||||
else if (params[1].equals_ci("OFF"))
|
||||
{
|
||||
Log(LOG_ADMIN, source, this, ci) << "to disable noexpire";
|
||||
ci->Shrink("NO_EXPIRE");
|
||||
ci->Shrink<bool>("CS_NO_EXPIRE");
|
||||
source.Reply(_("Channel %s \002will\002 expire."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
@@ -1102,16 +987,17 @@ class CommandCSSetNoexpire : public Command
|
||||
|
||||
class CSSet : public Module
|
||||
{
|
||||
SerializableExtensibleItem<bool> persist, noautoop, stats, peace, securefounder,
|
||||
restricted, secure, secureops, signkick, signkick_level, noexpire;
|
||||
|
||||
CommandCSSet commandcsset;
|
||||
CommandCSSetAutoOp commandcssetautoop;
|
||||
CommandCSSetBanType commandcssetbantype;
|
||||
CommandCSSetChanstats commandcssetchanstats;
|
||||
CommandCSSetDescription commandcssetdescription;
|
||||
CommandCSSetFounder commandcssetfounder;
|
||||
CommandCSSetKeepTopic commandcssetkeeptopic;
|
||||
CommandCSSetPeace commandcssetpeace;
|
||||
CommandCSSetPersist commandcssetpersist;
|
||||
CommandCSSetPrivate commandcssetprivate;
|
||||
CommandCSSetRestricted commandcssetrestricted;
|
||||
CommandCSSetSecure commandcssetsecure;
|
||||
CommandCSSetSecureFounder commandcssetsecurefounder;
|
||||
@@ -1122,17 +1008,27 @@ class CSSet : public Module
|
||||
|
||||
public:
|
||||
CSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
persist(this, "PERSIST"), noautoop(this, "NOAUTOOP"), stats(this, "CS_STATS"), peace(this, "PEACE"),
|
||||
securefounder(this, "SECUREFOUNDER"), restricted(this, "RESTRICTED"),
|
||||
secure(this, "CS_SECURE"), secureops(this, "SECUREOPS"), signkick(this, "SIGNKICK"),
|
||||
signkick_level(this, "SIGNKICK_LEVEL"), noexpire(this, "CS_NO_EXPIRE"),
|
||||
|
||||
commandcsset(this), commandcssetautoop(this), commandcssetbantype(this), commandcssetchanstats(this),
|
||||
commandcssetdescription(this), commandcssetfounder(this), commandcssetkeeptopic(this),
|
||||
commandcssetpeace(this), commandcssetpersist(this), commandcssetprivate(this), commandcssetrestricted(this),
|
||||
commandcssetdescription(this), commandcssetfounder(this),
|
||||
commandcssetpeace(this), commandcssetpersist(this), commandcssetrestricted(this),
|
||||
commandcssetsecure(this), commandcssetsecurefounder(this), commandcssetsecureops(this), commandcssetsignkick(this),
|
||||
commandcssetsuccessor(this), commandcssetnoexpire(this)
|
||||
{
|
||||
}
|
||||
|
||||
void OnCreateChan(ChannelInfo *ci) anope_override
|
||||
{
|
||||
ci->bantype = Config->GetModule(this)->Get<int>("defbantype", "2");
|
||||
}
|
||||
|
||||
EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) anope_override
|
||||
{
|
||||
if (!c->ci || !c->ci->HasExt("RESTRICTED") || c->MatchesList(u, "EXCEPT"))
|
||||
if (!c->ci || !restricted.HasExt(c->ci) || c->MatchesList(u, "EXCEPT"))
|
||||
return EVENT_CONTINUE;
|
||||
|
||||
if (c->ci->AccessFor(u).empty() && (!c->ci->GetFounder() || u->Account() != c->ci->GetFounder()))
|
||||
@@ -1143,30 +1039,30 @@ class CSSet : public Module
|
||||
|
||||
void OnDelChan(ChannelInfo *ci) anope_override
|
||||
{
|
||||
if (ci->c && ci->HasExt("PERSIST"))
|
||||
if (ci->c && persist.HasExt(ci))
|
||||
ci->c->RemoveMode(ci->WhoSends(), "PERM", "", false);
|
||||
ci->Shrink("PERSIST");
|
||||
persist.Unset(ci);
|
||||
}
|
||||
|
||||
EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, const Anope::string &mname, const Anope::string ¶m) anope_override
|
||||
EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) anope_override
|
||||
{
|
||||
/* Channel mode +P or so was set, mark this channel as persistent */
|
||||
if (mname == "PERM" && c->ci)
|
||||
if (mode->name == "PERM" && c->ci)
|
||||
{
|
||||
c->ci->ExtendMetadata("PERSIST");
|
||||
persist.Set(c->ci, true);
|
||||
}
|
||||
|
||||
return EVENT_CONTINUE;
|
||||
}
|
||||
|
||||
EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, const Anope::string &mname, const Anope::string ¶m) anope_override
|
||||
EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) anope_override
|
||||
{
|
||||
if (mname == "PERM")
|
||||
if (mode->name == "PERM")
|
||||
{
|
||||
if (c->ci)
|
||||
c->ci->Shrink("PERSIST");
|
||||
persist.Unset(c->ci);
|
||||
|
||||
if (c->users.empty() && !c->syncing && c->CheckDelete())
|
||||
if (c->CheckDelete())
|
||||
{
|
||||
delete c;
|
||||
return EVENT_STOP;
|
||||
@@ -1178,14 +1074,14 @@ class CSSet : public Module
|
||||
|
||||
EventReturn OnCheckDelete(Channel *c) anope_override
|
||||
{
|
||||
if (c->ci && c->ci->HasExt("PERSIST"))
|
||||
if (c->ci && persist.HasExt(c->ci))
|
||||
return EVENT_STOP;
|
||||
return EVENT_CONTINUE;
|
||||
}
|
||||
|
||||
void OnJoinChannel(User *u, Channel *c) anope_override
|
||||
{
|
||||
if (c->ci && c->ci->HasExt("PERSIST") && c->creation_time > c->ci->time_registered)
|
||||
if (c->ci && persist.HasExt(c->ci) && c->creation_time > c->ci->time_registered)
|
||||
{
|
||||
Log(LOG_DEBUG) << "Changing TS of " << c->name << " from " << c->creation_time << " to " << c->ci->time_registered;
|
||||
c->creation_time = c->ci->time_registered;
|
||||
@@ -1198,10 +1094,47 @@ class CSSet : public Module
|
||||
{
|
||||
if (chan->ci)
|
||||
{
|
||||
give_modes &= !chan->ci->HasExt("NOAUTOOP");
|
||||
take_modes |= chan->ci->HasExt("SECUREOPS");
|
||||
if (noautoop.HasExt(chan->ci))
|
||||
give_modes = false;
|
||||
if (secureops.HasExt(chan->ci))
|
||||
take_modes = true;
|
||||
}
|
||||
}
|
||||
|
||||
void OnPreChanExpire(ChannelInfo *ci, bool &expire) anope_override
|
||||
{
|
||||
if (noexpire.HasExt(ci))
|
||||
expire = false;
|
||||
}
|
||||
|
||||
void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_all) anope_override
|
||||
{
|
||||
if (!show_all)
|
||||
return;
|
||||
|
||||
if (peace.HasExt(ci))
|
||||
info.AddOption(_("Peace"));
|
||||
if (restricted.HasExt(ci))
|
||||
info.AddOption(_("Restricted Access"));
|
||||
if (secure.HasExt(ci))
|
||||
info.AddOption(_("Secure"));
|
||||
if (securefounder.HasExt(ci))
|
||||
info.AddOption(_("Secure Founder"));
|
||||
if (secureops.HasExt(ci))
|
||||
info.AddOption(_("Secure Ops"));
|
||||
if (signkick.HasExt(ci) || signkick_level.HasExt(ci))
|
||||
info.AddOption(_("Signed kicks"));
|
||||
if (persist.HasExt(ci))
|
||||
info.AddOption(_("Persistent"));
|
||||
if (noexpire.HasExt(ci))
|
||||
info.AddOption(_("No expire"));
|
||||
if (stats.HasExt(ci))
|
||||
info.AddOption(_("Chanstats"));
|
||||
|
||||
time_t chanserv_expire = Config->GetModule(this)->Get<time_t>("expire", "14d");
|
||||
if (!noexpire.HasExt(ci) && chanserv_expire && !Anope::NoExpire)
|
||||
info["Expires on"] = Anope::strftime(ci->last_used + chanserv_expire);
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_INIT(CSSet)
|
||||
|
||||
@@ -10,14 +10,24 @@
|
||||
|
||||
#include "module.h"
|
||||
|
||||
static Module *me;
|
||||
|
||||
static std::map<Anope::string, Anope::string> descriptions;
|
||||
|
||||
struct CSMiscData : ExtensibleItem, Serializable
|
||||
struct CSMiscData;
|
||||
static Anope::map<ExtensibleItem<CSMiscData> *> items;
|
||||
static ExtensibleItem<CSMiscData> *GetItem(const Anope::string &name);
|
||||
|
||||
struct CSMiscData : Serializable
|
||||
{
|
||||
Serialize::Reference<ChannelInfo> ci;
|
||||
Anope::string name;
|
||||
Anope::string data;
|
||||
|
||||
CSMiscData(Extensible *obj) : Serializable("CSMiscData"), ci(anope_dynamic_static_cast<ChannelInfo *>(obj))
|
||||
{
|
||||
}
|
||||
|
||||
CSMiscData(ChannelInfo *c, const Anope::string &n, const Anope::string &d) : Serializable("CSMiscData"), ci(c), name(n), data(d)
|
||||
{
|
||||
}
|
||||
@@ -41,7 +51,7 @@ struct CSMiscData : ExtensibleItem, Serializable
|
||||
if (ci == NULL)
|
||||
return NULL;
|
||||
|
||||
CSMiscData *d;
|
||||
CSMiscData *d = NULL;
|
||||
if (obj)
|
||||
{
|
||||
d = anope_dynamic_static_cast<CSMiscData *>(obj);
|
||||
@@ -51,14 +61,27 @@ struct CSMiscData : ExtensibleItem, Serializable
|
||||
}
|
||||
else
|
||||
{
|
||||
d = new CSMiscData(ci, sname, sdata);
|
||||
ci->Extend(sname, d);
|
||||
ExtensibleItem<CSMiscData> *item = GetItem(sname);
|
||||
if (item)
|
||||
d = item->Set(ci, CSMiscData(ci, sname, sdata));
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
};
|
||||
|
||||
static ExtensibleItem<CSMiscData> *GetItem(const Anope::string &name)
|
||||
{
|
||||
ExtensibleItem<CSMiscData>* &it = items[name];
|
||||
if (!it)
|
||||
try
|
||||
{
|
||||
it = new ExtensibleItem<CSMiscData>(me, name);
|
||||
}
|
||||
catch (const ModuleException &) { }
|
||||
return it;
|
||||
}
|
||||
|
||||
static Anope::string GetAttribute(const Anope::string &command)
|
||||
{
|
||||
size_t sp = command.rfind(' ');
|
||||
@@ -97,14 +120,20 @@ class CommandCSSetMisc : public Command
|
||||
|
||||
Anope::string scommand = GetAttribute(source.command);
|
||||
Anope::string key = "cs_set_misc:" + scommand;
|
||||
ci->Shrink(key);
|
||||
ExtensibleItem<CSMiscData> *item = GetItem(key);
|
||||
if (item == NULL)
|
||||
return;
|
||||
|
||||
if (params.size() > 1)
|
||||
{
|
||||
ci->Extend(key, new CSMiscData(ci, key, params[1]));
|
||||
item->Set(ci, CSMiscData(ci, key, params[1]));
|
||||
source.Reply(CHAN_SETTING_CHANGED, scommand.c_str(), ci->name.c_str(), params[1].c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
item->Unset(ci);
|
||||
source.Reply(CHAN_SETTING_UNSET, scommand.c_str(), ci->name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void OnServHelp(CommandSource &source) anope_override
|
||||
@@ -136,6 +165,7 @@ class CSSetMisc : public Module
|
||||
CSSetMisc(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
csmiscdata_type("CSMiscData", CSMiscData::Unserialize), commandcssetmisc(this)
|
||||
{
|
||||
me = this;
|
||||
}
|
||||
|
||||
void OnReload(Configuration::Conf *conf) anope_override
|
||||
@@ -161,17 +191,14 @@ class CSSetMisc : public Module
|
||||
|
||||
void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool ShowHidden) anope_override
|
||||
{
|
||||
std::deque<Anope::string> list;
|
||||
ci->GetExtList(list);
|
||||
|
||||
for (unsigned i = 0; i < list.size(); ++i)
|
||||
Anope::map<ExtensibleItem<CSMiscData> *> items;
|
||||
for (Anope::map<ExtensibleItem<CSMiscData> *>::iterator it = items.begin(); it != items.end(); ++it)
|
||||
{
|
||||
if (list[i].find("cs_set_misc:") != 0)
|
||||
continue;
|
||||
|
||||
CSMiscData *data = ci->GetExt<CSMiscData *>(list[i]);
|
||||
ExtensibleItem<CSMiscData> *e = it->second;
|
||||
CSMiscData *data = e->Get(ci);
|
||||
|
||||
if (data != NULL)
|
||||
info[list[i].substr(12).replace_all_cs("_", " ")] = data->data;
|
||||
info[e->name.substr(12).replace_all_cs("_", " ")] = data->data;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -10,6 +10,45 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/cs_suspend.h"
|
||||
|
||||
struct CSSuspendInfoImpl : CSSuspendInfo, Serializable
|
||||
{
|
||||
CSSuspendInfoImpl(Extensible *) : Serializable("CSSuspendInfo") { }
|
||||
|
||||
void Serialize(Serialize::Data &data) const anope_override
|
||||
{
|
||||
data["chan"] << chan;
|
||||
data["by"] << by;
|
||||
data["reason"] << reason;
|
||||
data["time"] << time;
|
||||
data["expires"] << expires;
|
||||
}
|
||||
|
||||
static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
{
|
||||
Anope::string schan;
|
||||
data["chan"] >> schan;
|
||||
|
||||
CSSuspendInfoImpl *si;
|
||||
if (obj)
|
||||
si = anope_dynamic_static_cast<CSSuspendInfoImpl *>(obj);
|
||||
else
|
||||
{
|
||||
ChannelInfo *ci = ChannelInfo::Find(schan);
|
||||
if (!ci)
|
||||
return NULL;
|
||||
si = ci->Extend<CSSuspendInfoImpl>("cs_suspend");
|
||||
data["chan"] >> si->chan;
|
||||
}
|
||||
|
||||
data["bi"] >> si->by;
|
||||
data["reason"] >> si->reason;
|
||||
data["time"] >> si->time;
|
||||
data["expires"] >> si->expires;
|
||||
return si;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSSuspend : public Command
|
||||
{
|
||||
@@ -46,11 +85,12 @@ class CommandCSSuspend : public Command
|
||||
return;
|
||||
}
|
||||
|
||||
ci->ExtendMetadata("SUSPENDED");
|
||||
ci->ExtendMetadata("suspend:by", source.GetNick());
|
||||
if (!reason.empty())
|
||||
ci->ExtendMetadata("suspend:reason", reason);
|
||||
ci->ExtendMetadata("suspend:time", stringify(Anope::CurTime));
|
||||
CSSuspendInfo *si = ci->Extend<CSSuspendInfo>("cs_suspend");
|
||||
si->chan = ci->name;
|
||||
si->by = source.GetNick();
|
||||
si->reason = reason;
|
||||
si->time = Anope::CurTime;
|
||||
si->expires = expiry_secs ? expiry_secs + Anope::CurTime : 0;
|
||||
|
||||
if (ci->c)
|
||||
{
|
||||
@@ -68,15 +108,10 @@ class CommandCSSuspend : public Command
|
||||
ci->c->Kick(NULL, users[i], "%s", !reason.empty() ? reason.c_str() : Language::Translate(users[i], _("This channel has been suspended.")));
|
||||
}
|
||||
|
||||
if (expiry_secs > 0)
|
||||
ci->ExtendMetadata("suspend:expire", stringify(Anope::CurTime + expiry_secs));
|
||||
|
||||
Log(LOG_ADMIN, source, this, ci) << (!reason.empty() ? reason : "No reason") << ", expires in " << (expiry_secs ? Anope::strftime(Anope::CurTime + expiry_secs) : "never");
|
||||
source.Reply(_("Channel \002%s\002 is now suspended."), ci->name.c_str());
|
||||
|
||||
FOREACH_MOD(OnChanSuspend, (ci));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
|
||||
@@ -118,21 +153,16 @@ class CommandCSUnSuspend : public Command
|
||||
}
|
||||
|
||||
/* Only UNSUSPEND already suspended channels */
|
||||
if (!ci->HasExt("SUSPENDED"))
|
||||
CSSuspendInfo *si = ci->GetExt<CSSuspendInfo>("cs_suspend");
|
||||
if (!si)
|
||||
{
|
||||
source.Reply(_("Channel \002%s\002 isn't suspended."), ci->name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
Anope::string *by = ci->GetExt<ExtensibleItemClass<Anope::string> *>("suspend:by"), *reason = ci->GetExt<ExtensibleItemClass<Anope::string> *>("suspend:reason");
|
||||
if (by != NULL)
|
||||
Log(LOG_ADMIN, source, this, ci) << " which was suspended by " << *by << " for: " << (reason && !reason->empty() ? *reason : "No reason");
|
||||
Log(LOG_ADMIN, source, this, ci) << " which was suspended by " << si->by << " for: " << (!si->reason.empty() ? si->reason : "No reason");
|
||||
|
||||
ci->Shrink("SUSPENDED");
|
||||
ci->Shrink("suspend:by");
|
||||
ci->Shrink("suspend:reason");
|
||||
ci->Shrink("suspend:expire");
|
||||
ci->Shrink("suspend:time");
|
||||
ci->Shrink<CSSuspendInfo>("cs_suspend");
|
||||
|
||||
source.Reply(_("Channel \002%s\002 is now released."), ci->name.c_str());
|
||||
|
||||
@@ -155,66 +185,73 @@ class CSSuspend : public Module
|
||||
{
|
||||
CommandCSSuspend commandcssuspend;
|
||||
CommandCSUnSuspend commandcsunsuspend;
|
||||
ExtensibleItem<CSSuspendInfoImpl> suspend;
|
||||
Serialize::Type suspend_type;
|
||||
|
||||
public:
|
||||
CSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
commandcssuspend(this), commandcsunsuspend(this)
|
||||
commandcssuspend(this), commandcsunsuspend(this), suspend(this, "cs_suspend"),
|
||||
suspend_type("CSSuspendInfo", CSSuspendInfoImpl::Unserialize)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_hidden) anope_override
|
||||
{
|
||||
if (ci->HasExt("SUSPENDED"))
|
||||
CSSuspendInfo *si = suspend.Get(ci);
|
||||
if (si)
|
||||
{
|
||||
Anope::string *by = ci->GetExt<ExtensibleItemClass<Anope::string> *>("suspend:by"), *reason = ci->GetExt<ExtensibleItemClass<Anope::string> *>("suspend:reason"), *t = ci->GetExt<ExtensibleItemClass<Anope::string> *>("suspend:time");
|
||||
info["Suspended"] = "This channel is \2suspended\2.";
|
||||
if (by)
|
||||
info["Suspended by"] = *by;
|
||||
if (reason)
|
||||
info["Suspend reason"] = *reason;
|
||||
if (t)
|
||||
info["Suspended on"] = Anope::strftime(convertTo<time_t>(*t), source.GetAccount(), true);
|
||||
if (!si->by.empty())
|
||||
info["Suspended by"] = si->by;
|
||||
if (!si->reason.empty())
|
||||
info["Suspend reason"] = si->reason;
|
||||
if (si->time)
|
||||
info["Suspended on"] = Anope::strftime(si->time, source.GetAccount(), true);
|
||||
if (si->expires)
|
||||
info["Suspended expires"] = Anope::strftime(si->expires, source.GetAccount(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void OnPreChanExpire(ChannelInfo *ci, bool &expire) anope_override
|
||||
{
|
||||
if (!ci->HasExt("SUSPENDED"))
|
||||
CSSuspendInfo *si = suspend.Get(ci);
|
||||
if (!si)
|
||||
return;
|
||||
|
||||
expire = false;
|
||||
|
||||
Anope::string *str = ci->GetExt<ExtensibleItemClass<Anope::string> *>("suspend:expire");
|
||||
if (str == NULL)
|
||||
if (!si->expires)
|
||||
return;
|
||||
|
||||
try
|
||||
if (si->expires < Anope::CurTime)
|
||||
{
|
||||
time_t when = convertTo<time_t>(*str);
|
||||
if (when < Anope::CurTime)
|
||||
{
|
||||
ci->last_used = Anope::CurTime;
|
||||
ci->Shrink("SUSPENDED");
|
||||
ci->Shrink("suspend:expire");
|
||||
ci->Shrink("suspend:by");
|
||||
ci->Shrink("suspend:reason");
|
||||
ci->Shrink("suspend:time");
|
||||
ci->last_used = Anope::CurTime;
|
||||
suspend.Unset(ci);
|
||||
|
||||
Log(this) << "Expiring suspend for " << ci->name;
|
||||
}
|
||||
Log(this) << "Expiring suspend for " << ci->name;
|
||||
}
|
||||
catch (const ConvertException &) { }
|
||||
}
|
||||
|
||||
EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) anope_override
|
||||
{
|
||||
if (u->HasMode("OPER") || !c->ci || !c->ci->HasExt("SUSPENDED"))
|
||||
if (u->HasMode("OPER") || !c->ci || !suspend.HasExt(c->ci))
|
||||
return EVENT_CONTINUE;
|
||||
|
||||
reason = Language::Translate(u, _("This channel may not be used."));
|
||||
return EVENT_STOP;
|
||||
}
|
||||
|
||||
EventReturn OnChanDrop(CommandSource &source, ChannelInfo *ci) anope_override
|
||||
{
|
||||
CSSuspendInfo *si = suspend.Get(ci);
|
||||
if (si && !source.HasCommand("chanserv/drop"))
|
||||
{
|
||||
source.Reply(CHAN_X_SUSPENDED, ci->name.c_str());
|
||||
return EVENT_STOP;
|
||||
}
|
||||
|
||||
return EVENT_CONTINUE;
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_INIT(CSSuspend)
|
||||
|
||||
@@ -10,9 +10,70 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/cs_mode.h"
|
||||
|
||||
class CommandCSSetKeepTopic : public Command
|
||||
{
|
||||
public:
|
||||
CommandCSSetKeepTopic(Module *creator, const Anope::string &cname = "chanserv/set/keeptopic") : Command(creator, cname, 2, 2)
|
||||
{
|
||||
this->SetDesc(_("Retain topic when channel is not in use"));
|
||||
this->SetSyntax(_("\037channel\037 {ON | OFF}"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
ChannelInfo *ci = ChannelInfo::Find(params[0]);
|
||||
if (ci == NULL)
|
||||
{
|
||||
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
EventReturn MOD_RESULT;
|
||||
FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
return;
|
||||
|
||||
if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
|
||||
{
|
||||
source.Reply(ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (params[1].equals_ci("ON"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable keeptopic";
|
||||
ci->Extend<bool>("KEEPTOPIC");
|
||||
source.Reply(_("Topic retention option for %s is now \002on\002."), ci->name.c_str());
|
||||
}
|
||||
else if (params[1].equals_ci("OFF"))
|
||||
{
|
||||
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable keeptopic";
|
||||
ci->Shrink<bool>("KEEPTOPIC");
|
||||
source.Reply(_("Topic retention option for %s is now \002off\002."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, "KEEPTOPIC");
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_("Enables or disables the \002topic retention\002 option for a\n"
|
||||
"channel. When \002%s\002 is set, the topic for the\n"
|
||||
"channel will be remembered by %s even after the\n"
|
||||
"last user leaves the channel, and will be restored the\n"
|
||||
"next time the channel is created."), source.command.c_str(), source.service->nick.c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSTopic : public Command
|
||||
{
|
||||
ExtensibleRef<bool> topiclock;
|
||||
|
||||
void Lock(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
EventReturn MOD_RESULT;
|
||||
@@ -20,7 +81,7 @@ class CommandCSTopic : public Command
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
return;
|
||||
|
||||
ci->ExtendMetadata("TOPICLOCK");
|
||||
topiclock->Set(ci, true);
|
||||
source.Reply(_("Topic lock option for %s is now \002on\002."), ci->name.c_str());
|
||||
}
|
||||
|
||||
@@ -31,7 +92,7 @@ class CommandCSTopic : public Command
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
return;
|
||||
|
||||
ci->Shrink("TOPICLOCK");
|
||||
topiclock->Unset(ci);
|
||||
source.Reply(_("Topic lock option for %s is now \002off\002."), ci->name.c_str());
|
||||
}
|
||||
|
||||
@@ -39,11 +100,11 @@ class CommandCSTopic : public Command
|
||||
{
|
||||
const Anope::string &topic = params.size() > 2 ? params[2] : "";
|
||||
|
||||
bool has_topiclock = ci->HasExt("TOPICLOCK");
|
||||
ci->Shrink("TOPICLOCK");
|
||||
bool *has_topiclock = topiclock->Get(ci);
|
||||
topiclock->Unset(ci);
|
||||
ci->c->ChangeTopic(source.GetNick(), topic, Anope::CurTime);
|
||||
if (has_topiclock)
|
||||
ci->ExtendMetadata("TOPICLOCK");
|
||||
topiclock->Set(ci, *has_topiclock);
|
||||
|
||||
bool override = !source.AccessFor(ci).HasPriv("TOPIC");
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << (!topic.empty() ? "to change the topic to: " : "to unset the topic") << (!topic.empty() ? topic : "");
|
||||
@@ -71,7 +132,8 @@ class CommandCSTopic : public Command
|
||||
}
|
||||
|
||||
public:
|
||||
CommandCSTopic(Module *creator) : Command(creator, "chanserv/topic", 2, 3)
|
||||
CommandCSTopic(Module *creator) : Command(creator, "chanserv/topic", 2, 3),
|
||||
topiclock("TOPICLOCK")
|
||||
{
|
||||
this->SetDesc(_("Manipulate the topic of the specified channel"));
|
||||
this->SetSyntax(_("\037channel\037 SET [\037topic\037]"));
|
||||
@@ -120,13 +182,66 @@ class CommandCSTopic : public Command
|
||||
class CSTopic : public Module
|
||||
{
|
||||
CommandCSTopic commandcstopic;
|
||||
CommandCSSetKeepTopic commandcssetkeeptopic;
|
||||
|
||||
SerializableExtensibleItem<bool> topiclock, keeptopic;
|
||||
|
||||
public:
|
||||
CSTopic(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
commandcstopic(this)
|
||||
commandcstopic(this), commandcssetkeeptopic(this), topiclock(this, "TOPICLOCK"), keeptopic(this, "KEEPTOPIC")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void OnChannelSync(Channel *c) anope_override
|
||||
{
|
||||
if (Me && Me->IsSynced() && c->ci)
|
||||
{
|
||||
/* Update channel topic */
|
||||
if ((topiclock.HasExt(c->ci) || keeptopic.HasExt(c->ci)) && c->ci->last_topic != c->topic)
|
||||
{
|
||||
c->ChangeTopic(!c->ci->last_topic_setter.empty() ? c->ci->last_topic_setter : c->ci->WhoSends()->nick, c->ci->last_topic, c->ci->last_topic_time ? c->ci->last_topic_time : Anope::CurTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnTopicUpdated(Channel *c, const Anope::string &user, const Anope::string &topic) anope_override
|
||||
{
|
||||
if (!c->ci)
|
||||
return;
|
||||
|
||||
/* We only compare the topics here, not the time or setter. This is because some (old) IRCds do not
|
||||
* allow us to set the topic as someone else, meaning we have to bump the TS and change the setter to us.
|
||||
* This desyncs what is really set with what we have stored, and we end up resetting the topic often when
|
||||
* it is not required
|
||||
*/
|
||||
if (topiclock.HasExt(c->ci) && c->ci->last_topic != c->topic)
|
||||
{
|
||||
c->ChangeTopic(c->ci->last_topic_setter, c->ci->last_topic, c->ci->last_topic_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
c->ci->last_topic = c->topic;
|
||||
c->ci->last_topic_setter = c->topic_setter;
|
||||
c->ci->last_topic_time = c->topic_ts;
|
||||
}
|
||||
}
|
||||
|
||||
void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_all)
|
||||
{
|
||||
if (keeptopic.HasExt(ci))
|
||||
info.AddOption(_("Topic Retention"));
|
||||
if (topiclock.HasExt(ci))
|
||||
info.AddOption(_("Topic Lock"));
|
||||
|
||||
ModeLocks *ml = ci->GetExt<ModeLocks>("modelocks");
|
||||
const ModeLock *secret = ml ? ml->GetMLock("SECRET") : NULL;
|
||||
if (!ci->last_topic.empty() && (show_all || ((!secret || secret->set == false) && (!ci->c || !ci->c->HasMode("SECRET")))))
|
||||
{
|
||||
info["Last topic"] = ci->last_topic;
|
||||
info["Topic set by"] = ci->last_topic_setter;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_INIT(CSTopic)
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
*
|
||||
* (C) 2003-2013 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
*
|
||||
* Based on the original code of Epona by Lara.
|
||||
* Based on the original code of Services by Andy Church.
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
|
||||
class CommandBSSetGreet : public Command
|
||||
{
|
||||
public:
|
||||
CommandBSSetGreet(Module *creator, const Anope::string &sname = "botserv/set/greet") : Command(creator, sname, 2, 2)
|
||||
{
|
||||
this->SetDesc(_("Enable greet messages"));
|
||||
this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
ChannelInfo *ci = ChannelInfo::Find(params[0]);
|
||||
const Anope::string &value = params[1];
|
||||
|
||||
if (ci == NULL)
|
||||
{
|
||||
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!source.HasPriv("botserv/administration") && !source.AccessFor(ci).HasPriv("SET"))
|
||||
{
|
||||
source.Reply(ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Anope::ReadOnly)
|
||||
{
|
||||
source.Reply(_("Sorry, bot option setting is temporarily disabled."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.equals_ci("ON"))
|
||||
{
|
||||
bool override = !source.AccessFor(ci).HasPriv("SET");
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable greets";
|
||||
|
||||
ci->Extend<bool>("BS_GREET");
|
||||
source.Reply(_("Greet mode is now \002on\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else if (value.equals_ci("OFF"))
|
||||
{
|
||||
bool override = !source.AccessFor(ci).HasPriv("SET");
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable greets";
|
||||
|
||||
ci->Shrink<bool>("BS_GREET");
|
||||
source.Reply(_("Greet mode is now \002off\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, source.command);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(_(" \n"
|
||||
"Enables or disables \002greet\002 mode on a channel.\n"
|
||||
"When it is enabled, the bot will display greet\n"
|
||||
"messages of users joining the channel, provided\n"
|
||||
"they have enough access to the channel."));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandNSSetGreet : public Command
|
||||
{
|
||||
public:
|
||||
CommandNSSetGreet(Module *creator, const Anope::string &sname = "nickserv/set/greet", size_t min = 0) : Command(creator, sname, min, min + 1)
|
||||
{
|
||||
this->SetDesc(_("Associate a greet message with your nickname"));
|
||||
this->SetSyntax(_("\037message\037"));
|
||||
}
|
||||
|
||||
void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m)
|
||||
{
|
||||
const NickAlias *na = NickAlias::Find(user);
|
||||
if (!na)
|
||||
{
|
||||
source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
|
||||
return;
|
||||
}
|
||||
NickCore *nc = na->nc;
|
||||
|
||||
EventReturn MOD_RESULT;
|
||||
FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
return;
|
||||
|
||||
if (!param.empty())
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the greet of " << nc->display;
|
||||
nc->Extend<Anope::string>("greet", param);
|
||||
source.Reply(_("Greet message for \002%s\002 changed to \002%s\002."), nc->display.c_str(), param.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to unset the greet of " << nc->display;
|
||||
nc->Shrink<Anope::string>("greet");
|
||||
source.Reply(_("Greet message for \002%s\002 unset."), nc->display.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
this->Run(source, source.nc->display, params.size() > 0 ? params[0] : "");
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_("Makes the given message the greet of your nickname, that\n"
|
||||
"will be displayed when joining a channel that has GREET\n"
|
||||
"option enabled, provided that you have the necessary\n"
|
||||
"access on it."));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandNSSASetGreet : public CommandNSSetGreet
|
||||
{
|
||||
public:
|
||||
CommandNSSASetGreet(Module *creator) : CommandNSSetGreet(creator, "nickserv/saset/greet", 1)
|
||||
{
|
||||
this->ClearSyntax();
|
||||
this->SetSyntax(_("\037nickname\037 \037message\037"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
this->Run(source, params[0], params.size() > 1 ? params[1] : "");
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_("Makes the given message the greet of the nickname, that\n"
|
||||
"will be displayed when joining a channel that has GREET\n"
|
||||
"option enabled, provided that the user has the necessary\n"
|
||||
"access on it."));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class Greet : public Module
|
||||
{
|
||||
/* channel setting for whether or not greet should be shown */
|
||||
SerializableExtensibleItem<bool> bs_greet;
|
||||
/* user greets */
|
||||
SerializableExtensibleItem<Anope::string> ns_greet;
|
||||
|
||||
CommandBSSetGreet commandbssetgreet;
|
||||
CommandNSSetGreet commandnssetgreet;
|
||||
CommandNSSASetGreet commandnssasetgreet;
|
||||
|
||||
public:
|
||||
Greet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
bs_greet(this, "BS_GREET"),
|
||||
ns_greet(this, "greet"),
|
||||
commandbssetgreet(this),
|
||||
commandnssetgreet(this), commandnssasetgreet(this)
|
||||
{
|
||||
}
|
||||
|
||||
void OnJoinChannel(User *user, Channel *c) anope_override
|
||||
{
|
||||
/* Only display the greet if the main uplink we're connected
|
||||
* to has synced, or we'll get greet-floods when the net
|
||||
* recovers from a netsplit. -GD
|
||||
*/
|
||||
if (!c->ci || !c->ci->bi || !user->server->IsSynced() || !user->Account())
|
||||
return;
|
||||
|
||||
Anope::string *greet = ns_greet.Get(user->Account());
|
||||
if (bs_greet.HasExt(c->ci) && greet != NULL && !greet->empty() && c->FindUser(c->ci->bi) && c->ci->AccessFor(user).HasPriv("GREET"))
|
||||
{
|
||||
IRCD->SendPrivmsg(c->ci->bi, c->name, "[%s] %s", user->Account()->display.c_str(), greet->c_str());
|
||||
c->ci->bi->lastmsg = Anope::CurTime;
|
||||
}
|
||||
}
|
||||
|
||||
void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) anope_override
|
||||
{
|
||||
Anope::string *greet = ns_greet.Get(na->nc);
|
||||
if (greet != NULL)
|
||||
info[_("Greet")] = *greet;
|
||||
}
|
||||
|
||||
void OnBotInfo(CommandSource &source, BotInfo *bi, ChannelInfo *ci, InfoFormatter &info) anope_override
|
||||
{
|
||||
if (bs_greet.HasExt(ci))
|
||||
info.AddOption(_("Greet"));
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_INIT(Greet)
|
||||
@@ -21,14 +21,14 @@ static ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ")
|
||||
|
||||
static void req_send_memos(Module *me, CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost);
|
||||
|
||||
struct HostRequest : ExtensibleItem, Serializable
|
||||
struct HostRequest : Serializable
|
||||
{
|
||||
Anope::string nick;
|
||||
Anope::string ident;
|
||||
Anope::string host;
|
||||
time_t time;
|
||||
|
||||
HostRequest() : Serializable("HostRequest") { }
|
||||
HostRequest(Extensible *) : Serializable("HostRequest") { }
|
||||
|
||||
void Serialize(Serialize::Data &data) const anope_override
|
||||
{
|
||||
@@ -51,14 +51,15 @@ struct HostRequest : ExtensibleItem, Serializable
|
||||
if (obj)
|
||||
req = anope_dynamic_static_cast<HostRequest *>(obj);
|
||||
else
|
||||
req = new HostRequest;
|
||||
req->nick = na->nick;
|
||||
data["ident"] >> req->ident;
|
||||
data["host"] >> req->host;
|
||||
data["time"] >> req->time;
|
||||
req = na->Extend<HostRequest>("hostrequest");
|
||||
if (req)
|
||||
{
|
||||
req->nick = na->nick;
|
||||
data["ident"] >> req->ident;
|
||||
data["host"] >> req->host;
|
||||
data["time"] >> req->time;
|
||||
}
|
||||
|
||||
if (!obj)
|
||||
na->Extend("hs_request", req);
|
||||
return req;
|
||||
}
|
||||
};
|
||||
@@ -148,12 +149,12 @@ class CommandHSRequest : public Command
|
||||
return;
|
||||
}
|
||||
|
||||
HostRequest *req = new HostRequest;
|
||||
req->nick = source.GetNick();
|
||||
req->ident = user;
|
||||
req->host = host;
|
||||
req->time = Anope::CurTime;
|
||||
na->Extend("hs_request", req);
|
||||
HostRequest req(na);
|
||||
req.nick = source.GetNick();
|
||||
req.ident = user;
|
||||
req.host = host;
|
||||
req.time = Anope::CurTime;
|
||||
na->Extend<HostRequest>("hostrequest", req);
|
||||
|
||||
source.Reply(_("Your vHost has been requested."));
|
||||
req_send_memos(owner, source, user, host);
|
||||
@@ -186,7 +187,7 @@ class CommandHSActivate : public Command
|
||||
const Anope::string &nick = params[0];
|
||||
|
||||
NickAlias *na = NickAlias::Find(nick);
|
||||
HostRequest *req = na ? na->GetExt<HostRequest *>("hs_request") : NULL;
|
||||
HostRequest *req = na ? na->GetExt<HostRequest>("hostrequest") : NULL;
|
||||
if (req)
|
||||
{
|
||||
na->SetVhost(req->ident, req->host, source.GetNick(), req->time);
|
||||
@@ -197,7 +198,7 @@ class CommandHSActivate : public Command
|
||||
|
||||
source.Reply(_("vHost for %s has been activated."), na->nick.c_str());
|
||||
Log(LOG_COMMAND, source, this) << "for " << na->nick << " for vhost " << (!req->ident.empty() ? req->ident + "@" : "") << req->host;
|
||||
na->Shrink("hs_request");
|
||||
na->Shrink<HostRequest>("hostrequest");
|
||||
}
|
||||
else
|
||||
source.Reply(_("No request for nick %s found."), nick.c_str());
|
||||
@@ -231,10 +232,10 @@ class CommandHSReject : public Command
|
||||
const Anope::string &reason = params.size() > 1 ? params[1] : "";
|
||||
|
||||
NickAlias *na = NickAlias::Find(nick);
|
||||
HostRequest *req = na ? na->GetExt<HostRequest *>("hs_request") : NULL;
|
||||
HostRequest *req = na ? na->GetExt<HostRequest>("hostrequest") : NULL;
|
||||
if (req)
|
||||
{
|
||||
na->Shrink("hs_request");
|
||||
na->Shrink<HostRequest>("hostrequest");
|
||||
|
||||
if (Config->GetModule(this->owner)->Get<bool>("memouser") && memoserv)
|
||||
{
|
||||
@@ -244,7 +245,7 @@ class CommandHSReject : public Command
|
||||
else
|
||||
message = _("[auto memo] Your requested vHost has been rejected.");
|
||||
|
||||
memoserv->Send(source.service->nick, nick, message, true);
|
||||
memoserv->Send(source.service->nick, nick, Language::Translate(source.GetAccount(), message.c_str()), true);
|
||||
}
|
||||
|
||||
source.Reply(_("vHost for %s has been rejected."), nick.c_str());
|
||||
@@ -252,8 +253,6 @@ class CommandHSReject : public Command
|
||||
}
|
||||
else
|
||||
source.Reply(_("No request for nick %s found."), nick.c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
|
||||
@@ -287,7 +286,7 @@ class CommandHSWaiting : public Command
|
||||
for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; ++it)
|
||||
{
|
||||
const NickAlias *na = it->second;
|
||||
HostRequest *hr = na->GetExt<HostRequest *>("hs_request");
|
||||
HostRequest *hr = na->GetExt<HostRequest>("hostrequest");
|
||||
if (!hr)
|
||||
continue;
|
||||
|
||||
@@ -334,24 +333,17 @@ class HSRequest : public Module
|
||||
CommandHSActivate commandhsactive;
|
||||
CommandHSReject commandhsreject;
|
||||
CommandHSWaiting commandhswaiting;
|
||||
ExtensibleItem<HostRequest> hostrequest;
|
||||
|
||||
public:
|
||||
HSRequest(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
request_type("HostRequest", HostRequest::Unserialize), commandhsrequest(this), commandhsactive(this), commandhsreject(this), commandhswaiting(this)
|
||||
request_type("HostRequest", HostRequest::Unserialize), commandhsrequest(this), commandhsactive(this),
|
||||
commandhsreject(this), commandhswaiting(this), hostrequest(this, "hostrequest")
|
||||
{
|
||||
|
||||
if (!IRCD || !IRCD->CanSetVHost)
|
||||
throw ModuleException("Your IRCd does not support vhosts");
|
||||
}
|
||||
|
||||
~HSRequest()
|
||||
{
|
||||
for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; ++it)
|
||||
{
|
||||
NickAlias *na = it->second;
|
||||
na->Shrink("hs_request");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static void req_send_memos(Module *me, CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost)
|
||||
|
||||
@@ -27,7 +27,7 @@ class CommandMSInfo : public Command
|
||||
const NickAlias *na = NULL;
|
||||
ChannelInfo *ci = NULL;
|
||||
const Anope::string &nname = !params.empty() ? params[0] : "";
|
||||
int hardmax = 0;
|
||||
bool hardmax;
|
||||
|
||||
if (!nname.empty() && nname[0] != '#' && source.HasPriv("memoserv/info"))
|
||||
{
|
||||
@@ -38,7 +38,7 @@ class CommandMSInfo : public Command
|
||||
return;
|
||||
}
|
||||
mi = &na->nc->memos;
|
||||
hardmax = na->nc->HasExt("MEMO_HARDMAX") ? 1 : 0;
|
||||
hardmax = na->nc->HasExt("MEMO_HARDMAX");
|
||||
}
|
||||
else if (!nname.empty() && nname[0] == '#')
|
||||
{
|
||||
@@ -54,7 +54,7 @@ class CommandMSInfo : public Command
|
||||
return;
|
||||
}
|
||||
mi = &ci->memos;
|
||||
hardmax = ci->HasExt("MEMO_HARDMAX") ? 1 : 0;
|
||||
hardmax = ci->HasExt("MEMO_HARDMAX");
|
||||
}
|
||||
else if (!nname.empty()) /* It's not a chan and we aren't services admin */
|
||||
{
|
||||
@@ -64,7 +64,7 @@ class CommandMSInfo : public Command
|
||||
else
|
||||
{
|
||||
mi = &nc->memos;
|
||||
hardmax = nc->HasExt("MEMO_HARDMAX") ? 1 : 0;
|
||||
hardmax = nc->HasExt("MEMO_HARDMAX");
|
||||
}
|
||||
|
||||
if (!nname.empty() && (ci || na->nc != nc))
|
||||
@@ -178,7 +178,6 @@ class CommandMSInfo : public Command
|
||||
else
|
||||
source.Reply(_("You will not be notified of new memos."));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
|
||||
|
||||
+18
-18
@@ -25,27 +25,27 @@ class CommandMSSet : public Command
|
||||
|
||||
if (param.equals_ci("ON"))
|
||||
{
|
||||
nc->ExtendMetadata("MEMO_SIGNON");
|
||||
nc->ExtendMetadata("MEMO_RECEIVE");
|
||||
nc->Extend<bool>("MEMO_SIGNON");
|
||||
nc->Extend<bool>("MEMO_RECEIVE");
|
||||
source.Reply(_("%s will now notify you of memos when you log on and when they are sent to you."), MemoServ->nick.c_str());
|
||||
}
|
||||
else if (param.equals_ci("LOGON"))
|
||||
{
|
||||
nc->ExtendMetadata("MEMO_SIGNON");
|
||||
nc->Shrink("MEMO_RECEIVE");
|
||||
nc->Extend<bool>("MEMO_SIGNON");
|
||||
nc->Shrink<bool>("MEMO_RECEIVE");
|
||||
source.Reply(_("%s will now notify you of memos when you log on or unset /AWAY."), MemoServ->nick.c_str());
|
||||
}
|
||||
else if (param.equals_ci("NEW"))
|
||||
{
|
||||
nc->Shrink("MEMO_SIGNON");
|
||||
nc->ExtendMetadata("MEMO_RECEIVE");
|
||||
nc->Shrink<bool>("MEMO_SIGNON");
|
||||
nc->Extend<bool>("MEMO_RECEIVE");
|
||||
source.Reply(_("%s will now notify you of memos when they are sent to you."), MemoServ->nick.c_str());
|
||||
}
|
||||
else if (param.equals_ci("MAIL"))
|
||||
{
|
||||
if (!nc->email.empty())
|
||||
{
|
||||
nc->ExtendMetadata("MEMO_MAIL");
|
||||
nc->Extend<bool>("MEMO_MAIL");
|
||||
source.Reply(_("You will now be informed about new memos via email."));
|
||||
}
|
||||
else
|
||||
@@ -53,20 +53,18 @@ class CommandMSSet : public Command
|
||||
}
|
||||
else if (param.equals_ci("NOMAIL"))
|
||||
{
|
||||
nc->Shrink("MEMO_MAIL");
|
||||
nc->Shrink<bool>("MEMO_MAIL");
|
||||
source.Reply(_("You will no longer be informed via email."));
|
||||
}
|
||||
else if (param.equals_ci("OFF"))
|
||||
{
|
||||
nc->Shrink("MEMO_SIGNON");
|
||||
nc->Shrink("MEMO_RECEIVE");
|
||||
nc->Shrink("MEMO_MAIL");
|
||||
nc->Shrink<bool>("MEMO_SIGNON");
|
||||
nc->Shrink<bool>("MEMO_RECEIVE");
|
||||
nc->Shrink<bool>("MEMO_MAIL");
|
||||
source.Reply(_("%s will not send you any notification of memos."), MemoServ->nick.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, "");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void DoLimit(CommandSource &source, const std::vector<Anope::string> ¶ms, MemoInfo *mi)
|
||||
@@ -125,16 +123,16 @@ class CommandMSSet : public Command
|
||||
if (!chan.empty())
|
||||
{
|
||||
if (!p2.empty())
|
||||
ci->ExtendMetadata("MEMO_HARDMAX");
|
||||
ci->Extend<bool>("MEMO_HARDMAX");
|
||||
else
|
||||
ci->Shrink("MEMO_HARDMAX");
|
||||
ci->Shrink<bool>("MEMO_HARDMAX");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!p2.empty())
|
||||
nc->ExtendMetadata("MEMO_HARDMAX");
|
||||
nc->Extend<bool>("MEMO_HARDMAX");
|
||||
else
|
||||
nc->Shrink("MEMO_HARDMAX");
|
||||
nc->Shrink<bool>("MEMO_HARDMAX");
|
||||
}
|
||||
limit = -1;
|
||||
try
|
||||
@@ -301,10 +299,12 @@ class CommandMSSet : public Command
|
||||
class MSSet : public Module
|
||||
{
|
||||
CommandMSSet commandmsset;
|
||||
PrimitiveExtensibleItem<bool> memo_signon, memo_receive, memo_mail, memo_hardmax;
|
||||
|
||||
public:
|
||||
MSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
commandmsset(this)
|
||||
commandmsset(this), memo_signon(this, "MEMO_SIGNON"), memo_receive(this, "MEMO_RECEIVE"), memo_mail(this, "MEMO_MAIL"),
|
||||
memo_hardmax(this, "MEMO_HARDMAX")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
|
||||
struct AJoinEntry;
|
||||
|
||||
struct AJoinList : Serialize::Checker<std::vector<AJoinEntry *> >, ExtensibleItem
|
||||
struct AJoinList : Serialize::Checker<std::vector<AJoinEntry *> >
|
||||
{
|
||||
AJoinList() : Serialize::Checker<std::vector<AJoinEntry *> >("AJoinEntry") { }
|
||||
AJoinList(Extensible *) : Serialize::Checker<std::vector<AJoinEntry *> >("AJoinEntry") { }
|
||||
~AJoinList();
|
||||
};
|
||||
|
||||
@@ -25,7 +25,7 @@ struct AJoinEntry : Serializable
|
||||
Anope::string channel;
|
||||
Anope::string key;
|
||||
|
||||
AJoinEntry() : Serializable("AJoinEntry") { }
|
||||
AJoinEntry(Extensible *) : Serializable("AJoinEntry") { }
|
||||
|
||||
void Serialize(Serialize::Data &sd) const anope_override
|
||||
{
|
||||
@@ -52,7 +52,7 @@ struct AJoinEntry : Serializable
|
||||
aj = anope_dynamic_static_cast<AJoinEntry *>(obj);
|
||||
else
|
||||
{
|
||||
aj = new AJoinEntry();
|
||||
aj = new AJoinEntry(nc);
|
||||
aj->owner = nc;
|
||||
}
|
||||
|
||||
@@ -61,12 +61,7 @@ struct AJoinEntry : Serializable
|
||||
|
||||
if (!obj)
|
||||
{
|
||||
AJoinList *channels = nc->GetExt<AJoinList *>("ns_ajoin_channels");
|
||||
if (channels == NULL)
|
||||
{
|
||||
channels = new AJoinList();
|
||||
nc->Extend("ns_ajoin_channels", channels);
|
||||
}
|
||||
AJoinList *channels = nc->Require<AJoinList>("ajoinlist");
|
||||
(*channels)->push_back(aj);
|
||||
}
|
||||
|
||||
@@ -84,12 +79,7 @@ class CommandNSAJoin : public Command
|
||||
{
|
||||
void DoList(CommandSource &source, NickCore *nc)
|
||||
{
|
||||
AJoinList *channels = nc->GetExt<AJoinList *>("ns_ajoin_channels");
|
||||
if (channels == NULL)
|
||||
{
|
||||
channels = new AJoinList();
|
||||
nc->Extend("ns_ajoin_channels", channels);
|
||||
}
|
||||
AJoinList *channels = nc->Require<AJoinList>("ajoinlist");
|
||||
|
||||
if ((*channels)->empty())
|
||||
source.Reply(_("%s's auto join list is empty."), nc->display.c_str());
|
||||
@@ -119,12 +109,7 @@ class CommandNSAJoin : public Command
|
||||
|
||||
void DoAdd(CommandSource &source, NickCore *nc, const Anope::string &chan, const Anope::string &key)
|
||||
{
|
||||
AJoinList *channels = nc->GetExt<AJoinList *>("ns_ajoin_channels");
|
||||
if (channels == NULL)
|
||||
{
|
||||
channels = new AJoinList();
|
||||
nc->Extend("ns_ajoin_channels", channels);
|
||||
}
|
||||
AJoinList *channels = nc->Require<AJoinList>("ajoinlist");
|
||||
|
||||
unsigned i = 0;
|
||||
for (; i < (*channels)->size(); ++i)
|
||||
@@ -139,7 +124,7 @@ class CommandNSAJoin : public Command
|
||||
source.Reply(CHAN_X_INVALID, chan.c_str());
|
||||
else
|
||||
{
|
||||
AJoinEntry *entry = new AJoinEntry();
|
||||
AJoinEntry *entry = new AJoinEntry(nc);
|
||||
entry->owner = nc;
|
||||
entry->channel = chan;
|
||||
entry->key = key;
|
||||
@@ -150,12 +135,7 @@ class CommandNSAJoin : public Command
|
||||
|
||||
void DoDel(CommandSource &source, NickCore *nc, const Anope::string &chan)
|
||||
{
|
||||
AJoinList *channels = nc->GetExt<AJoinList *>("ns_ajoin_channels");
|
||||
if (channels == NULL)
|
||||
{
|
||||
channels = new AJoinList();
|
||||
nc->Extend("ns_ajoin_channels", channels);
|
||||
}
|
||||
AJoinList *channels = nc->Require<AJoinList>("ajoinlist");
|
||||
|
||||
unsigned i = 0;
|
||||
for (; i < (*channels)->size(); ++i)
|
||||
@@ -170,6 +150,9 @@ class CommandNSAJoin : public Command
|
||||
(*channels)->erase((*channels)->begin() + i);
|
||||
source.Reply(_("%s was removed from %s's auto join list."), chan.c_str(), nc->display.c_str());
|
||||
}
|
||||
|
||||
if ((*channels)->empty())
|
||||
nc->Shrink<AJoinList>("ajoinlist");
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -233,10 +216,11 @@ class NSAJoin : public Module
|
||||
{
|
||||
Serialize::Type ajoinentry_type;
|
||||
CommandNSAJoin commandnsajoin;
|
||||
ExtensibleItem<AJoinList> ajoinlist;
|
||||
|
||||
public:
|
||||
NSAJoin(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
ajoinentry_type("AJoinEntry", AJoinEntry::Unserialize), commandnsajoin(this)
|
||||
ajoinentry_type("AJoinEntry", AJoinEntry::Unserialize), commandnsajoin(this), ajoinlist(this, "ajoinlist")
|
||||
{
|
||||
|
||||
if (!IRCD->CanSVSJoin)
|
||||
@@ -250,12 +234,9 @@ class NSAJoin : public Module
|
||||
if (!NickServ)
|
||||
return;
|
||||
|
||||
AJoinList *channels = u->Account()->GetExt<AJoinList *>("ns_ajoin_channels");
|
||||
AJoinList *channels = u->Account()->GetExt<AJoinList>("ajoinlist");
|
||||
if (channels == NULL)
|
||||
{
|
||||
channels = new AJoinList();
|
||||
u->Account()->Extend("ns_ajoin_channels", channels);
|
||||
}
|
||||
channels = u->Account()->Extend<AJoinList>("ajoinlist");
|
||||
|
||||
for (unsigned i = 0; i < (*channels)->size(); ++i)
|
||||
{
|
||||
@@ -284,7 +265,7 @@ class NSAJoin : public Module
|
||||
continue;
|
||||
else if (c->HasMode("ADMINONLY") && !u->HasMode("ADMIN"))
|
||||
continue;
|
||||
else if (c->HasMode("SSL") && !(u->HasMode("SSL") || u->HasExt("SSL")))
|
||||
else if (c->HasMode("SSL") && !(u->HasMode("SSL") || u->HasExt("ssl")))
|
||||
continue;
|
||||
else if (c->MatchesList(u, "BAN") == true && c->MatchesList(u, "EXCEPT") == false)
|
||||
need_invite = true;
|
||||
|
||||
@@ -62,7 +62,7 @@ class CommandNSAList : public Command
|
||||
{
|
||||
++chan_count;
|
||||
entry["Number"] = stringify(chan_count);
|
||||
entry["Channel"] = (ci->HasExt("NO_EXPIRE") ? "!" : "") + ci->name;
|
||||
entry["Channel"] = (ci->HasExt("CS_NO_EXPIRE") ? "!" : "") + ci->name;
|
||||
entry["Access"] = "Founder";
|
||||
list.AddEntry(entry);
|
||||
continue;
|
||||
@@ -72,7 +72,7 @@ class CommandNSAList : public Command
|
||||
{
|
||||
++chan_count;
|
||||
entry["Number"] = stringify(chan_count);
|
||||
entry["Channel"] = (ci->HasExt("NO_EXPIRE") ? "!" : "") + ci->name;
|
||||
entry["Channel"] = (ci->HasExt("CS_NO_EXPIRE") ? "!" : "") + ci->name;
|
||||
entry["Access"] = "Successor";
|
||||
list.AddEntry(entry);
|
||||
continue;
|
||||
@@ -85,7 +85,7 @@ class CommandNSAList : public Command
|
||||
++chan_count;
|
||||
|
||||
entry["Number"] = stringify(chan_count);
|
||||
entry["Channel"] = (ci->HasExt("NO_EXPIRE") ? "!" : "") + ci->name;
|
||||
entry["Channel"] = (ci->HasExt("CS_NO_EXPIRE") ? "!" : "") + ci->name;
|
||||
for (unsigned j = 0; j < access.size(); ++j)
|
||||
entry["Access"] = entry["Access"] + ", " + access[j]->AccessSerialize();
|
||||
entry["Access"] = entry["Access"].substr(2);
|
||||
|
||||
+176
-48
@@ -10,15 +10,135 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/ns_cert.h"
|
||||
|
||||
static unsigned accessmax;
|
||||
struct NSCertListImpl : NSCertList
|
||||
{
|
||||
Serialize::Reference<NickCore> nc;
|
||||
std::vector<Anope::string> certs;
|
||||
|
||||
public:
|
||||
NSCertListImpl(Extensible *obj) : nc(anope_dynamic_static_cast<NickCore *>(obj)) { }
|
||||
|
||||
/** Add an entry to the nick's certificate list
|
||||
*
|
||||
* @param entry The fingerprint to add to the cert list
|
||||
*
|
||||
* Adds a new entry into the cert list.
|
||||
*/
|
||||
void AddCert(const Anope::string &entry) anope_override
|
||||
{
|
||||
this->certs.push_back(entry);
|
||||
FOREACH_MOD(OnNickAddCert, (this->nc, entry));
|
||||
}
|
||||
|
||||
/** Get an entry from the nick's cert list by index
|
||||
*
|
||||
* @param entry Index in the certificaate list vector to retrieve
|
||||
* @return The fingerprint entry of the given index if within bounds, an empty string if the vector is empty or the index is out of bounds
|
||||
*
|
||||
* Retrieves an entry from the certificate list corresponding to the given index.
|
||||
*/
|
||||
Anope::string GetCert(unsigned entry) const anope_override
|
||||
{
|
||||
if (entry >= this->certs.size())
|
||||
return "";
|
||||
return this->certs[entry];
|
||||
}
|
||||
|
||||
unsigned GetCertCount() const anope_override
|
||||
{
|
||||
return this->certs.size();
|
||||
}
|
||||
|
||||
/** Find an entry in the nick's cert list
|
||||
*
|
||||
* @param entry The fingerprint to search for
|
||||
* @return True if the fingerprint is found in the cert list, false otherwise
|
||||
*
|
||||
* Search for an fingerprint within the cert list.
|
||||
*/
|
||||
bool FindCert(const Anope::string &entry) const anope_override
|
||||
{
|
||||
return std::find(this->certs.begin(), this->certs.end(), entry) != this->certs.end();
|
||||
}
|
||||
|
||||
/** Erase a fingerprint from the nick's certificate list
|
||||
*
|
||||
* @param entry The fingerprint to remove
|
||||
*
|
||||
* Removes the specified fingerprint from the cert list.
|
||||
*/
|
||||
void EraseCert(const Anope::string &entry) anope_override
|
||||
{
|
||||
std::vector<Anope::string>::iterator it = std::find(this->certs.begin(), this->certs.end(), entry);
|
||||
if (it != this->certs.end())
|
||||
{
|
||||
FOREACH_MOD(OnNickEraseCert, (this->nc, entry));
|
||||
this->certs.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
/** Clears the entire nick's cert list
|
||||
*
|
||||
* Deletes all the memory allocated in the certificate list vector and then clears the vector.
|
||||
*/
|
||||
void ClearCert() anope_override
|
||||
{
|
||||
FOREACH_MOD(OnNickClearCert, (this->nc));
|
||||
this->certs.clear();
|
||||
}
|
||||
|
||||
void Check() anope_override
|
||||
{
|
||||
if (this->certs.empty())
|
||||
nc->Shrink<NSCertList>("certificates");
|
||||
}
|
||||
|
||||
struct ExtensibleItem : ::ExtensibleItem<NSCertListImpl>
|
||||
{
|
||||
ExtensibleItem(Module *m, const Anope::string &name) : ::ExtensibleItem<NSCertListImpl>(m, name) { }
|
||||
|
||||
void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override
|
||||
{
|
||||
if (s->GetSerializableType()->GetName() != "NickCore")
|
||||
return;
|
||||
|
||||
const NickCore *nc = anope_dynamic_static_cast<const NickCore *>(e);
|
||||
NSCertList *certs = this->Get(nc);
|
||||
if (certs == NULL || !certs->GetCertCount())
|
||||
return;
|
||||
|
||||
for (unsigned i = 0; i < certs->GetCertCount(); ++i)
|
||||
data["cert"] << certs->GetCert(i) << " ";
|
||||
}
|
||||
|
||||
void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override
|
||||
{
|
||||
if (s->GetSerializableType()->GetName() != "NickCore")
|
||||
return;
|
||||
|
||||
NickCore *nc = anope_dynamic_static_cast<NickCore *>(e);
|
||||
NSCertListImpl *certs = this->Require(nc);
|
||||
|
||||
Anope::string buf;
|
||||
data["cert"] >> buf;
|
||||
spacesepstream sep(buf);
|
||||
certs->certs.clear();
|
||||
while (sep.GetToken(buf))
|
||||
certs->certs.push_back(buf);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class CommandNSCert : public Command
|
||||
{
|
||||
private:
|
||||
void DoServAdminList(CommandSource &source, const NickCore *nc)
|
||||
{
|
||||
if (nc->cert.empty())
|
||||
NSCertList *cl = nc->GetExt<NSCertList>("certificates");
|
||||
|
||||
if (!cl || !cl->GetCertCount())
|
||||
{
|
||||
source.Reply(_("Certificate list for \002%s\002 is empty."), nc->display.c_str());
|
||||
return;
|
||||
@@ -33,9 +153,9 @@ class CommandNSCert : public Command
|
||||
ListFormatter list;
|
||||
list.AddColumn("Certificate");
|
||||
|
||||
for (unsigned i = 0, end = nc->cert.size(); i < end; ++i)
|
||||
for (unsigned i = 0; i < cl->GetCertCount(); ++i)
|
||||
{
|
||||
Anope::string fingerprint = nc->GetCert(i);
|
||||
const Anope::string &fingerprint = cl->GetCert(i);
|
||||
ListFormatter::ListEntry entry;
|
||||
entry["Certificate"] = fingerprint;
|
||||
list.AddEntry(entry);
|
||||
@@ -47,74 +167,74 @@ class CommandNSCert : public Command
|
||||
list.Process(replies);
|
||||
for (unsigned i = 0; i < replies.size(); ++i)
|
||||
source.Reply(replies[i]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void DoAdd(CommandSource &source, NickCore *nc, const Anope::string &mask)
|
||||
{
|
||||
NSCertList *cl = nc->Require<NSCertList>("certificates");
|
||||
|
||||
if (nc->cert.size() >= Config->GetModule(this->owner)->Get<unsigned>("accessmax"))
|
||||
if (cl->GetCertCount() >= Config->GetModule(this->owner)->Get<unsigned>("accessmax"))
|
||||
{
|
||||
source.Reply(_("Sorry, you can only have %d certificate entries for a nickname."), Config->GetModule(this->owner)->Get<unsigned>("accessmax"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (source.GetUser() && !source.GetUser()->fingerprint.empty() && !nc->FindCert(source.GetUser()->fingerprint))
|
||||
{
|
||||
nc->AddCert(source.GetUser()->fingerprint);
|
||||
source.Reply(_("\002%s\002 added to your certificate list."), source.GetUser()->fingerprint.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (mask.empty())
|
||||
{
|
||||
this->OnSyntaxError(source, "ADD");
|
||||
if (source.GetUser() && !source.GetUser()->fingerprint.empty() && !cl->FindCert(source.GetUser()->fingerprint))
|
||||
{
|
||||
cl->AddCert(source.GetUser()->fingerprint);
|
||||
source.Reply(_("\002%s\002 added to your certificate list."), source.GetUser()->fingerprint.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, "ADD");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (nc->FindCert(mask))
|
||||
if (cl->FindCert(mask))
|
||||
{
|
||||
source.Reply(_("Fingerprint \002%s\002 already present on your certificate list."), mask.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
nc->AddCert(mask);
|
||||
cl->AddCert(mask);
|
||||
source.Reply(_("\002%s\002 added to your certificate list."), mask.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
void DoDel(CommandSource &source, NickCore *nc, const Anope::string &mask)
|
||||
{
|
||||
if (source.GetUser() && !source.GetUser()->fingerprint.empty() && nc->FindCert(source.GetUser()->fingerprint))
|
||||
{
|
||||
nc->EraseCert(source.GetUser()->fingerprint);
|
||||
source.Reply(_("\002%s\002 deleted from your certificate list."), source.GetUser()->fingerprint.c_str());
|
||||
return;
|
||||
}
|
||||
NSCertList *cl = nc->Require<NSCertList>("certificates");
|
||||
|
||||
if (mask.empty())
|
||||
{
|
||||
this->OnSyntaxError(source, "DEL");
|
||||
if (source.GetUser() && !source.GetUser()->fingerprint.empty() && cl->FindCert(source.GetUser()->fingerprint))
|
||||
{
|
||||
cl->EraseCert(source.GetUser()->fingerprint);
|
||||
source.Reply(_("\002%s\002 deleted from your certificate list."), source.GetUser()->fingerprint.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, "DEL");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!nc->FindCert(mask))
|
||||
if (!cl->FindCert(mask))
|
||||
{
|
||||
source.Reply(_("\002%s\002 not found on your certificate list."), mask.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
source.Reply(_("\002%s\002 deleted from your certificate list."), mask.c_str());
|
||||
nc->EraseCert(mask);
|
||||
|
||||
return;
|
||||
cl->EraseCert(mask);
|
||||
cl->Check();
|
||||
}
|
||||
|
||||
void DoList(CommandSource &source, const NickCore *nc)
|
||||
{
|
||||
NSCertList *cl = nc->GetExt<NSCertList>("certificates");
|
||||
|
||||
if (nc->cert.empty())
|
||||
if (!cl || !cl->GetCertCount())
|
||||
{
|
||||
source.Reply(_("Your certificate list is empty."));
|
||||
return;
|
||||
@@ -123,10 +243,10 @@ class CommandNSCert : public Command
|
||||
ListFormatter list;
|
||||
list.AddColumn("Certificate");
|
||||
|
||||
for (unsigned i = 0, end = nc->cert.size(); i < end; ++i)
|
||||
for (unsigned i = 0; i < cl->GetCertCount(); ++i)
|
||||
{
|
||||
ListFormatter::ListEntry entry;
|
||||
entry["Certificate"] = nc->GetCert(i);
|
||||
entry["Certificate"] = cl->GetCert(i);
|
||||
list.AddEntry(entry);
|
||||
}
|
||||
|
||||
@@ -197,8 +317,17 @@ class CommandNSCert : public Command
|
||||
class NSCert : public Module
|
||||
{
|
||||
CommandNSCert commandnscert;
|
||||
NSCertListImpl::ExtensibleItem certs;
|
||||
|
||||
void DoAutoIdentify(User *u)
|
||||
public:
|
||||
NSCert(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
commandnscert(this), certs(this, "certificates")
|
||||
{
|
||||
if (!IRCD || !IRCD->CanCertFP)
|
||||
throw ModuleException("Your IRCd does not support ssl client certificates");
|
||||
}
|
||||
|
||||
void OnFingerprint(User *u) anope_override
|
||||
{
|
||||
NickAlias *na = NickAlias::Find(u->nick);
|
||||
BotInfo *NickServ = Config->GetClient("NickServ");
|
||||
@@ -208,29 +337,28 @@ class NSCert : public Module
|
||||
return;
|
||||
if (na->nc->HasExt("SUSPENDED"))
|
||||
return;
|
||||
if (!na->nc->FindCert(u->fingerprint))
|
||||
|
||||
NSCertList *cl = certs.Get(na->nc);
|
||||
if (!cl || !cl->FindCert(u->fingerprint))
|
||||
return;
|
||||
|
||||
u->Identify(na);
|
||||
u->SendMessage(NickServ, _("SSL Fingerprint accepted. You are now identified."));
|
||||
Log(u) << "automatically identified for account " << na->nc->display << " using a valid SSL fingerprint";
|
||||
return;
|
||||
Log(u) << "automatically identified for account " << na->nc->display << " via SSL certificate fingerprint";
|
||||
}
|
||||
|
||||
public:
|
||||
NSCert(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
commandnscert(this)
|
||||
EventReturn OnNickValidate(User *u, NickAlias *na) anope_override
|
||||
{
|
||||
NSCertList *cl = certs.Get(na->nc);
|
||||
if (!u->fingerprint.empty() && cl && cl->FindCert(u->fingerprint))
|
||||
{
|
||||
u->Identify(na);
|
||||
u->SendMessage(Config->GetClient("NickServ"), _("SSL fingerprint accepted, you are now identified."));
|
||||
Log(u) << "automatically identified for account " << na->nc->display << " via SSL fingerprint.";
|
||||
return EVENT_ALLOW;
|
||||
}
|
||||
|
||||
if (!IRCD || !IRCD->CanCertFP)
|
||||
throw ModuleException("Your IRCd does not support ssl client certificates");
|
||||
|
||||
|
||||
}
|
||||
|
||||
void OnFingerprint(User *u) anope_override
|
||||
{
|
||||
DoAutoIdentify(u);
|
||||
return EVENT_CONTINUE;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/ns_cert.h"
|
||||
|
||||
class NSGroupRequest : public IdentifyRequest
|
||||
{
|
||||
@@ -43,7 +44,6 @@ class NSGroupRequest : public IdentifyRequest
|
||||
na->time_registered = na->last_seen = Anope::CurTime;
|
||||
|
||||
u->Login(target->nc);
|
||||
IRCD->SendLogin(u);
|
||||
FOREACH_MOD(OnNickGroup, (u, target));
|
||||
|
||||
Log(LOG_COMMAND, source, cmd) << "makes " << nick << " join group of " << target->nick << " (" << target->nc->display << ") (email: " << (!target->nc->email.empty() ? target->nc->email : "none") << ")";
|
||||
@@ -141,7 +141,9 @@ class CommandNSGroup : public Command
|
||||
bool ok = false;
|
||||
if (!na && u->Account())
|
||||
ok = true;
|
||||
else if (!u->fingerprint.empty() && target->nc->FindCert(u->fingerprint))
|
||||
|
||||
NSCertList *cl = target->nc->GetExt<NSCertList>("certificates");
|
||||
if (!u->fingerprint.empty() && cl && cl->FindCert(u->fingerprint))
|
||||
ok = true;
|
||||
|
||||
if (ok == false && !pass.empty())
|
||||
@@ -236,8 +238,6 @@ class CommandNSUngroup : public Command
|
||||
nc->pass = oldcore->pass;
|
||||
if (!oldcore->email.empty())
|
||||
nc->email = oldcore->email;
|
||||
if (!oldcore->greet.empty())
|
||||
nc->greet = oldcore->greet;
|
||||
nc->language = oldcore->language;
|
||||
|
||||
source.Reply(_("Nick %s has been ungrouped from %s."), na->nick.c_str(), oldcore->display.c_str());
|
||||
@@ -303,7 +303,7 @@ class CommandNSGList : public Command
|
||||
|
||||
ListFormatter::ListEntry entry;
|
||||
entry["Nick"] = na2->nick;
|
||||
entry["Expires"] = (na2->HasExt("NO_EXPIRE") || !nickserv_expire || Anope::NoExpire) ? "Does not expire" : ("expires in " + Anope::strftime(na2->last_seen + nickserv_expire));
|
||||
entry["Expires"] = (na2->HasExt("NS_NO_EXPIRE") || !nickserv_expire || Anope::NoExpire) ? "Does not expire" : ("expires in " + Anope::strftime(na2->last_seen + nickserv_expire));
|
||||
list.AddEntry(entry);
|
||||
}
|
||||
|
||||
|
||||
+130
-40
@@ -13,17 +13,6 @@
|
||||
|
||||
class CommandNSInfo : public Command
|
||||
{
|
||||
private:
|
||||
void CheckOptStr(NickCore *core, Anope::string &buf, const Anope::string &opt, const char *str, const Extensible *e, bool reverse_logic = false)
|
||||
{
|
||||
if (reverse_logic != e->HasExt(opt))
|
||||
{
|
||||
if (!buf.empty())
|
||||
buf += ", ";
|
||||
|
||||
buf += Language::Translate(core, str);
|
||||
}
|
||||
}
|
||||
public:
|
||||
CommandNSInfo(Module *creator) : Command(creator, "nickserv/info", 0, 2)
|
||||
{
|
||||
@@ -105,34 +94,6 @@ class CommandNSInfo : public Command
|
||||
else
|
||||
info[_("VHost")] = na->GetVhostHost();
|
||||
}
|
||||
|
||||
if (!na->nc->greet.empty())
|
||||
info[_("Greet")] = na->nc->greet;
|
||||
|
||||
Anope::string optbuf;
|
||||
|
||||
CheckOptStr(source.nc, optbuf, "KILLPROTECT", _("Protection"), na->nc);
|
||||
CheckOptStr(source.nc, optbuf, "SECURE", _("Security"), na->nc);
|
||||
CheckOptStr(source.nc, optbuf, "PRIVATE", _("Private"), na->nc);
|
||||
CheckOptStr(source.nc, optbuf, "MSG", _("Message mode"), na->nc);
|
||||
CheckOptStr(source.nc, optbuf, "AUTOOP", _("Auto-op"), na->nc);
|
||||
CheckOptStr(source.nc, optbuf, "SUSPENDED", _("Suspended"), na->nc);
|
||||
CheckOptStr(source.nc, optbuf, "STATS", _("Chanstats"), na->nc);
|
||||
CheckOptStr(source.nc, optbuf, "NO_EXPIRE", _("No expire"), na);
|
||||
|
||||
info[_("Options")] = optbuf.empty() ? _("None") : optbuf;
|
||||
|
||||
if (na->nc->HasExt("UNCONFIRMED") == false)
|
||||
{
|
||||
time_t nickserv_expire = Config->GetModule("nickserv")->Get<time_t>("expire");
|
||||
if (!na->HasExt("NO_EXPIRE") && nickserv_expire && !Anope::NoExpire)
|
||||
info[_("Expires")] = Anope::strftime(na->last_seen + nickserv_expire);
|
||||
}
|
||||
else
|
||||
{
|
||||
time_t unconfirmed_expire = Config->GetModule("nickserv")->Get<time_t>("unconfirmedexpire", "1d");
|
||||
info[_("Expires")] = Anope::strftime(na->time_registered + unconfirmed_expire);
|
||||
}
|
||||
}
|
||||
|
||||
FOREACH_MOD(OnNickInfo, (source, na, info, show_hidden));
|
||||
@@ -159,13 +120,142 @@ class CommandNSInfo : public Command
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class CommandNSSetHide : public Command
|
||||
{
|
||||
public:
|
||||
CommandNSSetHide(Module *creator, const Anope::string &sname = "nickserv/set/hide", size_t min = 2) : Command(creator, sname, min, min + 1)
|
||||
{
|
||||
this->SetDesc(_("Hide certain pieces of nickname information"));
|
||||
this->SetSyntax(_("{EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"));
|
||||
}
|
||||
|
||||
void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m, const Anope::string &arg)
|
||||
{
|
||||
const NickAlias *na = NickAlias::Find(user);
|
||||
if (!na)
|
||||
{
|
||||
source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
|
||||
return;
|
||||
}
|
||||
NickCore *nc = na->nc;
|
||||
|
||||
EventReturn MOD_RESULT;
|
||||
FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
return;
|
||||
|
||||
Anope::string onmsg, offmsg, flag;
|
||||
|
||||
if (param.equals_ci("EMAIL"))
|
||||
{
|
||||
flag = "HIDE_EMAIL";
|
||||
onmsg = _("The E-mail address of \002%s\002 will now be hidden from %s INFO displays.");
|
||||
offmsg = _("The E-mail address of \002%s\002 will now be shown in %s INFO displays.");
|
||||
}
|
||||
else if (param.equals_ci("USERMASK"))
|
||||
{
|
||||
flag = "HIDE_MASK";
|
||||
onmsg = _("The last seen user@host mask of \002%s\002 will now be hidden from %s INFO displays.");
|
||||
offmsg = _("The last seen user@host mask of \002%s\002 will now be shown in %s INFO displays.");
|
||||
}
|
||||
else if (param.equals_ci("STATUS"))
|
||||
{
|
||||
flag = "HIDE_STATUS";
|
||||
onmsg = _("The services access status of \002%s\002 will now be hidden from %s INFO displays.");
|
||||
offmsg = _("The services access status of \002%s\002 will now be shown in %s INFO displays.");
|
||||
}
|
||||
else if (param.equals_ci("QUIT"))
|
||||
{
|
||||
flag = "HIDE_QUIT";
|
||||
onmsg = _("The last quit message of \002%s\002 will now be hidden from %s INFO displays.");
|
||||
offmsg = _("The last quit message of \002%s\002 will now be shown in %s INFO displays.");
|
||||
}
|
||||
else
|
||||
{
|
||||
this->OnSyntaxError(source, "HIDE");
|
||||
return;
|
||||
}
|
||||
|
||||
if (arg.equals_ci("ON"))
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change hide " << param << " to " << arg << " for " << nc->display;
|
||||
nc->Extend<bool>(flag);
|
||||
source.Reply(onmsg.c_str(), nc->display.c_str(), source.service->nick.c_str());
|
||||
}
|
||||
else if (arg.equals_ci("OFF"))
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change hide " << param << " to " << arg << " for " << nc->display;
|
||||
nc->Shrink<bool>(flag);
|
||||
source.Reply(offmsg.c_str(), nc->display.c_str(), source.service->nick.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, "HIDE");
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
this->Run(source, source.nc->display, params[0], params[1]);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_("Allows you to prevent certain pieces of information from\n"
|
||||
"being displayed when someone does a %s \002INFO\002 on your\n"
|
||||
"nick. You can hide your E-mail address (\002EMAIL\002), last seen\n"
|
||||
"user@host mask (\002USERMASK\002), your services access status\n"
|
||||
"(\002STATUS\002) and last quit message (\002QUIT\002).\n"
|
||||
"The second parameter specifies whether the information should\n"
|
||||
"be displayed (\002OFF\002) or hidden (\002ON\002)."), source.service->nick.c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandNSSASetHide : public CommandNSSetHide
|
||||
{
|
||||
public:
|
||||
CommandNSSASetHide(Module *creator) : CommandNSSetHide(creator, "nickserv/saset/hide", 3)
|
||||
{
|
||||
this->SetSyntax("\037nickname\037 {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}");
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
this->ClearSyntax();
|
||||
this->Run(source, params[0], params[1], params[2]);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_("Allows you to prevent certain pieces of information from\n"
|
||||
"being displayed when someone does a %s \002INFO\002 on the\n"
|
||||
"nick. You can hide the E-mail address (\002EMAIL\002), last seen\n"
|
||||
"user@host mask (\002USERMASK\002), the services access status\n"
|
||||
"(\002STATUS\002) and last quit message (\002QUIT\002).\n"
|
||||
"The second parameter specifies whether the information should\n"
|
||||
"be displayed (\002OFF\002) or hidden (\002ON\002)."), source.service->nick.c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class NSInfo : public Module
|
||||
{
|
||||
CommandNSInfo commandnsinfo;
|
||||
|
||||
CommandNSSetHide commandnssethide;
|
||||
CommandNSSASetHide commandnssasethide;
|
||||
|
||||
SerializableExtensibleItem<bool> hide_email, hide_usermask, hide_status, hide_quit;
|
||||
|
||||
public:
|
||||
NSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
commandnsinfo(this)
|
||||
commandnsinfo(this), commandnssethide(this), commandnssasethide(this),
|
||||
hide_email(this, "HIDE_EMAIL"), hide_usermask(this, "HIDE_MASK"), hide_status(this, "HIDE_STATUS"),
|
||||
hide_quit(this, "HIDE_QUIT")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -83,9 +83,9 @@ class CommandNSList : public Command
|
||||
const NickAlias *na = it->second;
|
||||
|
||||
/* Don't show private nicks to non-services admins. */
|
||||
if (na->nc->HasExt("PRIVATE") && !is_servadmin && na->nc != mync)
|
||||
if (na->nc->HasExt("NS_PRIVATE") && !is_servadmin && na->nc != mync)
|
||||
continue;
|
||||
else if (nsnoexpire && !na->HasExt("NO_EXPIRE"))
|
||||
else if (nsnoexpire && !na->HasExt("NS_NO_EXPIRE"))
|
||||
continue;
|
||||
else if (suspended && !na->nc->HasExt("SUSPENDED"))
|
||||
continue;
|
||||
@@ -101,7 +101,7 @@ class CommandNSList : public Command
|
||||
if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nnicks <= listmax)
|
||||
{
|
||||
bool isnoexpire = false;
|
||||
if (is_servadmin && na->HasExt("NO_EXPIRE"))
|
||||
if (is_servadmin && na->HasExt("NS_NO_EXPIRE"))
|
||||
isnoexpire = true;
|
||||
|
||||
ListFormatter::ListEntry entry;
|
||||
@@ -177,15 +177,119 @@ class CommandNSList : public Command
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class CommandNSSetPrivate : public Command
|
||||
{
|
||||
public:
|
||||
CommandNSSetPrivate(Module *creator, const Anope::string &sname = "nickserv/set/private", size_t min = 1) : Command(creator, sname, min, min + 1)
|
||||
{
|
||||
this->SetDesc(_("Prevent the nickname from appearing in the LIST command"));
|
||||
this->SetSyntax(_("{ON | OFF}"));
|
||||
}
|
||||
|
||||
void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m)
|
||||
{
|
||||
const NickAlias *na = NickAlias::Find(user);
|
||||
if (!na)
|
||||
{
|
||||
source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
|
||||
return;
|
||||
}
|
||||
NickCore *nc = na->nc;
|
||||
|
||||
EventReturn MOD_RESULT;
|
||||
FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
return;
|
||||
|
||||
if (param.equals_ci("ON"))
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable private for " << nc->display;
|
||||
nc->Extend<bool>("NS_PRIVATE");
|
||||
source.Reply(_("Private option is now \002on\002 for \002%s\002."), nc->display.c_str());
|
||||
}
|
||||
else if (param.equals_ci("OFF"))
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable private for " << nc->display;
|
||||
nc->Shrink<bool>("NS_PRIVATE");
|
||||
source.Reply(_("Private option is now \002off\002 for \002%s\002."), nc->display.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, "PRIVATE");
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
this->Run(source, source.nc->display, params[0]);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_("Turns %s's privacy option on or off for your nick.\n"
|
||||
"With \002PRIVATE\002 set, your nickname will not appear in\n"
|
||||
"nickname lists generated with %s's \002LIST\002 command.\n"
|
||||
"(However, anyone who knows your nickname can still get\n"
|
||||
"information on it using the \002INFO\002 command.)"),
|
||||
source.service->nick.c_str(), source.service->nick.c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandNSSASetPrivate : public CommandNSSetPrivate
|
||||
{
|
||||
public:
|
||||
CommandNSSASetPrivate(Module *creator) : CommandNSSetPrivate(creator, "nickserv/saset/private", 2)
|
||||
{
|
||||
this->ClearSyntax();
|
||||
this->SetSyntax(_("\037nickname\037 {ON | OFF}"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
this->Run(source, params[0], params[1]);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_("Turns %s's privacy option on or off for the nick.\n"
|
||||
"With \002PRIVATE\002 set, the nickname will not appear in\n"
|
||||
"nickname lists generated with %s's \002LIST\002 command.\n"
|
||||
"(However, anyone who knows the nickname can still get\n"
|
||||
"information on it using the \002INFO\002 command.)"),
|
||||
source.service->nick.c_str(), source.service->nick.c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class NSList : public Module
|
||||
{
|
||||
CommandNSList commandnslist;
|
||||
|
||||
CommandNSSetPrivate commandnssetprivate;
|
||||
CommandNSSASetPrivate commandnssasetprivate;
|
||||
|
||||
SerializableExtensibleItem<bool> priv;
|
||||
|
||||
public:
|
||||
NSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
commandnslist(this)
|
||||
commandnslist(this), commandnssetprivate(this), commandnssasetprivate(this),
|
||||
priv(this, "NS_PRIVATE")
|
||||
{
|
||||
}
|
||||
|
||||
void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_all) anope_override
|
||||
{
|
||||
if (!show_all)
|
||||
return;
|
||||
|
||||
if (priv.HasExt(na->nc))
|
||||
info.AddOption(_("Private"));
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_INIT(NSList)
|
||||
|
||||
@@ -10,10 +10,11 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/ns_cert.h"
|
||||
|
||||
static ServiceReference<NickServService> nickserv("NickServService", "NickServ");
|
||||
|
||||
struct NSRecoverExtensibleInfo : ExtensibleItem, std::map<Anope::string, ChannelStatus> { };
|
||||
typedef std::map<Anope::string, ChannelStatus> NSRecoverInfo;
|
||||
|
||||
class NSRecoverRequest : public IdentifyRequest
|
||||
{
|
||||
@@ -50,7 +51,7 @@ class NSRecoverRequest : public IdentifyRequest
|
||||
// same person that is executing the command, so kill them off (old GHOST command).
|
||||
else if (u->Account() == na->nc)
|
||||
{
|
||||
if (!source.GetAccount() && na->nc->HasExt("SECURE"))
|
||||
if (!source.GetAccount() && na->nc->HasExt("NS_SECURE"))
|
||||
{
|
||||
source.GetUser()->Login(u->Account());
|
||||
Log(LOG_COMMAND, source, cmd) << "and was automatically identified to " << u->Account()->display;
|
||||
@@ -60,11 +61,9 @@ class NSRecoverRequest : public IdentifyRequest
|
||||
{
|
||||
if (!u->chans.empty())
|
||||
{
|
||||
NSRecoverExtensibleInfo *ei = new NSRecoverExtensibleInfo;
|
||||
NSRecoverInfo *ei = source.GetUser()->Extend<NSRecoverInfo>("recover");
|
||||
for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it)
|
||||
(*ei)[it->first->name] = it->second->status;
|
||||
|
||||
source.GetUser()->Extend("ns_recover_info", ei);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +82,7 @@ class NSRecoverRequest : public IdentifyRequest
|
||||
/* User is not identified or not identified to the same account as the person using this command */
|
||||
else
|
||||
{
|
||||
if (!source.GetAccount() && na->nc->HasExt("SECURE"))
|
||||
if (!source.GetAccount() && na->nc->HasExt("NS_SECURE"))
|
||||
{
|
||||
source.GetUser()->Login(na->nc); // Identify the user using the command if they arent identified
|
||||
Log(LOG_COMMAND, source, cmd) << "and was automatically identified to " << na->nick << " (" << na->nc->display << ")";
|
||||
@@ -161,9 +160,11 @@ class CommandNSRecover : public Command
|
||||
bool ok = false;
|
||||
if (source.GetAccount() == na->nc)
|
||||
ok = true;
|
||||
else if (!na->nc->HasExt("SECURE") && source.GetUser() && na->nc->IsOnAccess(source.GetUser()))
|
||||
else if (!na->nc->HasExt("NS_SECURE") && source.GetUser() && na->nc->IsOnAccess(source.GetUser()))
|
||||
ok = true;
|
||||
else if (source.GetUser() && !source.GetUser()->fingerprint.empty() && na->nc->FindCert(source.GetUser()->fingerprint))
|
||||
|
||||
NSCertList *cl = na->nc->GetExt<NSCertList>("certificates");
|
||||
if (source.GetUser() && !source.GetUser()->fingerprint.empty() && cl && cl->FindCert(source.GetUser()->fingerprint))
|
||||
ok = true;
|
||||
|
||||
if (ok == false && !pass.empty())
|
||||
@@ -200,10 +201,11 @@ class CommandNSRecover : public Command
|
||||
class NSRecover : public Module
|
||||
{
|
||||
CommandNSRecover commandnsrecover;
|
||||
PrimitiveExtensibleItem<NSRecoverInfo> recover;
|
||||
|
||||
public:
|
||||
NSRecover(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
commandnsrecover(this)
|
||||
commandnsrecover(this), recover(this, "recover")
|
||||
{
|
||||
|
||||
if (Config->GetBlock("options")->Get<bool>("nonicknameownership"))
|
||||
@@ -211,34 +213,15 @@ class NSRecover : public Module
|
||||
|
||||
}
|
||||
|
||||
~NSRecover()
|
||||
{
|
||||
for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
|
||||
it->second->Shrink("ns_recover_info");
|
||||
|
||||
OnShutdown();
|
||||
}
|
||||
|
||||
void OnShutdown() anope_override
|
||||
{
|
||||
/* On shutdown, restart, or mod unload, remove all of our holds for nicks (svshold or qlines)
|
||||
* because some IRCds do not allow us to have these automatically expire
|
||||
*/
|
||||
for (nickalias_map::const_iterator it = NickAliasList->begin(); it != NickAliasList->end(); ++it)
|
||||
nickserv->Release(it->second);
|
||||
}
|
||||
|
||||
void OnRestart() anope_override { OnShutdown(); }
|
||||
|
||||
void OnUserNickChange(User *u, const Anope::string &oldnick) anope_override
|
||||
{
|
||||
if (Config->GetModule(this)->Get<bool>("restoreonrecover"))
|
||||
{
|
||||
NSRecoverExtensibleInfo *ei = u->GetExt<NSRecoverExtensibleInfo *>("ns_recover_info");
|
||||
NSRecoverInfo *ei = recover.Get(u);
|
||||
BotInfo *NickServ = Config->GetClient("NickServ");
|
||||
|
||||
if (ei != NULL && NickServ != NULL)
|
||||
for (std::map<Anope::string, ChannelStatus>::iterator it = ei->begin(), it_end = ei->end(); it != it_end;)
|
||||
for (NSRecoverInfo::iterator it = ei->begin(), it_end = ei->end(); it != it_end;)
|
||||
{
|
||||
Channel *c = Channel::Find(it->first);
|
||||
const Anope::string &cname = it->first;
|
||||
@@ -257,11 +240,11 @@ class NSRecover : public Module
|
||||
{
|
||||
if (Config->GetModule(this)->Get<bool>("restoreonrecover"))
|
||||
{
|
||||
NSRecoverExtensibleInfo *ei = u->GetExt<NSRecoverExtensibleInfo *>("ns_recover_info");
|
||||
NSRecoverInfo *ei = recover.Get(u);
|
||||
|
||||
if (ei != NULL)
|
||||
{
|
||||
std::map<Anope::string, ChannelStatus>::iterator it = ei->find(c->name);
|
||||
NSRecoverInfo::iterator it = ei->find(c->name);
|
||||
if (it != ei->end())
|
||||
{
|
||||
for (size_t i = 0; i < it->second.Modes().length(); ++i)
|
||||
@@ -269,7 +252,7 @@ class NSRecover : public Module
|
||||
|
||||
ei->erase(it);
|
||||
if (ei->empty())
|
||||
u->Shrink("ns_recover_info");
|
||||
recover.Unset(u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,27 +36,27 @@ class CommandNSConfirm : public Command
|
||||
source.Reply(_("Nick \002%s\002 is already confirmed."), na->nick.c_str());
|
||||
else
|
||||
{
|
||||
na->nc->Shrink("UNCONFIRMED");
|
||||
na->nc->Shrink<bool>("UNCONFIRMED");
|
||||
Log(LOG_ADMIN, source, this) << "to confirm nick " << na->nick << " (" << na->nc->display << ")";
|
||||
source.Reply(_("Nick \002%s\002 has been confirmed."), na->nick.c_str());
|
||||
}
|
||||
}
|
||||
else if (source.nc)
|
||||
{
|
||||
Anope::string *code = source.nc->GetExt<ExtensibleItemClass<Anope::string> *>("ns_register_passcode");
|
||||
Anope::string *code = source.nc->GetExt<Anope::string>("passcode");
|
||||
if (code != NULL && *code == passcode)
|
||||
{
|
||||
NickCore *nc = source.nc;
|
||||
nc->Shrink("ns_register_passcode");
|
||||
nc->Shrink<Anope::string>("passcode");
|
||||
Log(LOG_COMMAND, source, this) << "to confirm their email";
|
||||
source.Reply(_("Your email address of \002%s\002 has been confirmed."), source.nc->email.c_str());
|
||||
nc->Shrink("UNCONFIRMED");
|
||||
nc->Shrink<bool>("UNCONFIRMED");
|
||||
|
||||
if (source.GetUser())
|
||||
{
|
||||
IRCD->SendLogin(source.GetUser());
|
||||
const NickAlias *na = NickAlias::Find(source.GetNick());
|
||||
if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && na != NULL && na->nc == source.GetAccount() && na->nc->HasExt("UNCONFIRMED") == false)
|
||||
if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && na != NULL && na->nc == source.GetAccount() && !na->nc->HasExt("UNCONFIRMED"))
|
||||
source.GetUser()->SetMode(source.service, "REGISTERED");
|
||||
}
|
||||
}
|
||||
@@ -207,12 +207,12 @@ class CommandNSRegister : public Command
|
||||
|
||||
if (nsregister.equals_ci("admin"))
|
||||
{
|
||||
nc->ExtendMetadata("UNCONFIRMED");
|
||||
nc->Extend<bool>("UNCONFIRMED");
|
||||
source.Reply(_("All new accounts must be validated by an administrator. Please wait for your registration to be confirmed."));
|
||||
}
|
||||
else if (nsregister.equals_ci("mail"))
|
||||
{
|
||||
nc->ExtendMetadata("UNCONFIRMED");
|
||||
nc->Extend<bool>("UNCONFIRMED");
|
||||
if (SendRegmail(u, na, source.service))
|
||||
{
|
||||
time_t unconfirmed_expire = Config->GetModule("nickserv")->Get<time_t>("unconfirmedexpire", "1d");
|
||||
@@ -292,7 +292,7 @@ class CommandNSResend : public Command
|
||||
|
||||
if (na == NULL)
|
||||
source.Reply(NICK_NOT_REGISTERED);
|
||||
else if (na->nc != source.GetAccount() || source.nc->HasExt("UNCONFIRMED") == false)
|
||||
else if (na->nc != source.GetAccount() || !source.nc->HasExt("UNCONFIRMED"))
|
||||
source.Reply(_("Your account is already confirmed."));
|
||||
else
|
||||
{
|
||||
@@ -336,23 +336,55 @@ class NSRegister : public Module
|
||||
CommandNSConfirm commandnsconfirm;
|
||||
CommandNSResend commandnsrsend;
|
||||
|
||||
PrimitiveExtensibleItem<bool> unconfirmed;
|
||||
PrimitiveExtensibleItem<Anope::string> passcode;
|
||||
|
||||
public:
|
||||
NSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
commandnsregister(this), commandnsconfirm(this), commandnsrsend(this)
|
||||
commandnsregister(this), commandnsconfirm(this), commandnsrsend(this), unconfirmed(this, "UNCONFIRMED"),
|
||||
passcode(this, "passcode")
|
||||
{
|
||||
if (Config->GetModule(this)->Get<const Anope::string>("registration").equals_ci("disable"))
|
||||
throw ModuleException("Module " + this->name + " will not load with registration disabled.");
|
||||
}
|
||||
|
||||
void OnNickIdentify(User *u) anope_override
|
||||
{
|
||||
BotInfo *NickServ;
|
||||
if (unconfirmed.HasExt(u->Account()) && (NickServ = Config->GetClient("NickServ")))
|
||||
{
|
||||
const Anope::string &nsregister = Config->GetModule(this)->Get<const Anope::string>("registration");
|
||||
if (nsregister.equals_ci("admin"))
|
||||
u->SendMessage(NickServ, _("All new accounts must be validated by an administrator. Please wait for your registration to be confirmed."));
|
||||
else
|
||||
u->SendMessage(NickServ, _("Your email address is not confirmed. To confirm it, follow the instructions that were emailed to you when you registered."));
|
||||
const NickAlias *this_na = NickAlias::Find(u->Account()->display);
|
||||
time_t time_registered = Anope::CurTime - this_na->time_registered;
|
||||
time_t unconfirmed_expire = Config->GetModule(this)->Get<time_t>("unconfirmedexpire", "1d");
|
||||
if (unconfirmed_expire > time_registered)
|
||||
u->SendMessage(NickServ, _("Your account will expire, if not confirmed, in %s"), Anope::Duration(unconfirmed_expire - time_registered).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void OnPreNickExpire(NickAlias *na, bool &expire) anope_override
|
||||
{
|
||||
if (unconfirmed.HasExt(na->nc))
|
||||
{
|
||||
time_t unconfirmed_expire = Config->GetModule(this)->Get<time_t>("unconfirmedexpire", "1d");
|
||||
if (unconfirmed_expire && Anope::CurTime - na->time_registered >= unconfirmed_expire)
|
||||
expire = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static bool SendRegmail(User *u, const NickAlias *na, const BotInfo *bi)
|
||||
{
|
||||
NickCore *nc = na->nc;
|
||||
|
||||
Anope::string *code = na->nc->GetExt<ExtensibleItemClass<Anope::string> *>("ns_register_passcode");
|
||||
Anope::string codebuf;
|
||||
Anope::string *code = na->nc->GetExt<Anope::string>("passcode");
|
||||
if (code == NULL)
|
||||
{
|
||||
code = na->nc->Extend<Anope::string>("passcode");
|
||||
int chars[] = {
|
||||
' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
|
||||
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
|
||||
@@ -362,22 +394,19 @@ static bool SendRegmail(User *u, const NickAlias *na, const BotInfo *bi)
|
||||
};
|
||||
int idx, min = 1, max = 62;
|
||||
for (idx = 0; idx < 9; ++idx)
|
||||
codebuf += chars[1 + static_cast<int>((static_cast<float>(max - min)) * static_cast<uint16_t>(rand()) / 65536.0) + min];
|
||||
nc->Extend("ns_register_passcode", new ExtensibleItemClass<Anope::string>(codebuf));
|
||||
*code += chars[1 + static_cast<int>((static_cast<float>(max - min)) * static_cast<uint16_t>(rand()) / 65536.0) + min];
|
||||
}
|
||||
else
|
||||
codebuf = *code;
|
||||
|
||||
Anope::string subject = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const Anope::string>("registration_subject").c_str()),
|
||||
message = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const Anope::string>("registration_message").c_str());
|
||||
|
||||
subject = subject.replace_all_cs("%n", na->nick);
|
||||
subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
|
||||
subject = subject.replace_all_cs("%c", codebuf);
|
||||
subject = subject.replace_all_cs("%c", *code);
|
||||
|
||||
message = message.replace_all_cs("%n", na->nick);
|
||||
message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
|
||||
message = message.replace_all_cs("%c", codebuf);
|
||||
message = message.replace_all_cs("%c", *code);
|
||||
|
||||
return Mail::Send(u, nc, bi, subject, message);
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ class CommandNSResetPass : public Command
|
||||
}
|
||||
};
|
||||
|
||||
struct ResetInfo : ExtensibleItem
|
||||
struct ResetInfo
|
||||
{
|
||||
Anope::string code;
|
||||
time_t time;
|
||||
@@ -62,21 +62,14 @@ struct ResetInfo : ExtensibleItem
|
||||
class NSResetPass : public Module
|
||||
{
|
||||
CommandNSResetPass commandnsresetpass;
|
||||
PrimitiveExtensibleItem<ResetInfo> reset;
|
||||
|
||||
public:
|
||||
NSResetPass(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
commandnsresetpass(this)
|
||||
commandnsresetpass(this), reset(this, "reset")
|
||||
{
|
||||
if (!Config->GetBlock("mail")->Get<bool>("usemail"))
|
||||
throw ModuleException("Not using mail.");
|
||||
|
||||
|
||||
}
|
||||
|
||||
~NSResetPass()
|
||||
{
|
||||
for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it)
|
||||
it->second->Shrink("ns_resetpass");
|
||||
}
|
||||
|
||||
EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> ¶ms) anope_override
|
||||
@@ -85,24 +78,23 @@ class NSResetPass : public Module
|
||||
{
|
||||
NickAlias *na = NickAlias::Find(params[0]);
|
||||
|
||||
ResetInfo *ri = na ? na->nc->GetExt<ResetInfo *>("ns_resetpass") : NULL;
|
||||
ResetInfo *ri = na ? reset.Get(na->nc) : NULL;
|
||||
if (na && ri)
|
||||
{
|
||||
NickCore *nc = na->nc;
|
||||
const Anope::string &passcode = params[1];
|
||||
if (ri->time < Anope::CurTime - 3600)
|
||||
{
|
||||
nc->Shrink("ns_resetpass");
|
||||
reset.Unset(nc);
|
||||
source.Reply(_("Your password reset request has expired."));
|
||||
}
|
||||
else if (passcode.equals_cs(ri->code))
|
||||
{
|
||||
nc->Shrink("ns_resetpass");
|
||||
reset.Unset(nc);
|
||||
nc->Shrink<bool>("UNCONFIRMED");
|
||||
|
||||
Log(LOG_COMMAND, source, &commandnsresetpass) << "confirmed RESETPASS to forcefully identify as " << na->nick;
|
||||
|
||||
nc->Shrink("UNCONFIRMED");
|
||||
|
||||
if (source.GetUser())
|
||||
{
|
||||
source.GetUser()->Identify(na);
|
||||
@@ -147,13 +139,11 @@ static bool SendResetEmail(User *u, const NickAlias *na, const BotInfo *bi)
|
||||
message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
|
||||
message = message.replace_all_cs("%c", passcode);
|
||||
|
||||
ResetInfo *ri = new ResetInfo;
|
||||
ResetInfo *ri = na->nc->Extend<ResetInfo>("reset");
|
||||
ri->code = passcode;
|
||||
ri->time = Anope::CurTime;
|
||||
NickCore *nc = na->nc;
|
||||
nc->Extend("ns_resetpass", ri);
|
||||
|
||||
return Mail::Send(u, nc, bi, subject, message);
|
||||
return Mail::Send(u, na->nc, bi, subject, message);
|
||||
}
|
||||
|
||||
MODULE_INIT(NSResetPass)
|
||||
|
||||
+76
-351
@@ -191,8 +191,6 @@ class CommandNSSASetPassword : public Command
|
||||
source.Reply(_("Password for \002%s\002 changed to \002%s\002."), nc->display.c_str(), tmp_pass.c_str());
|
||||
else
|
||||
source.Reply(_("Password for \002%s\002 changed."), nc->display.c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
@@ -231,13 +229,13 @@ class CommandNSSetAutoOp : public Command
|
||||
if (param.equals_ci("ON"))
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable autoop for " << na->nc->display;
|
||||
nc->ExtendMetadata("AUTOOP");
|
||||
nc->Extend<bool>("AUTOOP");
|
||||
source.Reply(_("Services will from now on set status modes on %s in channels."), nc->display.c_str());
|
||||
}
|
||||
else if (param.equals_ci("OFF"))
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable autoop for " << na->nc->display;
|
||||
nc->Shrink("AUTOOP");
|
||||
nc->Shrink<bool>("AUTOOP");
|
||||
source.Reply(_("Services will no longer set status modes on %s in channels."), nc->display.c_str());
|
||||
}
|
||||
else
|
||||
@@ -313,19 +311,17 @@ class CommandNSSetChanstats : public Command
|
||||
if (param.equals_ci("ON"))
|
||||
{
|
||||
Log(na->nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable chanstats for " << na->nc->display;
|
||||
na->nc->ExtendMetadata("STATS");
|
||||
na->nc->Extend<bool>("NS_STATS");
|
||||
source.Reply(_("Chanstat statistics are now enabled for your nick."));
|
||||
}
|
||||
else if (param.equals_ci("OFF"))
|
||||
{
|
||||
Log(na->nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable chanstats for " << na->nc->display;
|
||||
na->nc->Shrink("STATS");
|
||||
na->nc->Shrink<bool>("NS_STATS");
|
||||
source.Reply(_("Chanstat statistics are now disabled for your nick."));
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, "CHANSTATS");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
@@ -446,7 +442,7 @@ class CommandNSSASetDisplay : public CommandNSSetDisplay
|
||||
|
||||
class CommandNSSetEmail : public Command
|
||||
{
|
||||
static bool SendConfirmMail(User *u, const BotInfo *bi)
|
||||
static bool SendConfirmMail(User *u, const BotInfo *bi, const Anope::string &new_email)
|
||||
{
|
||||
int chars[] = {
|
||||
' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
|
||||
@@ -460,7 +456,9 @@ class CommandNSSetEmail : public Command
|
||||
for (idx = 0; idx < 9; ++idx)
|
||||
code += chars[1 + static_cast<int>((static_cast<float>(max - min)) * static_cast<uint16_t>(rand()) / 65536.0) + min];
|
||||
|
||||
u->Account()->Extend("ns_set_email_passcode", new ExtensibleItemClass<Anope::string>(code));
|
||||
std::pair<Anope::string, Anope::string> *n = u->Account()->Extend<std::pair<Anope::string, Anope::string> >("ns_set_email");
|
||||
n->first = new_email;
|
||||
n->second = code;
|
||||
|
||||
Anope::string subject = Config->GetBlock("mail")->Get<const Anope::string>("emailchange_subject"),
|
||||
message = Config->GetBlock("mail")->Get<const Anope::string>("emailchange_message");
|
||||
@@ -473,7 +471,11 @@ class CommandNSSetEmail : public Command
|
||||
message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
|
||||
message = message.replace_all_cs("%c", code);
|
||||
|
||||
return Mail::Send(u, u->Account(), bi, subject, message);
|
||||
Anope::string old = u->Account()->email;
|
||||
u->Account()->email = new_email;
|
||||
bool b = Mail::Send(u, u->Account(), bi, subject, message);
|
||||
u->Account()->email = old;
|
||||
return b;
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -516,12 +518,8 @@ class CommandNSSetEmail : public Command
|
||||
|
||||
if (!param.empty() && Config->GetModule("nickserv")->Get<bool>("forceemail", "yes") && !source.IsServicesOper())
|
||||
{
|
||||
source.nc->Extend("ns_set_email", new ExtensibleItemClass<Anope::string>(param));
|
||||
Anope::string old = source.nc->email;
|
||||
source.nc->email = param;
|
||||
if (SendConfirmMail(source.GetUser(), source.service))
|
||||
if (SendConfirmMail(source.GetUser(), source.service, param))
|
||||
source.Reply(_("A confirmation e-mail has been sent to \002%s\002. Follow the instructions in it to change your e-mail address."), param.c_str());
|
||||
source.nc->email = old;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -579,212 +577,6 @@ class CommandNSSASetEmail : public CommandNSSetEmail
|
||||
}
|
||||
};
|
||||
|
||||
class CommandNSSetGreet : public Command
|
||||
{
|
||||
public:
|
||||
CommandNSSetGreet(Module *creator, const Anope::string &sname = "nickserv/set/greet", size_t min = 0) : Command(creator, sname, min, min + 1)
|
||||
{
|
||||
this->SetDesc(_("Associate a greet message with your nickname"));
|
||||
this->SetSyntax(_("\037message\037"));
|
||||
}
|
||||
|
||||
void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m)
|
||||
{
|
||||
const NickAlias *na = NickAlias::Find(user);
|
||||
if (!na)
|
||||
{
|
||||
source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
|
||||
return;
|
||||
}
|
||||
NickCore *nc = na->nc;
|
||||
|
||||
EventReturn MOD_RESULT;
|
||||
FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
return;
|
||||
|
||||
if (!param.empty())
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the greet of " << nc->display;
|
||||
nc->greet = param;
|
||||
source.Reply(_("Greet message for \002%s\002 changed to \002%s\002."), nc->display.c_str(), nc->greet.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to unset the greet of " << nc->display;
|
||||
nc->greet.clear();
|
||||
source.Reply(_("Greet message for \002%s\002 unset."), nc->display.c_str());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
this->Run(source, source.nc->display, params.size() > 0 ? params[0] : "");
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_("Makes the given message the greet of your nickname, that\n"
|
||||
"will be displayed when joining a channel that has GREET\n"
|
||||
"option enabled, provided that you have the necessary\n"
|
||||
"access on it."));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandNSSASetGreet : public CommandNSSetGreet
|
||||
{
|
||||
public:
|
||||
CommandNSSASetGreet(Module *creator) : CommandNSSetGreet(creator, "nickserv/saset/greet", 1)
|
||||
{
|
||||
this->ClearSyntax();
|
||||
this->SetSyntax(_("\037nickname\037 \037message\037"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
this->Run(source, params[0], params.size() > 1 ? params[1] : "");
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_("Makes the given message the greet of the nickname, that\n"
|
||||
"will be displayed when joining a channel that has GREET\n"
|
||||
"option enabled, provided that the user has the necessary\n"
|
||||
"access on it."));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandNSSetHide : public Command
|
||||
{
|
||||
public:
|
||||
CommandNSSetHide(Module *creator, const Anope::string &sname = "nickserv/set/hide", size_t min = 2) : Command(creator, sname, min, min + 1)
|
||||
{
|
||||
this->SetDesc(_("Hide certain pieces of nickname information"));
|
||||
this->SetSyntax(_("{EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"));
|
||||
}
|
||||
|
||||
void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m, const Anope::string &arg)
|
||||
{
|
||||
const NickAlias *na = NickAlias::Find(user);
|
||||
if (!na)
|
||||
{
|
||||
source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
|
||||
return;
|
||||
}
|
||||
NickCore *nc = na->nc;
|
||||
|
||||
EventReturn MOD_RESULT;
|
||||
FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
return;
|
||||
|
||||
Anope::string onmsg, offmsg, flag;
|
||||
|
||||
if (param.equals_ci("EMAIL"))
|
||||
{
|
||||
flag = "HIDE_EMAIL";
|
||||
onmsg = _("The E-mail address of \002%s\002 will now be hidden from %s INFO displays.");
|
||||
offmsg = _("The E-mail address of \002%s\002 will now be shown in %s INFO displays.");
|
||||
}
|
||||
else if (param.equals_ci("USERMASK"))
|
||||
{
|
||||
flag = "HIDE_MASK";
|
||||
onmsg = _("The last seen user@host mask of \002%s\002 will now be hidden from %s INFO displays.");
|
||||
offmsg = _("The last seen user@host mask of \002%s\002 will now be shown in %s INFO displays.");
|
||||
}
|
||||
else if (param.equals_ci("STATUS"))
|
||||
{
|
||||
flag = "HIDE_STATUS";
|
||||
onmsg = _("The services access status of \002%s\002 will now be hidden from %s INFO displays.");
|
||||
offmsg = _("The services access status of \002%s\002 will now be shown in %s INFO displays.");
|
||||
}
|
||||
else if (param.equals_ci("QUIT"))
|
||||
{
|
||||
flag = "HIDE_QUIT";
|
||||
onmsg = _("The last quit message of \002%s\002 will now be hidden from %s INFO displays.");
|
||||
offmsg = _("The last quit message of \002%s\002 will now be shown in %s INFO displays.");
|
||||
}
|
||||
else
|
||||
{
|
||||
this->OnSyntaxError(source, "HIDE");
|
||||
return;
|
||||
}
|
||||
|
||||
if (arg.equals_ci("ON"))
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change hide " << param << " to " << arg << " for " << nc->display;
|
||||
nc->ExtendMetadata(flag);
|
||||
source.Reply(onmsg.c_str(), nc->display.c_str(), source.service->nick.c_str());
|
||||
}
|
||||
else if (arg.equals_ci("OFF"))
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change hide " << param << " to " << arg << " for " << nc->display;
|
||||
nc->Shrink(flag);
|
||||
source.Reply(offmsg.c_str(), nc->display.c_str(), source.service->nick.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, "HIDE");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
this->Run(source, source.nc->display, params[0], params[1]);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_("Allows you to prevent certain pieces of information from\n"
|
||||
"being displayed when someone does a %s \002INFO\002 on your\n"
|
||||
"nick. You can hide your E-mail address (\002EMAIL\002), last seen\n"
|
||||
"user@host mask (\002USERMASK\002), your services access status\n"
|
||||
"(\002STATUS\002) and last quit message (\002QUIT\002).\n"
|
||||
"The second parameter specifies whether the information should\n"
|
||||
"be displayed (\002OFF\002) or hidden (\002ON\002)."), source.service->nick.c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandNSSASetHide : public CommandNSSetHide
|
||||
{
|
||||
public:
|
||||
CommandNSSASetHide(Module *creator) : CommandNSSetHide(creator, "nickserv/saset/hide", 3)
|
||||
{
|
||||
this->SetSyntax("\037nickname\037 {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}");
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
this->ClearSyntax();
|
||||
this->Run(source, params[0], params[1], params[2]);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_("Allows you to prevent certain pieces of information from\n"
|
||||
"being displayed when someone does a %s \002INFO\002 on the\n"
|
||||
"nick. You can hide the E-mail address (\002EMAIL\002), last seen\n"
|
||||
"user@host mask (\002USERMASK\002), the services access status\n"
|
||||
"(\002STATUS\002) and last quit message (\002QUIT\002).\n"
|
||||
"The second parameter specifies whether the information should\n"
|
||||
"be displayed (\002OFF\002) or hidden (\002ON\002)."), source.service->nick.c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandNSSetKill : public Command
|
||||
{
|
||||
public:
|
||||
@@ -817,17 +609,17 @@ class CommandNSSetKill : public Command
|
||||
|
||||
if (param.equals_ci("ON"))
|
||||
{
|
||||
nc->ExtendMetadata("KILLPROTECT");
|
||||
nc->Shrink("KILL_QUICK");
|
||||
nc->Shrink("KILL_IMMED");
|
||||
nc->Extend<bool>("KILLPROTECT");
|
||||
nc->Shrink<bool>("KILL_QUICK");
|
||||
nc->Shrink<bool>("KILL_IMMED");
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to set kill on for " << nc->display;
|
||||
source.Reply(_("Protection is now \002on\002 for \002%s\002."), nc->display.c_str());
|
||||
}
|
||||
else if (param.equals_ci("QUICK"))
|
||||
{
|
||||
nc->ExtendMetadata("KILLPROTECT");
|
||||
nc->ExtendMetadata("KILL_QUICK");
|
||||
nc->Shrink("KILL_IMMED");
|
||||
nc->Extend<bool>("KILLPROTECT");
|
||||
nc->Extend<bool>("KILL_QUICK");
|
||||
nc->Shrink<bool>("KILL_IMMED");
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to set kill quick for " << nc->display;
|
||||
source.Reply(_("Protection is now \002on\002 for \002%s\002, with a reduced delay."), nc->display.c_str());
|
||||
}
|
||||
@@ -835,9 +627,9 @@ class CommandNSSetKill : public Command
|
||||
{
|
||||
if (Config->GetModule(this->owner)->Get<bool>("allowkillimmed"))
|
||||
{
|
||||
nc->ExtendMetadata("KILLPROTECT");
|
||||
nc->ExtendMetadata("KILL_IMMED");
|
||||
nc->Shrink("KILL_QUICK");
|
||||
nc->Extend<bool>("KILLPROTECT");
|
||||
nc->Shrink<bool>("KILL_QUICK");
|
||||
nc->Extend<bool>("KILL_IMMED");
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to set kill immed for " << nc->display;
|
||||
source.Reply(_("Protection is now \002on\002 for \002%s\002, with no delay."), nc->display.c_str());
|
||||
}
|
||||
@@ -846,9 +638,9 @@ class CommandNSSetKill : public Command
|
||||
}
|
||||
else if (param.equals_ci("OFF"))
|
||||
{
|
||||
nc->Shrink("KILLPROTECT");
|
||||
nc->Shrink("KILL_QUICK");
|
||||
nc->Shrink("KILL_IMMED");
|
||||
nc->Shrink<bool>("KILLPROTECT");
|
||||
nc->Shrink<bool>("KILL_QUICK");
|
||||
nc->Shrink<bool>("KILL_IMMED");
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable kill for " << nc->display;
|
||||
source.Reply(_("Protection is now \002off\002 for \002%s\002."), nc->display.c_str());
|
||||
}
|
||||
@@ -1053,19 +845,17 @@ class CommandNSSetMessage : public Command
|
||||
if (param.equals_ci("ON"))
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable " << source.command << " for " << nc->display;
|
||||
nc->ExtendMetadata("MSG");
|
||||
nc->Extend<bool>("MSG");
|
||||
source.Reply(_("Services will now reply to \002%s\002 with \002messages\002."), nc->display.c_str());
|
||||
}
|
||||
else if (param.equals_ci("OFF"))
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable " << source.command << " for " << nc->display;
|
||||
nc->Shrink("MSG");
|
||||
nc->Shrink<bool>("MSG");
|
||||
source.Reply(_("Services will now reply to \002%s\002 with \002notices\002."), nc->display.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, "MSG");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
@@ -1115,95 +905,6 @@ class CommandNSSASetMessage : public CommandNSSetMessage
|
||||
}
|
||||
};
|
||||
|
||||
class CommandNSSetPrivate : public Command
|
||||
{
|
||||
public:
|
||||
CommandNSSetPrivate(Module *creator, const Anope::string &sname = "nickserv/set/private", size_t min = 1) : Command(creator, sname, min, min + 1)
|
||||
{
|
||||
this->SetDesc(_("Prevent the nickname from appearing in the LIST command"));
|
||||
this->SetSyntax(_("{ON | OFF}"));
|
||||
}
|
||||
|
||||
void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m)
|
||||
{
|
||||
const NickAlias *na = NickAlias::Find(user);
|
||||
if (!na)
|
||||
{
|
||||
source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
|
||||
return;
|
||||
}
|
||||
NickCore *nc = na->nc;
|
||||
|
||||
EventReturn MOD_RESULT;
|
||||
FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
return;
|
||||
|
||||
if (param.equals_ci("ON"))
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable private for " << nc->display;
|
||||
nc->ExtendMetadata("PRIVATE");
|
||||
source.Reply(_("Private option is now \002on\002 for \002%s\002."), nc->display.c_str());
|
||||
}
|
||||
else if (param.equals_ci("OFF"))
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable private for " << nc->display;
|
||||
nc->Shrink("PRIVATE");
|
||||
source.Reply(_("Private option is now \002off\002 for \002%s\002."), nc->display.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, "PRIVATE");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
this->Run(source, source.nc->display, params[0]);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_("Turns %s's privacy option on or off for your nick.\n"
|
||||
"With \002PRIVATE\002 set, your nickname will not appear in\n"
|
||||
"nickname lists generated with %s's \002LIST\002 command.\n"
|
||||
"(However, anyone who knows your nickname can still get\n"
|
||||
"information on it using the \002INFO\002 command.)"),
|
||||
source.service->nick.c_str(), source.service->nick.c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandNSSASetPrivate : public CommandNSSetPrivate
|
||||
{
|
||||
public:
|
||||
CommandNSSASetPrivate(Module *creator) : CommandNSSetPrivate(creator, "nickserv/saset/private", 2)
|
||||
{
|
||||
this->ClearSyntax();
|
||||
this->SetSyntax(_("\037nickname\037 {ON | OFF}"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
this->Run(source, params[0], params[1]);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_("Turns %s's privacy option on or off for the nick.\n"
|
||||
"With \002PRIVATE\002 set, the nickname will not appear in\n"
|
||||
"nickname lists generated with %s's \002LIST\002 command.\n"
|
||||
"(However, anyone who knows the nickname can still get\n"
|
||||
"information on it using the \002INFO\002 command.)"),
|
||||
source.service->nick.c_str(), source.service->nick.c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandNSSetSecure : public Command
|
||||
{
|
||||
public:
|
||||
@@ -1231,13 +932,13 @@ class CommandNSSetSecure : public Command
|
||||
if (param.equals_ci("ON"))
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable secure for " << nc->display;
|
||||
nc->ExtendMetadata("SECURE");
|
||||
nc->Extend<bool>("NS_SECURE");
|
||||
source.Reply(_("Secure option is now \002on\002 for \002%s\002."), nc->display.c_str());
|
||||
}
|
||||
else if (param.equals_ci("OFF"))
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable secure for " << nc->display;
|
||||
nc->Shrink("SECURE");
|
||||
nc->Shrink<bool>("NS_SECURE");
|
||||
source.Reply(_("Secure option is now \002off\002 for \002%s\002."), nc->display.c_str());
|
||||
}
|
||||
else
|
||||
@@ -1316,13 +1017,13 @@ class CommandNSSASetNoexpire : public Command
|
||||
if (param.equals_ci("ON"))
|
||||
{
|
||||
Log(LOG_ADMIN, source, this) << "to enable noexpire " << na->nc->display;
|
||||
na->ExtendMetadata("NO_EXPIRE");
|
||||
na->Extend<bool>("NS_NO_EXPIRE");
|
||||
source.Reply(_("Nick %s \002will not\002 expire."), na->nick.c_str());
|
||||
}
|
||||
else if (param.equals_ci("OFF"))
|
||||
{
|
||||
Log(LOG_ADMIN, source, this) << "to disable noexpire " << na->nc->display;
|
||||
na->Shrink("NO_EXPIRE");
|
||||
na->Shrink<bool>("NS_NO_EXPIRE");
|
||||
source.Reply(_("Nick %s \002will\002 expire."), na->nick.c_str());
|
||||
}
|
||||
else
|
||||
@@ -1355,12 +1056,6 @@ class NSSet : public Module
|
||||
|
||||
CommandNSSetEmail commandnssetemail;
|
||||
CommandNSSASetEmail commandnssasetemail;
|
||||
|
||||
CommandNSSetGreet commandnssetgreet;
|
||||
CommandNSSASetGreet commandnssasetgreet;
|
||||
|
||||
CommandNSSetHide commandnssethide;
|
||||
CommandNSSASetHide commandnssasethide;
|
||||
|
||||
CommandNSSetKill commandnssetkill;
|
||||
CommandNSSASetKill commandnssasetkill;
|
||||
@@ -1374,14 +1069,17 @@ class NSSet : public Module
|
||||
CommandNSSetPassword commandnssetpassword;
|
||||
CommandNSSASetPassword commandnssasetpassword;
|
||||
|
||||
CommandNSSetPrivate commandnssetprivate;
|
||||
CommandNSSASetPrivate commandnssasetprivate;
|
||||
|
||||
CommandNSSetSecure commandnssetsecure;
|
||||
CommandNSSASetSecure commandnssasetsecure;
|
||||
|
||||
CommandNSSASetNoexpire commandnssasetnoexpire;
|
||||
|
||||
SerializableExtensibleItem<bool> autoop, chanstats, killprotect, kill_quick, kill_immed,
|
||||
message, secure, noexpire;
|
||||
|
||||
/* email, passcode */
|
||||
PrimitiveExtensibleItem<std::pair<Anope::string, Anope::string > > ns_set_email;
|
||||
|
||||
public:
|
||||
NSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
commandnsset(this), commandnssaset(this),
|
||||
@@ -1389,15 +1087,18 @@ class NSSet : public Module
|
||||
commandnssetchanstats(this), commandnssasetchanstats(this),
|
||||
commandnssetdisplay(this), commandnssasetdisplay(this),
|
||||
commandnssetemail(this), commandnssasetemail(this),
|
||||
commandnssetgreet(this), commandnssasetgreet(this),
|
||||
commandnssethide(this), commandnssasethide(this),
|
||||
commandnssetkill(this), commandnssasetkill(this),
|
||||
commandnssetlanguage(this), commandnssasetlanguage(this),
|
||||
commandnssetmessage(this), commandnssasetmessage(this),
|
||||
commandnssetpassword(this), commandnssasetpassword(this),
|
||||
commandnssetprivate(this), commandnssasetprivate(this),
|
||||
commandnssetsecure(this), commandnssasetsecure(this),
|
||||
commandnssasetnoexpire(this)
|
||||
commandnssasetnoexpire(this),
|
||||
|
||||
autoop(this, "AUTOOP"), chanstats(this, "NS_STATS"), killprotect(this, "KILLPROTECT"),
|
||||
kill_quick(this, "KILL_QUICK"), kill_immed(this, "KILL_IMMED"), message(this, "MSG"),
|
||||
secure(this, "NS_SECURE"), noexpire(this, "NS_NO_EXPIRE"),
|
||||
|
||||
ns_set_email(this, "ns_set_email")
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1408,16 +1109,15 @@ class NSSet : public Module
|
||||
|
||||
if (command->name == "nickserv/confirm" && !params.empty() && uac)
|
||||
{
|
||||
Anope::string *new_email = uac->GetExt<ExtensibleItemClass<Anope::string> *>("ns_set_email"), *passcode = uac->GetExt<ExtensibleItemClass<Anope::string> *>("ns_set_email_passcode");
|
||||
if (new_email && passcode)
|
||||
std::pair<Anope::string, Anope::string> *n = ns_set_email.Get(uac);
|
||||
if (n)
|
||||
{
|
||||
if (params[0] == *passcode)
|
||||
if (params[0] == n->second)
|
||||
{
|
||||
uac->email = *new_email;
|
||||
uac->email = n->first;
|
||||
Log(LOG_COMMAND, source, command) << "to confirm their email address change to " << uac->email;
|
||||
source.Reply(_("Your email address has been changed to \002%s\002."), uac->email.c_str());
|
||||
uac->Shrink("ns_set_email");
|
||||
uac->Shrink("ns_set_email_passcode");
|
||||
ns_set_email.Unset(uac);
|
||||
return EVENT_STOP;
|
||||
}
|
||||
}
|
||||
@@ -1431,9 +1131,34 @@ class NSSet : public Module
|
||||
if (chan->ci)
|
||||
{
|
||||
/* Only give modes if autoop is set */
|
||||
give_modes &= !user->Account() || user->Account()->HasExt("AUTOOP");
|
||||
give_modes &= !user->Account() || autoop.HasExt(user->Account());
|
||||
}
|
||||
}
|
||||
|
||||
void OnPreNickExpire(NickAlias *na, bool &expire) anope_override
|
||||
{
|
||||
if (noexpire.HasExt(na))
|
||||
expire = false;
|
||||
}
|
||||
|
||||
void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) anope_override
|
||||
{
|
||||
if (!show_hidden)
|
||||
return;
|
||||
|
||||
if (killprotect.HasExt(na->nc))
|
||||
info.AddOption(_("Protection"));
|
||||
if (secure.HasExt(na->nc))
|
||||
info.AddOption(_("Security"));
|
||||
if (message.HasExt(na->nc))
|
||||
info.AddOption(_("Message mode"));
|
||||
if (autoop.HasExt(na->nc))
|
||||
info.AddOption(_("Auto-op"));
|
||||
if (chanstats.HasExt(na->nc))
|
||||
info.AddOption(_("Chanstats"));
|
||||
if (noexpire.HasExt(na->nc))
|
||||
info.AddOption(_("No expire"));
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_INIT(NSSet)
|
||||
|
||||
@@ -11,14 +11,24 @@
|
||||
|
||||
#include "module.h"
|
||||
|
||||
static Module *me;
|
||||
|
||||
static std::map<Anope::string, Anope::string> descriptions;
|
||||
|
||||
struct NSMiscData : ExtensibleItem, Serializable
|
||||
struct NSMiscData;
|
||||
static Anope::map<ExtensibleItem<NSMiscData> *> items;
|
||||
static ExtensibleItem<NSMiscData> *GetItem(const Anope::string &name);
|
||||
|
||||
struct NSMiscData : Serializable
|
||||
{
|
||||
Serialize::Reference<NickCore> nc;
|
||||
Anope::string name;
|
||||
Anope::string data;
|
||||
|
||||
NSMiscData(Extensible *obj) : Serializable("NSMiscData"), nc(anope_dynamic_static_cast<NickCore *>(obj))
|
||||
{
|
||||
}
|
||||
|
||||
NSMiscData(NickCore *ncore, const Anope::string &n, const Anope::string &d) : Serializable("NSMiscData"), nc(ncore), name(n), data(d)
|
||||
{
|
||||
}
|
||||
@@ -52,14 +62,27 @@ struct NSMiscData : ExtensibleItem, Serializable
|
||||
}
|
||||
else
|
||||
{
|
||||
d = new NSMiscData(nc, sname, sdata);
|
||||
nc->Extend(sname, d);
|
||||
ExtensibleItem<NSMiscData> *item = GetItem(sname);
|
||||
if (item)
|
||||
d = item->Set(nc, NSMiscData(nc, sname, sdata));
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
};
|
||||
|
||||
static ExtensibleItem<NSMiscData> *GetItem(const Anope::string &name)
|
||||
{
|
||||
ExtensibleItem<NSMiscData>* &it = items[name];
|
||||
if (!it)
|
||||
try
|
||||
{
|
||||
it = new ExtensibleItem<NSMiscData>(me, name);
|
||||
}
|
||||
catch (const ModuleException &) { }
|
||||
return it;
|
||||
}
|
||||
|
||||
static Anope::string GetAttribute(const Anope::string &command)
|
||||
{
|
||||
size_t sp = command.rfind(' ');
|
||||
@@ -93,16 +116,20 @@ class CommandNSSetMisc : public Command
|
||||
|
||||
Anope::string scommand = GetAttribute(source.command);
|
||||
Anope::string key = "ns_set_misc:" + scommand;
|
||||
nc->Shrink(key);
|
||||
ExtensibleItem<NSMiscData> *item = GetItem(key);
|
||||
if (item == NULL)
|
||||
return;
|
||||
|
||||
if (!param.empty())
|
||||
{
|
||||
nc->Extend(key, new NSMiscData(nc, key, param));
|
||||
item->Set(nc, NSMiscData(nc, key, param));
|
||||
source.Reply(CHAN_SETTING_CHANGED, scommand.c_str(), nc->display.c_str(), param.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
item->Unset(nc);
|
||||
source.Reply(CHAN_SETTING_UNSET, scommand.c_str(), nc->display.c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
@@ -155,6 +182,7 @@ class NSSetMisc : public Module
|
||||
NSSetMisc(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
nsmiscdata_type("NSMiscData", NSMiscData::Unserialize), commandnssetmisc(this), commandnssasetmisc(this)
|
||||
{
|
||||
me = this;
|
||||
}
|
||||
|
||||
void OnReload(Configuration::Conf *conf) anope_override
|
||||
@@ -182,17 +210,14 @@ class NSSetMisc : public Module
|
||||
|
||||
void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool ShowHidden) anope_override
|
||||
{
|
||||
std::deque<Anope::string> list;
|
||||
na->nc->GetExtList(list);
|
||||
|
||||
for (unsigned i = 0; i < list.size(); ++i)
|
||||
Anope::map<ExtensibleItem<NSMiscData> *> items;
|
||||
for (Anope::map<ExtensibleItem<NSMiscData> *>::iterator it = items.begin(); it != items.end(); ++it)
|
||||
{
|
||||
if (list[i].find("ns_set_misc:") != 0)
|
||||
continue;
|
||||
ExtensibleItem<NSMiscData> *e = it->second;
|
||||
NSMiscData *data = e->Get(na->nc);
|
||||
|
||||
NSMiscData *data = na->nc->GetExt<NSMiscData *>(list[i]);
|
||||
if (data)
|
||||
info[list[i].substr(12).replace_all_cs("_", " ")] = data->data;
|
||||
if (data != NULL)
|
||||
info[e->name.substr(12).replace_all_cs("_", " ")] = data->data;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -10,9 +10,48 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/ns_suspend.h"
|
||||
|
||||
static ServiceReference<NickServService> nickserv("NickServService", "NickServ");
|
||||
|
||||
struct NSSuspendInfoImpl : NSSuspendInfo, Serializable
|
||||
{
|
||||
NSSuspendInfoImpl(Extensible *) : Serializable("NSSuspendInfo") { }
|
||||
|
||||
void Serialize(Serialize::Data &data) const anope_override
|
||||
{
|
||||
data["nick"] << nick;
|
||||
data["by"] << by;
|
||||
data["reason"] << reason;
|
||||
data["time"] << when;
|
||||
data["expires"] << expires;
|
||||
}
|
||||
|
||||
static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
{
|
||||
Anope::string snick;
|
||||
data["nick"] >> snick;
|
||||
|
||||
NSSuspendInfoImpl *si;
|
||||
if (obj)
|
||||
si = anope_dynamic_static_cast<NSSuspendInfoImpl *>(obj);
|
||||
else
|
||||
{
|
||||
NickAlias *na = NickAlias::Find(snick);
|
||||
if (!na)
|
||||
return NULL;
|
||||
si = na->Extend<NSSuspendInfoImpl>("SUSPENDED");
|
||||
data["nick"] >> si->nick;
|
||||
}
|
||||
|
||||
data["bi"] >> si->by;
|
||||
data["reason"] >> si->reason;
|
||||
data["time"] >> si->when;
|
||||
data["expires"] >> si->expires;
|
||||
return si;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandNSSuspend : public Command
|
||||
{
|
||||
public:
|
||||
@@ -60,18 +99,12 @@ class CommandNSSuspend : public Command
|
||||
|
||||
NickCore *nc = na->nc;
|
||||
|
||||
nc->ExtendMetadata("SUSPENDED");
|
||||
nc->ExtendMetadata("SECURE");
|
||||
nc->Shrink("KILLPROTECT");
|
||||
nc->Shrink("KILL_QUICK");
|
||||
nc->Shrink("KILL_IMMED");
|
||||
|
||||
nc->ExtendMetadata("suspend:by", source.GetNick());
|
||||
if (!reason.empty())
|
||||
nc->ExtendMetadata("suspend:reason", reason);
|
||||
if (expiry_secs > 0)
|
||||
nc->ExtendMetadata("suspend:expire", stringify(Anope::CurTime + expiry_secs));
|
||||
nc->ExtendMetadata("suspend:time", stringify(Anope::CurTime));
|
||||
NSSuspendInfo *si = nc->Extend<NSSuspendInfo>("SUSPENDED");
|
||||
si->nick = nc->display;
|
||||
si->by = source.GetNick();
|
||||
si->reason = reason;
|
||||
si->when = Anope::CurTime;
|
||||
si->expires = expiry_secs ? expiry_secs + Anope::CurTime : 0;
|
||||
|
||||
for (unsigned i = 0; i < nc->aliases->size(); ++i)
|
||||
{
|
||||
@@ -81,7 +114,7 @@ class CommandNSSuspend : public Command
|
||||
{
|
||||
na2->last_quit = reason;
|
||||
|
||||
User *u2 = User::Find(na2->nick);
|
||||
User *u2 = User::Find(na2->nick, true);
|
||||
if (u2)
|
||||
{
|
||||
u2->Logout();
|
||||
@@ -141,18 +174,12 @@ class CommandNSUnSuspend : public Command
|
||||
return;
|
||||
}
|
||||
|
||||
na->nc->Shrink("SUSPENDED");
|
||||
na->nc->Shrink("suspend:expire");
|
||||
na->nc->Shrink("suspend:by");
|
||||
na->nc->Shrink("suspend:reason");
|
||||
na->nc->Shrink("suspend:time");
|
||||
na->nc->Shrink<NSSuspendInfo>("SUSPENDED");
|
||||
|
||||
Log(LOG_ADMIN, source, this) << "for " << na->nick;
|
||||
source.Reply(_("Nick %s is now released."), nick.c_str());
|
||||
|
||||
FOREACH_MOD(OnNickUnsuspended, (na));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
|
||||
@@ -168,55 +195,61 @@ class NSSuspend : public Module
|
||||
{
|
||||
CommandNSSuspend commandnssuspend;
|
||||
CommandNSUnSuspend commandnsunsuspend;
|
||||
ExtensibleItem<NSSuspendInfoImpl> suspend;
|
||||
Serialize::Type suspend_type;
|
||||
|
||||
public:
|
||||
NSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
commandnssuspend(this), commandnsunsuspend(this)
|
||||
commandnssuspend(this), commandnsunsuspend(this), suspend(this, "SUSPENDED"),
|
||||
suspend_type("NSSuspendInfo", NSSuspendInfoImpl::Unserialize)
|
||||
{
|
||||
}
|
||||
|
||||
void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) anope_override
|
||||
{
|
||||
if (na->nc->HasExt("SUSPENDED"))
|
||||
NSSuspendInfo *s = suspend.Get(na->nc);
|
||||
if (s)
|
||||
{
|
||||
Anope::string *by = na->nc->GetExt<ExtensibleItemClass<Anope::string> *>("suspend:by"), *reason = na->nc->GetExt<ExtensibleItemClass<Anope::string> *>("suspend:reason"), *t = na->nc->GetExt<ExtensibleItemClass<Anope::string> *>("suspend:time");
|
||||
info["Suspended"] = "This nickname is \2suspended\2.";
|
||||
if (by)
|
||||
info["Suspended by"] = *by;
|
||||
if (reason)
|
||||
info["Suspend reason"] = *reason;
|
||||
if (t)
|
||||
info["Suspended on"] = Anope::strftime(convertTo<time_t>(*t), source.GetAccount(), true);
|
||||
if (!s->by.empty())
|
||||
info["Suspended by"] = s->by;
|
||||
if (!s->reason.empty())
|
||||
info["Suspend reason"] = s->reason;
|
||||
if (s->when)
|
||||
info["Suspended on"] = Anope::strftime(s->when, source.GetAccount(), true);
|
||||
if (s->expires)
|
||||
info["Suspended expires"] = Anope::strftime(s->expires, source.GetAccount(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void OnPreNickExpire(NickAlias *na, bool &expire) anope_override
|
||||
{
|
||||
if (!na->nc->HasExt("SUSPENDED"))
|
||||
NSSuspendInfo *s = suspend.Get(na->nc);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
expire = false;
|
||||
|
||||
Anope::string *str = na->nc->GetExt<ExtensibleItemClass<Anope::string> *>("suspend:expire");
|
||||
if (str == NULL)
|
||||
if (!s->expires)
|
||||
return;
|
||||
|
||||
try
|
||||
if (s->expires < Anope::CurTime)
|
||||
{
|
||||
time_t when = convertTo<time_t>(*str);
|
||||
if (when < Anope::CurTime)
|
||||
{
|
||||
na->last_seen = Anope::CurTime;
|
||||
na->nc->Shrink("SUSPENDED");
|
||||
na->nc->Shrink("suspend:expire");
|
||||
na->nc->Shrink("suspend:by");
|
||||
na->nc->Shrink("suspend:reason");
|
||||
na->nc->Shrink("suspend:time");
|
||||
na->last_seen = Anope::CurTime;
|
||||
suspend.Unset(na->nc);
|
||||
|
||||
Log(LOG_NORMAL, "expire", Config->GetClient("NickServ")) << "Expiring suspend for " << na->nick;
|
||||
}
|
||||
Log(LOG_NORMAL, "expire", Config->GetClient("NickServ")) << "Expiring suspend for " << na->nick;
|
||||
}
|
||||
catch (const ConvertException &) { }
|
||||
}
|
||||
|
||||
EventReturn OnNickValidate(User *u, NickAlias *na) anope_override
|
||||
{
|
||||
NSSuspendInfo *s = suspend.Get(na->nc);
|
||||
if (!s)
|
||||
return EVENT_CONTINUE;
|
||||
|
||||
u->SendMessage(Config->GetClient("NickServ"), NICK_X_SUSPENDED, u->nick.c_str());
|
||||
return EVENT_STOP;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -407,13 +407,11 @@ class OSDefcon : public Module
|
||||
this->ParseModeString();
|
||||
}
|
||||
|
||||
EventReturn OnChannelModeSet(Channel *c, MessageSource &, const Anope::string &mname, const Anope::string ¶m) anope_override
|
||||
EventReturn OnChannelModeSet(Channel *c, MessageSource &, ChannelMode *mode, const Anope::string ¶m) anope_override
|
||||
{
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(mname);
|
||||
|
||||
if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && cm && DConfig.DefConModesOff.count(mname))
|
||||
if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && DConfig.DefConModesOff.count(mode->name))
|
||||
{
|
||||
c->RemoveMode(Config->GetClient("OperServ"), cm, param);
|
||||
c->RemoveMode(Config->GetClient("OperServ"), mode, param);
|
||||
|
||||
return EVENT_STOP;
|
||||
}
|
||||
@@ -421,18 +419,16 @@ class OSDefcon : public Module
|
||||
return EVENT_CONTINUE;
|
||||
}
|
||||
|
||||
EventReturn OnChannelModeUnset(Channel *c, MessageSource &, const Anope::string &mname, const Anope::string &) anope_override
|
||||
EventReturn OnChannelModeUnset(Channel *c, MessageSource &, ChannelMode *mode, const Anope::string &) anope_override
|
||||
{
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(mname);
|
||||
|
||||
if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && cm && DConfig.DefConModesOn.count(mname))
|
||||
if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && DConfig.DefConModesOn.count(mode->name))
|
||||
{
|
||||
Anope::string param;
|
||||
|
||||
if (DConfig.GetDefConParam(mname, param))
|
||||
c->SetMode(Config->GetClient("OperServ"), cm, param);
|
||||
if (DConfig.GetDefConParam(mode->name, param))
|
||||
c->SetMode(Config->GetClient("OperServ"), mode, param);
|
||||
else
|
||||
c->SetMode(Config->GetClient("OperServ"), cm);
|
||||
c->SetMode(Config->GetClient("OperServ"), mode);
|
||||
|
||||
return EVENT_STOP;
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ class CommandOSLogin : public Command
|
||||
source.Reply(_("No oper block for your nick."));
|
||||
else if (o->password.empty())
|
||||
source.Reply(_("Your oper block doesn't require logging in."));
|
||||
else if (u->HasExt("os_login_password_correct"))
|
||||
else if (u->HasExt("os_login"))
|
||||
source.Reply(_("You are already identified."));
|
||||
else if (o->password != password)
|
||||
{
|
||||
@@ -41,11 +41,9 @@ class CommandOSLogin : public Command
|
||||
else
|
||||
{
|
||||
Log(LOG_ADMIN, source, this) << "and successfully identified to " << source.service->nick;
|
||||
u->Extend("os_login_password_correct");
|
||||
u->Extend<bool>("os_login");
|
||||
source.Reply(_("Password accepted."));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
|
||||
@@ -80,12 +78,12 @@ class CommandOSLogout : public Command
|
||||
source.Reply(_("No oper block for your nick."));
|
||||
else if (o->password.empty())
|
||||
source.Reply(_("Your oper block doesn't require logging in."));
|
||||
else if (!u->HasExt("os_login_password_correct"))
|
||||
else if (!u->HasExt("os_login"))
|
||||
source.Reply(_("You are not identified."));
|
||||
else
|
||||
{
|
||||
Log(LOG_ADMIN, source, this);
|
||||
u->Shrink("os_login_password_correct");
|
||||
u->Shrink<bool>("os_login");
|
||||
source.Reply(_("You have been logged out."));
|
||||
}
|
||||
}
|
||||
@@ -110,25 +108,20 @@ class OSLogin : public Module
|
||||
{
|
||||
CommandOSLogin commandoslogin;
|
||||
CommandOSLogout commandoslogout;
|
||||
ExtensibleItem<bool> os_login;
|
||||
|
||||
public:
|
||||
OSLogin(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
commandoslogin(this), commandoslogout(this)
|
||||
commandoslogin(this), commandoslogout(this), os_login(this, "os_login")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
~OSLogin()
|
||||
{
|
||||
for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
|
||||
it->second->Shrink("os_login_password_correct");
|
||||
}
|
||||
|
||||
EventReturn IsServicesOper(User *u) anope_override
|
||||
{
|
||||
if (!u->Account()->o->password.empty())
|
||||
{
|
||||
if (u->HasExt("os_login_password_correct"))
|
||||
if (os_login.HasExt(u))
|
||||
return EVENT_ALLOW;
|
||||
return EVENT_STOP;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ class CommandOSNOOP : public Command
|
||||
{
|
||||
/* Remove the O:lines */
|
||||
IRCD->SendSVSNOOP(s, true);
|
||||
s->Extend("noop", new ExtensibleItemClass<Anope::string>(source.GetNick()));
|
||||
s->Extend<Anope::string>("noop", source.GetNick());
|
||||
|
||||
Log(LOG_ADMIN, source, this) << "SET on " << s->GetName();
|
||||
source.Reply(_("All operators from \002%s\002 have been removed."), s->GetName().c_str());
|
||||
@@ -52,7 +52,7 @@ class CommandOSNOOP : public Command
|
||||
}
|
||||
else if (cmd.equals_ci("REVOKE"))
|
||||
{
|
||||
s->Shrink("noop");
|
||||
s->Shrink<Anope::string>("noop");
|
||||
IRCD->SendSVSNOOP(s, false);
|
||||
Log(LOG_ADMIN, source, this) << "REVOKE on " << s->GetName();
|
||||
source.Reply(_("All O:lines of \002%s\002 have been reset."), s->GetName().c_str());
|
||||
@@ -76,25 +76,23 @@ class CommandOSNOOP : public Command
|
||||
class OSNOOP : public Module
|
||||
{
|
||||
CommandOSNOOP commandosnoop;
|
||||
PrimitiveExtensibleItem<Anope::string> noop;
|
||||
|
||||
public:
|
||||
OSNOOP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
commandosnoop(this)
|
||||
commandosnoop(this), noop(this, "noop")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void OnUserModeSet(User *u, const Anope::string &mname) anope_override
|
||||
{
|
||||
if (mname == "OPER" && u->server->HasExt("noop"))
|
||||
Anope::string *setter;
|
||||
if (mname == "OPER" && (setter = noop.Get(u->server)))
|
||||
{
|
||||
Anope::string *setter = u->server->GetExt<ExtensibleItemClass<Anope::string> *>("noop");
|
||||
if (setter)
|
||||
{
|
||||
Anope::string reason = "NOOP command used by " + *setter;
|
||||
BotInfo *OperServ = Config->GetClient("OperServ");
|
||||
u->Kill(OperServ ? OperServ->nick : "", reason);
|
||||
}
|
||||
Anope::string reason = "NOOP command used by " + *setter;
|
||||
BotInfo *OperServ = Config->GetClient("OperServ");
|
||||
u->Kill(OperServ ? OperServ->nick : "", reason);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
+93
-82
@@ -10,6 +10,9 @@
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/os_session.h"
|
||||
#include "modules/bs_kick.h"
|
||||
#include "modules/cs_mode.h"
|
||||
#include "modules/bs_badwords.h"
|
||||
|
||||
#define READ(x) \
|
||||
if (true) \
|
||||
@@ -81,13 +84,6 @@ else \
|
||||
#define OLD_BS_KICK_FLOOD 0x02000000
|
||||
#define OLD_BS_KICK_REPEAT 0x01000000
|
||||
|
||||
struct ExtensibleItemUint32 : ExtensibleItem
|
||||
{
|
||||
uint32_t u;
|
||||
ExtensibleItemUint32(uint32_t i) : u(i) { }
|
||||
};
|
||||
|
||||
|
||||
static struct mlock_info
|
||||
{
|
||||
char c;
|
||||
@@ -139,12 +135,13 @@ enum
|
||||
|
||||
static void process_mlock(ChannelInfo *ci, uint32_t lock, bool status)
|
||||
{
|
||||
ModeLocks *ml = ci->Require<ModeLocks>("modelocks");
|
||||
for (unsigned i = 0; i < (sizeof(mlock_infos) / sizeof(mlock_info)); ++i)
|
||||
if (lock & mlock_infos[i].m)
|
||||
{
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByChar(mlock_infos[i].c);
|
||||
if (cm)
|
||||
ci->SetMLock(cm, status);
|
||||
if (cm && ml)
|
||||
ml->SetMLock(cm, status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -448,7 +445,7 @@ static void LoadNicks()
|
||||
nc->email = buffer;
|
||||
|
||||
READ(read_string(buffer, f));
|
||||
nc->greet = buffer;
|
||||
nc->Extend<Anope::string>("greet", buffer);
|
||||
|
||||
uint32_t uint;
|
||||
READ(read_uint32(&uint, f));
|
||||
@@ -459,37 +456,37 @@ static void LoadNicks()
|
||||
|
||||
READ(read_uint32(&uint, f));
|
||||
if (uint & OLD_NI_KILLPROTECT)
|
||||
nc->ExtendMetadata("KILLPROTECT");
|
||||
nc->Extend<bool>("KILLPROTECT");
|
||||
if (uint & OLD_NI_SECURE)
|
||||
nc->ExtendMetadata("SECURE");
|
||||
nc->Extend<bool>("NS_SECURE");
|
||||
if (uint & OLD_NI_MSG)
|
||||
nc->ExtendMetadata("MSG");
|
||||
nc->Extend<bool>("MSG");
|
||||
if (uint & OLD_NI_MEMO_HARDMAX)
|
||||
nc->ExtendMetadata("MEMO_HARDMAX");
|
||||
nc->Extend<bool>("MEMO_HARDMAX");
|
||||
if (uint & OLD_NI_MEMO_SIGNON)
|
||||
nc->ExtendMetadata("MEMO_SIGNON");
|
||||
nc->Extend<bool>("MEMO_SIGNON");
|
||||
if (uint & OLD_NI_MEMO_RECEIVE)
|
||||
nc->ExtendMetadata("MEMO_RECEIVE");
|
||||
nc->Extend<bool>("MEMO_RECEIVE");
|
||||
if (uint & OLD_NI_PRIVATE)
|
||||
nc->ExtendMetadata("PRIVATE");
|
||||
nc->Extend<bool>("NS_PRIVATE");
|
||||
if (uint & OLD_NI_HIDE_EMAIL)
|
||||
nc->ExtendMetadata("HIDE_EMAIL");
|
||||
nc->Extend<bool>("HIDE_EMAIL");
|
||||
if (uint & OLD_NI_HIDE_MASK)
|
||||
nc->ExtendMetadata("HIDE_MASK");
|
||||
nc->Extend<bool>("HIDE_MASK");
|
||||
if (uint & OLD_NI_HIDE_QUIT)
|
||||
nc->ExtendMetadata("HIDE_QUIT");
|
||||
nc->Extend<bool>("HIDE_QUIT");
|
||||
if (uint & OLD_NI_KILL_QUICK)
|
||||
nc->ExtendMetadata("KILL_QUICK");
|
||||
nc->Extend<bool>("KILL_QUICK");
|
||||
if (uint & OLD_NI_KILL_IMMED)
|
||||
nc->ExtendMetadata("KILL_IMMED");
|
||||
nc->Extend<bool>("KILL_IMMED");
|
||||
if (uint & OLD_NI_MEMO_MAIL)
|
||||
nc->ExtendMetadata("MEMO_MAIL");
|
||||
nc->Extend<bool>("MEMO_MAIL");
|
||||
if (uint & OLD_NI_HIDE_STATUS)
|
||||
nc->ExtendMetadata("HIDE_STATUS");
|
||||
nc->Extend<bool>("HIDE_STATUS");
|
||||
if (uint & OLD_NI_SUSPENDED)
|
||||
nc->ExtendMetadata("SUSPENDED");
|
||||
nc->Extend<bool>("SUSPENDED");
|
||||
if (!(uint & OLD_NI_AUTOOP))
|
||||
nc->ExtendMetadata("AUTOOP");
|
||||
nc->Extend<bool>("AUTOOP");
|
||||
|
||||
uint16_t u16;
|
||||
READ(read_uint16(&u16, f));
|
||||
@@ -607,7 +604,7 @@ static void LoadNicks()
|
||||
na->last_seen = last_seen;
|
||||
|
||||
if (tmpu16 & OLD_NS_NO_EXPIRE)
|
||||
na->ExtendMetadata("NO_EXPIRE");
|
||||
na->Extend<bool>("NS_NO_EXPIRE");
|
||||
|
||||
Log(LOG_DEBUG) << "Loaded NickAlias " << na->nick;
|
||||
}
|
||||
@@ -728,31 +725,31 @@ static void LoadChannels()
|
||||
// Temporary flags cleanup
|
||||
tmpu32 &= ~0x80000000;
|
||||
if (tmpu32 & OLD_CI_KEEPTOPIC)
|
||||
ci->ExtendMetadata("KEEPTOPIC");
|
||||
ci->Extend<bool>("KEEPTOPIC");
|
||||
if (tmpu32 & OLD_CI_SECUREOPS)
|
||||
ci->ExtendMetadata("SECUREOPS");
|
||||
ci->Extend<bool>("SECUREOPS");
|
||||
if (tmpu32 & OLD_CI_PRIVATE)
|
||||
ci->ExtendMetadata("PRIVATE");
|
||||
ci->Extend<bool>("CS_PRIVATE");
|
||||
if (tmpu32 & OLD_CI_TOPICLOCK)
|
||||
ci->ExtendMetadata("TOPICLOCK");
|
||||
ci->Extend<bool>("TOPICLOCK");
|
||||
if (tmpu32 & OLD_CI_RESTRICTED)
|
||||
ci->ExtendMetadata("RESTRICTED");
|
||||
ci->Extend<bool>("RESTRICTED");
|
||||
if (tmpu32 & OLD_CI_PEACE)
|
||||
ci->ExtendMetadata("PEACE");
|
||||
ci->Extend<bool>("PEACE");
|
||||
if (tmpu32 & OLD_CI_SECURE)
|
||||
ci->ExtendMetadata("SECURE");
|
||||
ci->Extend<bool>("CS_SECURE");
|
||||
if (tmpu32 & OLD_CI_NO_EXPIRE)
|
||||
ci->ExtendMetadata("NO_EXPIRE");
|
||||
ci->Extend<bool>("CI_NO_EXPIRE");
|
||||
if (tmpu32 & OLD_CI_MEMO_HARDMAX)
|
||||
ci->ExtendMetadata("MEMO_HARDMAX");
|
||||
ci->Extend<bool>("MEMO_HARDMAX");
|
||||
if (tmpu32 & OLD_CI_SECUREFOUNDER)
|
||||
ci->ExtendMetadata("SECUREFOUNDER");
|
||||
ci->Extend<bool>("SECUREFOUNDER");
|
||||
if (tmpu32 & OLD_CI_SIGNKICK)
|
||||
ci->ExtendMetadata("SIGNKICK");
|
||||
ci->Extend<bool>("SIGNKICK");
|
||||
if (tmpu32 & OLD_CI_SIGNKICK_LEVEL)
|
||||
ci->ExtendMetadata("SIGNKICK_LEVEL");
|
||||
ci->Extend<bool>("SIGNKICK_LEVEL");
|
||||
if (tmpu32 & OLD_CI_SUSPENDED)
|
||||
ci->ExtendMetadata("SUSPENDED");
|
||||
ci->Extend<bool>("SUSPENDED");
|
||||
|
||||
READ(read_string(buffer, f));
|
||||
READ(read_string(buffer, f));
|
||||
@@ -773,7 +770,7 @@ static void LoadChannels()
|
||||
level = ACCESS_FOUNDER;
|
||||
|
||||
if (j == 10 && level < 0) // NOJOIN
|
||||
ci->Shrink("RESTRICTED"); // If CSDefRestricted was enabled this can happen
|
||||
ci->Shrink<bool>("RESTRICTED"); // If CSDefRestricted was enabled this can happen
|
||||
|
||||
ci->SetLevel(GetLevelName(j), level);
|
||||
}
|
||||
@@ -831,9 +828,9 @@ static void LoadChannels()
|
||||
}
|
||||
|
||||
READ(read_uint32(&tmpu32, f)); // mlock on
|
||||
ci->Extend("mlock_on", new ExtensibleItemUint32(tmpu32));
|
||||
ci->Extend<uint32_t>("mlock_on", tmpu32);
|
||||
READ(read_uint32(&tmpu32, f)); // mlock off
|
||||
ci->Extend("mlock_off", new ExtensibleItemUint32(tmpu32));
|
||||
ci->Extend<uint32_t>("mlock_off", tmpu32);
|
||||
READ(read_uint32(&tmpu32, f)); // mlock limit
|
||||
READ(read_string(buffer, f));
|
||||
READ(read_string(buffer, f));
|
||||
@@ -863,52 +860,63 @@ static void LoadChannels()
|
||||
|
||||
READ(read_int32(&tmp32, f));
|
||||
if (tmp32 & OLD_BS_DONTKICKOPS)
|
||||
ci->ExtendMetadata("BS_DONTKICKOPS");
|
||||
ci->Extend<bool>("BS_DONTKICKOPS");
|
||||
if (tmp32 & OLD_BS_DONTKICKVOICES)
|
||||
ci->ExtendMetadata("BS_DONTKICKVOICES");
|
||||
ci->Extend<bool>("BS_DONTKICKVOICES");
|
||||
if (tmp32 & OLD_BS_FANTASY)
|
||||
ci->ExtendMetadata("BS_FANTASY");
|
||||
ci->Extend<bool>("BS_FANTASY");
|
||||
if (tmp32 & OLD_BS_GREET)
|
||||
ci->ExtendMetadata("BS_GREET");
|
||||
ci->Extend<bool>("BS_GREET");
|
||||
if (tmp32 & OLD_BS_NOBOT)
|
||||
ci->ExtendMetadata("BS_NOBOT");
|
||||
if (tmp32 & OLD_BS_KICK_BOLDS)
|
||||
ci->ExtendMetadata("BS_KICK_BOLDS");
|
||||
if (tmp32 & OLD_BS_KICK_COLORS)
|
||||
ci->ExtendMetadata("BS_KICK_COLORS");
|
||||
if (tmp32 & OLD_BS_KICK_REVERSES)
|
||||
ci->ExtendMetadata("BS_KICK_REVERSES");
|
||||
if (tmp32 & OLD_BS_KICK_UNDERLINES)
|
||||
ci->ExtendMetadata("BS_KICK_UNDERLINES");
|
||||
if (tmp32 & OLD_BS_KICK_BADWORDS)
|
||||
ci->ExtendMetadata("BS_KICK_BADWORDS");
|
||||
if (tmp32 & OLD_BS_KICK_CAPS)
|
||||
ci->ExtendMetadata("BS_KICK_CAPS");
|
||||
if (tmp32 & OLD_BS_KICK_FLOOD)
|
||||
ci->ExtendMetadata("BS_KICK_FLOOD");
|
||||
if (tmp32 & OLD_BS_KICK_REPEAT)
|
||||
ci->ExtendMetadata("BS_KICK_REPEAT");
|
||||
ci->Extend<bool>("BS_NOBOT");
|
||||
|
||||
KickerData *kd = ci->Require<KickerData>("kickerdata");
|
||||
if (kd)
|
||||
{
|
||||
if (tmp32 & OLD_BS_KICK_BOLDS)
|
||||
kd->bolds = true;
|
||||
if (tmp32 & OLD_BS_KICK_COLORS)
|
||||
kd->colors = true;
|
||||
if (tmp32 & OLD_BS_KICK_REVERSES)
|
||||
kd->reverses = true;
|
||||
if (tmp32 & OLD_BS_KICK_UNDERLINES)
|
||||
kd->underlines = true;
|
||||
if (tmp32 & OLD_BS_KICK_BADWORDS)
|
||||
kd->badwords = true;
|
||||
if (tmp32 & OLD_BS_KICK_CAPS)
|
||||
kd->caps = true;
|
||||
if (tmp32 & OLD_BS_KICK_FLOOD)
|
||||
kd->flood = true;
|
||||
if (tmp32 & OLD_BS_KICK_REPEAT)
|
||||
kd->repeat = true;
|
||||
}
|
||||
|
||||
READ(read_int16(&tmp16, f));
|
||||
for (int16_t j = 0; j < tmp16; ++j)
|
||||
{
|
||||
int16_t ttb;
|
||||
READ(read_int16(&ttb, f));
|
||||
if (j < TTB_SIZE)
|
||||
ci->ttb[j] = ttb;
|
||||
if (j < TTB_SIZE && kd)
|
||||
kd->ttb[j] = ttb;
|
||||
}
|
||||
|
||||
READ(read_int16(&tmp16, f));
|
||||
ci->capsmin = tmp16;
|
||||
if (kd)
|
||||
kd->capsmin = tmp16;
|
||||
READ(read_int16(&tmp16, f));
|
||||
ci->capspercent = tmp16;
|
||||
if (kd)
|
||||
kd->capspercent = tmp16;
|
||||
READ(read_int16(&tmp16, f));
|
||||
ci->floodlines = tmp16;
|
||||
if (kd)
|
||||
kd->floodlines = tmp16;
|
||||
READ(read_int16(&tmp16, f));
|
||||
ci->floodsecs = tmp16;
|
||||
if (kd)
|
||||
kd->floodsecs = tmp16;
|
||||
READ(read_int16(&tmp16, f));
|
||||
ci->repeattimes = tmp16;
|
||||
if (kd)
|
||||
kd->repeattimes = tmp16;
|
||||
|
||||
BadWords *bw = ci->Require<BadWords>("badwords");
|
||||
READ(read_uint16(&tmpu16, f));
|
||||
for (uint16_t j = 0; j < tmpu16; ++j)
|
||||
{
|
||||
@@ -928,7 +936,8 @@ static void LoadChannels()
|
||||
else if (type == 3)
|
||||
bwtype = BW_END;
|
||||
|
||||
ci->AddBadWord(buffer, bwtype);
|
||||
if (bw)
|
||||
bw->AddBadWord(buffer, bwtype);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1089,8 +1098,11 @@ static void LoadExceptions()
|
||||
|
||||
class DBOld : public Module
|
||||
{
|
||||
PrimitiveExtensibleItem<uint32_t> mlock_on, mlock_off;
|
||||
|
||||
public:
|
||||
DBOld(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR)
|
||||
DBOld(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR),
|
||||
mlock_on(this, "mlock_on"), mlock_off(this, "mlock_off")
|
||||
{
|
||||
|
||||
|
||||
@@ -1114,22 +1126,21 @@ class DBOld : public Module
|
||||
|
||||
void OnUplinkSync(Server *s) anope_override
|
||||
{
|
||||
ExtensibleItemUint32 *mlock;
|
||||
for (registered_channel_map::iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
|
||||
{
|
||||
ChannelInfo *ci = it->second;
|
||||
if (ci->HasExt("mlock_on"))
|
||||
|
||||
uint32_t *u = mlock_on.Get(ci);
|
||||
if (u)
|
||||
{
|
||||
mlock = ci->GetExt<ExtensibleItemUint32 *>("mlock_on");
|
||||
process_mlock(ci, mlock->u, true);
|
||||
ci->Shrink("mlock_on");
|
||||
process_mlock(ci, *u, true);
|
||||
mlock_on.Unset(ci);
|
||||
}
|
||||
|
||||
if (ci->HasExt("mlock_off"))
|
||||
u = mlock_off.Get(ci);
|
||||
{
|
||||
mlock = ci->GetExt<ExtensibleItemUint32 *>("mlock_off");
|
||||
process_mlock(ci, mlock->u, false);
|
||||
ci->Shrink("mlock_off");
|
||||
process_mlock(ci, *u, false);
|
||||
mlock_off.Unset(ci);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+56
-279
@@ -10,6 +10,11 @@
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/os_session.h"
|
||||
#include "modules/cs_suspend.h"
|
||||
#include "modules/bs_kick.h"
|
||||
#include "modules/cs_log.h"
|
||||
#include "modules/cs_mode.h"
|
||||
#include "modules/bs_badwords.h"
|
||||
|
||||
Anope::string DatabaseFile;
|
||||
Anope::string BackupFile;
|
||||
@@ -71,15 +76,13 @@ EventReturn OnDatabaseReadMetadata(NickCore *nc, const Anope::string &key, const
|
||||
else if (key.equals_ci("EMAIL"))
|
||||
nc->email = params[0];
|
||||
else if (key.equals_ci("GREET"))
|
||||
nc->greet = params[0];
|
||||
nc->Extend<Anope::string>("greet", params[0]);
|
||||
else if (key.equals_ci("ACCESS"))
|
||||
nc->AddAccess(params[0]);
|
||||
else if (key.equals_ci("CERT"))
|
||||
nc->AddCert(params[0]);
|
||||
else if (key.equals_ci("FLAGS"))
|
||||
{
|
||||
for (unsigned i = 0; i < params.size(); ++i)
|
||||
nc->ExtendMetadata(params[i]);
|
||||
nc->Extend<bool>(params[i]);
|
||||
}
|
||||
else if (key.equals_ci("MI"))
|
||||
{
|
||||
@@ -118,7 +121,7 @@ EventReturn OnDatabaseReadMetadata(NickAlias *na, const Anope::string &key, cons
|
||||
na->last_quit = params[0];
|
||||
else if (key.equals_ci("FLAGS"))
|
||||
for (unsigned i = 0; i < params.size(); ++i)
|
||||
na->ExtendMetadata(params[i]);
|
||||
na->Extend<bool>(params[i]);
|
||||
else if (key.equals_ci("VHOST"))
|
||||
na->SetVhost(params.size() > 3 ? params[3] : "", params[2], params[0], params[1].is_pos_number_only() ? convertTo<time_t>(params[1]) : 0);
|
||||
return EVENT_CONTINUE;
|
||||
@@ -131,6 +134,7 @@ EventReturn OnDatabaseReadMetadata(BotInfo *bi, const Anope::string &key, const
|
||||
|
||||
EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
KickerData *kd = ci->GetExt<KickerData>("kickerdata");
|
||||
try
|
||||
{
|
||||
if (key.equals_ci("BANTYPE"))
|
||||
@@ -153,7 +157,7 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co
|
||||
}
|
||||
else if (key.equals_ci("FLAGS"))
|
||||
for (unsigned i = 0; i < params.size(); ++i)
|
||||
ci->ExtendMetadata(params[i]);
|
||||
ci->Extend<bool>(params[i]);
|
||||
else if (key.equals_ci("DESC"))
|
||||
ci->desc = params[0];
|
||||
else if (key.equals_ci("TOPIC"))
|
||||
@@ -164,8 +168,9 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co
|
||||
}
|
||||
else if (key.equals_ci("SUSPEND"))
|
||||
{
|
||||
ci->ExtendMetadata("suspend:by", params[0]);
|
||||
ci->ExtendMetadata("suspend:reason", params[1]);
|
||||
CSSuspendInfo *si = ci->Extend<CSSuspendInfo>("suspend");
|
||||
si->by = params[0];
|
||||
si->reason = params[1];
|
||||
}
|
||||
else if (key.equals_ci("ACCESS")) // Older access system, from Anope 1.9.4.
|
||||
{
|
||||
@@ -220,18 +225,22 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co
|
||||
}
|
||||
else if (key.equals_ci("LOG"))
|
||||
{
|
||||
LogSetting *l = new LogSetting();
|
||||
LogSettings *ls = ci->Require<LogSettings>("logsettings");
|
||||
if (ls)
|
||||
{
|
||||
LogSetting *l = ls->Create();
|
||||
|
||||
l->ci = ci;
|
||||
l->service_name = params[0];
|
||||
l->command_service = params[1];
|
||||
l->command_name = params[2];
|
||||
l->method = params[3];
|
||||
l->creator = params[4];
|
||||
l->created = params[5].is_pos_number_only() ? convertTo<time_t>(params[5]) : Anope::CurTime;
|
||||
l->extra = params.size() > 6 ? params[6] : "";
|
||||
l->chan = ci->name;
|
||||
l->service_name = params[0];
|
||||
l->command_service = params[1];
|
||||
l->command_name = params[2];
|
||||
l->method = params[3];
|
||||
l->creator = params[4];
|
||||
l->created = params[5].is_pos_number_only() ? convertTo<time_t>(params[5]) : Anope::CurTime;
|
||||
l->extra = params.size() > 6 ? params[6] : "";
|
||||
|
||||
ci->log_settings->push_back(l);
|
||||
(*ls)->push_back(l);
|
||||
}
|
||||
}
|
||||
else if (key.equals_ci("MLOCK"))
|
||||
{
|
||||
@@ -240,7 +249,9 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co
|
||||
Anope::string setter = params[2];
|
||||
time_t mcreated = params[3].is_pos_number_only() ? convertTo<time_t>(params[3]) : Anope::CurTime;
|
||||
Anope::string param = params.size() > 4 ? params[4] : "";
|
||||
ci->mode_locks->insert(std::make_pair(mode_name, new ModeLock(ci, set, mode_name, param, setter, mcreated)));
|
||||
ModeLocks *ml = ci->Require<ModeLocks>("modelocks");
|
||||
if (ml)
|
||||
ml->SetMLock(ModeManager::FindChannelModeByName(mode_name), set, param, setter, mcreated);
|
||||
}
|
||||
else if (key.equals_ci("MI"))
|
||||
{
|
||||
@@ -265,44 +276,44 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co
|
||||
ci->bi = BotInfo::Find(params[1]);
|
||||
else if (params[0].equals_ci("FLAGS"))
|
||||
for (unsigned i = 0; i < params.size(); ++i)
|
||||
ci->ExtendMetadata(params[i]);
|
||||
ci->Extend<bool>(params[i]);
|
||||
else if (params[0].equals_ci("TTB"))
|
||||
{
|
||||
for (unsigned j = 1, end = params.size(); j < end; j += 2)
|
||||
for (unsigned j = 1, end = params.size(); j < end &&& kd; j += 2)
|
||||
{
|
||||
if (params[j].equals_ci("BOLDS"))
|
||||
ci->ttb[0] = params[j + 1].is_pos_number_only() ? convertTo<int16_t>(params[j + 1]) : 0;
|
||||
kd->ttb[0] = params[j + 1].is_pos_number_only() ? convertTo<int16_t>(params[j + 1]) : 0;
|
||||
else if (params[j].equals_ci("COLORS"))
|
||||
ci->ttb[1] = params[j + 1].is_pos_number_only() ? convertTo<int16_t>(params[j + 1]) : 0;
|
||||
kd->ttb[1] = params[j + 1].is_pos_number_only() ? convertTo<int16_t>(params[j + 1]) : 0;
|
||||
else if (params[j].equals_ci("REVERSES"))
|
||||
ci->ttb[2] = params[j + 1].is_pos_number_only() ? convertTo<int16_t>(params[j + 1]) : 0;
|
||||
kd->ttb[2] = params[j + 1].is_pos_number_only() ? convertTo<int16_t>(params[j + 1]) : 0;
|
||||
else if (params[j].equals_ci("UNDERLINES"))
|
||||
ci->ttb[3] = params[j + 1].is_pos_number_only() ? convertTo<int16_t>(params[j + 1]) : 0;
|
||||
kd->ttb[3] = params[j + 1].is_pos_number_only() ? convertTo<int16_t>(params[j + 1]) : 0;
|
||||
else if (params[j].equals_ci("BADWORDS"))
|
||||
ci->ttb[4] = params[j + 1].is_pos_number_only() ? convertTo<int16_t>(params[j + 1]) : 0;
|
||||
kd->ttb[4] = params[j + 1].is_pos_number_only() ? convertTo<int16_t>(params[j + 1]) : 0;
|
||||
else if (params[j].equals_ci("CAPS"))
|
||||
ci->ttb[5] = params[j + 1].is_pos_number_only() ? convertTo<int16_t>(params[j + 1]) : 0;
|
||||
kd->ttb[5] = params[j + 1].is_pos_number_only() ? convertTo<int16_t>(params[j + 1]) : 0;
|
||||
else if (params[j].equals_ci("FLOOD"))
|
||||
ci->ttb[6] = params[j + 1].is_pos_number_only() ? convertTo<int16_t>(params[j + 1]) : 0;
|
||||
kd->ttb[6] = params[j + 1].is_pos_number_only() ? convertTo<int16_t>(params[j + 1]) : 0;
|
||||
else if (params[j].equals_ci("REPEAT"))
|
||||
ci->ttb[7] = params[j + 1].is_pos_number_only() ? convertTo<int16_t>(params[j + 1]) : 0;
|
||||
kd->ttb[7] = params[j + 1].is_pos_number_only() ? convertTo<int16_t>(params[j + 1]) : 0;
|
||||
else if (params[j].equals_ci("ITALICS"))
|
||||
ci->ttb[8] = params[j + 1].is_pos_number_only() ? convertTo<int16_t>(params[j + 1]) : 0;
|
||||
kd->ttb[8] = params[j + 1].is_pos_number_only() ? convertTo<int16_t>(params[j + 1]) : 0;
|
||||
else if (params[j].equals_ci("AMSGS"))
|
||||
ci->ttb[9] = params[j + 1].is_pos_number_only() ? convertTo<int16_t>(params[j + 1]) : 0;
|
||||
kd->ttb[9] = params[j + 1].is_pos_number_only() ? convertTo<int16_t>(params[j + 1]) : 0;
|
||||
}
|
||||
}
|
||||
else if (params[0].equals_ci("CAPSMIN"))
|
||||
ci->capsmin = params[1].is_pos_number_only() ? convertTo<int16_t>(params[1]) : 0;
|
||||
else if (params[0].equals_ci("CAPSPERCENT"))
|
||||
ci->capspercent = params[1].is_pos_number_only() ? convertTo<int16_t>(params[1]) : 0;
|
||||
else if (params[0].equals_ci("FLOODLINES"))
|
||||
ci->floodlines = params[1].is_pos_number_only() ? convertTo<int16_t>(params[1]) : 0;
|
||||
else if (params[0].equals_ci("FLOODSECS"))
|
||||
ci->floodsecs = params[1].is_pos_number_only() ? convertTo<int16_t>(params[1]) : 0;
|
||||
else if (params[0].equals_ci("REPEATTIMES"))
|
||||
ci->repeattimes = params[1].is_pos_number_only() ? convertTo<int16_t>(params[1]) : 0;
|
||||
else if (params[0].equals_ci("BADWORD"))
|
||||
else if (kd && params[0].equals_ci("CAPSMIN"))
|
||||
kd->capsmin = params[1].is_pos_number_only() ? convertTo<int16_t>(params[1]) : 0;
|
||||
else if (kd && params[0].equals_ci("CAPSPERCENT"))
|
||||
kd->capspercent = params[1].is_pos_number_only() ? convertTo<int16_t>(params[1]) : 0;
|
||||
else if (kd && params[0].equals_ci("FLOODLINES"))
|
||||
kd->floodlines = params[1].is_pos_number_only() ? convertTo<int16_t>(params[1]) : 0;
|
||||
else if (kd && params[0].equals_ci("FLOODSECS"))
|
||||
kd->floodsecs = params[1].is_pos_number_only() ? convertTo<int16_t>(params[1]) : 0;
|
||||
else if (kd && params[0].equals_ci("REPEATTIMES"))
|
||||
kd->repeattimes = params[1].is_pos_number_only() ? convertTo<int16_t>(params[1]) : 0;
|
||||
else if (kd && params[0].equals_ci("BADWORD"))
|
||||
{
|
||||
BadWordType Type;
|
||||
if (params[1].equals_ci("SINGLE"))
|
||||
@@ -313,7 +324,9 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co
|
||||
Type = BW_END;
|
||||
else
|
||||
Type = BW_ANY;
|
||||
ci->AddBadWord(params[2], Type);
|
||||
BadWords *bw = ci->Require<BadWords>("badwords");
|
||||
if (bw)
|
||||
bw->AddBadWord(params[2], Type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -467,11 +480,6 @@ static void ReadDatabase(Module *m = NULL)
|
||||
static void LoadNickCore(const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
NickCore *nc = new NickCore(params[0]);
|
||||
/* Clear default flags */
|
||||
std::deque<Anope::string> list;
|
||||
nc->GetExtList(list);
|
||||
for (unsigned i = 0; i < list.size(); ++i)
|
||||
nc->Shrink(list[i]);
|
||||
|
||||
nc->pass = params.size() > 1 ? params[1] : "";
|
||||
|
||||
@@ -512,13 +520,6 @@ static void LoadBotInfo(const std::vector<Anope::string> ¶ms)
|
||||
static void LoadChanInfo(const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelInfo *ci = new ChannelInfo(params[0]);
|
||||
/* CLear default mlock */
|
||||
ci->ClearMLock();
|
||||
/* Remove default channel flags */
|
||||
std::deque<Anope::string> list;
|
||||
ci->GetExtList(list);
|
||||
for (unsigned i = 0; i < list.size(); ++i)
|
||||
ci->Shrink(list[i]);
|
||||
|
||||
ci->time_registered = params[1].is_pos_number_only() ? convertTo<time_t>(params[1]) : 0;
|
||||
|
||||
@@ -645,230 +646,6 @@ class DBPlain : public Module
|
||||
|
||||
return EVENT_STOP;
|
||||
}
|
||||
|
||||
|
||||
void OnSaveDatabase() anope_override
|
||||
{
|
||||
BackupDatabase();
|
||||
|
||||
db_buffer << "VER 2" << endl;
|
||||
|
||||
for (nickcore_map::const_iterator nit = NickCoreList->begin(), nit_end = NickCoreList->end(); nit != nit_end; ++nit)
|
||||
{
|
||||
const NickCore *nc = nit->second;
|
||||
|
||||
db_buffer << "NC " << nc->display << " " << nc->pass << endl;
|
||||
|
||||
db_buffer << "MD MEMOMAX " << nc->memos.memomax << endl;
|
||||
|
||||
if (!nc->language.empty())
|
||||
db_buffer << "MD LANGUAGE " << nc->language << endl;
|
||||
if (!nc->email.empty())
|
||||
db_buffer << "MD EMAIL " << nc->email << endl;
|
||||
if (!nc->greet.empty())
|
||||
db_buffer << "MD GREET :" << nc->greet << endl;
|
||||
|
||||
if (!nc->access.empty())
|
||||
{
|
||||
for (std::vector<Anope::string>::const_iterator it = nc->access.begin(), it_end = nc->access.end(); it != it_end; ++it)
|
||||
db_buffer << "MD ACCESS " << *it << endl;
|
||||
}
|
||||
if (!nc->cert.empty())
|
||||
{
|
||||
for (std::vector<Anope::string>::const_iterator it = nc->cert.begin(), it_end = nc->cert.end(); it != it_end; ++it)
|
||||
db_buffer << "MD CERT " << *it << endl;
|
||||
}
|
||||
db_buffer << "MD FLAGS ";
|
||||
std::deque<Anope::string> list;
|
||||
nc->GetExtList(list);
|
||||
for (unsigned i = 0; i < list.size(); ++i)
|
||||
db_buffer << list[i] << " ";
|
||||
db_buffer << std::endl;
|
||||
const MemoInfo *mi = &nc->memos;
|
||||
for (unsigned k = 0, end = mi->memos->size(); k < end; ++k)
|
||||
{
|
||||
const Memo *m = mi->GetMemo(k);
|
||||
db_buffer << "MD MI " << m->time << " " << m->sender;
|
||||
if (m->unread)
|
||||
db_buffer << " UNREAD";
|
||||
if (m->receipt)
|
||||
db_buffer << " RECEIPT";
|
||||
db_buffer << " :" << m->text << endl;
|
||||
}
|
||||
for (unsigned k = 0, end = mi->ignores.size(); k < end; ++k)
|
||||
db_buffer << "MD MIG " << Anope::string(mi->ignores[k]) << endl;
|
||||
//FOREACH_MOD(OnDatabaseWriteMetadata, (WriteMetadata, nc));
|
||||
}
|
||||
|
||||
for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; ++it)
|
||||
{
|
||||
const NickAlias *na = it->second;
|
||||
|
||||
db_buffer << "NA " << na->nc->display << " " << na->nick << " " << na->time_registered << " " << na->last_seen << endl;
|
||||
if (!na->last_usermask.empty())
|
||||
db_buffer << "MD LAST_USERMASK " << na->last_usermask << endl;
|
||||
if (!na->last_realhost.empty())
|
||||
db_buffer << "MD LAST_REALHOST " << na->last_realhost << endl;
|
||||
if (!na->last_realname.empty())
|
||||
db_buffer << "MD LAST_REALNAME :" << na->last_realname << endl;
|
||||
if (!na->last_quit.empty())
|
||||
db_buffer << "MD LAST_QUIT :" << na->last_quit << endl;
|
||||
db_buffer << "MD FLAGS ";
|
||||
std::deque<Anope::string> list;
|
||||
na->GetExtList(list);
|
||||
for (unsigned i = 0; i < list.size(); ++i)
|
||||
db_buffer << list[i] << " ";
|
||||
db_buffer << std::endl;
|
||||
if (na->HasVhost())
|
||||
db_buffer << "MD VHOST " << na->GetVhostCreator() << " " << na->GetVhostCreated() << " " << na->GetVhostHost() << " :" << na->GetVhostIdent() << endl;
|
||||
|
||||
//FOREACH_MOD(OnDatabaseWriteMetadata, (WriteMetadata, na));
|
||||
}
|
||||
|
||||
for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
|
||||
{
|
||||
BotInfo *bi = it->second;
|
||||
|
||||
if (bi->HasExt("CONF"))
|
||||
continue;
|
||||
|
||||
db_buffer << "BI " << bi->nick << " " << bi->GetIdent() << " " << bi->host << " " << bi->created << " " << bi->GetChannelCount() << " :" << bi->realname << endl;
|
||||
db_buffer << "MD FLAGS ";
|
||||
std::deque<Anope::string> list;
|
||||
bi->GetExtList(list);
|
||||
for (unsigned i = 0; i < list.size(); ++i)
|
||||
db_buffer << list[i] << " ";
|
||||
db_buffer << std::endl;
|
||||
}
|
||||
|
||||
for (registered_channel_map::const_iterator cit = RegisteredChannelList->begin(), cit_end = RegisteredChannelList->end(); cit != cit_end; ++cit)
|
||||
{
|
||||
const ChannelInfo *ci = cit->second;
|
||||
|
||||
db_buffer << "CH " << ci->name << " " << ci->time_registered << " " << ci->last_used << endl;
|
||||
db_buffer << "MD BANTYPE " << ci->bantype << endl;
|
||||
db_buffer << "MD MEMOMAX " << ci->memos.memomax << endl;
|
||||
if (ci->GetFounder())
|
||||
db_buffer << "MD FOUNDER " << ci->GetFounder()->display << endl;
|
||||
if (ci->GetSuccessor())
|
||||
db_buffer << "MD SUCCESSOR " << ci->GetSuccessor()->display << endl;
|
||||
if (!ci->desc.empty())
|
||||
db_buffer << "MD DESC :" << ci->desc << endl;
|
||||
if (!ci->last_topic.empty())
|
||||
db_buffer << "MD TOPIC " << ci->last_topic_setter << " " << ci->last_topic_time << " :" << ci->last_topic << endl;
|
||||
db_buffer << "MD LEVELS";
|
||||
const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
|
||||
for (unsigned i = 0; i < privs.size(); ++i)
|
||||
{
|
||||
const Privilege &p = privs[i];
|
||||
db_buffer << p.name << " " << ci->GetLevel(p.name);
|
||||
}
|
||||
db_buffer << endl;
|
||||
std::deque<Anope::string> list;
|
||||
ci->GetExtList(list);
|
||||
for (unsigned i = 0; i < list.size(); ++i)
|
||||
db_buffer << list[i];
|
||||
db_buffer << std::endl;
|
||||
if (ci->HasExt("SUSPENDED"))
|
||||
{
|
||||
Anope::string *by = ci->GetExt<ExtensibleItemClass<Anope::string> *>("suspend_by"), *reason = ci->GetExt<ExtensibleItemClass<Anope::string> *>("suspend_reason");
|
||||
if (by && reason)
|
||||
db_buffer << "MD SUSPEND " << *by << " :" << *reason << endl;
|
||||
}
|
||||
for (unsigned k = 0, end = ci->GetAccessCount(); k < end; ++k)
|
||||
{
|
||||
const ChanAccess *access = ci->GetAccess(k);
|
||||
db_buffer << "MD ACCESS2 " << access->provider->name << " " << access->mask << " " << access->AccessSerialize() << " " << access->last_seen << " " << access->creator << " " << access->created << endl;
|
||||
}
|
||||
for (unsigned k = 0, end = ci->GetAkickCount(); k < end; ++k)
|
||||
{
|
||||
db_buffer << "MD AKICK 0 " << (ci->GetAkick(k)->nc ? "NICK " : "MASK ") <<
|
||||
(ci->GetAkick(k)->nc ? ci->GetAkick(k)->nc->display : ci->GetAkick(k)->mask) << " " << ci->GetAkick(k)->creator << " " << ci->GetAkick(k)->addtime << " " << ci->last_used << " :";
|
||||
if (!ci->GetAkick(k)->reason.empty())
|
||||
db_buffer << ci->GetAkick(k)->reason;
|
||||
db_buffer << endl;
|
||||
}
|
||||
for (unsigned k = 0, end = ci->log_settings->size(); k < end; ++k)
|
||||
{
|
||||
const LogSetting &l = *ci->log_settings->at(k);
|
||||
|
||||
db_buffer << "MD LOG " << l.service_name << " " << l.command_service << " " << l.command_name << " " << l.method << " " << l.creator << " " << l.created << " " << l.extra << endl;
|
||||
}
|
||||
for (ChannelInfo::ModeList::const_iterator it = ci->GetMLock().begin(), it_end = ci->GetMLock().end(); it != it_end; ++it)
|
||||
{
|
||||
const ModeLock &ml = *it->second;
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(ml.name);
|
||||
if (cm != NULL)
|
||||
db_buffer << "MD MLOCK " << (ml.set ? 1 : 0) << " " << cm->name << " " << ml.setter << " " << ml.created << " " << ml.param << endl;
|
||||
}
|
||||
const MemoInfo *memos = &ci->memos;
|
||||
for (unsigned k = 0, end = memos->memos->size(); k < end; ++k)
|
||||
{
|
||||
const Memo *m = memos->GetMemo(k);
|
||||
db_buffer << "MD MI " << m->time << " " << m->sender;
|
||||
if (m->unread)
|
||||
db_buffer << " UNREAD";
|
||||
if (m->receipt)
|
||||
db_buffer << " RECEIPT";
|
||||
db_buffer << " :" << m->text << endl;
|
||||
}
|
||||
for (unsigned k = 0, end = memos->ignores.size(); k < end; ++k)
|
||||
db_buffer << "MD MIG " << Anope::string(memos->ignores[k]) << endl;
|
||||
if (ci->bi)
|
||||
db_buffer << "MD BI NAME " << ci->bi->nick << endl;
|
||||
db_buffer << "MD BI TTB BOLDS " << ci->ttb[0] << " COLORS " << ci->ttb[1] << " REVERSES " << ci->ttb[2] << " UNDERLINES " << ci->ttb[3] << " BADWORDS " << ci->ttb[4] << " CAPS " << ci->ttb[5] << " FLOOD " << ci->ttb[6] << " REPEAT " << ci->ttb[7] << " ITALICS " << ci->ttb[8] << " AMSGS " << ci->ttb[9] << endl;
|
||||
if (ci->capsmin)
|
||||
db_buffer << "MD BI CAPSMIN " << ci->capsmin << endl;
|
||||
if (ci->capspercent)
|
||||
db_buffer << "MD BI CAPSPERCENT " << ci->capspercent << endl;
|
||||
if (ci->floodlines)
|
||||
db_buffer << "MD BI FLOODLINES " << ci->floodlines << endl;
|
||||
if (ci->floodsecs)
|
||||
db_buffer << "MD BI FLOODSECS " << ci->floodsecs << endl;
|
||||
if (ci->repeattimes)
|
||||
db_buffer << "MD BI REPEATTIMES " << ci->repeattimes << endl;
|
||||
for (unsigned k = 0, end = ci->GetBadWordCount(); k < end; ++k)
|
||||
db_buffer << "MD BI BADWORD " << (ci->GetBadWord(k)->type == BW_ANY ? "ANY " : "") << (ci->GetBadWord(k)->type == BW_SINGLE ? "SINGLE " : "") << (ci->GetBadWord(k)->type == BW_START ? "START " : "") <<
|
||||
(ci->GetBadWord(k)->type == BW_END ? "END " : "") << ":" << ci->GetBadWord(k)->word << endl;
|
||||
|
||||
//FOREACH_MOD(OnDatabaseWriteMetadata, (WriteMetadata, ci));
|
||||
}
|
||||
|
||||
db_buffer << "OS STATS " << MaxUserCount << " " << MaxUserTime << endl;
|
||||
|
||||
for (std::list<XLineManager *>::iterator it = XLineManager::XLineManagers.begin(), it_end = XLineManager::XLineManagers.end(); it != it_end; ++it)
|
||||
{
|
||||
XLineManager *xl = *it;
|
||||
for (unsigned i = 0, end = xl->GetCount(); i < end; ++i)
|
||||
{
|
||||
const XLine *x = xl->GetEntry(i);
|
||||
db_buffer << "OS SXLINE " << xl->Type() << " " << x->GetUser() << " " << x->GetHost() << " " << x->by << " " << x->created << " " << x->expires << " :" << x->reason << endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (session_service)
|
||||
for (SessionService::ExceptionVector::iterator it = session_service->GetExceptions().begin(); it != session_service->GetExceptions().end(); ++it)
|
||||
{
|
||||
Exception *e = *it;
|
||||
db_buffer << "OS EXCEPTION " << e->mask << " " << e->limit << " " << e->who << " " << e->time << " " << e->expires << " " << e->reason << endl;
|
||||
}
|
||||
|
||||
//FOREACH_MOD(OnDatabaseWrite, (Write));
|
||||
|
||||
std::fstream db;
|
||||
db.open(DatabaseFile.c_str(), std::ios_base::out | std::ios_base::trunc);
|
||||
|
||||
if (!db.is_open())
|
||||
{
|
||||
IRCD->SendGlobops(NULL, "Unable to open %s for writing!", DatabaseFile.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
db << db_buffer.str();
|
||||
db_buffer.str("");
|
||||
|
||||
db.close();
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_INIT(DBPlain)
|
||||
|
||||
@@ -56,7 +56,7 @@ class MChanstats : public Module
|
||||
|
||||
const Anope::string GetDisplay(User *u)
|
||||
{
|
||||
if (u && u->Account() && u->Account()->HasExt("STATS"))
|
||||
if (u && u->Account() && u->Account()->HasExt("NS_STATS"))
|
||||
return u->Account()->display;
|
||||
else
|
||||
return "";
|
||||
@@ -357,7 +357,7 @@ class MChanstats : public Module
|
||||
void OnTopicUpdated(Channel *c, const Anope::string &user, const Anope::string &topic) anope_override
|
||||
{
|
||||
User *u = User::Find(user);
|
||||
if (!u || !u->Account() || !c->ci || !c->ci->HasExt("STATS"))
|
||||
if (!u || !u->Account() || !c->ci || !c->ci->HasExt("CS_STATS"))
|
||||
return;
|
||||
query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);";
|
||||
query.SetValue("channel", c->name);
|
||||
@@ -365,13 +365,13 @@ class MChanstats : public Module
|
||||
this->RunQuery(query);
|
||||
}
|
||||
|
||||
EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, const Anope::string &, const Anope::string ¶m) anope_override
|
||||
EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) anope_override
|
||||
{
|
||||
this->OnModeChange(c, setter.GetUser());
|
||||
return EVENT_CONTINUE;
|
||||
}
|
||||
|
||||
EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, const Anope::string &, const Anope::string ¶m) anope_override
|
||||
EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *, const Anope::string ¶m) anope_override
|
||||
{
|
||||
this->OnModeChange(c, setter.GetUser());
|
||||
return EVENT_CONTINUE;
|
||||
@@ -380,7 +380,7 @@ class MChanstats : public Module
|
||||
private:
|
||||
void OnModeChange(Channel *c, User *u)
|
||||
{
|
||||
if (!u || !u->Account() || !c->ci || !c->ci->HasExt("STATS"))
|
||||
if (!u || !u->Account() || !c->ci || !c->ci->HasExt("CS_STATS"))
|
||||
return;
|
||||
|
||||
query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);";
|
||||
@@ -391,7 +391,7 @@ class MChanstats : public Module
|
||||
public:
|
||||
void OnPreUserKicked(MessageSource &source, ChanUserContainer *cu, const Anope::string &kickmsg) anope_override
|
||||
{
|
||||
if (!cu->chan->ci || !cu->chan->ci->HasExt("STATS"))
|
||||
if (!cu->chan->ci || !cu->chan->ci->HasExt("CS_STATS"))
|
||||
return;
|
||||
|
||||
query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);";
|
||||
@@ -406,7 +406,7 @@ class MChanstats : public Module
|
||||
}
|
||||
void OnPrivmsg(User *u, Channel *c, Anope::string &msg) anope_override
|
||||
{
|
||||
if (!c->ci || !c->ci->HasExt("STATS"))
|
||||
if (!c->ci || !c->ci->HasExt("CS_STATS"))
|
||||
return;
|
||||
|
||||
size_t letters = msg.length();
|
||||
@@ -452,7 +452,7 @@ class MChanstats : public Module
|
||||
query.SetValue("new_display", newdisplay);
|
||||
this->RunQuery(query);
|
||||
}
|
||||
void OnChanDrop(ChannelInfo *ci) anope_override
|
||||
void OnDelChan(ChannelInfo *ci) anope_override
|
||||
{
|
||||
query = "DELETE FROM `" + prefix + "chanstats` WHERE `chan` = @channel@;";
|
||||
query.SetValue("channel", ci->name);
|
||||
|
||||
@@ -111,7 +111,7 @@ class IdentifyInterface : public LDAPInterface
|
||||
// encrypt and store the password in the nickcore
|
||||
Anope::Encrypt(ii->req->GetPassword(), na->nc->pass);
|
||||
|
||||
na->nc->Extend("m_ldap_authentication_dn", new ExtensibleItemClass<Anope::string>(ii->dn));
|
||||
na->nc->Extend<Anope::string>("m_ldap_authentication_dn", ii->dn);
|
||||
ii->req->Success(me);
|
||||
}
|
||||
break;
|
||||
@@ -207,12 +207,15 @@ class NSIdentifyLDAP : public Module
|
||||
OnIdentifyInterface oninterface;
|
||||
OnRegisterInterface orinterface;
|
||||
|
||||
PrimitiveExtensibleItem<Anope::string> dn;
|
||||
|
||||
Anope::string password_attribute;
|
||||
Anope::string disable_register_reason;
|
||||
Anope::string disable_email_reason;
|
||||
public:
|
||||
NSIdentifyLDAP(const Anope::string &modname, const Anope::string &creator) :
|
||||
Module(modname, creator, EXTRA | VENDOR), ldap("LDAPProvider", "ldap/main"), iinterface(this), oninterface(this), orinterface(this)
|
||||
Module(modname, creator, EXTRA | VENDOR), ldap("LDAPProvider", "ldap/main"), iinterface(this), oninterface(this), orinterface(this),
|
||||
dn(this, "m_ldap_authentication_dn")
|
||||
{
|
||||
|
||||
me = this;
|
||||
@@ -274,16 +277,16 @@ class NSIdentifyLDAP : public Module
|
||||
|
||||
void OnNickIdentify(User *u) anope_override
|
||||
{
|
||||
if (email_attribute.empty() || !this->ldap || !u->Account()->HasExt("m_ldap_authentication_dn"))
|
||||
if (email_attribute.empty() || !this->ldap)
|
||||
return;
|
||||
|
||||
Anope::string *dn = u->Account()->GetExt<ExtensibleItemClass<Anope::string> *>("m_ldap_authentication_dn");
|
||||
if (!dn || dn->empty())
|
||||
Anope::string *d = dn.Get(u->Account());
|
||||
if (!d || d->empty())
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
LDAPQuery id = this->ldap->Search(&this->oninterface, *dn, "(" + email_attribute + "=*)");
|
||||
LDAPQuery id = this->ldap->Search(&this->oninterface, *d, "(" + email_attribute + "=*)");
|
||||
this->oninterface.Add(id, u->nick);
|
||||
}
|
||||
catch (const LDAPException &ex)
|
||||
|
||||
@@ -32,57 +32,57 @@ bool WebCPanel::ChanServ::Set::OnRequest(HTTPProvider *server, const Anope::stri
|
||||
if (ci->HasExt("KEEPTOPIC") != message.post_data.count("keeptopic"))
|
||||
{
|
||||
if (!ci->HasExt("KEEPTOPIC"))
|
||||
ci->ExtendMetadata("KEEPTOPIC");
|
||||
ci->Extend<bool>("KEEPTOPIC");
|
||||
else
|
||||
ci->Shrink("KEEPTOPIC");
|
||||
ci->Shrink<bool>("KEEPTOPIC");
|
||||
replacements["MESSAGES"] = "Secure updated";
|
||||
}
|
||||
if (ci->HasExt("PEACE") != message.post_data.count("peace"))
|
||||
{
|
||||
if (!ci->HasExt("PEACE"))
|
||||
ci->ExtendMetadata("PEACE");
|
||||
ci->Extend<bool>("PEACE");
|
||||
else
|
||||
ci->Shrink("PEACE");
|
||||
ci->Shrink<bool>("PEACE");
|
||||
replacements["MESSAGES"] = "Peace updated";
|
||||
}
|
||||
if (ci->HasExt("PRIVATE") != message.post_data.count("private"))
|
||||
if (ci->HasExt("CS_PRIVATE") != message.post_data.count("private"))
|
||||
{
|
||||
if (!ci->HasExt("PRIVATE"))
|
||||
ci->ExtendMetadata("PRIVATE");
|
||||
if (!ci->HasExt("CS_PRIVATE"))
|
||||
ci->Extend<bool>("CS_PRIVATE");
|
||||
else
|
||||
ci->Shrink("PRIVATE");
|
||||
ci->Shrink<bool>("CS_PRIVATE");
|
||||
replacements["MESSAGES"] = "Private updated";
|
||||
}
|
||||
if (ci->HasExt("RESTRICTED") != message.post_data.count("restricted"))
|
||||
{
|
||||
if (!ci->HasExt("RESTRICTED"))
|
||||
ci->ExtendMetadata("RESTRICTED");
|
||||
ci->Extend<bool>("RESTRICTED");
|
||||
else
|
||||
ci->Shrink("RESTRICTED");
|
||||
ci->Shrink<bool>("RESTRICTED");
|
||||
replacements["MESSAGES"] = "Restricted updated";
|
||||
}
|
||||
if (ci->HasExt("SECURE") != message.post_data.count("secure"))
|
||||
if (ci->HasExt("CS_SECURE") != message.post_data.count("secure"))
|
||||
{
|
||||
if (!ci->HasExt("SECURE"))
|
||||
ci->ExtendMetadata("SECURE");
|
||||
if (!ci->HasExt("CS_SECURE"))
|
||||
ci->Extend<bool>("CS_SECURE");
|
||||
else
|
||||
ci->Shrink("SECURE");
|
||||
ci->Shrink<bool>("CS_SECURE");
|
||||
replacements["MESSAGES"] = "Secure updated";
|
||||
}
|
||||
if (ci->HasExt("SECUREOPS") != message.post_data.count("secureops"))
|
||||
{
|
||||
if (!ci->HasExt("SECUREOPS"))
|
||||
ci->ExtendMetadata("SECUREOPS");
|
||||
ci->Extend<bool>("SECUREOPS");
|
||||
else
|
||||
ci->Shrink("SECUREOPS");
|
||||
ci->Shrink<bool>("SECUREOPS");
|
||||
replacements["MESSAGES"] = "Secureops updated";
|
||||
}
|
||||
if (ci->HasExt("TOPICLOCK") != message.post_data.count("topiclock"))
|
||||
{
|
||||
if (!ci->HasExt("TOPICLOCK"))
|
||||
ci->ExtendMetadata("TOPICLOCK");
|
||||
ci->Extend<bool>("TOPICLOCK");
|
||||
else
|
||||
ci->Shrink("TOPICLOCK");
|
||||
ci->Shrink<bool>("TOPICLOCK");
|
||||
replacements["MESSAGES"] = "Topiclock updated";
|
||||
}
|
||||
}
|
||||
@@ -108,13 +108,13 @@ bool WebCPanel::ChanServ::Set::OnRequest(HTTPProvider *server, const Anope::stri
|
||||
if (ci->HasExt("PEACE"))
|
||||
replacements["PEACE"];
|
||||
|
||||
if (ci->HasExt("PRIVATE"))
|
||||
if (ci->HasExt("CS_PRIVATE"))
|
||||
replacements["PRIVATE"];
|
||||
|
||||
if (ci->HasExt("RESTRICTED"))
|
||||
replacements["RESTRICTED"];
|
||||
|
||||
if (ci->HasExt("SECURE"))
|
||||
if (ci->HasExt("CS_SECURE"))
|
||||
replacements["SECURE"];
|
||||
|
||||
if (ci->HasExt("SECUREOPS"))
|
||||
|
||||
@@ -40,8 +40,8 @@ class WebpanelRequest : public IdentifyRequest
|
||||
id += c;
|
||||
}
|
||||
|
||||
na->Extend("webcpanel_id", new ExtensibleItemClass<Anope::string>(id));
|
||||
na->Extend("webcpanel_ip", new ExtensibleItemClass<Anope::string>(client->GetIP()));
|
||||
na->Extend<Anope::string>("webcpanel_id", id);
|
||||
na->Extend<Anope::string>("webcpanel_ip", client->GetIP());
|
||||
|
||||
{
|
||||
HTTPReply::cookie c;
|
||||
|
||||
@@ -13,8 +13,8 @@ WebCPanel::Logout::Logout(const Anope::string &u) : WebPanelProtectedPage("", u)
|
||||
|
||||
bool WebCPanel::Logout::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements)
|
||||
{
|
||||
na->Shrink("webcpanel_id");
|
||||
na->Shrink("webcpanel_ip");
|
||||
na->Shrink<Anope::string>("webcpanel_id");
|
||||
na->Shrink<Anope::string>("webcpanel_ip");
|
||||
|
||||
reply.error = HTTP_FOUND;
|
||||
reply.headers["Location"] = Anope::string("http") + (use_ssl ? "s" : "") + "://" + message.headers["Host"] + "/";
|
||||
|
||||
@@ -24,7 +24,7 @@ bool WebCPanel::NickServ::Alist::OnRequest(HTTPProvider *server, const Anope::st
|
||||
++chan_count;
|
||||
|
||||
replacements["NUMBERS"] = stringify(chan_count);
|
||||
replacements["CHANNELS"] = (ci->HasExt("NO_EXPIRE") ? "!" : "") + ci->name;
|
||||
replacements["CHANNELS"] = (ci->HasExt("CS_NO_EXPIRE") ? "!" : "") + ci->name;
|
||||
replacements["ACCESSES"] = "Founder";
|
||||
continue;
|
||||
}
|
||||
@@ -36,7 +36,7 @@ bool WebCPanel::NickServ::Alist::OnRequest(HTTPProvider *server, const Anope::st
|
||||
++chan_count;
|
||||
|
||||
replacements["NUMBERS"] = stringify(chan_count);
|
||||
replacements["CHANNELS"] = (ci->HasExt("NO_EXPIRE") ? "!" : "") + ci->name;
|
||||
replacements["CHANNELS"] = (ci->HasExt("CS_NO_EXPIRE") ? "!" : "") + ci->name;
|
||||
Anope::string access_str;
|
||||
for (unsigned i = 0; i < access.size(); ++i)
|
||||
access_str += ", " + access[i]->AccessSerialize();
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "../../webcpanel.h"
|
||||
#include "modules/ns_cert.h"
|
||||
|
||||
WebCPanel::NickServ::Cert::Cert(const Anope::string &cat, const Anope::string &u) : WebPanelProtectedPage(cat, u)
|
||||
{
|
||||
@@ -30,8 +31,10 @@ bool WebCPanel::NickServ::Cert::OnRequest(HTTPProvider *server, const Anope::str
|
||||
WebPanel::RunCommand(na->nc->display, na->nc, "NickServ", "nickserv/cert", params, replacements);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < na->nc->cert.size(); ++i)
|
||||
replacements["CERTS"] = na->nc->cert[i];
|
||||
NSCertList *cl = na->nc->GetExt<NSCertList>("certificates");
|
||||
if (cl)
|
||||
for (unsigned i = 0; i < cl->GetCertCount(); ++i)
|
||||
replacements["CERTS"] = cl->GetCert(i);
|
||||
|
||||
TemplateFileServer page("nickserv/cert.html");
|
||||
page.Serve(server, page_name, client, message, reply, replacements);
|
||||
|
||||
@@ -30,52 +30,56 @@ bool WebCPanel::NickServ::Info::OnRequest(HTTPProvider *server, const Anope::str
|
||||
}
|
||||
if (message.post_data.count("greet") > 0)
|
||||
{
|
||||
if (message.post_data["greet"].replace_all_cs("+", " ") != na->nc->greet)
|
||||
{
|
||||
na->nc->greet = HTTPUtils::URLDecode(message.post_data["greet"]);
|
||||
replacements["MESSAGES"] = "Greet updated";
|
||||
}
|
||||
Anope::string *greet = na->nc->GetExt<Anope::string>("greet");
|
||||
const Anope::string &post_greet = HTTPUtils::URLDecode(message.post_data["greet"].replace_all_cs("+", " "));
|
||||
|
||||
if (post_greet.empty())
|
||||
na->nc->Shrink<Anope::string>("greet");
|
||||
else if (!greet || post_greet != *greet)
|
||||
na->nc->Extend<Anope::string>("greet", post_greet);
|
||||
|
||||
replacements["MESSAGES"] = "Greet updated";
|
||||
}
|
||||
if (na->nc->HasExt("AUTOOP") != message.post_data.count("autoop"))
|
||||
{
|
||||
if (!na->nc->HasExt("AUTOOP"))
|
||||
na->nc->ExtendMetadata("AUTOOP");
|
||||
na->nc->Extend<bool>("AUTOOP");
|
||||
else
|
||||
na->nc->Shrink("AUTOOP");
|
||||
na->nc->Shrink<bool>("AUTOOP");
|
||||
replacements["MESSAGES"] = "Autoop updated";
|
||||
}
|
||||
if (na->nc->HasExt("PRIVATE") != message.post_data.count("private"))
|
||||
if (na->nc->HasExt("NS_PRIVATE") != message.post_data.count("private"))
|
||||
{
|
||||
if (!na->nc->HasExt("PRIVATE"))
|
||||
na->nc->ExtendMetadata("PRIVATE");
|
||||
if (!na->nc->HasExt("NS_PRIVATE"))
|
||||
na->nc->Extend<bool>("NS_PRIVATE");
|
||||
else
|
||||
na->nc->Shrink("PRIVATE");
|
||||
na->nc->Shrink<bool>("NS_PRIVATE");
|
||||
replacements["MESSAGES"] = "Private updated";
|
||||
}
|
||||
if (na->nc->HasExt("SECURE") != message.post_data.count("secure"))
|
||||
if (na->nc->HasExt("NS_SECURE") != message.post_data.count("secure"))
|
||||
{
|
||||
if (!na->nc->HasExt("SECURE"))
|
||||
na->nc->ExtendMetadata("SECURE");
|
||||
if (!na->nc->HasExt("NS_SECURE"))
|
||||
na->nc->Extend<bool>("NS_SECURE");
|
||||
else
|
||||
na->nc->Shrink("SECURE");
|
||||
na->nc->Shrink<bool>("NS_SECURE");
|
||||
replacements["MESSAGES"] = "Secure updated";
|
||||
}
|
||||
if (message.post_data["kill"] == "on" && !na->nc->HasExt("KILLPROTECT"))
|
||||
{
|
||||
na->nc->ExtendMetadata("KILLPROTECT");
|
||||
na->nc->Shrink("KILL_QUICK");
|
||||
na->nc->Extend<bool>("KILLPROTECT");
|
||||
na->nc->Shrink<bool>("KILL_QUICK");
|
||||
replacements["MESSAGES"] = "Kill updated";
|
||||
}
|
||||
else if (message.post_data["kill"] == "quick" && !na->nc->HasExt("KILL_QUICK"))
|
||||
{
|
||||
na->nc->Shrink("KILLPROTECT");
|
||||
na->nc->ExtendMetadata("KILL_QUICK");
|
||||
na->nc->Shrink<bool>("KILLPROTECT");
|
||||
na->nc->Extend<bool>("KILL_QUICK");
|
||||
replacements["MESSAGES"] = "Kill updated";
|
||||
}
|
||||
else if (message.post_data["kill"] == "off" && (na->nc->HasExt("KILLPROTECT") || na->nc->HasExt("KILL_QUICK")))
|
||||
{
|
||||
na->nc->Shrink("KILLPROTECT");
|
||||
na->nc->Shrink("KILL_QUICK");
|
||||
na->nc->Shrink<bool>("KILLPROTECT");
|
||||
na->nc->Shrink<bool>("KILL_QUICK");
|
||||
replacements["MESSAGES"] = "Kill updated";
|
||||
}
|
||||
}
|
||||
@@ -91,12 +95,14 @@ bool WebCPanel::NickServ::Info::OnRequest(HTTPProvider *server, const Anope::str
|
||||
else
|
||||
replacements["VHOST"] = na->GetVhostHost();
|
||||
}
|
||||
replacements["GREET"] = HTTPUtils::Escape(na->nc->greet);
|
||||
Anope::string *greet = na->nc->GetExt<Anope::string>("greet");
|
||||
if (greet)
|
||||
replacements["GREET"] = HTTPUtils::Escape(*greet);
|
||||
if (na->nc->HasExt("AUTOOP"))
|
||||
replacements["AUTOOP"];
|
||||
if (na->nc->HasExt("PRIVATE"))
|
||||
if (na->nc->HasExt("NS_PRIVATE"))
|
||||
replacements["PRIVATE"];
|
||||
if (na->nc->HasExt("SECURE"))
|
||||
if (na->nc->HasExt("NS_SECURE"))
|
||||
replacements["SECURE"];
|
||||
if (na->nc->HasExt("KILLPROTECT"))
|
||||
replacements["KILL_ON"];
|
||||
|
||||
@@ -15,6 +15,7 @@ class ModuleWebCPanel : public Module
|
||||
{
|
||||
ServiceReference<HTTPProvider> provider;
|
||||
Panel panel;
|
||||
PrimitiveExtensibleItem<Anope::string> id, ip;
|
||||
|
||||
StaticFileServer style_css, logo_png, favicon_ico;
|
||||
|
||||
@@ -43,7 +44,7 @@ class ModuleWebCPanel : public Module
|
||||
|
||||
public:
|
||||
ModuleWebCPanel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR),
|
||||
panel(this, "webcpanel"),
|
||||
panel(this, "webcpanel"), id(this, "webcpanel_id"), ip(this, "webcpanel_ip"),
|
||||
style_css("style.css", "/static/style.css", "text/css"), logo_png("logo.png", "/static/logo.png", "image/png"), favicon_ico("favicon.ico", "/favicon.ico", "image/x-icon"),
|
||||
index("/"), logout("/logout"), _register("/register"), confirm("/confirm"),
|
||||
nickserv_info("NickServ", "/nickserv/info"), nickserv_cert("NickServ", "/nickserv/cert"), nickserv_access("NickServ", "/nickserv/access"), nickserv_alist("NickServ", "/nickserv/alist"),
|
||||
|
||||
@@ -50,7 +50,7 @@ class Panel : public Section, public Service
|
||||
if (na == NULL)
|
||||
return NULL;
|
||||
|
||||
Anope::string *n_id = na->GetExt<ExtensibleItemClass<Anope::string> *>("webcpanel_id"), *n_ip = na->GetExt<ExtensibleItemClass<Anope::string> *>("webcpanel_ip");
|
||||
Anope::string *n_id = na->GetExt<Anope::string>("webcpanel_id"), *n_ip = na->GetExt<Anope::string>("webcpanel_ip");
|
||||
if (n_id == NULL || n_ip == NULL)
|
||||
return NULL;
|
||||
else if (id != *n_id)
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
/* Fantasy functionality
|
||||
*
|
||||
* (C) 2003-2013 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 CommandBSSetFantasy : public Command
|
||||
{
|
||||
public:
|
||||
CommandBSSetFantasy(Module *creator, const Anope::string &sname = "botserv/set/fantasy") : Command(creator, sname, 2, 2)
|
||||
{
|
||||
this->SetDesc(_("Enable fantaisist commands"));
|
||||
this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
|
||||
{
|
||||
ChannelInfo *ci = ChannelInfo::Find(params[0]);
|
||||
const Anope::string &value = params[1];
|
||||
|
||||
if (ci == NULL)
|
||||
{
|
||||
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!source.HasPriv("botserv/administration") && !source.AccessFor(ci).HasPriv("SET"))
|
||||
{
|
||||
source.Reply(ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Anope::ReadOnly)
|
||||
{
|
||||
source.Reply(_("Sorry, bot option setting is temporarily disabled."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.equals_ci("ON"))
|
||||
{
|
||||
bool override = !source.AccessFor(ci).HasPriv("SET");
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable fantasy";
|
||||
|
||||
ci->Extend<bool>("BS_FANTASY");
|
||||
source.Reply(_("Fantasy mode is now \002on\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else if (value.equals_ci("OFF"))
|
||||
{
|
||||
bool override = !source.AccessFor(ci).HasPriv("SET");
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable fantasy";
|
||||
|
||||
ci->Shrink<bool>("BS_FANTASY");
|
||||
source.Reply(_("Fantasy mode is now \002off\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, source.command);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(_(" \n"
|
||||
"Enables or disables \002fantasy\002 mode on a channel.\n"
|
||||
"When it is enabled, users will be able to use\n"
|
||||
"fantasy commands on a channel when prefixed\n"
|
||||
"with one of the following fantasy characters: \002%s\002\n"
|
||||
" \n"
|
||||
"Note that users wanting to use fantaisist\n"
|
||||
"commands MUST have enough access for both\n"
|
||||
"the FANTASIA and the command they are executing."),
|
||||
Config->GetModule(this->owner)->Get<const Anope::string>("fantasycharacter", "!").c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class Fantasy : public Module
|
||||
{
|
||||
SerializableExtensibleItem<bool> fantasy;
|
||||
|
||||
CommandBSSetFantasy commandbssetfantasy;
|
||||
|
||||
public:
|
||||
Fantasy(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
fantasy(this, "BS_FANTASY"), commandbssetfantasy(this)
|
||||
{
|
||||
}
|
||||
|
||||
void OnPrivmsg(User *u, Channel *c, Anope::string &msg) anope_override
|
||||
{
|
||||
if (!u || !c || !c->ci || !c->ci->bi || msg.empty() || msg[0] == '\1')
|
||||
return;
|
||||
|
||||
if (!fantasy.HasExt(c->ci))
|
||||
return;
|
||||
|
||||
std::vector<Anope::string> params;
|
||||
spacesepstream(msg).GetTokens(params);
|
||||
|
||||
if (!msg.find(c->ci->bi->nick))
|
||||
params.erase(params.begin());
|
||||
else if (!msg.find_first_of(Config->GetModule(this)->Get<const Anope::string>("fantasycharacter", "!")))
|
||||
params[0].erase(params[0].begin());
|
||||
else
|
||||
return;
|
||||
|
||||
if (params.empty())
|
||||
return;
|
||||
|
||||
CommandInfo::map::const_iterator it = Config->Fantasy.end();
|
||||
unsigned count = 0;
|
||||
for (unsigned max = params.size(); it == Config->Fantasy.end() && max > 0; --max)
|
||||
{
|
||||
Anope::string full_command;
|
||||
for (unsigned i = 0; i < max; ++i)
|
||||
full_command += " " + params[i];
|
||||
full_command.erase(full_command.begin());
|
||||
|
||||
++count;
|
||||
it = Config->Fantasy.find(full_command);
|
||||
}
|
||||
|
||||
if (it == Config->Fantasy.end())
|
||||
return;
|
||||
|
||||
const CommandInfo &info = it->second;
|
||||
ServiceReference<Command> cmd("Command", info.name);
|
||||
if (!cmd)
|
||||
{
|
||||
Log(LOG_DEBUG) << "Fantasy command " << it->first << " exists for nonexistant service " << info.name << "!";
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned i = 0, j = params.size() - (count - 1); i < j; ++i)
|
||||
params.erase(params.begin());
|
||||
|
||||
/* Some commands take the channel as a first parameter */
|
||||
if (info.prepend_channel)
|
||||
params.insert(params.begin(), c->name);
|
||||
|
||||
while (cmd->max_params > 0 && params.size() > cmd->max_params)
|
||||
{
|
||||
params[cmd->max_params - 1] += " " + params[cmd->max_params];
|
||||
params.erase(params.begin() + cmd->max_params);
|
||||
}
|
||||
|
||||
// Command requires registered users only
|
||||
if (!cmd->AllowUnregistered() && !u->Account())
|
||||
return;
|
||||
|
||||
if (params.size() < cmd->min_params)
|
||||
return;
|
||||
|
||||
CommandSource source(u->nick, u, u->Account(), u, c->ci->bi);
|
||||
source.c = c;
|
||||
source.command = it->first;
|
||||
source.permission = info.permission;
|
||||
|
||||
EventReturn MOD_RESULT;
|
||||
if (c->ci->AccessFor(u).HasPriv("FANTASIA"))
|
||||
{
|
||||
FOREACH_RESULT(OnBotFantasy, MOD_RESULT, (source, cmd, c->ci, params));
|
||||
}
|
||||
else
|
||||
{
|
||||
FOREACH_RESULT(OnBotNoFantasyAccess, MOD_RESULT, (source, cmd, c->ci, params));
|
||||
}
|
||||
|
||||
if (MOD_RESULT == EVENT_STOP || !c->ci->AccessFor(u).HasPriv("FANTASIA"))
|
||||
return;
|
||||
|
||||
if (MOD_RESULT != EVENT_ALLOW && !info.permission.empty() && !source.HasCommand(info.permission))
|
||||
return;
|
||||
|
||||
FOREACH_RESULT(OnPreCommand, MOD_RESULT, (source, cmd, params));
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
return;
|
||||
|
||||
Reference<NickCore> nc_reference(u->Account());
|
||||
cmd->Execute(source, params);
|
||||
if (!nc_reference)
|
||||
source.nc = NULL;
|
||||
FOREACH_MOD(OnPostCommand, (source, cmd, params));
|
||||
}
|
||||
|
||||
void OnBotInfo(CommandSource &source, BotInfo *bi, ChannelInfo *ci, InfoFormatter &info)
|
||||
{
|
||||
if (fantasy.HasExt(ci))
|
||||
info.AddOption(_("Fantasy"));
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_INIT(Fantasy)
|
||||
|
||||
+1
-3
@@ -34,7 +34,7 @@ class DNSBLResolver : public Request
|
||||
|
||||
void OnLookupComplete(const Query *record) anope_override
|
||||
{
|
||||
if (!user || user->HasExt("m_dnsbl_akilled"))
|
||||
if (!user || user->Quitting())
|
||||
return;
|
||||
|
||||
const ResourceRecord &ans_record = record->answers[0];
|
||||
@@ -54,8 +54,6 @@ class DNSBLResolver : public Request
|
||||
record_reason = this->blacklist.replies[result];
|
||||
}
|
||||
|
||||
user->Extend("m_dnsbl_akilled");
|
||||
|
||||
Anope::string reason = this->blacklist.reason;
|
||||
reason = reason.replace_all_cs("%n", user->nick);
|
||||
reason = reason.replace_all_cs("%u", user->GetIdent());
|
||||
|
||||
@@ -14,9 +14,9 @@ class HelpChannel : public Module
|
||||
{
|
||||
}
|
||||
|
||||
EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, const Anope::string &mname, const Anope::string ¶m) anope_override
|
||||
EventReturn OnChannelModeSet(Channel *c, MessageSource &, ChannelMode *mode, const Anope::string ¶m) anope_override
|
||||
{
|
||||
if (mname == "OP" && c && c->ci && c->name.equals_ci(Config->GetModule(this)->Get<const Anope::string>("helpchannel")))
|
||||
if (mode->name == "OP" && c && c->ci && c->name.equals_ci(Config->GetModule(this)->Get<const Anope::string>("helpchannel")))
|
||||
{
|
||||
User *u = User::Find(param);
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/cs_mode.h"
|
||||
|
||||
static bool sasl = true;
|
||||
static Anope::string UplinkSID;
|
||||
@@ -435,19 +436,24 @@ class ProtoCharybdis : public Module
|
||||
|
||||
void OnChannelSync(Channel *c) anope_override
|
||||
{
|
||||
if (use_server_side_mlock && c->ci && Servers::Capab.count("MLOCK") > 0)
|
||||
if (!c->ci)
|
||||
return;
|
||||
|
||||
ModeLocks *modelocks = c->ci->GetExt<ModeLocks>("modelocks");
|
||||
if (use_server_side_mlock && modelocks && Servers::Capab.count("MLOCK") > 0)
|
||||
{
|
||||
Anope::string modes = c->ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
|
||||
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
|
||||
UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(c->creation_time) << " " << c->ci->name << " " << modes;
|
||||
}
|
||||
}
|
||||
|
||||
EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
|
||||
{
|
||||
ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
|
||||
if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
|
||||
if (use_server_side_mlock && cm && ci->c && modelocks && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
|
||||
{
|
||||
Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
|
||||
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
|
||||
UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
|
||||
}
|
||||
|
||||
@@ -456,10 +462,11 @@ class ProtoCharybdis : public Module
|
||||
|
||||
EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
|
||||
{
|
||||
ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
|
||||
if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
|
||||
if (use_server_side_mlock && cm && modelocks && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
|
||||
{
|
||||
Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
|
||||
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
|
||||
UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
|
||||
}
|
||||
|
||||
|
||||
@@ -947,7 +947,7 @@ struct IRCDMessageMetadata : IRCDMessage
|
||||
User *u = User::Find(params[0]);
|
||||
if (!u)
|
||||
return;
|
||||
u->Extend("SSL");
|
||||
u->Extend<bool>("ssl");
|
||||
Anope::string data = params[2].c_str();
|
||||
size_t pos1 = data.find(' ') + 1;
|
||||
size_t pos2 = data.find(' ', pos1);
|
||||
@@ -1271,6 +1271,7 @@ struct IRCDMessageEncap : IRCDMessage
|
||||
class ProtoInspIRCd : public Module
|
||||
{
|
||||
InspIRCd12Proto ircd_proto;
|
||||
ExtensibleItem<bool> ssl;
|
||||
|
||||
/* Core message handlers */
|
||||
Message::Away message_away;
|
||||
@@ -1311,7 +1312,7 @@ class ProtoInspIRCd : public Module
|
||||
|
||||
public:
|
||||
ProtoInspIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR),
|
||||
ircd_proto(this),
|
||||
ircd_proto(this), ssl(this, "ssl"),
|
||||
message_away(this), message_error(this), message_invite(this), message_join(this), message_kick(this), message_kill(this),
|
||||
message_motd(this), message_part(this), message_ping(this), message_privmsg(this), message_quit(this), message_squit(this),
|
||||
message_stats(this), message_topic(this),
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/cs_mode.h"
|
||||
|
||||
static unsigned int spanningtree_proto_ver = 0;
|
||||
|
||||
@@ -137,7 +138,7 @@ class InspIRCdExtBan : public ChannelModeList
|
||||
{
|
||||
Anope::string real_mask = mask.substr(2);
|
||||
|
||||
if (Anope::Match(u->fingerprint, real_mask))
|
||||
if (!u->fingerprint.empty() && Anope::Match(u->fingerprint, real_mask))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -759,9 +760,10 @@ class ProtoInspIRCd : public Module
|
||||
|
||||
void OnChanRegistered(ChannelInfo *ci) anope_override
|
||||
{
|
||||
if (use_server_side_mlock && ci->c && !ci->GetMLockAsString(false).empty())
|
||||
ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
|
||||
if (use_server_side_mlock && ci->c && modelocks && !modelocks->GetMLockAsString(false).empty())
|
||||
{
|
||||
Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
|
||||
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
|
||||
SendChannelMetadata(ci->c, "mlock", modes);
|
||||
}
|
||||
|
||||
@@ -783,10 +785,11 @@ class ProtoInspIRCd : public Module
|
||||
|
||||
EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
|
||||
{
|
||||
ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
|
||||
if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM))
|
||||
if (use_server_side_mlock && cm && ci->c && modelocks && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM))
|
||||
{
|
||||
Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
|
||||
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
|
||||
SendChannelMetadata(ci->c, "mlock", modes);
|
||||
}
|
||||
|
||||
@@ -795,10 +798,11 @@ class ProtoInspIRCd : public Module
|
||||
|
||||
EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
|
||||
{
|
||||
ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
|
||||
if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM))
|
||||
if (use_server_side_mlock && cm && ci->c && modelocks && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM))
|
||||
{
|
||||
Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
|
||||
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
|
||||
SendChannelMetadata(ci->c, "mlock", modes);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/cs_mode.h"
|
||||
|
||||
static bool sasl = true;
|
||||
|
||||
@@ -1226,18 +1227,23 @@ class ProtoUnreal : public Module
|
||||
|
||||
void OnChannelSync(Channel *c) anope_override
|
||||
{
|
||||
if (use_server_side_mlock && Servers::Capab.count("MLOCK") > 0 && c->ci)
|
||||
if (!c->ci)
|
||||
return;
|
||||
|
||||
ModeLocks *modelocks = c->ci->GetExt<ModeLocks>("modelocks");
|
||||
if (use_server_side_mlock && Servers::Capab.count("MLOCK") > 0 && modelocks)
|
||||
{
|
||||
Anope::string modes = c->ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
|
||||
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
|
||||
UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(c->creation_time) << " " << c->ci->name << " " << modes;
|
||||
}
|
||||
}
|
||||
|
||||
void OnChanRegistered(ChannelInfo *ci) anope_override
|
||||
{
|
||||
if (!ci->c || !use_server_side_mlock || !Servers::Capab.count("MLOCK"))
|
||||
ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
|
||||
if (!ci->c || !use_server_side_mlock || !modelocks || !Servers::Capab.count("MLOCK"))
|
||||
return;
|
||||
Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
|
||||
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
|
||||
UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
|
||||
}
|
||||
|
||||
@@ -1250,10 +1256,11 @@ class ProtoUnreal : public Module
|
||||
|
||||
EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
|
||||
{
|
||||
ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
|
||||
if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
|
||||
if (use_server_side_mlock && cm && modelocks && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
|
||||
{
|
||||
Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
|
||||
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
|
||||
UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
|
||||
}
|
||||
|
||||
@@ -1262,10 +1269,11 @@ class ProtoUnreal : public Module
|
||||
|
||||
EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
|
||||
{
|
||||
ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
|
||||
if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
|
||||
if (use_server_side_mlock && cm && modelocks && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
|
||||
{
|
||||
Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
|
||||
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
|
||||
UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,9 +14,11 @@
|
||||
class BotServCore : public Module
|
||||
{
|
||||
Reference<BotInfo> BotServ;
|
||||
ExtensibleRef<bool> persist, inhabit;
|
||||
|
||||
public:
|
||||
BotServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR)
|
||||
BotServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
|
||||
persist("persist"), inhabit("inhabit")
|
||||
{
|
||||
}
|
||||
|
||||
@@ -54,121 +56,6 @@ class BotServCore : public Module
|
||||
}
|
||||
}
|
||||
|
||||
void OnPrivmsg(User *u, Channel *c, Anope::string &msg) anope_override
|
||||
{
|
||||
if (!u || !c || !c->ci || !c->ci->bi || msg.empty())
|
||||
return;
|
||||
|
||||
/* Answer to ping if needed */
|
||||
if (msg.substr(0, 6).equals_ci("\1PING ") && msg[msg.length() - 1] == '\1')
|
||||
{
|
||||
Anope::string ctcp = msg;
|
||||
ctcp.erase(ctcp.begin());
|
||||
ctcp.erase(ctcp.length() - 1);
|
||||
IRCD->SendCTCP(c->ci->bi, u->nick, "%s", ctcp.c_str());
|
||||
}
|
||||
|
||||
Anope::string realbuf = msg;
|
||||
|
||||
if (realbuf.substr(0, 8).equals_ci("\1ACTION ") && realbuf[realbuf.length() - 1] == '\1')
|
||||
{
|
||||
realbuf.erase(0, 8);
|
||||
realbuf.erase(realbuf.length() - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (realbuf.empty() || !c->ci->HasExt("BS_FANTASY"))
|
||||
return;
|
||||
|
||||
std::vector<Anope::string> params;
|
||||
spacesepstream(realbuf).GetTokens(params);
|
||||
|
||||
if (!realbuf.find(c->ci->bi->nick))
|
||||
params.erase(params.begin());
|
||||
else if (!realbuf.find_first_of(Config->GetModule(this)->Get<const Anope::string>("fantasycharacter", "!")))
|
||||
params[0].erase(params[0].begin());
|
||||
else
|
||||
return;
|
||||
|
||||
if (params.empty())
|
||||
return;
|
||||
|
||||
CommandInfo::map::const_iterator it = Config->Fantasy.end();
|
||||
unsigned count = 0;
|
||||
for (unsigned max = params.size(); it == Config->Fantasy.end() && max > 0; --max)
|
||||
{
|
||||
Anope::string full_command;
|
||||
for (unsigned i = 0; i < max; ++i)
|
||||
full_command += " " + params[i];
|
||||
full_command.erase(full_command.begin());
|
||||
|
||||
++count;
|
||||
it = Config->Fantasy.find(full_command);
|
||||
}
|
||||
|
||||
if (it == Config->Fantasy.end())
|
||||
return;
|
||||
|
||||
const CommandInfo &info = it->second;
|
||||
ServiceReference<Command> cmd("Command", info.name);
|
||||
if (!cmd)
|
||||
{
|
||||
Log(LOG_DEBUG) << "Fantasy command " << it->first << " exists for nonexistant service " << info.name << "!";
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned i = 0, j = params.size() - (count - 1); i < j; ++i)
|
||||
params.erase(params.begin());
|
||||
|
||||
/* Some commands take the channel as a first parameter */
|
||||
if (info.prepend_channel)
|
||||
params.insert(params.begin(), c->name);
|
||||
|
||||
while (cmd->max_params > 0 && params.size() > cmd->max_params)
|
||||
{
|
||||
params[cmd->max_params - 1] += " " + params[cmd->max_params];
|
||||
params.erase(params.begin() + cmd->max_params);
|
||||
}
|
||||
|
||||
// Command requires registered users only
|
||||
if (!cmd->AllowUnregistered() && !u->Account())
|
||||
return;
|
||||
|
||||
if (params.size() < cmd->min_params)
|
||||
return;
|
||||
|
||||
CommandSource source(u->nick, u, u->Account(), u, c->ci->bi);
|
||||
source.c = c;
|
||||
source.command = it->first;
|
||||
source.permission = info.permission;
|
||||
|
||||
EventReturn MOD_RESULT;
|
||||
if (c->ci->AccessFor(u).HasPriv("FANTASIA"))
|
||||
{
|
||||
FOREACH_RESULT(OnBotFantasy, MOD_RESULT, (source, cmd, c->ci, params));
|
||||
}
|
||||
else
|
||||
{
|
||||
FOREACH_RESULT(OnBotNoFantasyAccess, MOD_RESULT, (source, cmd, c->ci, params));
|
||||
}
|
||||
|
||||
if (MOD_RESULT == EVENT_STOP || !c->ci->AccessFor(u).HasPriv("FANTASIA"))
|
||||
return;
|
||||
|
||||
if (MOD_RESULT != EVENT_ALLOW && !info.permission.empty() && !source.HasCommand(info.permission))
|
||||
return;
|
||||
|
||||
FOREACH_RESULT(OnPreCommand, MOD_RESULT, (source, cmd, params));
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
return;
|
||||
|
||||
Reference<NickCore> nc_reference(u->Account());
|
||||
cmd->Execute(source, params);
|
||||
if (!nc_reference)
|
||||
source.nc = NULL;
|
||||
FOREACH_MOD(OnPostCommand, (source, cmd, params));
|
||||
}
|
||||
|
||||
void OnJoinChannel(User *user, Channel *c) anope_override
|
||||
{
|
||||
if (!Config || !IRCD)
|
||||
@@ -221,22 +108,13 @@ class BotServCore : public Module
|
||||
ChannelStatus status(Config->GetModule(this)->Get<const Anope::string>("botmodes"));
|
||||
c->ci->bi->Join(c, &status);
|
||||
}
|
||||
/* Only display the greet if the main uplink we're connected
|
||||
* to has synced, or we'll get greet-floods when the net
|
||||
* recovers from a netsplit. -GD
|
||||
*/
|
||||
if (c->FindUser(c->ci->bi) && c->ci->HasExt("BS_GREET") && user->Account() && !user->Account()->greet.empty() && c->ci->AccessFor(user).HasPriv("GREET") && user->server->IsSynced())
|
||||
{
|
||||
IRCD->SendPrivmsg(c->ci->bi, c->name, "[%s] %s", user->Account()->display.c_str(), user->Account()->greet.c_str());
|
||||
c->ci->bi->lastmsg = Anope::CurTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnLeaveChannel(User *u, Channel *c) anope_override
|
||||
{
|
||||
/* Channel is persistent, it shouldn't be deleted and the service bot should stay */
|
||||
if (c->ci && c->ci->HasExt("PERSIST"))
|
||||
if (c->ci && persist && persist->Get(c->ci))
|
||||
return;
|
||||
|
||||
/* Channel is syncing from a netburst, don't destroy it as more users are probably wanting to join immediatly
|
||||
@@ -246,7 +124,7 @@ class BotServCore : public Module
|
||||
return;
|
||||
|
||||
/* Additionally, do not delete this channel if ChanServ/a BotServ bot is inhabiting it */
|
||||
if (c->HasExt("INHABIT"))
|
||||
if (inhabit && inhabit->Get(c))
|
||||
return;
|
||||
|
||||
/* This is called prior to removing the user from the channnel, so c->users.size() - 1 should be safe */
|
||||
@@ -304,9 +182,9 @@ class BotServCore : public Module
|
||||
"one of the following characters: %s"), fantasycharacters.c_str());
|
||||
}
|
||||
|
||||
EventReturn OnChannelModeSet(Channel *c, MessageSource &, const Anope::string &mname, const Anope::string ¶m) anope_override
|
||||
EventReturn OnChannelModeSet(Channel *c, MessageSource &, ChannelMode *mode, const Anope::string ¶m) anope_override
|
||||
{
|
||||
if (Config->GetModule(this)->Get<bool>("smartjoin") && mname == "BAN" && c->ci && c->ci->bi && c->FindUser(c->ci->bi))
|
||||
if (Config->GetModule(this)->Get<bool>("smartjoin") && mode->name == "BAN" && c->ci && c->ci->bi && c->FindUser(c->ci->bi))
|
||||
{
|
||||
BotInfo *bi = c->ci->bi;
|
||||
|
||||
@@ -323,7 +201,7 @@ class BotServCore : public Module
|
||||
/* Set default bot flags */
|
||||
spacesepstream sep(Config->GetModule(this)->Get<const Anope::string>("defaults", "greet fantasy"));
|
||||
for (Anope::string token; sep.GetToken(token);)
|
||||
ci->ExtendMetadata("BS_" + token.upper());
|
||||
ci->Extend<bool>("BS_" + token.upper());
|
||||
}
|
||||
|
||||
void OnUserKicked(MessageSource &source, User *target, const Anope::string &channel, ChannelStatus &status, const Anope::string &kickmsg) anope_override
|
||||
|
||||
@@ -10,15 +10,18 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/cs_mode.h"
|
||||
|
||||
class ChanServCore : public Module, public ChanServService
|
||||
{
|
||||
Reference<BotInfo> ChanServ;
|
||||
std::vector<Anope::string> defaults;
|
||||
ExtensibleItem<bool> inhabit;
|
||||
ExtensibleRef<bool> persist;
|
||||
|
||||
public:
|
||||
ChanServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
|
||||
ChanServService(this)
|
||||
ChanServService(this), inhabit(this, "inhabit"), persist("PERSIST")
|
||||
{
|
||||
}
|
||||
|
||||
@@ -30,17 +33,18 @@ class ChanServCore : public Module, public ChanServService
|
||||
class ChanServTimer : public Timer
|
||||
{
|
||||
Reference<BotInfo> &ChanServ;
|
||||
ExtensibleItem<bool> &inhabit;
|
||||
Reference<Channel> c;
|
||||
|
||||
public:
|
||||
/** Constructor
|
||||
* @param chan The channel
|
||||
*/
|
||||
ChanServTimer(Reference<BotInfo> &cs, Module *m, Channel *chan) : Timer(m, Config->GetModule(m)->Get<time_t>("inhabit", "15s")), ChanServ(cs), c(chan)
|
||||
ChanServTimer(Reference<BotInfo> &cs, ExtensibleItem<bool> &i, Module *m, Channel *chan) : Timer(m, Config->GetModule(m)->Get<time_t>("inhabit", "15s")), ChanServ(cs), inhabit(i), c(chan)
|
||||
{
|
||||
if (!ChanServ || !c)
|
||||
return;
|
||||
c->Extend("INHABIT");
|
||||
inhabit.Set(c, true);
|
||||
if (!c->ci || !c->ci->bi)
|
||||
ChanServ->Join(c);
|
||||
else if (!c->FindUser(c->ci->bi))
|
||||
@@ -61,7 +65,7 @@ class ChanServCore : public Module, public ChanServService
|
||||
if (!c)
|
||||
return;
|
||||
|
||||
c->Shrink("INHABIT");
|
||||
inhabit.Unset(c);
|
||||
|
||||
if (!c->ci || !c->ci->bi)
|
||||
{
|
||||
@@ -73,10 +77,10 @@ class ChanServCore : public Module, public ChanServService
|
||||
}
|
||||
};
|
||||
|
||||
if (c->HasExt("INHABIT"))
|
||||
if (inhabit.HasExt(c))
|
||||
return;
|
||||
|
||||
new ChanServTimer(ChanServ, this->owner, c);
|
||||
new ChanServTimer(ChanServ, inhabit, this->owner, c);
|
||||
}
|
||||
|
||||
void OnReload(Configuration::Conf *conf) anope_override
|
||||
@@ -96,7 +100,7 @@ class ChanServCore : public Module, public ChanServService
|
||||
if (defaults.empty())
|
||||
{
|
||||
defaults.push_back("KEEPTOPIC");
|
||||
defaults.push_back("SECURE");
|
||||
defaults.push_back("CS_SECURE");
|
||||
defaults.push_back("SECUREFOUNDER");
|
||||
defaults.push_back("SIGNKICK");
|
||||
}
|
||||
@@ -243,34 +247,9 @@ class ChanServCore : public Module, public ChanServService
|
||||
|
||||
void OnCreateChan(ChannelInfo *ci) anope_override
|
||||
{
|
||||
ci->bantype = Config->GetModule(this)->Get<int>("defbantype", "2");
|
||||
|
||||
/* Set default chan flags */
|
||||
for (unsigned i = 0; i < defaults.size(); ++i)
|
||||
ci->ExtendMetadata(defaults[i].upper());
|
||||
|
||||
{
|
||||
Anope::string modes;
|
||||
spacesepstream sep(Config->GetModule(this)->Get<const Anope::string>("mlock", "+nrt"));
|
||||
if (sep.GetToken(modes))
|
||||
{
|
||||
bool add = true;
|
||||
for (unsigned i = 0; i < modes.length(); ++i)
|
||||
{
|
||||
if (modes[i] == '+')
|
||||
add = true;
|
||||
else if (modes[i] == '-')
|
||||
add = false;
|
||||
else
|
||||
{
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
|
||||
Anope::string param;
|
||||
if (cm && (cm->type == MODE_REGULAR || sep.GetToken(param)))
|
||||
ci->SetMLock(cm, add, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ci->Extend<bool>(defaults[i].upper());
|
||||
}
|
||||
|
||||
EventReturn OnCanSet(User *u, const ChannelMode *cm) anope_override
|
||||
@@ -283,21 +262,13 @@ class ChanServCore : public Module, public ChanServService
|
||||
|
||||
void OnChannelSync(Channel *c) anope_override
|
||||
{
|
||||
bool perm = c->HasMode("PERM") || (c->ci && c->ci->HasExt("PERSIST"));
|
||||
if (!perm && !c->HasExt("BOTCHANNEL") && (c->users.empty() || (c->users.size() == 1 && c->users.begin()->second->user->server == Me)))
|
||||
bool perm = c->HasMode("PERM") || (c->ci && persist && persist->Get(c->ci));
|
||||
if (!perm && !c->botchannel && (c->users.empty() || (c->users.size() == 1 && c->users.begin()->second->user->server == Me)))
|
||||
{
|
||||
this->Hold(c);
|
||||
}
|
||||
|
||||
c->CheckModes();
|
||||
if (Me && Me->IsSynced() && c->ci)
|
||||
{
|
||||
/* Update channel topic */
|
||||
if ((c->ci->HasExt("KEEPTOPIC") || c->ci->HasExt("TOPICLOCK")) && c->ci->last_topic != c->topic)
|
||||
{
|
||||
c->ChangeTopic(!c->ci->last_topic_setter.empty() ? c->ci->last_topic_setter : c->ci->WhoSends()->nick, c->ci->last_topic, c->ci->last_topic_time ? c->ci->last_topic_time : Anope::CurTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EventReturn OnBotKick(BotInfo *bi, Channel *c, User *u, const Anope::string &reason)
|
||||
@@ -307,7 +278,7 @@ class ChanServCore : public Module, public ChanServService
|
||||
* ChanServ always enforces channels like this to keep people from deleting bots etc
|
||||
* that are holding channels.
|
||||
*/
|
||||
if (c->ci && c->users.size() == (c->ci->bi && c->FindUser(c->ci->bi) ? 2 : 1) && !c->HasExt("INHABIT") && !c->syncing)
|
||||
if (c->ci && c->users.size() == (c->ci->bi && c->FindUser(c->ci->bi) ? 2 : 1) && !inhabit.HasExt(c) && !c->syncing)
|
||||
{
|
||||
/* Join ChanServ and set a timer for this channel to part ChanServ later */
|
||||
this->Hold(c);
|
||||
@@ -349,18 +320,11 @@ class ChanServCore : public Module, public ChanServService
|
||||
expire = true;
|
||||
}
|
||||
|
||||
if (ci->HasExt("NO_EXPIRE"))
|
||||
expire = false;
|
||||
|
||||
FOREACH_MOD(OnPreChanExpire, (ci, expire));
|
||||
|
||||
if (expire)
|
||||
{
|
||||
Anope::string extra;
|
||||
if (ci->HasExt("SUSPENDED"))
|
||||
extra = "suspended ";
|
||||
|
||||
Log(LOG_NORMAL, "chanserv/expire") << "Expiring " << extra << "channel " << ci->name << " (founder: " << (ci->GetFounder() ? ci->GetFounder()->display : "(none)") << ")";
|
||||
Log(LOG_NORMAL, "chanserv/expire") << "Expiring channel " << ci->name << " (founder: " << (ci->GetFounder() ? ci->GetFounder()->display : "(none)") << ")";
|
||||
FOREACH_MOD(OnChanExpire, (ci));
|
||||
delete ci;
|
||||
}
|
||||
@@ -370,11 +334,11 @@ class ChanServCore : public Module, public ChanServService
|
||||
EventReturn OnCheckDelete(Channel *c) anope_override
|
||||
{
|
||||
/* Do not delete this channel if ChanServ/a BotServ bot is inhabiting it */
|
||||
if (c->HasExt("INHABIT"))
|
||||
if (inhabit.HasExt(c))
|
||||
return EVENT_STOP;
|
||||
|
||||
/* Channel is persistent, it shouldn't be deleted and the service bot should stay */
|
||||
if (c->ci && c->ci->HasExt("PERSIST"))
|
||||
if (c->ci && persist && persist->Get(c->ci))
|
||||
return EVENT_STOP;
|
||||
|
||||
return EVENT_CONTINUE;
|
||||
@@ -382,11 +346,13 @@ class ChanServCore : public Module, public ChanServService
|
||||
|
||||
void OnPreUplinkSync(Server *serv) anope_override
|
||||
{
|
||||
if (!persist)
|
||||
return;
|
||||
/* Find all persistent channels and create them, as we are about to finish burst to our uplink */
|
||||
for (registered_channel_map::iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
|
||||
{
|
||||
ChannelInfo *ci = it->second;
|
||||
if (ci->HasExt("PERSIST"))
|
||||
if (persist->Get(ci))
|
||||
{
|
||||
bool created;
|
||||
ci->c = Channel::FindOrCreate(ci->name, created, ci->time_registered);
|
||||
@@ -414,35 +380,15 @@ class ChanServCore : public Module, public ChanServService
|
||||
|
||||
void OnChanRegistered(ChannelInfo *ci) anope_override
|
||||
{
|
||||
if (!persist)
|
||||
return;
|
||||
/* Mark the channel as persistent */
|
||||
if (ci->c->HasMode("PERM"))
|
||||
ci->ExtendMetadata("PERSIST");
|
||||
persist->Unset(ci);
|
||||
/* Persist may be in def cflags, set it here */
|
||||
else if (ci->HasExt("PERSIST"))
|
||||
else if (persist->Get(ci))
|
||||
ci->c->SetMode(NULL, "PERM");
|
||||
}
|
||||
|
||||
void OnTopicUpdated(Channel *c, const Anope::string &user, const Anope::string &topic) anope_override
|
||||
{
|
||||
if (!c->ci)
|
||||
return;
|
||||
|
||||
/* We only compare the topics here, not the time or setter. This is because some (old) IRCds do not
|
||||
* allow us to set the topic as someone else, meaning we have to bump the TS and change the setter to us.
|
||||
* This desyncs what is really set with what we have stored, and we end up resetting the topic often when
|
||||
* it is not required
|
||||
*/
|
||||
if (c->ci->HasExt("TOPICLOCK") && c->ci->last_topic != c->topic)
|
||||
{
|
||||
c->ChangeTopic(c->ci->last_topic_setter, c->ci->last_topic, c->ci->last_topic_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
c->ci->last_topic = c->topic;
|
||||
c->ci->last_topic_setter = c->topic_setter;
|
||||
c->ci->last_topic_time = c->topic_ts;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_INIT(ChanServCore)
|
||||
|
||||
@@ -46,12 +46,13 @@ class NickServHeld : public Timer
|
||||
public:
|
||||
NickServHeld(NickAlias *n, long l) : Timer(l), na(n), nick(na->nick)
|
||||
{
|
||||
n->Extend<bool>("HELD");
|
||||
}
|
||||
|
||||
void Tick(time_t)
|
||||
{
|
||||
if (na)
|
||||
na->Shrink("HELD");
|
||||
na->Shrink<bool>("HELD");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -95,13 +96,13 @@ class NickServCore : public Module, public NickServService
|
||||
{
|
||||
Reference<BotInfo> NickServ;
|
||||
std::vector<Anope::string> defaults;
|
||||
ExtensibleItem<bool> held, collided;
|
||||
|
||||
void OnCancel(User *u, NickAlias *na)
|
||||
{
|
||||
if (na->HasExt("COLLIDED"))
|
||||
if (collided.HasExt(na))
|
||||
{
|
||||
na->Extend("HELD");
|
||||
na->Shrink("COLLIDED");
|
||||
collided.Unset(na);
|
||||
|
||||
new NickServHeld(na, Config->GetBlock("options")->Get<time_t>("releasetimeout"));
|
||||
|
||||
@@ -113,36 +114,48 @@ class NickServCore : public Module, public NickServService
|
||||
}
|
||||
|
||||
public:
|
||||
NickServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR), NickServService(this)
|
||||
NickServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
|
||||
NickServService(this), held(this, "HELD"), collided(this, "COLLIDED")
|
||||
{
|
||||
}
|
||||
|
||||
~NickServCore()
|
||||
{
|
||||
OnShutdown();
|
||||
}
|
||||
|
||||
void OnShutdown() anope_override
|
||||
{
|
||||
/* On shutdown, restart, or mod unload, remove all of our holds for nicks (svshold or qlines)
|
||||
* because some IRCds do not allow us to have these automatically expire
|
||||
*/
|
||||
for (nickalias_map::const_iterator it = NickAliasList->begin(); it != NickAliasList->end(); ++it)
|
||||
this->Release(it->second);
|
||||
}
|
||||
|
||||
void OnRestart() anope_override
|
||||
{
|
||||
OnShutdown();
|
||||
}
|
||||
|
||||
void Validate(User *u) anope_override
|
||||
{
|
||||
NickAlias *na = NickAlias::Find(u->nick);
|
||||
if (!na)
|
||||
return;
|
||||
|
||||
if (na->nc->HasExt("SUSPENDED"))
|
||||
EventReturn MOD_RESULT;
|
||||
FOREACH_RESULT(OnNickValidate, MOD_RESULT, (u, na));
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
{
|
||||
u->SendMessage(NickServ, NICK_X_SUSPENDED, u->nick.c_str());
|
||||
this->Collide(u, na);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(u->Account() == na->nc) && !u->fingerprint.empty() && na->nc->FindCert(u->fingerprint))
|
||||
{
|
||||
u->SendMessage(NickServ, _("SSL Fingerprint accepted, you are now identified."));
|
||||
Log(u) << "automatically identified for account " << na->nc->display << " using a valid SSL fingerprint.";
|
||||
u->Identify(na);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!na->nc->HasExt("SECURE") && u->IsRecognized())
|
||||
if (!na->nc->HasExt("NS_SECURE") && u->IsRecognized())
|
||||
{
|
||||
na->last_seen = Anope::CurTime;
|
||||
Anope::string last_usermask = u->GetIdent() + "@" + u->GetDisplayedHost();
|
||||
na->last_usermask = last_usermask;
|
||||
na->last_usermask = u->GetIdent() + "@" + u->GetDisplayedHost();
|
||||
na->last_realname = u->realname;
|
||||
return;
|
||||
}
|
||||
@@ -150,15 +163,16 @@ class NickServCore : public Module, public NickServService
|
||||
if (Config->GetBlock("options")->Get<bool>("nonicknameownership"))
|
||||
return;
|
||||
|
||||
if (u->IsRecognized(false) || !na->nc->HasExt("KILL_IMMED"))
|
||||
bool on_access = u->IsRecognized(false);
|
||||
|
||||
if (on_access || !na->nc->HasExt("KILL_IMMED"))
|
||||
{
|
||||
if (na->nc->HasExt("SECURE"))
|
||||
if (na->nc->HasExt("NS_SECURE"))
|
||||
u->SendMessage(NickServ, NICK_IS_SECURE, Config->StrictPrivmsg.c_str(), NickServ->nick.c_str());
|
||||
else
|
||||
u->SendMessage(NickServ, NICK_IS_REGISTERED, Config->StrictPrivmsg.c_str(), NickServ->nick.c_str());
|
||||
}
|
||||
|
||||
if (na->nc->HasExt("KILLPROTECT") && !u->IsRecognized(false))
|
||||
if (na->nc->HasExt("KILLPROTECT") && !on_access)
|
||||
{
|
||||
if (na->nc->HasExt("KILL_IMMED"))
|
||||
{
|
||||
@@ -184,14 +198,14 @@ class NickServCore : public Module, public NickServService
|
||||
void OnUserLogin(User *u) anope_override
|
||||
{
|
||||
NickAlias *na = NickAlias::Find(u->nick);
|
||||
if (na && *na->nc == u->Account() && !Config->GetBlock("options")->Get<bool>("nonicknameownership") && na->nc->HasExt("UNCONFIRMED") == false)
|
||||
if (na && *na->nc == u->Account() && !Config->GetBlock("options")->Get<bool>("nonicknameownership") && !na->nc->HasExt("UNCONFIRMED"))
|
||||
u->SetMode(NickServ, "REGISTERED");
|
||||
}
|
||||
|
||||
void Collide(User *u, NickAlias *na) anope_override
|
||||
{
|
||||
if (na)
|
||||
na->Extend("COLLIDED");
|
||||
collided.Set(na);
|
||||
|
||||
if (IRCD->CanSVSNick)
|
||||
{
|
||||
@@ -221,7 +235,7 @@ class NickServCore : public Module, public NickServService
|
||||
|
||||
void Release(NickAlias *na) anope_override
|
||||
{
|
||||
if (na->HasExt("HELD"))
|
||||
if (held.HasExt(na))
|
||||
{
|
||||
if (IRCD->CanSVSHold)
|
||||
IRCD->SendSVSHoldDel(na->nick);
|
||||
@@ -234,7 +248,7 @@ class NickServCore : public Module, public NickServService
|
||||
}
|
||||
}
|
||||
|
||||
na->Shrink("HELD");
|
||||
held.Unset(na);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,10 +265,10 @@ class NickServCore : public Module, public NickServService
|
||||
|
||||
NickServ = bi;
|
||||
|
||||
spacesepstream(conf->GetModule(this)->Get<const Anope::string>("defaults", "secure memo_signon memo_receive")).GetTokens(defaults);
|
||||
spacesepstream(conf->GetModule(this)->Get<const Anope::string>("defaults", "ns_secure memo_signon memo_receive")).GetTokens(defaults);
|
||||
if (defaults.empty())
|
||||
{
|
||||
defaults.push_back("SECURE");
|
||||
defaults.push_back("NS_SECURE");
|
||||
defaults.push_back("MEMO_SIGNON");
|
||||
defaults.push_back("MEMO_RECEIVE");
|
||||
}
|
||||
@@ -296,14 +310,8 @@ class NickServCore : public Module, public NickServService
|
||||
{
|
||||
Configuration::Block *block = Config->GetModule(this);
|
||||
|
||||
if (!Config->GetBlock("options")->Get<bool>("nonicknameownership"))
|
||||
{
|
||||
const NickAlias *this_na = NickAlias::Find(u->nick);
|
||||
if (this_na && this_na->nc == u->Account() && u->Account()->HasExt("UNCONFIRMED") == false)
|
||||
u->SetMode(NickServ, "REGISTERED");
|
||||
}
|
||||
|
||||
if (block->Get<bool>("modeonid", "yes"))
|
||||
|
||||
for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it)
|
||||
{
|
||||
ChanUserContainer *cc = it->second;
|
||||
@@ -325,25 +333,11 @@ class NickServCore : public Module, public NickServService
|
||||
"Your privacy is respected; this e-mail won't be given to\n"
|
||||
"any third-party person."), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str());
|
||||
}
|
||||
|
||||
if (u->Account()->HasExt("UNCONFIRMED"))
|
||||
{
|
||||
const Anope::string &nsregister = Config->GetModule("ns_register")->Get<const Anope::string>("registration");
|
||||
if (nsregister.equals_ci("admin"))
|
||||
u->SendMessage(NickServ, _("All new accounts must be validated by an administrator. Please wait for your registration to be confirmed."));
|
||||
else
|
||||
u->SendMessage(NickServ, _("Your email address is not confirmed. To confirm it, follow the instructions that were emailed to you when you registered."));
|
||||
const NickAlias *this_na = NickAlias::Find(u->Account()->display);
|
||||
time_t time_registered = Anope::CurTime - this_na->time_registered;
|
||||
time_t unconfirmed_expire = Config->GetModule(this)->Get<time_t>("unconfirmedexpire", "1d");
|
||||
if (unconfirmed_expire > time_registered)
|
||||
u->SendMessage(NickServ, _("Your account will expire, if not confirmed, in %s"), Anope::Duration(unconfirmed_expire - time_registered).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void OnNickGroup(User *u, NickAlias *target) anope_override
|
||||
{
|
||||
if (target->nc->HasExt("UNCONFIRMED") == false)
|
||||
if (!target->nc->HasExt("UNCONFIRMED"))
|
||||
u->SetMode(NickServ, "REGISTERED");
|
||||
}
|
||||
|
||||
@@ -404,7 +398,7 @@ class NickServCore : public Module, public NickServService
|
||||
{
|
||||
/* Reset +r and re-send account (even though it really should be set at this point) */
|
||||
IRCD->SendLogin(u);
|
||||
if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false)
|
||||
if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && na->nc == u->Account() && !na->nc->HasExt("UNCONFIRMED"))
|
||||
u->SetMode(NickServ, "REGISTERED");
|
||||
Log(NickServ) << u->GetMask() << " automatically identified for group " << u->Account()->display;
|
||||
}
|
||||
@@ -467,7 +461,7 @@ class NickServCore : public Module, public NickServService
|
||||
{
|
||||
/* Set default flags */
|
||||
for (unsigned i = 0; i < defaults.size(); ++i)
|
||||
nc->ExtendMetadata(defaults[i].upper());
|
||||
nc->Extend<bool>(defaults[i].upper());
|
||||
}
|
||||
|
||||
void OnUserQuit(User *u, const Anope::string &msg)
|
||||
@@ -489,7 +483,6 @@ class NickServCore : public Module, public NickServService
|
||||
if (Anope::NoExpire || Anope::ReadOnly)
|
||||
return;
|
||||
|
||||
time_t unconfirmed_expire = Config->GetModule(this)->Get<time_t>("unconfirmedexpire", "1d");
|
||||
time_t nickserv_expire = Config->GetModule(this)->Get<time_t>("expire");
|
||||
|
||||
for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; )
|
||||
@@ -498,32 +491,39 @@ class NickServCore : public Module, public NickServService
|
||||
++it;
|
||||
|
||||
User *u = User::Find(na->nick);
|
||||
if (u && (na->nc->HasExt("SECURE") ? u->IsIdentified(true) : u->IsRecognized()))
|
||||
if (u && (na->nc->HasExt("NS_SECURE") ? u->IsIdentified(true) : u->IsRecognized()))
|
||||
na->last_seen = Anope::CurTime;
|
||||
|
||||
bool expire = false;
|
||||
|
||||
if (na->nc->HasExt("UNCONFIRMED"))
|
||||
if (unconfirmed_expire && Anope::CurTime - na->time_registered >= unconfirmed_expire)
|
||||
expire = true;
|
||||
if (nickserv_expire && Anope::CurTime - na->last_seen >= nickserv_expire)
|
||||
expire = true;
|
||||
if (na->HasExt("NO_EXPIRE"))
|
||||
expire = false;
|
||||
|
||||
FOREACH_MOD(OnPreNickExpire, (na, expire));
|
||||
|
||||
if (expire)
|
||||
{
|
||||
Anope::string extra;
|
||||
if (na->nc->HasExt("SUSPENDED"))
|
||||
extra = "suspended ";
|
||||
Log(LOG_NORMAL, "expire") << "Expiring " << extra << "nickname " << na->nick << " (group: " << na->nc->display << ") (e-mail: " << (na->nc->email.empty() ? "none" : na->nc->email) << ")";
|
||||
Log(LOG_NORMAL, "expire") << "Expiring nickname " << na->nick << " (group: " << na->nc->display << ") (e-mail: " << (na->nc->email.empty() ? "none" : na->nc->email) << ")";
|
||||
FOREACH_MOD(OnNickExpire, (na));
|
||||
delete na;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) anope_override
|
||||
{
|
||||
if (!na->nc->HasExt("UNCONFIRMED"))
|
||||
{
|
||||
time_t nickserv_expire = Config->GetModule(this)->Get<time_t>("expire");
|
||||
if (!na->HasExt("NS_NO_EXPIRE") && nickserv_expire && !Anope::NoExpire)
|
||||
info[_("Expires")] = Anope::strftime(na->last_seen + nickserv_expire);
|
||||
}
|
||||
else
|
||||
{
|
||||
time_t unconfirmed_expire = Config->GetModule(this)->Get<time_t>("unconfirmedexpire", "1d");
|
||||
info[_("Expires")] = Anope::strftime(na->time_registered + unconfirmed_expire);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_INIT(NickServCore)
|
||||
|
||||
+2
-2
@@ -80,7 +80,7 @@ void BotInfo::Serialize(Serialize::Data &data) const
|
||||
data["created"] << this->created;
|
||||
data["oper_only"] << this->oper_only;
|
||||
|
||||
this->ExtensibleSerialize(data);
|
||||
Extensible::ExtensibleSerialize(this, this, data);
|
||||
}
|
||||
|
||||
Serializable* BotInfo::Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
@@ -101,7 +101,7 @@ Serializable* BotInfo::Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
data["created"] >> bi->created;
|
||||
data["oper_only"] >> bi->oper_only;
|
||||
|
||||
bi->ExtensibleUnserialize(data);
|
||||
Extensible::ExtensibleUnserialize(bi, bi, data);
|
||||
|
||||
return bi;
|
||||
}
|
||||
|
||||
+5
-67
@@ -35,7 +35,7 @@ Channel::Channel(const Anope::string &nname, time_t ts)
|
||||
this->name = nname;
|
||||
|
||||
this->creation_time = ts;
|
||||
this->syncing = false;
|
||||
this->syncing = this->botchannel = false;
|
||||
this->server_modetime = this->chanserv_modetime = 0;
|
||||
this->server_modecount = this->chanserv_modecount = this->bouncy_modes = this->topic_ts = this->topic_time = 0;
|
||||
|
||||
@@ -108,48 +108,6 @@ void Channel::CheckModes()
|
||||
FOREACH_RESULT(OnCheckModes, MOD_RESULT, (this));
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
return;
|
||||
|
||||
if (this->ci)
|
||||
for (ChannelInfo::ModeList::const_iterator it = this->ci->GetMLock().begin(), it_end = this->ci->GetMLock().end(); it != it_end; ++it)
|
||||
{
|
||||
const ModeLock *ml = it->second;
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name);
|
||||
if (!cm)
|
||||
continue;
|
||||
|
||||
if (cm->type == MODE_REGULAR)
|
||||
{
|
||||
if (!this->HasMode(cm->name) && ml->set)
|
||||
this->SetMode(NULL, cm);
|
||||
else if (this->HasMode(cm->name) && !ml->set)
|
||||
this->RemoveMode(NULL, cm);
|
||||
}
|
||||
else if (cm->type == MODE_PARAM)
|
||||
{
|
||||
/* If the channel doesnt have the mode, or it does and it isn't set correctly */
|
||||
if (ml->set)
|
||||
{
|
||||
Anope::string param;
|
||||
this->GetParam(cm->name, param);
|
||||
|
||||
if (!this->HasMode(cm->name) || (!param.empty() && !ml->param.empty() && !param.equals_cs(ml->param)))
|
||||
this->SetMode(NULL, cm, ml->param);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this->HasMode(cm->name))
|
||||
this->RemoveMode(NULL, cm);
|
||||
}
|
||||
|
||||
}
|
||||
else if (cm->type == MODE_LIST)
|
||||
{
|
||||
if (ml->set)
|
||||
this->SetMode(NULL, cm, ml->param);
|
||||
else
|
||||
this->RemoveMode(NULL, cm, ml->param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Channel::CheckDelete()
|
||||
@@ -312,7 +270,7 @@ void Channel::SetModeInternal(MessageSource &setter, ChannelMode *cm, const Anop
|
||||
if (cc)
|
||||
cc->status.AddMode(cm->mchar);
|
||||
|
||||
FOREACH_RESULT(OnChannelModeSet, MOD_RESULT, (this, setter, cm->name, param));
|
||||
FOREACH_RESULT(OnChannelModeSet, MOD_RESULT, (this, setter, cm, param));
|
||||
|
||||
/* Enforce secureops, etc */
|
||||
if (enforce_mlock && MOD_RESULT != EVENT_STOP)
|
||||
@@ -336,7 +294,7 @@ void Channel::SetModeInternal(MessageSource &setter, ChannelMode *cm, const Anop
|
||||
cml->OnAdd(this, param);
|
||||
}
|
||||
|
||||
FOREACH_RESULT(OnChannelModeSet, MOD_RESULT, (this, setter, cm->name, param));
|
||||
FOREACH_RESULT(OnChannelModeSet, MOD_RESULT, (this, setter, cm, param));
|
||||
|
||||
/* Check if we should enforce mlock */
|
||||
if (!enforce_mlock || MOD_RESULT == EVENT_STOP)
|
||||
@@ -377,7 +335,7 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *cm, const A
|
||||
if (cc)
|
||||
cc->status.DelMode(cm->mchar);
|
||||
|
||||
FOREACH_RESULT(OnChannelModeUnset, MOD_RESULT, (this, setter, cm->name, param));
|
||||
FOREACH_RESULT(OnChannelModeUnset, MOD_RESULT, (this, setter, cm, param));
|
||||
|
||||
if (enforce_mlock && MOD_RESULT != EVENT_STOP)
|
||||
this->SetCorrectModes(u, false);
|
||||
@@ -404,7 +362,7 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *cm, const A
|
||||
cml->OnDel(this, param);
|
||||
}
|
||||
|
||||
FOREACH_RESULT(OnChannelModeUnset, MOD_RESULT, (this, setter, cm->name, param));
|
||||
FOREACH_RESULT(OnChannelModeUnset, MOD_RESULT, (this, setter, cm, param));
|
||||
|
||||
/* Check for mlock */
|
||||
if (!enforce_mlock || MOD_RESULT == EVENT_STOP)
|
||||
@@ -865,26 +823,6 @@ void Channel::SetCorrectModes(User *user, bool give_modes)
|
||||
this->RemoveMode(NULL, cm, user->GetUID());
|
||||
}
|
||||
}
|
||||
|
||||
// Check mlock
|
||||
for (ChannelInfo::ModeList::const_iterator it = ci->GetMLock().begin(), it_end = ci->GetMLock().end(); it != it_end; ++it)
|
||||
{
|
||||
const ModeLock *ml = it->second;
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name);
|
||||
if (!cm || cm->type != MODE_STATUS)
|
||||
continue;
|
||||
|
||||
if (Anope::Match(user->nick, ml->param) || Anope::Match(user->GetDisplayedMask(), ml->param))
|
||||
{
|
||||
if (ml->set != this->HasUserStatus(user, ml->name))
|
||||
{
|
||||
if (ml->set)
|
||||
this->SetMode(NULL, cm, user->GetUID(), false);
|
||||
else if (!ml->set)
|
||||
this->RemoveMode(NULL, cm, user->GetUID(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Channel::Unban(User *u, bool full)
|
||||
|
||||
+2
-2
@@ -339,7 +339,7 @@ Conf::Conf() : Block("")
|
||||
if (!c)
|
||||
continue; // Can't happen
|
||||
|
||||
c->Extend("BOTCHANNEL");
|
||||
c->botchannel = true;
|
||||
|
||||
/* Remove all existing modes */
|
||||
ChanUserContainer *cu = c->FindUser(bi);
|
||||
@@ -377,7 +377,7 @@ Conf::Conf() : Block("")
|
||||
Channel *c = Channel::Find(chname);
|
||||
if (c)
|
||||
{
|
||||
c->Shrink("BOTCHANNEL");
|
||||
c->botchannel = false;
|
||||
bi->Part(c);
|
||||
}
|
||||
}
|
||||
|
||||
+43
-76
@@ -10,96 +10,63 @@
|
||||
|
||||
#include "extensible.h"
|
||||
|
||||
Extensible::Extensible() : extension_items(NULL)
|
||||
static std::set<ExtensibleBase *> extensible_items;
|
||||
|
||||
ExtensibleBase::ExtensibleBase(Module *m, const Anope::string &n) : Service(m, "Extensible", n)
|
||||
{
|
||||
extensible_items.insert(this);
|
||||
}
|
||||
|
||||
ExtensibleBase::~ExtensibleBase()
|
||||
{
|
||||
extensible_items.erase(this);
|
||||
}
|
||||
|
||||
Extensible::~Extensible()
|
||||
{
|
||||
if (extension_items)
|
||||
{
|
||||
for (extensible_map::iterator it = extension_items->begin(), it_end = extension_items->end(); it != it_end; ++it)
|
||||
delete it->second;
|
||||
delete extension_items;
|
||||
}
|
||||
for (std::set<ExtensibleBase *>::iterator it = extension_items.begin(); it != extension_items.end(); ++it)
|
||||
(*it)->Unset(this);
|
||||
}
|
||||
|
||||
void Extensible::Extend(const Anope::string &key, ExtensibleItem *p)
|
||||
bool Extensible::HasExt(const Anope::string &name) const
|
||||
{
|
||||
this->Shrink(key);
|
||||
if (!extension_items)
|
||||
extension_items = new extensible_map();
|
||||
(*this->extension_items)[key] = p;
|
||||
}
|
||||
|
||||
void Extensible::ExtendMetadata(const Anope::string &key, const Anope::string &value)
|
||||
{
|
||||
this->Extend(key, new ExtensibleMetadata(!value.empty() ? value : "1"));
|
||||
}
|
||||
|
||||
bool Extensible::Shrink(const Anope::string &key)
|
||||
{
|
||||
if (!extension_items)
|
||||
return false;
|
||||
|
||||
extensible_map::iterator it = this->extension_items->find(key);
|
||||
if (it != this->extension_items->end())
|
||||
{
|
||||
delete it->second;
|
||||
/* map::size_type map::erase( const key_type& key );
|
||||
* returns the number of elements removed, std::map
|
||||
* is single-associative so this should only be 0 or 1
|
||||
*/
|
||||
return this->extension_items->erase(key) > 0;
|
||||
}
|
||||
ExtensibleRef<void *> ref(name);
|
||||
if (ref)
|
||||
return ref->HasExt(this);
|
||||
|
||||
Log(LOG_DEBUG) << "HasExt for nonexistent type " << name << " on " << static_cast<const void *>(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Extensible::HasExt(const Anope::string &key) const
|
||||
void Extensible::ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data)
|
||||
{
|
||||
return this->extension_items != NULL && this->extension_items->count(key) > 0;
|
||||
}
|
||||
|
||||
void Extensible::GetExtList(std::deque<Anope::string> &list) const
|
||||
{
|
||||
if (extension_items)
|
||||
for (extensible_map::const_iterator it = extension_items->begin(), it_end = extension_items->end(); it != it_end; ++it)
|
||||
list.push_back(it->first);
|
||||
}
|
||||
|
||||
void Extensible::ExtensibleSerialize(Serialize::Data &data) const
|
||||
{
|
||||
if (extension_items)
|
||||
for (extensible_map::const_iterator it = extension_items->begin(), it_end = extension_items->end(); it != it_end; ++it)
|
||||
if (it->second && it->second->Serialize())
|
||||
data["extensible:" + it->first] << *it->second->Serialize();
|
||||
}
|
||||
|
||||
void Extensible::ExtensibleUnserialize(Serialize::Data &data)
|
||||
{
|
||||
/* Shrink existing extensible metadata items */
|
||||
std::deque<Anope::string> list;
|
||||
this->GetExtList(list);
|
||||
for (unsigned i = 0; i < list.size(); ++i)
|
||||
for (std::set<ExtensibleBase *>::iterator it = e->extension_items.begin(); it != e->extension_items.end(); ++it)
|
||||
{
|
||||
ExtensibleItem *item = extension_items->at(list[i]);
|
||||
if (item && item->Serialize())
|
||||
this->Shrink(list[i]);
|
||||
ExtensibleBase *eb = *it;
|
||||
eb->ExtensibleSerialize(e, s, data);
|
||||
}
|
||||
|
||||
std::set<Anope::string> keys = data.KeySet();
|
||||
for (std::set<Anope::string>::iterator it = keys.begin(), it_end = keys.end(); it != it_end; ++it)
|
||||
if (it->find("extensible:") == 0)
|
||||
{
|
||||
if (!extension_items)
|
||||
extension_items = new extensible_map();
|
||||
|
||||
Anope::string str;
|
||||
data[*it] >> str;
|
||||
|
||||
if (!str.empty())
|
||||
this->ExtendMetadata(it->substr(11), str);
|
||||
}
|
||||
}
|
||||
|
||||
void Extensible::ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data)
|
||||
{
|
||||
while (!e->extension_items.empty())
|
||||
(*e->extension_items.begin())->Unset(e);
|
||||
|
||||
for (std::set<ExtensibleBase *>::iterator it = extensible_items.begin(); it != extensible_items.end(); ++it)
|
||||
{
|
||||
ExtensibleBase *eb = *it;
|
||||
eb->ExtensibleUnserialize(e, s, data);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
bool* Extensible::Extend(const Anope::string &name, const bool &what)
|
||||
{
|
||||
ExtensibleRef<bool> ref(name);
|
||||
if (ref)
|
||||
return ref->Set(this);
|
||||
|
||||
Log(LOG_DEBUG) << "Shrink for nonexistant type " << name << " on " << static_cast<void *>(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
+20
-1
@@ -220,7 +220,7 @@ void InfoFormatter::Process(std::vector<Anope::string> &buffer)
|
||||
Anope::string s;
|
||||
for (unsigned i = it->first.length(); i < this->longest; ++i)
|
||||
s += " ";
|
||||
s += Anope::string(Language::Translate(this->nc, it->first.c_str())) + ": " + it->second;
|
||||
s += Anope::string(Language::Translate(this->nc, it->first.c_str())) + ": " + Language::Translate(this->nc, it->second.c_str());
|
||||
|
||||
buffer.push_back(s);
|
||||
}
|
||||
@@ -234,6 +234,25 @@ Anope::string& InfoFormatter::operator[](const Anope::string &key)
|
||||
return this->replies.back().second;
|
||||
}
|
||||
|
||||
void InfoFormatter::AddOption(const Anope::string &opt)
|
||||
{
|
||||
Anope::string *optstr = NULL;
|
||||
for (std::vector<std::pair<Anope::string, Anope::string> >::iterator it = this->replies.begin(), it_end = this->replies.end(); it != it_end; ++it)
|
||||
{
|
||||
if (it->first == "Options")
|
||||
{
|
||||
optstr = &it->second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!optstr)
|
||||
optstr = &(*this)["Options"];
|
||||
|
||||
if (!optstr->empty())
|
||||
*optstr += ", ";
|
||||
*optstr += Language::Translate(nc, opt.c_str());
|
||||
}
|
||||
|
||||
bool Anope::IsFile(const Anope::string &filename)
|
||||
{
|
||||
struct stat fileinfo;
|
||||
|
||||
+2
-11
@@ -140,7 +140,7 @@ void NickAlias::Serialize(Serialize::Data &data) const
|
||||
data.SetType("time_registered", Serialize::Data::DT_INT); data["time_registered"] << this->time_registered;
|
||||
data.SetType("time_registered", Serialize::Data::DT_INT); data["last_seen"] << this->last_seen;
|
||||
data["nc"] << this->nc->display;
|
||||
this->ExtensibleSerialize(data);
|
||||
Extensible::ExtensibleSerialize(this, this, data);
|
||||
|
||||
if (this->HasVhost())
|
||||
{
|
||||
@@ -189,7 +189,7 @@ Serializable* NickAlias::Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
data["last_realhost"] >> na->last_realhost;
|
||||
data["time_registered"] >> na->time_registered;
|
||||
data["last_seen"] >> na->last_seen;
|
||||
na->ExtensibleUnserialize(data);
|
||||
Extensible::ExtensibleUnserialize(na, na, data);
|
||||
|
||||
Anope::string vhost_ident, vhost_host, vhost_creator;
|
||||
time_t vhost_time;
|
||||
@@ -201,15 +201,6 @@ Serializable* NickAlias::Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
|
||||
na->SetVhost(vhost_ident, vhost_host, vhost_creator, vhost_time);
|
||||
|
||||
/* Compat */
|
||||
Anope::string sflags;
|
||||
data["flags"] >> sflags;
|
||||
spacesepstream sep(sflags);
|
||||
Anope::string tok;
|
||||
while (sep.GetToken(tok))
|
||||
na->ExtendMetadata(tok);
|
||||
/* End compat */
|
||||
|
||||
return na;
|
||||
}
|
||||
|
||||
|
||||
+11
-61
@@ -67,13 +67,10 @@ void NickCore::Serialize(Serialize::Data &data) const
|
||||
data["display"] << this->display;
|
||||
data["pass"] << this->pass;
|
||||
data["email"] << this->email;
|
||||
data["greet"] << this->greet;
|
||||
data["language"] << this->language;
|
||||
this->ExtensibleSerialize(data);
|
||||
Extensible::ExtensibleSerialize(this, this, data);
|
||||
for (unsigned i = 0; i < this->access.size(); ++i)
|
||||
data["access"] << this->access[i] << " ";
|
||||
for (unsigned i = 0; i < this->cert.size(); ++i)
|
||||
data["cert"] << this->cert[i] << " ";
|
||||
data["memomax"] << this->memos.memomax;
|
||||
for (unsigned i = 0; i < this->memos.ignores.size(); ++i)
|
||||
data["memoignores"] << this->memos.ignores[i] << " ";
|
||||
@@ -94,9 +91,8 @@ Serializable* NickCore::Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
|
||||
data["pass"] >> nc->pass;
|
||||
data["email"] >> nc->email;
|
||||
data["greet"] >> nc->greet;
|
||||
data["language"] >> nc->language;
|
||||
nc->ExtensibleUnserialize(data);
|
||||
Extensible::ExtensibleUnserialize(nc, nc, data);
|
||||
{
|
||||
Anope::string buf;
|
||||
data["access"] >> buf;
|
||||
@@ -105,14 +101,6 @@ Serializable* NickCore::Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
while (sep.GetToken(buf))
|
||||
nc->access.push_back(buf);
|
||||
}
|
||||
{
|
||||
Anope::string buf;
|
||||
data["cert"] >> buf;
|
||||
spacesepstream sep(buf);
|
||||
nc->cert.clear();
|
||||
while (sep.GetToken(buf))
|
||||
nc->cert.push_back(buf);
|
||||
}
|
||||
data["memomax"] >> nc->memos.memomax;
|
||||
{
|
||||
Anope::string buf;
|
||||
@@ -123,14 +111,15 @@ Serializable* NickCore::Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
nc->memos.ignores.push_back(buf);
|
||||
}
|
||||
|
||||
/* Compat */
|
||||
Anope::string sflags;
|
||||
data["flags"] >> sflags;
|
||||
spacesepstream sep(sflags);
|
||||
Anope::string tok;
|
||||
while (sep.GetToken(tok))
|
||||
nc->ExtendMetadata(tok);
|
||||
/* End compat */
|
||||
/* compat */
|
||||
bool b;
|
||||
data["extensible:SECURE"] >> b;
|
||||
if (b)
|
||||
nc->Extend<bool>("NS_SECURE");
|
||||
data["extensible:PRIVATE"] >> b;
|
||||
if (b)
|
||||
nc->Extend<bool>("NS_PRIVATE");
|
||||
/* end compat */
|
||||
|
||||
return nc;
|
||||
}
|
||||
@@ -216,45 +205,6 @@ bool NickCore::IsOnAccess(const User *u) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void NickCore::AddCert(const Anope::string &entry)
|
||||
{
|
||||
this->cert.push_back(entry);
|
||||
FOREACH_MOD(OnNickAddCert, (this, entry));
|
||||
}
|
||||
|
||||
Anope::string NickCore::GetCert(unsigned entry) const
|
||||
{
|
||||
if (this->cert.empty() || entry >= this->cert.size())
|
||||
return "";
|
||||
return this->cert[entry];
|
||||
}
|
||||
|
||||
bool NickCore::FindCert(const Anope::string &entry) const
|
||||
{
|
||||
for (unsigned i = 0, end = this->cert.size(); i < end; ++i)
|
||||
if (this->cert[i] == entry)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void NickCore::EraseCert(const Anope::string &entry)
|
||||
{
|
||||
for (unsigned i = 0, end = this->cert.size(); i < end; ++i)
|
||||
if (this->cert[i] == entry)
|
||||
{
|
||||
FOREACH_MOD(OnNickEraseCert, (this, entry));
|
||||
this->cert.erase(this->cert.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NickCore::ClearCert()
|
||||
{
|
||||
FOREACH_MOD(OnNickClearCert, (this));
|
||||
this->cert.clear();
|
||||
}
|
||||
|
||||
void NickCore::AddChannelReference(ChannelInfo *ci)
|
||||
{
|
||||
++(*this->chanaccess)[ci];
|
||||
|
||||
+14
-484
@@ -22,54 +22,6 @@
|
||||
|
||||
Serialize::Checker<registered_channel_map> RegisteredChannelList("ChannelInfo");
|
||||
|
||||
BadWord::BadWord() : Serializable("BadWord")
|
||||
{
|
||||
}
|
||||
|
||||
BadWord::~BadWord()
|
||||
{
|
||||
if (this->ci)
|
||||
{
|
||||
std::vector<BadWord *>::iterator it = std::find(this->ci->badwords->begin(), this->ci->badwords->end(), this);
|
||||
if (it != this->ci->badwords->end())
|
||||
this->ci->badwords->erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void BadWord::Serialize(Serialize::Data &data) const
|
||||
{
|
||||
data["ci"] << this->ci->name;
|
||||
data["word"] << this->word;
|
||||
data.SetType("type", Serialize::Data::DT_INT); data["type"] << this->type;
|
||||
}
|
||||
|
||||
Serializable* BadWord::Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
{
|
||||
Anope::string sci, sword;
|
||||
|
||||
data["ci"] >> sci;
|
||||
data["word"] >> sword;
|
||||
|
||||
ChannelInfo *ci = ChannelInfo::Find(sci);
|
||||
if (!ci)
|
||||
return NULL;
|
||||
|
||||
unsigned int n;
|
||||
data["type"] >> n;
|
||||
|
||||
BadWord *bw;
|
||||
if (obj)
|
||||
{
|
||||
bw = anope_dynamic_static_cast<BadWord *>(obj);
|
||||
data["word"] >> bw->word;
|
||||
bw->type = static_cast<BadWordType>(n);
|
||||
}
|
||||
else
|
||||
bw = ci->AddBadWord(sword, static_cast<BadWordType>(n));
|
||||
|
||||
return bw;
|
||||
}
|
||||
|
||||
AutoKick::AutoKick() : Serializable("AutoKick")
|
||||
{
|
||||
}
|
||||
@@ -145,122 +97,8 @@ Serializable* AutoKick::Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
return ak;
|
||||
}
|
||||
|
||||
ModeLock::ModeLock(ChannelInfo *ch, bool s, const Anope::string &n, const Anope::string &p, const Anope::string &se, time_t c) : Serializable("ModeLock"), ci(ch), set(s), name(n), param(p), setter(se), created(c)
|
||||
{
|
||||
}
|
||||
|
||||
ModeLock::~ModeLock()
|
||||
{
|
||||
if (this->ci)
|
||||
this->ci->RemoveMLock(this);
|
||||
}
|
||||
|
||||
void ModeLock::Serialize(Serialize::Data &data) const
|
||||
{
|
||||
if (!this->ci)
|
||||
return;
|
||||
|
||||
data["ci"] << this->ci->name;
|
||||
data["set"] << this->set;
|
||||
data["name"] << this->name;
|
||||
data["param"] << this->param;
|
||||
data["setter"] << this->setter;
|
||||
data.SetType("created", Serialize::Data::DT_INT); data["created"] << this->created;
|
||||
}
|
||||
|
||||
Serializable* ModeLock::Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
{
|
||||
Anope::string sci;
|
||||
|
||||
data["ci"] >> sci;
|
||||
|
||||
ChannelInfo *ci = ChannelInfo::Find(sci);
|
||||
if (!ci)
|
||||
return NULL;
|
||||
|
||||
ModeLock *ml;
|
||||
if (obj)
|
||||
{
|
||||
ml = anope_dynamic_static_cast<ModeLock *>(obj);
|
||||
|
||||
data["set"] >> ml->set;
|
||||
data["name"] >> ml->name;
|
||||
data["param"] >> ml->param;
|
||||
data["setter"] >> ml->setter;
|
||||
data["created"] >> ml->created;
|
||||
return ml;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool set;
|
||||
data["set"] >> set;
|
||||
|
||||
time_t created;
|
||||
data["created"] >> created;
|
||||
|
||||
Anope::string setter;
|
||||
data["setter"] >> setter;
|
||||
|
||||
Anope::string sname;
|
||||
data["name"] >> sname;
|
||||
|
||||
ml = new ModeLock(ci, set, sname, "", setter, created);
|
||||
data["param"] >> ml->param;
|
||||
|
||||
ci->mode_locks->insert(std::make_pair(ml->name, ml));
|
||||
return ml;
|
||||
}
|
||||
}
|
||||
|
||||
void LogSetting::Serialize(Serialize::Data &data) const
|
||||
{
|
||||
if (!ci)
|
||||
return;
|
||||
|
||||
data["ci"] << ci->name;
|
||||
data["service_name"] << service_name;
|
||||
data["command_service"] << command_service;
|
||||
data["command_name"] << command_name;
|
||||
data["method"] << method;
|
||||
data["extra"] << extra;
|
||||
data["creator"] << creator;
|
||||
data.SetType("created", Serialize::Data::DT_INT); data["created"] << created;
|
||||
}
|
||||
|
||||
Serializable* LogSetting::Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
{
|
||||
Anope::string sci;
|
||||
|
||||
data["ci"] >> sci;
|
||||
|
||||
ChannelInfo *ci = ChannelInfo::Find(sci);
|
||||
if (ci == NULL)
|
||||
return NULL;
|
||||
|
||||
LogSetting *ls;
|
||||
if (obj)
|
||||
ls = anope_dynamic_static_cast<LogSetting *>(obj);
|
||||
else
|
||||
{
|
||||
ls = new LogSetting();
|
||||
ci->log_settings->push_back(ls);
|
||||
}
|
||||
|
||||
ls->ci = ci;
|
||||
data["service_name"] >> ls->service_name;
|
||||
data["command_service"] >> ls->command_service;
|
||||
data["command_name"] >> ls->command_name;
|
||||
data["method"] >> ls->method;
|
||||
data["extra"] >> ls->extra;
|
||||
data["creator"] >> ls->creator;
|
||||
data["created"] >> ls->created;
|
||||
|
||||
return ls;
|
||||
}
|
||||
|
||||
ChannelInfo::ChannelInfo(const Anope::string &chname) : Serializable("ChannelInfo"),
|
||||
access("ChanAccess"), akick("AutoKick"),
|
||||
badwords("BadWord"), mode_locks("ModeLock"), log_settings("LogSetting")
|
||||
access("ChanAccess"), akick("AutoKick")
|
||||
{
|
||||
if (chname.empty())
|
||||
throw CoreException("Empty channel passed to ChannelInfo constructor");
|
||||
@@ -270,9 +108,6 @@ ChannelInfo::ChannelInfo(const Anope::string &chname) : Serializable("ChannelInf
|
||||
this->c = Channel::Find(chname);
|
||||
if (this->c)
|
||||
this->c->ci = this;
|
||||
this->capsmin = this->capspercent = 0;
|
||||
this->floodlines = this->floodsecs = 0;
|
||||
this->repeattimes = 0;
|
||||
this->banexpire = 0;
|
||||
this->bi = NULL;
|
||||
this->last_topic_time = 0;
|
||||
@@ -283,9 +118,6 @@ ChannelInfo::ChannelInfo(const Anope::string &chname) : Serializable("ChannelInf
|
||||
this->memos.memomax = 0;
|
||||
this->last_used = this->time_registered = Anope::CurTime;
|
||||
|
||||
for (int i = 0; i < TTB_SIZE; ++i)
|
||||
this->ttb[i] = 0;
|
||||
|
||||
size_t old = RegisteredChannelList->size();
|
||||
(*RegisteredChannelList)[this->name] = this;
|
||||
if (old == RegisteredChannelList->size())
|
||||
@@ -295,8 +127,7 @@ ChannelInfo::ChannelInfo(const Anope::string &chname) : Serializable("ChannelInf
|
||||
}
|
||||
|
||||
ChannelInfo::ChannelInfo(const ChannelInfo &ci) : Serializable("ChannelInfo"),
|
||||
access("ChanAccess"), akick("AutoKick"),
|
||||
badwords("BadWord"), mode_locks("ModeLock"), log_settings("LogSetting")
|
||||
access("ChanAccess"), akick("AutoKick")
|
||||
{
|
||||
*this = ci;
|
||||
|
||||
@@ -305,10 +136,6 @@ ChannelInfo::ChannelInfo(const ChannelInfo &ci) : Serializable("ChannelInfo"),
|
||||
|
||||
this->access->clear();
|
||||
this->akick->clear();
|
||||
this->badwords->clear();
|
||||
|
||||
for (int i = 0; i < TTB_SIZE; ++i)
|
||||
this->ttb[i] = ci.ttb[i];
|
||||
|
||||
for (unsigned i = 0; i < ci.GetAccessCount(); ++i)
|
||||
{
|
||||
@@ -334,18 +161,6 @@ ChannelInfo::ChannelInfo(const ChannelInfo &ci) : Serializable("ChannelInfo"),
|
||||
else
|
||||
this->AddAkick(takick->creator, takick->mask, takick->reason, takick->addtime, takick->last_used);
|
||||
}
|
||||
for (unsigned i = 0; i < ci.GetBadWordCount(); ++i)
|
||||
{
|
||||
const BadWord *bw = ci.GetBadWord(i);
|
||||
this->AddBadWord(bw->word, bw->type);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < ci.log_settings->size(); ++i)
|
||||
{
|
||||
LogSetting *l = new LogSetting(*ci.log_settings->at(i));
|
||||
l->ci = this;
|
||||
this->log_settings->push_back(l);
|
||||
}
|
||||
|
||||
FOREACH_MOD(OnCreateChan, (this));
|
||||
}
|
||||
@@ -379,14 +194,6 @@ ChannelInfo::~ChannelInfo()
|
||||
|
||||
this->ClearAccess();
|
||||
this->ClearAkick();
|
||||
this->ClearBadWords();
|
||||
|
||||
for (unsigned i = 0; i < this->log_settings->size(); ++i)
|
||||
delete this->log_settings->at(i);
|
||||
this->log_settings->clear();
|
||||
|
||||
while (!this->mode_locks->empty())
|
||||
delete this->mode_locks->begin()->second;
|
||||
|
||||
if (!this->memos.memos->empty())
|
||||
{
|
||||
@@ -413,7 +220,7 @@ void ChannelInfo::Serialize(Serialize::Data &data) const
|
||||
data["last_topic_setter"] << this->last_topic_setter;
|
||||
data.SetType("last_topic_time", Serialize::Data::DT_INT); data["last_topic_time"] << this->last_topic_time;
|
||||
data.SetType("bantype", Serialize::Data::DT_INT); data["bantype"] << this->bantype;
|
||||
this->ExtensibleSerialize(data);
|
||||
Extensible::ExtensibleSerialize(this, this, data);
|
||||
{
|
||||
Anope::string levels_buffer;
|
||||
for (Anope::map<int16_t>::const_iterator it = this->levels.begin(), it_end = this->levels.end(); it != it_end; ++it)
|
||||
@@ -422,13 +229,6 @@ void ChannelInfo::Serialize(Serialize::Data &data) const
|
||||
}
|
||||
if (this->bi)
|
||||
data["bi"] << this->bi->nick;
|
||||
for (int i = 0; i < TTB_SIZE; ++i)
|
||||
data["ttb"] << this->ttb[i] << " ";
|
||||
data.SetType("capsmin", Serialize::Data::DT_INT); data["capsmin"] << this->capsmin;
|
||||
data.SetType("capspercent", Serialize::Data::DT_INT); data["capspercent"] << this->capspercent;
|
||||
data.SetType("floodlines", Serialize::Data::DT_INT); data["floodlines"] << this->floodlines;
|
||||
data.SetType("floodsecs", Serialize::Data::DT_INT); data["floodsecs"] << this->floodsecs;
|
||||
data.SetType("repeattimes", Serialize::Data::DT_INT); data["repeattimes"] << this->repeattimes;
|
||||
data.SetType("banexpire", Serialize::Data::DT_INT); data["banexpire"] << this->banexpire;
|
||||
data["memomax"] << this->memos.memomax;
|
||||
for (unsigned i = 0; i < this->memos.ignores.size(); ++i)
|
||||
@@ -451,7 +251,7 @@ Serializable* ChannelInfo::Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
else
|
||||
ci = new ChannelInfo(sname);
|
||||
|
||||
ci->ExtensibleUnserialize(data);
|
||||
Extensible::ExtensibleUnserialize(ci, ci, data);
|
||||
|
||||
ci->SetFounder(NickCore::Find(sfounder));
|
||||
ci->SetSuccessor(NickCore::Find(ssuccessor));
|
||||
@@ -477,23 +277,6 @@ Serializable* ChannelInfo::Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
else if (ci->bi)
|
||||
ci->bi->UnAssign(NULL, ci);
|
||||
}
|
||||
{
|
||||
Anope::string ttb, tok;
|
||||
data["ttb"] >> ttb;
|
||||
spacesepstream sep(ttb);
|
||||
for (int i = 0; sep.GetToken(tok) && i < TTB_SIZE; ++i)
|
||||
try
|
||||
{
|
||||
ci->ttb[i] = convertTo<int16_t>(tok);
|
||||
}
|
||||
catch (const ConvertException &) { }
|
||||
|
||||
}
|
||||
data["capsmin"] >> ci->capsmin;
|
||||
data["capspercent"] >> ci->capspercent;
|
||||
data["floodlines"] >> ci->floodlines;
|
||||
data["floodsecs"] >> ci->floodsecs;
|
||||
data["repeattimes"] >> ci->repeattimes;
|
||||
data["banexpire"] >> ci->banexpire;
|
||||
data["memomax"] >> ci->memos.memomax;
|
||||
{
|
||||
@@ -505,18 +288,15 @@ Serializable* ChannelInfo::Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
ci->memos.ignores.push_back(buf);
|
||||
}
|
||||
|
||||
/* Compat */
|
||||
Anope::string sflags, sbotflags;
|
||||
data["flags"] >> sflags;
|
||||
data["botflags"] >> sbotflags;
|
||||
spacesepstream sep(sflags);
|
||||
Anope::string tok;
|
||||
while (sep.GetToken(tok))
|
||||
ci->ExtendMetadata(tok);
|
||||
spacesepstream sep2(sbotflags);
|
||||
while (sep2.GetToken(tok))
|
||||
ci->ExtendMetadata("BS_" + tok);
|
||||
/* End compat */
|
||||
/* compat */
|
||||
bool b;
|
||||
data["extensible:SECURE"] >> b;
|
||||
if (b)
|
||||
ci->Extend<bool>("CS_SECURE");
|
||||
data["extensible:PRIVATE"] >> b;
|
||||
if (b)
|
||||
ci->Extend<bool>("CS_PRIVATE");
|
||||
/* end compat */
|
||||
|
||||
return ci;
|
||||
}
|
||||
@@ -603,7 +383,7 @@ AccessGroup ChannelInfo::AccessFor(const User *u)
|
||||
return group;
|
||||
|
||||
const NickCore *nc = u->Account();
|
||||
if (nc == NULL && !this->HasExt("SECURE") && u->IsRecognized())
|
||||
if (nc == NULL && !this->HasExt("NS_SECURE") && u->IsRecognized())
|
||||
{
|
||||
const NickAlias *na = NickAlias::Find(u->nick);
|
||||
if (na != NULL)
|
||||
@@ -756,256 +536,6 @@ void ChannelInfo::ClearAkick()
|
||||
delete this->akick->back();
|
||||
}
|
||||
|
||||
BadWord* ChannelInfo::AddBadWord(const Anope::string &word, BadWordType type)
|
||||
{
|
||||
BadWord *bw = new BadWord();
|
||||
bw->ci = this;
|
||||
bw->word = word;
|
||||
bw->type = type;
|
||||
|
||||
this->badwords->push_back(bw);
|
||||
|
||||
FOREACH_MOD(OnBadWordAdd, (this, bw));
|
||||
|
||||
return bw;
|
||||
}
|
||||
|
||||
BadWord* ChannelInfo::GetBadWord(unsigned index) const
|
||||
{
|
||||
if (this->badwords->empty() || index >= this->badwords->size())
|
||||
return NULL;
|
||||
|
||||
BadWord *bw = (*this->badwords)[index];
|
||||
bw->QueueUpdate();
|
||||
return bw;
|
||||
}
|
||||
|
||||
unsigned ChannelInfo::GetBadWordCount() const
|
||||
{
|
||||
return this->badwords->size();
|
||||
}
|
||||
|
||||
void ChannelInfo::EraseBadWord(unsigned index)
|
||||
{
|
||||
if (this->badwords->empty() || index >= this->badwords->size())
|
||||
return;
|
||||
|
||||
FOREACH_MOD(OnBadWordDel, (this, (*this->badwords)[index]));
|
||||
|
||||
delete this->badwords->at(index);
|
||||
}
|
||||
|
||||
void ChannelInfo::ClearBadWords()
|
||||
{
|
||||
while (!this->badwords->empty())
|
||||
delete this->badwords->back();
|
||||
}
|
||||
|
||||
bool ChannelInfo::HasMLock(ChannelMode *mode, const Anope::string ¶m, bool status) const
|
||||
{
|
||||
if (!mode)
|
||||
return false;
|
||||
|
||||
std::multimap<Anope::string, ModeLock *>::const_iterator it = this->mode_locks->find(mode->name);
|
||||
|
||||
if (it != this->mode_locks->end())
|
||||
{
|
||||
if (mode->type != MODE_REGULAR)
|
||||
{
|
||||
std::multimap<Anope::string, ModeLock *>::const_iterator it_end = this->mode_locks->upper_bound(mode->name);
|
||||
|
||||
for (; it != it_end; ++it)
|
||||
{
|
||||
const ModeLock *ml = it->second;
|
||||
if (ml->param == param)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
return it->second->set == status;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ChannelInfo::SetMLock(ChannelMode *mode, bool status, const Anope::string ¶m, Anope::string setter, time_t created)
|
||||
{
|
||||
if (!mode)
|
||||
return false;
|
||||
|
||||
if (setter.empty())
|
||||
setter = this->founder ? this->founder->display : "Unknown";
|
||||
std::pair<Anope::string, ModeLock *> ml = std::make_pair(mode->name, new ModeLock(this, status, mode->name, param, setter, created));
|
||||
|
||||
EventReturn MOD_RESULT;
|
||||
FOREACH_RESULT(OnMLock, MOD_RESULT, (this, ml.second));
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
return false;
|
||||
|
||||
/* First, remove this */
|
||||
if (mode->type == MODE_REGULAR || mode->type == MODE_PARAM)
|
||||
{
|
||||
for (ChannelInfo::ModeList::const_iterator it; (it = this->mode_locks->find(mode->name)) != this->mode_locks->end();)
|
||||
delete it->second;
|
||||
this->mode_locks->erase(mode->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
// For list or status modes, we must check the parameter
|
||||
ChannelInfo::ModeList::iterator it = this->mode_locks->find(mode->name);
|
||||
if (it != this->mode_locks->end())
|
||||
{
|
||||
ChannelInfo::ModeList::iterator it_end = this->mode_locks->upper_bound(mode->name);
|
||||
for (; it != it_end; ++it)
|
||||
{
|
||||
const ModeLock *modelock = it->second;
|
||||
if (modelock->param == param)
|
||||
{
|
||||
delete it->second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this->mode_locks->insert(ml);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChannelInfo::RemoveMLock(ChannelMode *mode, bool status, const Anope::string ¶m)
|
||||
{
|
||||
if (!mode)
|
||||
return false;
|
||||
|
||||
if (mode->type == MODE_REGULAR || mode->type == MODE_PARAM)
|
||||
{
|
||||
ChannelInfo::ModeList::iterator it = this->mode_locks->find(mode->name), it_end = this->mode_locks->upper_bound(mode->name), it_next = it;
|
||||
if (it != this->mode_locks->end())
|
||||
for (; it != it_end; it = it_next)
|
||||
{
|
||||
const ModeLock *ml = it->second;
|
||||
++it_next;
|
||||
|
||||
if (status != ml->set)
|
||||
continue;
|
||||
|
||||
EventReturn MOD_RESULT;
|
||||
FOREACH_RESULT(OnUnMLock, MOD_RESULT, (this, it->second));
|
||||
if (MOD_RESULT != EVENT_STOP)
|
||||
{
|
||||
delete it->second;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// For list or status modes, we must check the parameter
|
||||
ChannelInfo::ModeList::iterator it = this->mode_locks->find(mode->name);
|
||||
if (it != this->mode_locks->end())
|
||||
{
|
||||
ChannelInfo::ModeList::iterator it_end = this->mode_locks->upper_bound(mode->name);
|
||||
for (; it != it_end; ++it)
|
||||
{
|
||||
const ModeLock *ml = it->second;
|
||||
if (ml->set == status && ml->param == param)
|
||||
{
|
||||
EventReturn MOD_RESULT;
|
||||
FOREACH_RESULT(OnUnMLock, MOD_RESULT, (this, it->second));
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
return false;
|
||||
delete it->second;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelInfo::RemoveMLock(ModeLock *mlock)
|
||||
{
|
||||
ChannelInfo::ModeList::iterator it = this->mode_locks->find(mlock->name);
|
||||
if (it != this->mode_locks->end())
|
||||
for (; it != this->mode_locks->upper_bound(mlock->name); ++it)
|
||||
if (it->second == mlock)
|
||||
{
|
||||
this->mode_locks->erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelInfo::ClearMLock()
|
||||
{
|
||||
while (!this->mode_locks->empty())
|
||||
delete this->mode_locks->begin()->second;
|
||||
this->mode_locks->clear();
|
||||
}
|
||||
|
||||
const ChannelInfo::ModeList &ChannelInfo::GetMLock() const
|
||||
{
|
||||
return this->mode_locks;
|
||||
}
|
||||
|
||||
std::pair<ChannelInfo::ModeList::iterator, ChannelInfo::ModeList::iterator> ChannelInfo::GetModeList(const Anope::string &mname)
|
||||
{
|
||||
ChannelInfo::ModeList::iterator it = this->mode_locks->find(mname), it_end = it;
|
||||
if (it != this->mode_locks->end())
|
||||
it_end = this->mode_locks->upper_bound(mname);
|
||||
return std::make_pair(it, it_end);
|
||||
}
|
||||
|
||||
const ModeLock *ChannelInfo::GetMLock(const Anope::string &mname, const Anope::string ¶m)
|
||||
{
|
||||
ChannelInfo::ModeList::iterator it = this->mode_locks->find(mname);
|
||||
if (it != this->mode_locks->end())
|
||||
{
|
||||
if (param.empty())
|
||||
return it->second;
|
||||
else
|
||||
{
|
||||
ChannelInfo::ModeList::iterator it_end = this->mode_locks->upper_bound(mname);
|
||||
for (; it != it_end; ++it)
|
||||
{
|
||||
if (Anope::Match(param, it->second->param))
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Anope::string ChannelInfo::GetMLockAsString(bool complete) const
|
||||
{
|
||||
Anope::string pos = "+", neg = "-", params;
|
||||
|
||||
for (ChannelInfo::ModeList::const_iterator it = this->GetMLock().begin(), it_end = this->GetMLock().end(); it != it_end; ++it)
|
||||
{
|
||||
const ModeLock *ml = it->second;
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name);
|
||||
if (!cm || cm->type == MODE_LIST || cm->type == MODE_STATUS)
|
||||
continue;
|
||||
|
||||
if (ml->set)
|
||||
pos += cm->mchar;
|
||||
else
|
||||
neg += cm->mchar;
|
||||
|
||||
if (complete && !ml->param.empty() && cm->type == MODE_PARAM)
|
||||
params += " " + ml->param;
|
||||
}
|
||||
|
||||
if (pos.length() == 1)
|
||||
pos.clear();
|
||||
if (neg.length() == 1)
|
||||
neg.clear();
|
||||
|
||||
return pos + neg + params;
|
||||
}
|
||||
|
||||
int16_t ChannelInfo::GetLevel(const Anope::string &priv) const
|
||||
{
|
||||
if (PrivilegeManager::FindPrivilege(priv) == NULL)
|
||||
|
||||
+2
-3
@@ -30,9 +30,8 @@ std::list<Serializable *> *Serializable::SerializableItems;
|
||||
void Serialize::RegisterTypes()
|
||||
{
|
||||
static Type nc("NickCore", NickCore::Unserialize), na("NickAlias", NickAlias::Unserialize), bi("BotInfo", BotInfo::Unserialize),
|
||||
ci("ChannelInfo", ChannelInfo::Unserialize), access("ChanAccess", ChanAccess::Unserialize), logsetting("LogSetting", LogSetting::Unserialize),
|
||||
modelock("ModeLock", ModeLock::Unserialize), akick("AutoKick", AutoKick::Unserialize), badword("BadWord", BadWord::Unserialize),
|
||||
memo("Memo", Memo::Unserialize), xline("XLine", XLine::Unserialize);
|
||||
ci("ChannelInfo", ChannelInfo::Unserialize), access("ChanAccess", ChanAccess::Unserialize),
|
||||
akick("AutoKick", AutoKick::Unserialize), memo("Memo", Memo::Unserialize), xline("XLine", XLine::Unserialize);
|
||||
}
|
||||
|
||||
void Serialize::CheckTypes()
|
||||
|
||||
+1
-1
@@ -259,7 +259,7 @@ bool cidr::match(const sockaddrs &other)
|
||||
if (byte)
|
||||
{
|
||||
uint8_t m = ~0 << (8 - byte);
|
||||
return *ip & m == *their_ip & m;
|
||||
return (*ip & m) == (*their_ip & m);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
+3
-2
@@ -301,7 +301,6 @@ void User::Identify(NickAlias *na)
|
||||
}
|
||||
|
||||
this->Login(na->nc);
|
||||
IRCD->SendLogin(this);
|
||||
|
||||
FOREACH_MOD(OnNickIdentify, (this));
|
||||
|
||||
@@ -336,6 +335,8 @@ void User::Login(NickCore *core)
|
||||
|
||||
this->UpdateHost();
|
||||
|
||||
IRCD->SendLogin(this);
|
||||
|
||||
if (this->server->IsSynced())
|
||||
Log(this, "account") << "is now identified as " << this->nc->display;
|
||||
|
||||
@@ -378,7 +379,7 @@ bool User::IsRecognized(bool check_secure) const
|
||||
{
|
||||
const NickAlias *na = NickAlias::Find(this->nick);
|
||||
|
||||
if (!na || na->nc->HasExt("SECURE"))
|
||||
if (!na || na->nc->HasExt("NS_SECURE"))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user