diff options
| author | Adam <Adam@anope.org> | 2015-09-06 16:47:57 -0400 |
|---|---|---|
| committer | Adam <Adam@anope.org> | 2015-09-06 16:48:25 -0400 |
| commit | c6a92296d4175a2d2276c2d5a46894af3d9085f4 (patch) | |
| tree | 8e6dfe9fd21825f53a1e32641bc71e701e6c853e | |
| parent | 263dc290d296af2fcdf7f8a9f04735935e9c2580 (diff) | |
Allow configuring modes
34 files changed, 2545 insertions, 1202 deletions
diff --git a/data/bahamut.example.conf b/data/bahamut.example.conf new file mode 100644 index 000000000..e43e2409f --- /dev/null +++ b/data/bahamut.example.conf @@ -0,0 +1,170 @@ + +module +{ + name = "bahamut" +} + +usermode +{ + name = "SERV_ADMIN" + character = "A" + oper_only = yes +} + +usermode +{ + name = "REGPRIF" + character = "R" +} + +usermode +{ + name = "INVIS" + character = "i" +} + +usermode +{ + name = "OPER" + character = "o" + oper_only = yes +} + +usermode +{ + name = "REGISTERED" + character = "r" + setable = no +} + +usermode +{ + name = "SNOMASK" + character = "s" +} + +usermode +{ + name = "WALLOPS" + character = "w" +} + +usermode +{ + name = "DEAF" + character = "d" +} + +channelmode +{ + name = "BAN" + character = "b" + list = yes +} + +channelmode +{ + name = "VOICE" + character = "v" + status = "+" + level = 1 +} + +channelmode +{ + name = "OP" + character = "o" + status = "@" + level = 2 +} + +channelmode +{ + name = "BLOCKCOLOR" + character = "c" +} + +channelmode +{ + name = "INVITE" + character = "i" +} + +channelmode +{ + name = "FLOOD" + character = "f" + param_regex = "\*?\d+:\d+" +} + +channelmode +{ + name = "KEY" + character = "k" + param_regex = "[^:,]+" +} + +channelmode +{ + name = "LIMIT" + character = "l" + param_regex = "\d+" + param_unset = no +} + +channelmode +{ + name = "MODERATED" + character = "m" +} + +channelmode +{ + name = "NOEXTERNAL" + character = "n" +} + +channelmode +{ + name = "PRIVATE" + character = "p" +} + +channelmode +{ + name = "REGISTERED" + character = "r" + setable = no +} + +channelmode +{ + name = "SECRET" + character = "s" +} + +channelmode +{ + name = "TOPIC" + character = "t" +} + +channelmode +{ + name = "REGMODERATED" + character = "M" +} + +channelmode +{ + name = "OPERONLY" + character = "O" + oper_only = yes +} + +channelmode +{ + name = "REGISTEREDONLY" + character = "R" +} + diff --git a/data/botserv.example.conf b/data/botserv.example.conf index fbb8f166d..83154e0c4 100644 --- a/data/botserv.example.conf +++ b/data/botserv.example.conf @@ -52,13 +52,21 @@ service #modes = "+o" /* - * An optional comma separated list of channels this service should join. Outside - * of log channels this is not very useful, as the service will just idle in the - * specified channels, and will not accept any types of commands. + * Channels this service should join. Outside of log channels this is not very useful, + * as the service will just idle in the specified channels, and will not accept any types of commands. * - * Prefixes may be given to the channels in the form of mode characters or prefix symbols. + * Status modes mave be given for the channel in the form of mode characters or prefix symbols. */ - #channels = "@#services,#mychan" + channel + { + modes = "o" + name = "#services" + } + + channel + { + name = "#mychan" + } } /* diff --git a/data/chanserv.example.conf b/data/chanserv.example.conf index 474d9d052..aa336f1e4 100644 --- a/data/chanserv.example.conf +++ b/data/chanserv.example.conf @@ -40,15 +40,6 @@ service * unable to do certain things if this option is enabled. */ #modes = "+o" - - /* - * An optional comma separated list of channels this service should join. Outside - * of log channels this is not very useful, as the service will just idle in the - * specified channels, and will not accept any types of commands. - * - * Prefixes may be given to the channels in the form of mode characters or prefix symbols. - */ - #channels = "@#services,#mychan" } /* diff --git a/data/example.conf b/data/example.conf index a56851b2f..ccaaf799b 100644 --- a/data/example.conf +++ b/data/example.conf @@ -241,10 +241,11 @@ serverinfo } /* - * [REQUIRED] Protocol module + * [REQUIRED] Protocol configuration. * * This directive tells Anope which IRCd Protocol to speak when connecting. - * You MUST modify this to match the IRCd you run. + * You MUST modify this to match the IRCd you run. You may want to modify + * the protocol configuration file to tune protocol specific features. * * Supported: * - bahamut @@ -256,25 +257,9 @@ serverinfo * - ratbox * - unreal */ -module +include { - name = "inspircd20" - - /* - * Some protocol modules can enforce mode locks server-side. This reduces the spam caused by - * services immediately reversing mode changes for locked modes. - * - * If the protocol module you have loaded does not support this, this setting will have no effect. - */ - use_server_side_mlock = yes - - /* - * Some protocol modules can enforce topic locks server-side. This reduces the spam caused by - * services immediately reversing topic changes. - * - * If the protocol module you have loaded does not support this, this setting will have no effect. - */ - use_server_side_topiclock = yes + name = "inspircd20.example.conf" } /* diff --git a/data/global.example.conf b/data/global.example.conf index 09534dae7..a299885aa 100644 --- a/data/global.example.conf +++ b/data/global.example.conf @@ -40,15 +40,6 @@ service * unable to do certain things if this option is enabled. */ #modes = "+o" - - /* - * An optional comma separated list of channels this service should join. Outside - * of log channels this is not very useful, as the service will just idle in the - * specified channels, and will not accept any types of commands. - * - * Prefixes may be given to the channels in the form of mode characters or prefix symbols. - */ - #channels = "@#services,#mychan" } /* diff --git a/data/hostserv.example.conf b/data/hostserv.example.conf index e13e8fdd1..47fa6f44f 100644 --- a/data/hostserv.example.conf +++ b/data/hostserv.example.conf @@ -40,15 +40,6 @@ service * unable to do certain things if this option is enabled. */ #modes = "+o" - - /* - * An optional comma separated list of channels this service should join. Outside - * of log channels this is not very useful, as the service will just idle in the - * specified channels, and will not accept any types of commands. - * - * Prefixes may be given to the channels in the form of mode characters or prefix symbols. - */ - #channels = "@#services,#mychan" } /* diff --git a/data/hybrid.example.conf b/data/hybrid.example.conf new file mode 100644 index 000000000..ce285b30c --- /dev/null +++ b/data/hybrid.example.conf @@ -0,0 +1,233 @@ + +module +{ + name = "hybrid" +} + +usermode +{ + name = "ADMIN" + character = "a" + oper_only = yes +} + +usermode +{ + name = "CALLERID" + character = "g" +} + +usermode +{ + name = "INVIS" + character = "i" +} + +usermode +{ + name = "LOCOPS" + character = "l" + oper_only = yes +} + +usermode +{ + name = "OPER" + character = "o" + oper_only = yes +} + +usermode +{ + name = "REGISTERED" + character = "r" + setable = no +} + +usermode +{ + name = "SNOMASK" + character = "s" + oper_only = yes +} + +usermode +{ + name = "WALLOPS" + character = "w" +} + +usermode +{ + name = "OPERWALL" + character = "z" + oper_only = yes +} + +usermode +{ + name = "DEAF" + character = "D" +} + +usermode +{ + name = "HIDEOPER" + character = "H" + oper_only = yes +} + +usermode +{ + name = "REGPRIF" + character = "R" +} + +usermode +{ + name = "SSL" + character = "S" + setable = no +} + +usermode +{ + name = "CLOAK" + character = "x" +} + +channelmode +{ + name = "BAN" + character = "b" + list = yes +} + +channelmode +{ + name = "EXCEPT" + character = "e" + list = yes +} + +channemode +{ + name = "INVITEOVERRIDE" + character = "I" + list = yes +} + +channelmode +{ + name = "VOICE" + character = "v" + status = "+" + level = 1 +} + +channelmode +{ + name = "HALFOP" + characater = "h" + status = "%" + level = 2 +} + +channelmode +{ + name = "OP" + character = "o" + status = "@" + level = 3 +} + +channelmode +{ + name = "BLOCKCOLOR" + character = "c" +} + +channelmode +{ + name = "INVITE" + character = "i" +} + +channelmode +{ + name = "KEY" + character = "k" + param_regex = "[^:,]+" +} + +channelmode +{ + name = "LIMIT" + character = "l" + param_regex = "\d+" + param_unset = no +} + +channelmode +{ + name = "MODERATED" + character = "m" +} + +channelmode +{ + name = "NOEXTERNAL" + character = "n" +} + +channelmode +{ + name = "PRIVATE" + character = "p" +} + +channelmode +{ + name = "REGISTERED" + character = "r" + setable = no +} + +channelmode +{ + name = "SECRET" + character = "s" +} + +channelmode +{ + name = "TOPIC" + character = "t" +} + +channelmode +{ + name = "REGMODERATED" + character = "M" +} + +channelmode +{ + name = "OPERONLY" + character = "O" + oper_only = yes +} + +channelmode +{ + name = "REGISTEREDONLY" + character = "R" +} + +channelmode +{ + name = "SSL" + character = "S" +} + + diff --git a/data/inspircd20.example.conf b/data/inspircd20.example.conf new file mode 100644 index 000000000..133b86089 --- /dev/null +++ b/data/inspircd20.example.conf @@ -0,0 +1,540 @@ + +module +{ + name = "inspircd20" + + /* + * Enables mode locks server-side. This reduces the spam caused by + * services immediately reversing mode changes for locked modes. + */ + use_server_side_mlock = yes + + /* + * Enforces topic locks server-side. This reduces the spam caused by + * services immediately reversing topic changes. + */ + use_server_side_topiclock = yes +} + +usermode +{ + name = "BOT" + character = "B" +} + +usermode +{ + name = "CALLERID" + character = "g" +} + +usermode +{ + name = "CLOAK" + character = "x" +} + +usermode +{ + name = "DEAF" + character = "d" +} + +usermode +{ + name = "COMMONCHANS" + character = "c" +} + +usermode +{ + name = "HELPOP" + character = "h" + oper_only = yes +} + +usermode +{ + name = "PRIV" + character = "I" +} + +usermode +{ + name = "HIDEOPER" + character = "H" + oper_only = yes +} + +usermode +{ + name = "INVIS" + character = "i" +} + +usermode +{ + name = "OPER" + character = "o" + oper_only = yes +} + +usermode +{ + name = "REGPRIV" + character = "R" +} + +usermode +{ + name = "PROTECTED" + character = "k" + setable = no +} + +usermode +{ + name = "WHOIS" + character = "W" + oper_only = yes +} + +usermode +{ + name = "CENSOR" + character = "G" +} + +usermode +{ + name = "REGISTERED" + character = "r" + setable = no +} + +usermode +{ + name = "STRIPCOLOR" + character = "S" +} + +usermode +{ + name = "WALLOPS" + character = "w" +} + +usermode +{ + name = "SNOMASK" + character = "s" + oper_only = yes +} + +channelmode +{ + name = "PROTECT" + character = "a" + status = "&" + level = 4 +} + +channelmode +{ + name = "ALLINVITE" + character = "A" +} + +channelmode +{ + name = "AUDITORIUM" + character = "u" +} + +channelmode +{ + name = "BAN" + character = "b" + list = yes +} + +channelmode +{ + name = "EXCEPT" + character = "e" + list = yes +} + +channelmode +{ + name = "BLOCKCAPS" + character = "B" +} + +channelmode +{ + name = "BLOCKCOLOR" + character = "c" +} + +channelmode +{ + name = "REGISTERED" + character = "r" + setable = false +} + +channelmode +{ + name = "CENSOR" + character = "G" +} + +channelmode +{ + name = "DELAYEDJOIN" + character = "D" +} + +channelmode +{ + name = "DELAYMSG" + character = "d" + param_regex = "[1-9]\d*" +} + +channelmode +{ + name = "FILTER" + character = "g" + list = yes +} + +channelmode +{ + name = "FLOOD" + character = "f" + param_regex = "\*?\d+:\d+" +} + +channelmode +{ + name = "OWNER" + character = "q" + status = "~" + level = 5 +} + +channelmode +{ + name = "HALFOP" + character = "h" + status = "%" + level = 2 +} + +channelmode +{ + name = "HISTORY" + character = "H" + param = yes +} + +channelmode +{ + name = "INVITEOVERRIDE" + character = "I" + list = yes +} + +channelmode +{ + name = "INVITE" + character = "i" +} + +channelmode +{ + name = "JOINFLOOD" + character = "j" + param_regex = "\d+:\d+" +} + +channelmode +{ + name = "KEY" + character = "k" + param_regex = "[^:,]+" +} + +channelmode +{ + name = "NOREJOIN" + character = "J" + param_regex = "\d+" +} + +channelmode +{ + name = "LIMIT" + character = "l" + param_regex = "\d+" + param_unset = no +} + +channelmode +{ + name = "MODERATED" + character = "m" +} + +channelmode +{ + name = "NICKFLOOD" + character = "F" + param_regex = "\d+:\d+" +} + +channelmode +{ + name = "NOCTCP" + character = "C" +} + +channelmode +{ + name = "NOEXTERNAL" + character = "n" +} + +channelmode +{ + name = "NOKICK" + character = "Q" +} + +channelmode +{ + name = "NOKNOCK" + character = "K" +} + +channelmode +{ + name = "NONICK" + character = "N" +} + +channelmode +{ + name = "NONOTICEB" + character = "T" +} + +channelmode +{ + name = "OP" + character = "o" + status = "@" + level = 3 +} + +channelmode +{ + name = "OPERONLY" + character = "O" + oper_only = yes +} + +channelmode +{ + name = "PERM" + character = "P" + oper_only = yes +} + +channelmode +{ + name = "PRIVATE" + character = "p" +} + +channelmode +{ + name = "REDIRECT" + character = "L" + param = yes +} + +channelmode +{ + name = "REGISTEREDONLY" + character = "R" +} + +channelmode +{ + name = "REGMODERATED" + character = "M" +} + +channelmode +{ + name = "SECRET" + character = "s" +} + +channelmode +{ + name = "SSLONLY" + character = "z" +} + +channelmode +{ + name = "STRIPCOLOR" + character = "S" +} + +channelmode +{ + name = "TOPIC" + character = "t" +} + +channelmode +{ + name = "VOICE" + character = "v" + status = "+" + level = 1 +} + +extban +{ + name = "INVITEBAN" + type = "entry" + base = "BAN" + chaacter = "A" +} + +extban +{ + name = "BLOCKCAPSBAN" + type = "entry" + base = "BAN" + character = "B" +} + +extban +{ + name = "BLOCKCOLORBAN" + type = "entry" + base = "BAN" + character = "c" +} + +extban +{ + name = "NOCTCPBAN" + type = "entry" + base = "BAN" + character = "C" +} + +extban +{ + name = "NOKICKBAN" + type = "entry" + base = "BAN" + character = "Q" +} + +extban +{ + name = "NONICKBAN" + type = "entry" + base = "BAN" + character = "N" +} + +extban +{ + name = "NONOTICEBAN" + type = "entry" + base = "BAN" + character = "T" +} + +extban +{ + name = "SSLBAN" + type = "fingerprint" + base = "BAN" + character = "z" +} + +extban +{ + name = "STRIPCOLORBAN" + type = "entry" + base = "BAN" + character = "S" +} + +extban +{ + name = "ACCOUNTBAN" + type = "account" + base = "BAN" + character = "R" +} + +extban +{ + name = "UNREGISTEREDBAN" + type = "unidentified" + base = "BAN" + character = "U" +} + +extban +{ + name = "CHANNELBAN" + type = "channel" + base = "BAN" + character = "j" +} + +extban +{ + name = "REALNAMEBAN" + type = "realname" + base = "BAN" + character = "r" +} + +extban +{ + name = "PARTMESSAGEBAN" + type = "entry" + base = "BAN" + character = "p" +} + +extban +{ + name = "SERVERBAN" + type = "server" + base = "BAN" + character = "s" +} + +extban +{ + name = "QUIET" + type = "entry" + base = "BAN" + character = "m" +} + diff --git a/data/memoserv.example.conf b/data/memoserv.example.conf index 9f07ec424..c001fa93d 100644 --- a/data/memoserv.example.conf +++ b/data/memoserv.example.conf @@ -40,15 +40,6 @@ service * unable to do certain things if this option is enabled. */ #modes = "+o" - - /* - * An optional comma separated list of channels this service should join. Outside - * of log channels this is not very useful, as the service will just idle in the - * specified channels, and will not accept any types of commands. - * - * Prefixes may be given to the channels in the form of mode characters or prefix symbols. - */ - #channels = "@#services,#mychan" } /* diff --git a/data/ngircd.example.conf b/data/ngircd.example.conf new file mode 100644 index 000000000..641b2cc20 --- /dev/null +++ b/data/ngircd.example.conf @@ -0,0 +1,234 @@ + +module +{ + name = "ngircd" +} + +usermode +{ + name = "NOCTCP" + character = "b" +} + +usermode +{ + name = "BOT" + character = "B" +} + +usermode +{ + name = "COMMONCHANS" + character = "C" +} + +usermode +{ + name = "INVIS" + character = "i" +} + +usermode +{ + name = "OPER" + character = "o" + oper_only = yes +} + +usermode +{ + name = "PROTECTED" + character = "q" + oper_only = yes +} + +usermode +{ + name = "RESTRICTED" + character = "r" + oper_only = yes +} + +usermode +{ + name = "REGISTERED" + character = "R" + setable = no +} + +usermode +{ + name = "SNOMASK" + character = "s" + oper_only = yes +} + +usermode +{ + name = "WALLOPS" + character = "w" +} + +usermode +{ + name = "CLOAK" + character = "x" +} + +channelmode +{ + name = "BAN" + character = "b" + list = yes +} + +channelmode +{ + name = "EXCEPT" + character = "e" + list = yes +} + +channemode +{ + name = "INVITEOVERRIDE" + character = "I" + list = yes +} + + +channelmode +{ + name = "VOICE" + character = "v" + status = "+" + level = 1 +} + +channelmode +{ + name = "HALFOP" + character = "h" + status = "%" + level = 2 +} + +channelmode +{ + name = "OP" + character = "@" + status = "@" + level = 3 +} + +channelmode +{ + name = "PROTECT" + character = "a" + status = "&" + level = 4 +} + +channelmode +{ + name = "OWNER" + character = "q" + status = "~" + level = 5 +} + +channelmode +{ + name = "INVITE" + character = "i" +} + +channelmode +{ + name = "KEY" + character = "k" + param_regex = "[^:,]+" +} + +channelmode +{ + name = "LIMIT" + character = "l" + param_regex = "\d+" + param_unset = no +} + +channelmode +{ + name = "MODERATED" + character = "m" +} + +channelmode +{ + name = "REGMODERATED" + character = "M" +} + +channelmode +{ + name = "NOEXTERNAL" + character = "n" +} + +channelmode +{ + name = "OPERONLY" + character = "O" + oper_only = yes +} + +channelmode +{ + name = "PERM" + character = "P" + oper_only = yes +} + +channelmode +{ + name = "NOKICK" + character = "Q" +} + +channelmode +{ + name = "REGISTERED" + character = "r" + setable = no +} + +channelmode +{ + name = "REGISTEREDONLY" + character = "R" +} + +channelmode +{ + name = "SECRET" + character = "s" +} + +channelmode +{ + name = "TOPIC" + character = "t" +} + +channelmode +{ + name = "NOINVITE" + character = "V" +} + +channelmode +{ + name = "SSL" + character = "z" +} diff --git a/data/nickserv.example.conf b/data/nickserv.example.conf index e8d02bed6..f23361eee 100644 --- a/data/nickserv.example.conf +++ b/data/nickserv.example.conf @@ -40,15 +40,6 @@ service * unable to do certain things if this option is enabled. */ #modes = "+o" - - /* - * An optional comma separated list of channels this service should join. Outside - * of log channels this is not very useful, as the service will just idle in the - * specified channels, and will not accept any types of commands. - * - * Prefixes may be given to the channels in the form of mode characters or prefix symbols. - */ - #channels = "@#services,#mychan" } /* diff --git a/data/operserv.example.conf b/data/operserv.example.conf index bfbce6013..5554dcb42 100644 --- a/data/operserv.example.conf +++ b/data/operserv.example.conf @@ -40,15 +40,6 @@ service * unable to do certain things if this option is enabled. */ #modes = "+o" - - /* - * An optional comma separated list of channels this service should join. Outside - * of log channels this is not very useful, as the service will just idle in the - * specified channels, and will not accept any types of commands. - * - * Prefixes may be given to the channels in the form of mode characters or prefix symbols. - */ - #channels = "@#services,#mychan" } /* diff --git a/data/plexus.example.conf b/data/plexus.example.conf new file mode 100644 index 000000000..5d9feace8 --- /dev/null +++ b/data/plexus.example.conf @@ -0,0 +1,294 @@ + +module +{ + name = "plexus" +} + +usermode +{ + name = "ADMIN" + character = "a" + oper_only = yes +} + +usermode +{ + name = "NOCTCP" + character = "c" +} + +usermode +{ + name = "SOFTCALLERID" + character = "G" +} + +usermode +{ + name = "CALLERID" + character = "g" +} + +usermode +{ + name = "INVIS" + character = "i" +} + +usermode +{ + name = "LOCOPS" + character = "l" + oper_only = yes +} + +usermode +{ + name = "OPER" + character = "o" + oper_only = yes +} + +usermode +{ + name = "NETADMIN" + character = "N" + oper_only = yes +} + +usermode +{ + name = "PRIV" + character = "p" +} + +usermode +{ + name = "ROUTING" + character = "q" + oper_only = yes +} + +usermode +{ + name = "REGISTERED" + character = "r" + setable = no +} + +usermode +{ + name = "REGPRIV" + character = "R" +} + +usermode +{ + name = "SNOMASK" + character = "s" + oper_only = yes +} + +usermode +{ + name = "SSL" + character = "S" + setable = no +} + +usermode +{ + name = "PROTECTEDF" + character = "U" + setable = no +} + +usermode +{ + name = "WALLOPS" + character = "w" +} + +usermode +{ + name = "WEBIRC" + character = "W" + setable = no +} + +usermode +{ + name = "CLOAK" + character = "x" +} + +usermode +{ + name = "OPERWALL" + character = "z" + oper_only = yes +} + +channelmode +{ + name = "BAN" + character = "b" + list = yes +} + +channelmode +{ + name = "EXCEPT" + character = "e" + list = yes +} + +channemode +{ + name = "INVITEOVERRIDE" + character = "I" + list = yes +} + +channelmode +{ + name = "VOICE" + character = "v" + status = "+" + level = 1 +} + +channelmode +{ + name = "HALFOP" + characater = "h" + status = "%" + level = 2 +} + +channelmode +{ + name = "OP" + character = "o" + status = "@" + level = 3 +} + +channelmode +{ + name = "PROTECT" + character = "a" + status = "~" + level = 4 +} + +channelmode +{ + name = "OWNER" + character = "q" + status = "*" + level = 5 +} + +_____________ + +channelmode +{ + name = "BANDWIDTHSAVER" + character = "B" +} + +channelmode +{ + name = "NOCTCP" + character = "C" +} + +channelmode +{ + name = "BLOCKCOLOR" + character = "c" +} + +channelmode +{ + name = "INVITE" + character = "i" +} + +channelmode +{ + name = "KEY" + character = "k" + param_regex = "[^:,]+" +} + +channelmode +{ + name = "LIMIT" + character = "l" + param_regex = "\d+" + param_unset = no +} + +channelmode +{ + name = "MODERATED" + character = "m" +} + +channelmode +{ + name = "NOEXTERNAL" + character = "n" +} + +channelmode +{ + name = "PRIVATE" + character = "p" +} + +channelmode +{ + name = "SECRET" + character = "s" +} + +channelmode +{ + name = "TOPIC" + character = "t" +} + +channelmode +{ + name = "REGMODERATED" + character = "M" +} + +channelmode +{ + name = "OPERONLY" + character = "O" + oper_only = yes +} + +channelmode +{ + name = "REGISTEREDONLY" + character = "R" +} + +channelmode +{ + name = "SSL" + character = "S" +} + +channelmode +{ + name = "PERM" + character = "z" +} + diff --git a/data/ratbox.example.conf b/data/ratbox.example.conf new file mode 100644 index 000000000..f3f191974 --- /dev/null +++ b/data/ratbox.example.conf @@ -0,0 +1,174 @@ + +module +{ + name = "ratbox" +} + +usermode +{ + name = "ADMIN" + character = "a" + oper_only = yes +} + +usermode +{ + name = "CALLERID" + character = "g" +} + +usermode +{ + name = "DEAF" + character = "D" +} + +usermode +{ + name = "INVIS" + character = "i" +} + +usermode +{ + name = "LOCOPS" + character = "l" + oper_only = yes +} + +usermode +{ + name = "OPER" + character = "o" + oper_only = yes +} + +usermode +{ + name = "SNOMASK" + character = "s" + oper_only = yes +} + +usermode +{ + name = "PROTECTED" + character = "S" + setable = no +} + + +usermode +{ + name = "WALLOPS" + character = "w" +} + +usermode +{ + name = "OPERWALL" + character = "z" + oper_only = yes +} + +channelmode +{ + name = "BAN" + character = "b" + list = yes +} + +channelmode +{ + name = "EXCEPT" + character = "e" + list = yes +} + +channemode +{ + name = "INVITEOVERRIDE" + character = "I" + list = yes +} + +channelmode +{ + name = "VOICE" + character = "v" + status = "+" + level = 1 +} + +channelmode +{ + name = "OP" + character = "o" + status = "@" + level = 2 +} + +channelmode +{ + name = "INVITE" + character = "i" +} + +channelmode +{ + name = "KEY" + character = "k" + param_regex = "[^:,]+" +} + +channelmode +{ + name = "LIMIT" + character = "l" + param_regex = "\d+" + param_unset = no +} + +channelmode +{ + name = "MODERATED" + character = "m" +} + +channelmode +{ + name = "NOEXTERNAL" + character = "n" +} + +channelmode +{ + name = "PRIVATE" + character = "p" +} + +channelmode +{ + name = "SECRET" + character = "s" +} + +channelmode +{ + name = "TOPIC" + character = "t" +} + +channelmode +{ + name = "REGISTEREDONLY" + character = "r" +} + +channelmode +{ + name = "SSL" + character = "S" +} + + diff --git a/data/unreal.example.conf b/data/unreal.example.conf new file mode 100644 index 000000000..35a4210e6 --- /dev/null +++ b/data/unreal.example.conf @@ -0,0 +1,478 @@ + +module +{ + name = "unreal" + + /* + * Enforces mode locks server-side. This reduces the spam caused by + * services immediately reversing mode changes for locked modes. + */ + use_server_side_mlock = yes +} + +usermode +{ + name = "SERV_ADMIN" + character = "A" + oper_only = yes +} + +usermode +{ + name = "BOT" + character = "B" +} + +usermode +{ + name = "CO_ADMIN" + character = "C" + oper_only = yes +} + +usermode +{ + name = "CENSOR" + character = "G" +} + + +usermode +{ + name = "HIDEOPER" + character = "H" + oper_only = yes +} + +usermode +{ + name = "HIDEIDLE" + character = "I" +} + +usermode +{ + name = "NETADMIN" + character = "N" + oper_only = yes +} + +usermode +{ + name = "REGPRIV" + character = "R" +} + +usermode +{ + name = "PROTECTED" + character = "S" + oper_only = yes +} + +usermode +{ + name = "NOCTCP" + character = "T" +} + +usermode +{ + name = "WEBTV" + character = "V" +} + +usermode +{ + name = "WHOIS" + character = "W" + oper_only = yes +} + +usermode +{ + name = "ADMIN" + character = "a" + oper_only = yes +} + +usermode +{ + name = "DEAF" + character = "d" +} + +usermode +{ + name = "GLOBOPS" + character = "g" + oper_only = yes +} + +usermode +{ + name = "HELPOP" + character = "h" + oper_only = yes +} + +usermode +{ + name = "INVIS" + character = "i" +} + +usermode +{ + name = "OPER" + character = "o" + oper_only = yes +} + +usermode +{ + name = "PRIV" + character = "p" +} + +usermode +{ + name = "GOD" + character = "q" + oper_only = yes +} + +usermode +{ + name = "REGISTERED" + character = "r" + oper_only = yes +} + +usermode +{ + name = "SNOMASK" + character = "s" + oper_only = yes +} + +usermode +{ + name = "VHOST" + character = "t" + setable = no +} + +usermode +{ + name = "WALLOPS" + character = "w" +} + +usermode +{ + name = "CLOAK" + character = "x" +} + +usermode +{ + name = "SSL" + character = "z" + setable = no +} + +channelmode +{ + name = "VOICE" + character = "v" + status = "+" + level = 1 +} + +channelmode +{ + name = "HALFOP" + character = "h" + status = "%" + level = 2 +} + +channelmode +{ + name = "OP" + character = "@" + status = "@" + level = 3 +} + +channelmode +{ + name = "PROTECT" + character = "a" + status = "~" + level = 4 +} + +channelmode +{ + name = "OWNER" + character = "q" + status = "*" + level = 5 +} + +channelmode +{ + name = "BAN" + character = "b" + list = yes +} + +channelmode +{ + name = "EXCEPT" + character = "e" + list = yes +} + +channemode +{ + name = "INVITEOVERRIDE" + character = "I" + list = yes +} + +channelmode +{ + name = "KEY" + character = "k" + param_regex = "[^:,]+" +} + +channelmode +{ + name = "FLOOD" + character = "f" + param_regex = "\[(?:(?:(?<=\[)|,)\d+[cjkmnt](?:#[CiKmNmMRb]\d*)?)+\]:\d+" +} + +channelmode +{ + name = "REDIRECT" + character = "L" + param = yes +} + +channelmode +{ + name = "LIMIT" + character = "l" + param_regex = "\d+" + param_unset = no +} + +channelmode +{ + name = "JOINFLOOD" + character = "j" + param_regex = "\d+:\d+" + param_unset = no +} + +channelmode +{ + name = "PRIVATE" + character = "p" +} + +channelmode +{ + name = "SECRET" + character = "s" +} + +channelmode +{ + name = "MODERATED" + character = "m" +} + +channelmode +{ + name = "NOEXTERNAL" + character = "n" +} + +channelmode +{ + name = "TOPIC" + character = "t" +} + +channelmode +{ + name = "INVITE" + character = "i" +} + +channelmode +{ + name = "REGISTERED" + character = "r" + setable = no +} + +channelmode +{ + name = "REGISTEREDONLY" + character = "R" +} + +channelmode +{ + name = "BLOCKCOLOR" + character = "c" +} + +channelmode +{ + name = "OPERONLY" + character = "O" + oper_only = yes +} + +channelmode +{ + name = "ADMINONLY" + character = "O" + oper_only = yes +} + +channelmode +{ + name = "NOKICK" + character = "Q" +} + +channelmode +{ + name = "NOKNOCK" + character = "K" +} + +channelmode +{ + name = "NOINVITE" + character = "V" +} + +channelmode +{ + name = "NOCTCP" + character = "C" +} + +channelmode +{ + name = "AUDITORIUM" + character = "u" +} + +channelmode +{ + name = "SSL" + character = "z" +} + +channelmode +{ + name = "NONICK" + character = "N" +} + +channelmode +{ + name = "STRIPCOLOR" + character = "S" +} + +channelmode +{ + name = "REGMODERATED" + character = "M" +} + +channelmode +{ + name = "NONOTICE" + character = "T" +} + +channelmode +{ + name = "CENSOR" + character = "G" +} + +channelmode +{ + name = "SSL2" + character = "Z" + setable = no +} + +extban +{ + name = "CHANNELBAN" + type = "channel" + character = "c" +} + +extban +{ + name = "JOINBAN" + type = "entry" + character = "j" +} + +extban +{ + name = "NONICKBAN" + type = "entry" + base = "BAN" + character = "n" +} + +extban +{ + name = "QUIET" + type = "entry" + base = "BAN" + character = "q" +} + +extban +{ + name = "REALNAMEBAN" + type = "realname" + base = "BAN" + character = "r" +} + +extban +{ + name = "REGISTEREDBAN" + type = "registered" + base = "BAN" + character = "R" +} + +extban +{ + name = "ACCOUNTBAN" + type = "account" + base = "BAN" + character = "a" +} + diff --git a/include/bots.h b/include/bots.h index 6adcb36a1..80efd8872 100644 --- a/include/bots.h +++ b/include/bots.h @@ -13,6 +13,7 @@ #include "anope.h" #include "serialize.h" #include "commands.h" +#include "config.h" /* A service bot (NickServ, ChanServ, a BotServ bot, etc). */ class CoreExport ServiceBot : public LocalUser @@ -24,12 +25,8 @@ class CoreExport ServiceBot : public LocalUser CommandInfo::map commands; /* Modes the bot should have as configured in service:modes */ Anope::string botmodes; - /* Channels the bot should be in as configured in service:channels */ - std::vector<Anope::string> botchannels; /* Whether or not this bot is introduced to the network */ bool introduced; - /* Bot is defined in the configuration file */ - bool conf; /** Create a new bot. * @param nick The nickname to assign to the bot. @@ -125,10 +122,13 @@ class BotInfo : public Serialize::Object { public: ServiceBot *bot; + Configuration::Block *conf = nullptr; BotInfo(Serialize::TypeBase *type) : Serialize::Object(type) { } BotInfo(Serialize::TypeBase *type, Serialize::ID id) : Serialize::Object(type, id) { } + void Delete() override; + void SetNick(const Anope::string &); Anope::string GetNick(); diff --git a/include/config.h b/include/config.h index fdeddf6dc..65a8bf55d 100644 --- a/include/config.h +++ b/include/config.h @@ -85,6 +85,8 @@ namespace Configuration }; struct Uplink; + struct Usermode; + struct Channelmode; struct CoreExport Conf : Block { @@ -123,6 +125,8 @@ namespace Configuration std::vector<Anope::string> ModulesAutoLoad; /* After how many characters do we wrap lines? */ unsigned int LineWrap; + std::vector<Usermode> Usermodes; + std::vector<Channelmode> Channelmodes; unsigned char CaseMapUpper[256], CaseMapLower[256]; /* module configuration blocks */ @@ -154,14 +158,26 @@ namespace Configuration inline bool operator==(const Uplink &other) const { return host == other.host && port == other.port && password == other.password && ipv6 == other.ipv6; } inline bool operator!=(const Uplink &other) const { return !(*this == other); } }; + + struct Usermode + { + Anope::string name; + char character; + bool param; + bool oper_only, setable; + }; + + struct Channelmode + { + Anope::string name, param_regex; + char character; + char status; /* status char, if any +/@ */ + int level; /* relative level */ + bool oper_only, list, param, param_unset, setable; + + }; } -/** This class can be used on its own to represent an exception, or derived to represent a module-specific exception. - * When a module whishes to abort, e.g. within a constructor, it should throw an exception using ModuleException or - * a class derived from ModuleException. If a module throws an exception during its constructor, the module will not - * be loaded. If this happens, the error message returned by ModuleException::GetReason will be displayed to the user - * attempting to load the module, or dumped to the console if the ircd is currently loading for the first time. - */ class ConfigException : public CoreException { public: @@ -171,11 +187,8 @@ class ConfigException : public CoreException /** This constructor can be used to specify an error message before throwing. */ ConfigException(const Anope::string &message) : CoreException(message, "Config Parser") { } - /** This destructor solves world hunger, cancels the world debt, and causes the world to end. - * Actually no, it does nothing. Never mind. - * @throws Nothing! - */ - virtual ~ConfigException() throw() { } + + virtual ~ConfigException() throw() = default; }; extern Configuration::File ServicesConf; diff --git a/include/modes.h b/include/modes.h index 1858da5e4..c010700ca 100644 --- a/include/modes.h +++ b/include/modes.h @@ -47,6 +47,9 @@ class CoreExport Mode : public Base /* Type of mode this is, eg MODE_LIST */ ModeType type; + bool setable = true; + bool oper_only = false; + /** constructor * @param mname The mode name * @param mclass The type of mode this is @@ -56,6 +59,9 @@ class CoreExport Mode : public Base Mode(const Anope::string &mname, ModeClass mclass, char mc, ModeType type); virtual ~Mode(); + void SetSetable(bool b) { setable = b; } + void SetOperOnly(bool b) { oper_only = b; } + /** Can a user set this mode, used for mlock * @param u The user */ @@ -143,18 +149,6 @@ class CoreExport ChannelModeList : public ChannelMode * @return true on match */ virtual bool Matches(User *u, const Entry *e) { return false; } - - /** Called when a mask is added to a channel - * @param chan The channel - * @param mask The mask - */ - virtual void OnAdd(Channel *chan, const Anope::string &mask) { } - - /** Called when a mask is removed from a channel - * @param chan The channel - * @param mask The mask - */ - virtual void OnDel(Channel *chan, const Anope::string &mask) { } }; /** This is a mode with a paramater, eg +k/l. These modes should use/inherit from this @@ -172,11 +166,13 @@ class CoreExport ChannelModeParam : public ChannelMode /* Should we send an arg when unsetting this mode? */ bool minus_no_arg; + std::regex param_validation; + /** Is the param valid * @param value The param * @return true for yes, false for no */ - virtual bool IsValid(Anope::string &value) const { return true; } + virtual bool IsValid(Anope::string &value) const; }; /** This is a mode that is a channel status, eg +v/h/o/a/q. @@ -235,53 +231,6 @@ class CoreExport ChannelStatus Anope::string BuildModePrefixList() const; }; -class CoreExport UserModeOperOnly : public UserMode -{ - public: - UserModeOperOnly(const Anope::string &mname, char um) : UserMode(mname, um) { } - - bool CanSet(User *u) const override; -}; - -class CoreExport UserModeNoone : public UserMode -{ - public: - UserModeNoone(const Anope::string &mname, char um) : UserMode(mname, um) { } - - bool CanSet(User *u) const override; -}; - -/** Channel mode +k (key) - */ -class CoreExport ChannelModeKey : public ChannelModeParam -{ - public: - ChannelModeKey(char mc) : ChannelModeParam("KEY", mc) { } - - bool IsValid(Anope::string &value) const override; -}; - -/** This class is used for oper only channel modes - */ -class CoreExport ChannelModeOperOnly : public ChannelMode -{ - public: - ChannelModeOperOnly(const Anope::string &mname, char mc) : ChannelMode(mname, mc) { } - - /* Opers only */ - bool CanSet(User *u) const override; -}; - -/** This class is used for channel modes only servers may set - */ -class CoreExport ChannelModeNoone : public ChannelMode -{ - public: - ChannelModeNoone(const Anope::string &mname, char mc) : ChannelMode(mname, mc) { } - - bool CanSet(User *u) const override; -}; - /** This is the mode manager * It contains functions for adding modes to Anope so Anope can track them * and do things such as MLOCK. @@ -291,11 +240,6 @@ class CoreExport ChannelModeNoone : public ChannelMode class CoreExport ModeManager { public: - - /* Number of generic channel and user modes we are tracking */ - static unsigned GenericChannelModes; - static unsigned GenericUserModes; - /** Add a user mode to Anope * @param um A UserMode or UserMode derived class * @return true on success, false on error @@ -380,6 +324,8 @@ class CoreExport ModeManager static void StackerDel(User *u); static void StackerDel(Channel *c); static void StackerDel(Mode *m); + + static void Apply(Configuration::Conf *old); }; /** Represents a mask set on a channel (b/e/I) diff --git a/include/servers.h b/include/servers.h index 5c09ab2d6..1d62938ec 100644 --- a/include/servers.h +++ b/include/servers.h @@ -82,6 +82,8 @@ class CoreExport Server : public Extensible /* Number of users on the server */ unsigned users; + void Burst(); + /** Delete this server with a reason * @param reason The reason */ diff --git a/modules/commands/bs_bot.cpp b/modules/commands/bs_bot.cpp index c67c5d168..1ba22531e 100644 --- a/modules/commands/bs_bot.cpp +++ b/modules/commands/bs_bot.cpp @@ -85,8 +85,6 @@ class CommandBSBot : public Command targ->Kill(Me, "Nickname is reserved for services"); ServiceBot *bi = new ServiceBot(nick, user, host, real); - bi->bi = botinfo.Create(); - bi->bi->bot = bi; Log(LOG_ADMIN, source, this) << "ADD " << bi->GetMask() << " " << bi->realname; @@ -116,7 +114,7 @@ class CommandBSBot : public Command return; } - if (bi->conf) + if (bi->bi->conf) { source.Reply(_("Bot \002{0}\002 is not changeable because it is configured in services configuration."), bi->nick.c_str()); return; @@ -259,7 +257,7 @@ class CommandBSBot : public Command return; } - if (bi->conf) + if (bi->bi->conf) { source.Reply(_("Bot \002{0}\002 is can not be deleted because it is configured in services configuration."), bi->nick); return; @@ -270,7 +268,6 @@ class CommandBSBot : public Command Log(LOG_ADMIN, source, this) << "DEL " << bi->nick; source.Reply(_("Bot \002{0}\002 has been deleted."), bi->nick); - // XXX delete bi->bi? delete bi; } diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp index cae16dcb9..52786b361 100644 --- a/modules/protocol/bahamut.cpp +++ b/modules/protocol/bahamut.cpp @@ -507,43 +507,6 @@ class ProtoBahamut : public Module IRCDMessageSJoin message_sjoin; IRCDMessageTopic message_topic; - void AddModes() - { - /* Add user modes */ - ModeManager::AddUserMode(new UserModeOperOnly("SERV_ADMIN", 'A')); - ModeManager::AddUserMode(new UserMode("REGPRIV", 'R')); - ModeManager::AddUserMode(new UserModeOperOnly("ADMIN", 'a')); - ModeManager::AddUserMode(new UserMode("INVIS", 'i')); - ModeManager::AddUserMode(new UserModeOperOnly("OPER", 'o')); - ModeManager::AddUserMode(new UserModeNoone("REGISTERED", 'r')); - ModeManager::AddUserMode(new UserModeOperOnly("SNOMASK", 's')); - ModeManager::AddUserMode(new UserModeOperOnly("WALLOPS", 'w')); - ModeManager::AddUserMode(new UserMode("DEAF", 'd')); - - /* b/e/I */ - ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b')); - - /* v/h/o/a/q */ - ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0)); - ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 1)); - - /* Add channel modes */ - ModeManager::AddChannelMode(new ChannelMode("BLOCKCOLOR", 'c')); - ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i')); - ModeManager::AddChannelMode(new ChannelModeFlood('f', false)); - ModeManager::AddChannelMode(new ChannelModeKey('k')); - ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l', true)); - ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm')); - ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n')); - ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p')); - ModeManager::AddChannelMode(new ChannelModeNoone("REGISTERED", 'r')); - ModeManager::AddChannelMode(new ChannelMode("SECRET", 's')); - ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't')); - ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M')); - ModeManager::AddChannelMode(new ChannelModeOperOnly("OPERONLY", 'O')); - ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R')); - } - public: ProtoBahamut(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR) , ircd_proto(this) @@ -574,9 +537,6 @@ class ProtoBahamut : public Module , message_sjoin(this) , message_topic(this) { - - this->AddModes(); - } void OnUserNickChange(User *u, const Anope::string &) override diff --git a/modules/protocol/charybdis.cpp b/modules/protocol/charybdis.cpp index e80b1d994..8477bc30e 100644 --- a/modules/protocol/charybdis.cpp +++ b/modules/protocol/charybdis.cpp @@ -9,6 +9,7 @@ * Based on the original code of Services by Andy Church. */ +#if 0 #include "module.h" #include "modules/cs_mode.h" #include "modules/sasl.h" @@ -429,3 +430,4 @@ class ProtoCharybdis : public Module }; MODULE_INIT(ProtoCharybdis) +#endif diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp index da412623a..772b9e0d9 100644 --- a/modules/protocol/hybrid.cpp +++ b/modules/protocol/hybrid.cpp @@ -630,53 +630,6 @@ class ProtoHybrid : public Module IRCDMessageUID message_uid; IRCDMessageCertFP message_certfp; - void AddModes() - { - /* Add user modes */ - ModeManager::AddUserMode(new UserModeOperOnly("ADMIN", 'a')); - ModeManager::AddUserMode(new UserModeOperOnly("CALLERID", 'g')); - ModeManager::AddUserMode(new UserMode("INVIS", 'i')); - ModeManager::AddUserMode(new UserModeOperOnly("LOCOPS", 'l')); - ModeManager::AddUserMode(new UserModeOperOnly("OPER", 'o')); - ModeManager::AddUserMode(new UserModeNoone("REGISTERED", 'r')); - ModeManager::AddUserMode(new UserModeOperOnly("SNOMASK", 's')); - ModeManager::AddUserMode(new UserMode("WALLOPS", 'w')); - ModeManager::AddUserMode(new UserModeOperOnly("OPERWALLS", 'z')); - ModeManager::AddUserMode(new UserMode("DEAF", 'D')); - ModeManager::AddUserMode(new UserModeOperOnly("HIDEOPER", 'H')); - ModeManager::AddUserMode(new UserMode("REGPRIV", 'R')); - ModeManager::AddUserMode(new UserModeNoone("SSL", 'S')); - ModeManager::AddUserMode(new UserMode("CLOAK", 'x')); - - /* b/e/I */ - ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b')); - ModeManager::AddChannelMode(new ChannelModeList("EXCEPT", 'e')); - ModeManager::AddChannelMode(new ChannelModeList("INVITEOVERRIDE", 'I')); - - /* v/h/o/a/q */ - ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0)); - ModeManager::AddChannelMode(new ChannelModeStatus("HALFOP", 'h', '%', 1)); - ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 2)); - - /* l/k */ - ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l', true)); - ModeManager::AddChannelMode(new ChannelModeKey('k')); - - /* Add channel modes */ - ModeManager::AddChannelMode(new ChannelMode("BLOCKCOLOR", 'c')); - ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i')); - ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm')); - ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n')); - ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p')); - ModeManager::AddChannelMode(new ChannelModeNoone("REGISTERED", 'r')); - ModeManager::AddChannelMode(new ChannelMode("SECRET", 's')); - ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't')); - ModeManager::AddChannelMode(new ChannelModeOperOnly("OPERONLY", 'O')); - ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M')); - ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R')); - ModeManager::AddChannelMode(new ChannelMode("SSL", 'S')); - } - public: ProtoHybrid(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR) , ircd_proto(this) @@ -714,8 +667,6 @@ public: , message_uid(this) , message_certfp(this) { - if (Config->GetModule(this)) - this->AddModes(); } void OnUserNickChange(User *u, const Anope::string &) override diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp index e7a315261..4a74995a2 100644 --- a/modules/protocol/inspircd20.cpp +++ b/modules/protocol/inspircd20.cpp @@ -560,10 +560,10 @@ namespace InspIRCdExtban } }; - class FinerprintMatcher : public InspIRCdExtBan + class FingerprintMatcher : public InspIRCdExtBan { public: - FinerprintMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : InspIRCdExtBan(mname, mbase, c) + FingerprintMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : InspIRCdExtBan(mname, mbase, c) { } @@ -591,121 +591,8 @@ namespace InspIRCdExtban }; } -class ColonDelimitedParamMode : public ChannelModeParam -{ - public: - ColonDelimitedParamMode(const Anope::string &modename, char modeChar) : ChannelModeParam(modename, modeChar, true) { } - - bool IsValid(Anope::string &value) const override - { - return IsValid(value, false); - } - - bool IsValid(const Anope::string &value, bool historymode) const - { - if (value.empty()) - return false; // empty param is never valid - - Anope::string::size_type pos = value.find(':'); - if ((pos == Anope::string::npos) || (pos == 0)) - return false; // no ':' or it's the first char, both are invalid - - Anope::string rest; - try - { - if (convertTo<int>(value, rest, false) <= 0) - return false; // negative numbers and zero are invalid - - rest = rest.substr(1); - int n; - if (historymode) - { - // For the history mode, the part after the ':' is a duration and it - // can be in the user friendly "1d3h20m" format, make sure we accept that - n = Anope::DoTime(rest); - } - else - n = convertTo<int>(rest); - - if (n <= 0) - return false; - } - catch (const ConvertException &e) - { - // conversion error, invalid - return false; - } - - return true; - } -}; - -class SimpleNumberParamMode : public ChannelModeParam -{ - public: - SimpleNumberParamMode(const Anope::string &modename, char modeChar) : ChannelModeParam(modename, modeChar, true) { } - - bool IsValid(Anope::string &value) const override - { - if (value.empty()) - return false; // empty param is never valid - - try - { - if (convertTo<int>(value) <= 0) - return false; - } - catch (const ConvertException &e) - { - // conversion error, invalid - return false; - } - - return true; - } -}; - -class ChannelModeFlood : public ColonDelimitedParamMode -{ - public: - ChannelModeFlood(char modeChar) : ColonDelimitedParamMode("FLOOD", modeChar) { } - - bool IsValid(Anope::string &value) const override - { - // The parameter of this mode is a bit different, it may begin with a '*', - // ignore it if that's the case - Anope::string v = value[0] == '*' ? value.substr(1) : value; - return ((!value.empty()) && (ColonDelimitedParamMode::IsValid(v))); - } -}; - -class ChannelModeHistory : public ColonDelimitedParamMode -{ - public: - ChannelModeHistory(char modeChar) : ColonDelimitedParamMode("HISTORY", modeChar) { } - - bool IsValid(Anope::string &value) const override - { - return (ColonDelimitedParamMode::IsValid(value, true)); - } -}; - -class ChannelModeRedirect : public ChannelModeParam -{ - public: - ChannelModeRedirect(char modeChar) : ChannelModeParam("REDIRECT", modeChar, true) { } - - bool IsValid(Anope::string &value) const override - { - // The parameter of this mode is a channel, and channel names start with '#' - return ((!value.empty()) && (value[0] == '#')); - } -}; - struct IRCDMessageCapab : Message::Capab { - std::map<char, Anope::string> chmodes, umodes; - IRCDMessageCapab(Module *creator) : Message::Capab(creator, "CAPAB") { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) override @@ -724,8 +611,6 @@ struct IRCDMessageCapab : Message::Capab } /* reset CAPAB */ - chmodes.clear(); - umodes.clear(); Servers::Capab.insert("SERVERS"); Servers::Capab.insert("CHGHOST"); Servers::Capab.insert("CHGIDENT"); @@ -739,130 +624,35 @@ struct IRCDMessageCapab : Message::Capab while (ssep.GetToken(capab)) { + if (capab.find('=') == Anope::string::npos) + continue; + Anope::string modename = capab.substr(0, capab.find('=')); Anope::string modechar = capab.substr(capab.find('=') + 1); - ChannelMode *cm = NULL; + char symbol = 0; - if (modename.equals_cs("admin")) - cm = new ChannelModeStatus("PROTECT", modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0, 3); - else if (modename.equals_cs("allowinvite")) - { - cm = new ChannelMode("ALLINVITE", modechar[0]); - ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("INVITEBAN", "BAN", 'A')); - } - else if (modename.equals_cs("auditorium")) - cm = new ChannelMode("AUDITORIUM", modechar[0]); - else if (modename.equals_cs("ban")) - cm = new ChannelModeList("BAN", modechar[0]); - else if (modename.equals_cs("banexception")) - cm = new ChannelModeList("EXCEPT", modechar[0]); - else if (modename.equals_cs("blockcaps")) - { - cm = new ChannelMode("BLOCKCAPS", modechar[0]); - ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("BLOCKCAPSBAN", "BAN", 'B')); - } - else if (modename.equals_cs("blockcolor")) - { - cm = new ChannelMode("BLOCKCOLOR", modechar[0]); - ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("BLOCKCOLORBAN", "BAN", 'c')); - } - else if (modename.equals_cs("c_registered")) - cm = new ChannelModeNoone("REGISTERED", modechar[0]); - else if (modename.equals_cs("censor")) - cm = new ChannelMode("CENSOR", modechar[0]); - else if (modename.equals_cs("delayjoin")) - cm = new ChannelMode("DELAYEDJOIN", modechar[0]); - else if (modename.equals_cs("delaymsg")) - cm = new SimpleNumberParamMode("DELAYMSG", modechar[0]); - else if (modename.equals_cs("filter")) - cm = new ChannelModeList("FILTER", modechar[0]); - else if (modename.equals_cs("flood")) - cm = new ChannelModeFlood(modechar[0]); - else if (modename.equals_cs("founder")) - cm = new ChannelModeStatus("OWNER", modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0, 4); - else if (modename.equals_cs("halfop")) - cm = new ChannelModeStatus("HALFOP", modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0, 1); - else if (modename.equals_cs("history")) - cm = new ChannelModeHistory(modechar[0]); - else if (modename.equals_cs("invex")) - cm = new ChannelModeList("INVITEOVERRIDE", modechar[0]); - else if (modename.equals_cs("inviteonly")) - cm = new ChannelMode("INVITE", modechar[0]); - else if (modename.equals_cs("joinflood")) - cm = new ColonDelimitedParamMode("JOINFLOOD", modechar[0]); - else if (modename.equals_cs("key")) - cm = new ChannelModeKey(modechar[0]); - else if (modename.equals_cs("kicknorejoin")) - cm = new SimpleNumberParamMode("NOREJOIN", modechar[0]); - else if (modename.equals_cs("limit")) - cm = new ChannelModeParam("LIMIT", modechar[0], true); - else if (modename.equals_cs("moderated")) - cm = new ChannelMode("MODERATED", modechar[0]); - else if (modename.equals_cs("nickflood")) - cm = new ColonDelimitedParamMode("NICKFLOOD", modechar[0]); - else if (modename.equals_cs("noctcp")) - { - cm = new ChannelMode("NOCTCP", modechar[0]); - ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("NOCTCPBAN", "BAN", 'C')); - } - else if (modename.equals_cs("noextmsg")) - cm = new ChannelMode("NOEXTERNAL", modechar[0]); - else if (modename.equals_cs("nokick")) - { - cm = new ChannelMode("NOKICK", modechar[0]); - ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("NOKICKBAN", "BAN", 'Q')); - } - else if (modename.equals_cs("noknock")) - cm = new ChannelMode("NOKNOCK", modechar[0]); - else if (modename.equals_cs("nonick")) - { - cm = new ChannelMode("NONICK", modechar[0]); - ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("NONICKBAN", "BAN", 'N')); - } - else if (modename.equals_cs("nonotice")) + if (modechar.empty()) + continue; + + if (modechar.length() == 2) { - cm = new ChannelMode("NONOTICE", modechar[0]); - ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("NONOTICEBAN", "BAN", 'T')); + symbol = modechar[0]; + modechar = modechar.substr(1); } - else if (modename.equals_cs("op")) - cm = new ChannelModeStatus("OP", modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0, 2); - else if (modename.equals_cs("operonly")) - cm = new ChannelModeOperOnly("OPERONLY", modechar[0]); - else if (modename.equals_cs("permanent")) - cm = new ChannelMode("PERM", modechar[0]); - else if (modename.equals_cs("private")) - cm = new ChannelMode("PRIVATE", modechar[0]); - else if (modename.equals_cs("redirect")) - cm = new ChannelModeRedirect(modechar[0]); - else if (modename.equals_cs("reginvite")) - cm = new ChannelMode("REGISTEREDONLY", modechar[0]); - else if (modename.equals_cs("regmoderated")) - cm = new ChannelMode("REGMODERATED", modechar[0]); - else if (modename.equals_cs("secret")) - cm = new ChannelMode("SECRET", modechar[0]); - else if (modename.equals_cs("sslonly")) + + ChannelMode *cm = ModeManager::FindChannelModeByChar(modechar[0]); + if (cm == nullptr) { - cm = new ChannelMode("SSL", modechar[0]); - ModeManager::AddChannelMode(new InspIRCdExtban::FinerprintMatcher("SSLBAN", "BAN", 'z')); + Log(owner) << "Warning: Uplink has unknown channel mode " << modename << "=" << modechar; + continue; } - else if (modename.equals_cs("stripcolor")) + + char modesymbol = cm->type == MODE_STATUS ? (anope_dynamic_static_cast<ChannelModeStatus *>(cm))->symbol : 0; + if (symbol != modesymbol) { - cm = new ChannelMode("STRIPCOLOR", modechar[0]); - ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("STRIPCOLORBAN", "BAN", 'S')); + Log(owner) << "Warning: Channel mode " << modename << " has a misconfigured status character"; + continue; } - else if (modename.equals_cs("topiclock")) - cm = new ChannelMode("TOPIC", modechar[0]); - else if (modename.equals_cs("voice")) - cm = new ChannelModeStatus("VOICE", modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0, 0); - /* Unknown status mode, (customprefix) - add it */ - else if (modechar.length() == 2) - cm = new ChannelModeStatus(modename.upper(), modechar[1], modechar[0], -1); - /* Unknown non status mode, add it to our list for later */ - else - chmodes[modechar[0]] = modename.upper(); - - if (cm) - ModeManager::AddChannelMode(cm); } } if (params[0].equals_cs("USERMODES") && params.size() > 1) @@ -872,54 +662,21 @@ struct IRCDMessageCapab : Message::Capab while (ssep.GetToken(capab)) { + if (capab.find('=') == Anope::string::npos) + continue; + Anope::string modename = capab.substr(0, capab.find('=')); Anope::string modechar = capab.substr(capab.find('=') + 1); - UserMode *um = NULL; - - if (modename.equals_cs("bot")) - um = new UserMode("BOT", modechar[0]); - else if (modename.equals_cs("callerid")) - um = new UserMode("CALLERID", modechar[0]); - else if (modename.equals_cs("cloak")) - um = new UserMode("CLOAK", modechar[0]); - else if (modename.equals_cs("deaf")) - um = new UserMode("DEAF", modechar[0]); - else if (modename.equals_cs("deaf_commonchan")) - um = new UserMode("COMMONCHANS", modechar[0]); - else if (modename.equals_cs("helpop")) - um = new UserModeOperOnly("HELPOP", modechar[0]); - else if (modename.equals_cs("hidechans")) - um = new UserMode("PRIV", modechar[0]); - else if (modename.equals_cs("hideoper")) - um = new UserModeOperOnly("HIDEOPER", modechar[0]); - else if (modename.equals_cs("invisible")) - um = new UserMode("INVIS", modechar[0]); - else if (modename.equals_cs("invis-oper")) - um = new UserModeOperOnly("INVISIBLE_OPER", modechar[0]); - else if (modename.equals_cs("oper")) - um = new UserModeOperOnly("OPER", modechar[0]); - else if (modename.equals_cs("regdeaf")) - um = new UserMode("REGPRIV", modechar[0]); - else if (modename.equals_cs("servprotect")) + + if (modechar.empty()) + continue; + + UserMode *um = ModeManager::FindUserModeByChar(modechar[0]); + if (um == nullptr) { - um = new UserModeNoone("PROTECTED", modechar[0]); - IRCD->DefaultPseudoclientModes += modechar; + Log(owner) << "Warning: Uplink has unknown user mode " << modename << "=" << modechar; + continue; } - else if (modename.equals_cs("showwhois")) - um = new UserMode("WHOIS", modechar[0]); - else if (modename.equals_cs("u_censor")) - um = new UserMode("CENSOR", modechar[0]); - else if (modename.equals_cs("u_registered")) - um = new UserModeNoone("REGISTERED", modechar[0]); - else if (modename.equals_cs("u_stripcolor")) - um = new UserMode("STRIPCOLOR", modechar[0]); - else if (modename.equals_cs("wallops")) - um = new UserMode("WALLOPS", modechar[0]); - else - umodes[modechar[0]] = modename.upper(); - - if (um) - ModeManager::AddUserMode(um); } } else if (params[0].equals_cs("MODULES") && params.size() > 1) @@ -950,25 +707,11 @@ struct IRCDMessageCapab : Message::Capab while (ssep.GetToken(module)) { if (module.equals_cs("m_services_account.so")) - { Servers::Capab.insert("SERVICES"); - ModeManager::AddChannelMode(new InspIRCdExtban::AccountMatcher("ACCOUNTBAN", "BAN", 'R')); - ModeManager::AddChannelMode(new InspIRCdExtban::UnidentifiedMatcher("UNREGISTEREDBAN", "BAN", 'U')); - } else if (module.equals_cs("m_chghost.so")) Servers::Capab.insert("CHGHOST"); else if (module.equals_cs("m_chgident.so")) Servers::Capab.insert("CHGIDENT"); - else if (module == "m_channelban.so") - ModeManager::AddChannelMode(new InspIRCdExtban::ChannelMatcher("CHANNELBAN", "BAN", 'j')); - else if (module == "m_gecosban.so") - ModeManager::AddChannelMode(new InspIRCdExtban::RealnameMatcher("REALNAMEBAN", "BAN", 'r')); - else if (module == "m_nopartmessage.so") - ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("PARTMESSAGEBAN", "BAN", 'p')); - else if (module == "m_serverban.so") - ModeManager::AddChannelMode(new InspIRCdExtban::ServerMatcher("SERVERBAN", "BAN", 's')); - else if (module == "m_muteban.so") - ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("QUIET", "BAN", 'm')); } } else if (params[0].equals_cs("CAPABILITIES") && params.size() > 1) @@ -977,89 +720,11 @@ struct IRCDMessageCapab : Message::Capab Anope::string capab; while (ssep.GetToken(capab)) { - if (capab.find("CHANMODES") != Anope::string::npos) - { - Anope::string modes(capab.begin() + 10, capab.end()); - commasepstream sep(modes); - Anope::string modebuf; - - sep.GetToken(modebuf); - for (size_t t = 0, end = modebuf.length(); t < end; ++t) - { - if (ModeManager::FindChannelModeByChar(modebuf[t])) - continue; - ModeManager::AddChannelMode(new ChannelModeList(chmodes[modebuf[t]], modebuf[t])); - } - - sep.GetToken(modebuf); - for (size_t t = 0, end = modebuf.length(); t < end; ++t) - { - if (ModeManager::FindChannelModeByChar(modebuf[t])) - continue; - ModeManager::AddChannelMode(new ChannelModeParam(chmodes[modebuf[t]], modebuf[t])); - } - - sep.GetToken(modebuf); - for (size_t t = 0, end = modebuf.length(); t < end; ++t) - { - if (ModeManager::FindChannelModeByChar(modebuf[t])) - continue; - ModeManager::AddChannelMode(new ChannelModeParam(chmodes[modebuf[t]], modebuf[t], true)); - } - - sep.GetToken(modebuf); - for (size_t t = 0, end = modebuf.length(); t < end; ++t) - { - if (ModeManager::FindChannelModeByChar(modebuf[t])) - continue; - ModeManager::AddChannelMode(new ChannelMode(chmodes[modebuf[t]], modebuf[t])); - } - } - else if (capab.find("USERMODES") != Anope::string::npos) - { - Anope::string modes(capab.begin() + 10, capab.end()); - commasepstream sep(modes); - Anope::string modebuf; - - sep.GetToken(modebuf); - sep.GetToken(modebuf); - - if (sep.GetToken(modebuf)) - for (size_t t = 0, end = modebuf.length(); t < end; ++t) - ModeManager::AddUserMode(new UserModeParam(umodes[modebuf[t]], modebuf[t])); - - if (sep.GetToken(modebuf)) - for (size_t t = 0, end = modebuf.length(); t < end; ++t) - ModeManager::AddUserMode(new UserMode(umodes[modebuf[t]], modebuf[t])); - } - else if (capab.find("MAXMODES=") != Anope::string::npos) + if (capab.find("MAXMODES=") != Anope::string::npos) { Anope::string maxmodes(capab.begin() + 9, capab.end()); IRCD->MaxModes = maxmodes.is_pos_number_only() ? convertTo<unsigned>(maxmodes) : 3; } - else if (capab.find("PREFIX=") != Anope::string::npos) - { - Anope::string modes(capab.begin() + 8, capab.begin() + capab.find(')')); - Anope::string chars(capab.begin() + capab.find(')') + 1, capab.end()); - short level = modes.length() - 1; - - for (size_t t = 0, end = modes.length(); t < end; ++t) - { - ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[t]); - if (cm == NULL || cm->type != MODE_STATUS) - { - Log() << "CAPAB PREFIX gave unknown channel status mode " << modes[t]; - continue; - } - - ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm); - cms->level = level--; - - Log(LOG_DEBUG) << cms->name << " is now level " << cms->level; - } - - ModeManager::RebuildStatusModes(); - } else if (capab == "GLOBOPS=1") Servers::Capab.insert("GLOBOPS"); } @@ -1086,9 +751,6 @@ struct IRCDMessageCapab : Message::Capab Log() << "CHGHOST missing, Usage disabled until module is loaded."; if (!Servers::Capab.count("CHGIDENT")) Log() << "CHGIDENT missing, Usage disabled until module is loaded."; - - chmodes.clear(); - umodes.clear(); } Message::Capab::Run(source, params); @@ -1695,6 +1357,40 @@ class ProtoInspIRCd20 : public Module { use_server_side_topiclock = conf->GetModule(this)->Get<bool>("use_server_side_topiclock"); use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock"); + + for (int i = 0; i < conf->CountBlock("extban"); ++i) + { + Configuration::Block *extban = conf->GetBlock("extban", i); + Anope::string name = extban->Get<Anope::string>("name"), + type = extban->Get<Anope::string>("type"), + base = extban->Get<Anope::string>("base"), + character = extban->Get<Anope::string>("character"); + + ChannelMode *cm; + + if (character.empty()) + continue; + + if (type == "channel") + cm = new InspIRCdExtban::ChannelMatcher(name, base, character[0]); + else if (type == "entry") + cm = new InspIRCdExtban::EntryMatcher(name, base, character[0]); + else if (type == "realname") + cm = new InspIRCdExtban::RealnameMatcher(name, base, character[0]); + else if (type == "account") + cm = new InspIRCdExtban::AccountMatcher(name, base, character[0]); + else if (type == "fingerprint") + cm = new InspIRCdExtban::FingerprintMatcher(name, base, character[0]); + else if (type == "unidentified") + cm = new InspIRCdExtban::UnidentifiedMatcher(name, base, character[0]); + else if (type == "server") + cm = new InspIRCdExtban::ServerMatcher(name, base, character[0]); + else + continue; + + if (!ModeManager::AddChannelMode(cm)) + delete cm; + } } void OnUserNickChange(User *u, const Anope::string &) override diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp index 9101a6788..6981e32bc 100644 --- a/modules/protocol/ngircd.cpp +++ b/modules/protocol/ngircd.cpp @@ -632,51 +632,6 @@ class ProtongIRCd : public Module IRCDMessageServer message_server; IRCDMessageTopic message_topic; - void AddModes() - { - /* Add user modes */ - ModeManager::AddUserMode(new UserMode("NOCTCP", 'b')); - ModeManager::AddUserMode(new UserMode("BOT", 'B')); - ModeManager::AddUserMode(new UserMode("COMMONCHANS", 'C')); - ModeManager::AddUserMode(new UserMode("INVIS", 'i')); - ModeManager::AddUserMode(new UserModeOperOnly("OPER", 'o')); - ModeManager::AddUserMode(new UserModeOperOnly("PROTECTED", 'q')); - ModeManager::AddUserMode(new UserModeOperOnly("RESTRICTED", 'r')); - ModeManager::AddUserMode(new UserModeNoone("REGISTERED", 'R')); - ModeManager::AddUserMode(new UserModeOperOnly("SNOMASK", 's')); - ModeManager::AddUserMode(new UserMode("WALLOPS", 'w')); - ModeManager::AddUserMode(new UserMode("CLOAK", 'x')); - - /* Add modes for ban, exception, and invite lists */ - ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b')); - ModeManager::AddChannelMode(new ChannelModeList("EXCEPT", 'e')); - ModeManager::AddChannelMode(new ChannelModeList("INVITEOVERRIDE", 'I')); - - /* Add channel user modes */ - ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0)); - ModeManager::AddChannelMode(new ChannelModeStatus("HALFOP", 'h', '%', 1)); - ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 2)); - ModeManager::AddChannelMode(new ChannelModeStatus("PROTECT", 'a', '&', 3)); - ModeManager::AddChannelMode(new ChannelModeStatus("OWNER", 'q', '~', 4)); - - /* Add channel modes */ - ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i')); - ModeManager::AddChannelMode(new ChannelModeKey('k')); - ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l', true)); - ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm')); - ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M')); - ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n')); - ModeManager::AddChannelMode(new ChannelMode("OPERONLY", 'O')); - ModeManager::AddChannelMode(new ChannelMode("PERM", 'P')); - ModeManager::AddChannelMode(new ChannelMode("NOKICK", 'Q')); - ModeManager::AddChannelMode(new ChannelModeNoone("REGISTERED", 'r')); - ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R')); - ModeManager::AddChannelMode(new ChannelMode("SECRET", 's')); - ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't')); - ModeManager::AddChannelMode(new ChannelMode("NOINVITE", 'V')); - ModeManager::AddChannelMode(new ChannelMode("SSL", 'z')); - } - public: ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR) , ircd_proto(this) @@ -713,8 +668,6 @@ class ProtongIRCd : public Module Servers::Capab.insert("QS"); - this->AddModes(); - } void OnUserNickChange(User *u, const Anope::string &) override diff --git a/modules/protocol/plexus.cpp b/modules/protocol/plexus.cpp index 32eeaeaba..027fa2a14 100644 --- a/modules/protocol/plexus.cpp +++ b/modules/protocol/plexus.cpp @@ -323,64 +323,6 @@ class ProtoPlexus : public Module IRCDMessageServer message_server; IRCDMessageUID message_uid; - void AddModes() - { - /* Add user modes */ - ModeManager::AddUserMode(new UserModeOperOnly("ADMIN", 'a')); - ModeManager::AddUserMode(new UserMode("NOCTCP", 'C')); - ModeManager::AddUserMode(new UserMode("DEAF", 'D')); - ModeManager::AddUserMode(new UserMode("SOFTCALLERID", 'G')); - ModeManager::AddUserMode(new UserMode("CALLERID", 'g')); - ModeManager::AddUserMode(new UserMode("INVIS", 'i')); - ModeManager::AddUserMode(new UserModeOperOnly("LOCOPS", 'l')); - ModeManager::AddUserMode(new UserModeOperOnly("OPER", 'o')); - ModeManager::AddUserMode(new UserModeOperOnly("NETADMIN", 'N')); - ModeManager::AddUserMode(new UserMode("PRIV", 'p')); - ModeManager::AddUserMode(new UserModeOperOnly("ROUTING", 'q')); - ModeManager::AddUserMode(new UserModeNoone("REGISTERED", 'r')); - ModeManager::AddUserMode(new UserMode("REGPRIV", 'R')); - ModeManager::AddUserMode(new UserModeOperOnly("SNOMASK", 's')); - ModeManager::AddUserMode(new UserModeNoone("SSL", 'S')); - ModeManager::AddUserMode(new UserModeNoone("PROTECTED", 'U')); - ModeManager::AddUserMode(new UserMode("WALLOPS", 'w')); - ModeManager::AddUserMode(new UserModeNoone("WEBIRC", 'W')); - ModeManager::AddUserMode(new UserMode("CLOAK", 'x')); - ModeManager::AddUserMode(new UserModeOperOnly("OPERWALLS", 'z')); - - /* b/e/I */ - ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b')); - ModeManager::AddChannelMode(new ChannelModeList("EXCEPT", 'e')); - ModeManager::AddChannelMode(new ChannelModeList("INVITEOVERRIDE", 'I')); - - /* v/h/o/a/q */ - ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0)); - ModeManager::AddChannelMode(new ChannelModeStatus("HALFOP", 'h', '%', 1)); - ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 2)); - ModeManager::AddChannelMode(new ChannelModeStatus("PROTECT", 'a', '&', 3)); - ModeManager::AddChannelMode(new ChannelModeStatus("OWNER", 'q', '~', 4)); - - /* l/k */ - ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l', true)); - ModeManager::AddChannelMode(new ChannelModeKey('k')); - - /* Add channel modes */ - ModeManager::AddChannelMode(new ChannelMode("BANDWIDTH", 'B')); - ModeManager::AddChannelMode(new ChannelMode("NOCTCP", 'C')); - ModeManager::AddChannelMode(new ChannelMode("BLOCKCOLOR", 'c')); - ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i')); - ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm')); - ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M')); - ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n')); - ModeManager::AddChannelMode(new ChannelMode("NONOTICE", 'N')); - ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p')); - ModeManager::AddChannelMode(new ChannelMode("SECRET", 's')); - ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't')); - ModeManager::AddChannelMode(new ChannelModeOperOnly("OPERONLY", 'O')); - ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R')); - ModeManager::AddChannelMode(new ChannelMode("SSL", 'S')); - ModeManager::AddChannelMode(new ChannelMode("PERM", 'z')); - } - public: ProtoPlexus(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR) , ircd_proto(this) @@ -426,8 +368,6 @@ class ProtoPlexus : public Module throw ModuleException("Unable to find hybrid"); if (!hybrid) throw ModuleException("No protocol interface for hybrid"); - - this->AddModes(); } ~ProtoPlexus() diff --git a/modules/protocol/ratbox.cpp b/modules/protocol/ratbox.cpp index 4156d1fbf..ec3e406b1 100644 --- a/modules/protocol/ratbox.cpp +++ b/modules/protocol/ratbox.cpp @@ -239,55 +239,6 @@ class ProtoRatbox : public Module IRCDMessageTBurst message_tburst; IRCDMessageUID message_uid; - void AddModes() - { - /* user modes */ - ModeManager::AddUserMode(new UserModeOperOnly("ADMIN", 'a')); - ModeManager::AddUserMode(new UserModeOperOnly("BOT", 'b')); - // c/C = con - // d = debug? - ModeManager::AddUserMode(new UserMode("DEAF", 'D')); - // f = full? - ModeManager::AddUserMode(new UserMode("CALLERID", 'g')); - ModeManager::AddUserMode(new UserMode("INVIS", 'i')); - // k = skill? - ModeManager::AddUserMode(new UserModeOperOnly("LOCOPS", 'l')); - // n = nchange - ModeManager::AddUserMode(new UserModeOperOnly("OPER", 'o')); - // r = rej - ModeManager::AddUserMode(new UserModeOperOnly("SNOMASK", 's')); - ModeManager::AddUserMode(new UserModeNoone("PROTECTED", 'S')); - // u = unauth? - ModeManager::AddUserMode(new UserMode("WALLOPS", 'w')); - // x = external? - // y = spy? - ModeManager::AddUserMode(new UserModeOperOnly("OPERWALLS", 'z')); - // Z = spy? - - /* b/e/I */ - ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b')); - ModeManager::AddChannelMode(new ChannelModeList("EXCEPT", 'e')); - ModeManager::AddChannelMode(new ChannelModeList("INVITEOVERRIDE", 'I')); - - /* v/h/o/a/q */ - ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0)); - ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 1)); - - /* l/k */ - ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l', true)); - ModeManager::AddChannelMode(new ChannelModeKey('k')); - - /* channel modes */ - ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i')); - ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm')); - ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n')); - ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p')); - ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'r')); - ModeManager::AddChannelMode(new ChannelMode("SECRET", 's')); - ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't')); - ModeManager::AddChannelMode(new ChannelMode("SSL", 'S')); - } - public: ProtoRatbox(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR) , ircd_proto(this) @@ -333,8 +284,6 @@ class ProtoRatbox : public Module throw ModuleException("Unable to find hybrid"); if (!hybrid) throw ModuleException("No protocol interface for hybrid"); - - this->AddModes(); } ~ProtoRatbox() diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp index 6324d18ca..b4b9893d3 100644 --- a/modules/protocol/unreal.cpp +++ b/modules/protocol/unreal.cpp @@ -606,169 +606,6 @@ class ChannelModeUnrealSSL : public ChannelMode } }; -struct IRCDMessageCapab : Message::Capab -{ - IRCDMessageCapab(Module *creator) : Message::Capab(creator, "PROTOCTL") { } - - void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) override - { - for (unsigned i = 0; i < params.size(); ++i) - { - Anope::string capab = params[i]; - - if (capab.find("CHANMODES") != Anope::string::npos) - { - Anope::string modes(capab.begin() + 10, capab.end()); - commasepstream sep(modes); - Anope::string modebuf; - - sep.GetToken(modebuf); - for (size_t t = 0, end = modebuf.length(); t < end; ++t) - { - switch (modebuf[t]) - { - case 'b': - ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b')); - - ModeManager::AddChannelMode(new UnrealExtban::ChannelMatcher("CHANNELBAN", "BAN", 'c')); - ModeManager::AddChannelMode(new UnrealExtban::EntryMatcher("JOINBAN", "BAN", 'j')); - ModeManager::AddChannelMode(new UnrealExtban::EntryMatcher("NONICKBAN", "BAN", 'n')); - ModeManager::AddChannelMode(new UnrealExtban::EntryMatcher("QUIET", "BAN", 'q')); - ModeManager::AddChannelMode(new UnrealExtban::RealnameMatcher("REALNAMEBAN", "BAN", 'r')); - ModeManager::AddChannelMode(new UnrealExtban::RegisteredMatcher("REGISTEREDBAN", "BAN", 'R')); - ModeManager::AddChannelMode(new UnrealExtban::AccountMatcher("ACCOUNTBAN", "BAN", 'a')); - continue; - case 'e': - ModeManager::AddChannelMode(new ChannelModeList("EXCEPT", 'e')); - continue; - case 'I': - ModeManager::AddChannelMode(new ChannelModeList("INVITEOVERRIDE", 'I')); - continue; - default: - ModeManager::AddChannelMode(new ChannelModeList("", modebuf[t])); - } - } - - sep.GetToken(modebuf); - for (size_t t = 0, end = modebuf.length(); t < end; ++t) - { - switch (modebuf[t]) - { - case 'k': - ModeManager::AddChannelMode(new ChannelModeKey('k')); - continue; - case 'f': - ModeManager::AddChannelMode(new ChannelModeFlood('f', false)); - continue; - case 'L': - ModeManager::AddChannelMode(new ChannelModeParam("REDIRECT", 'L')); - continue; - default: - ModeManager::AddChannelMode(new ChannelModeParam("", modebuf[t])); - } - } - - sep.GetToken(modebuf); - for (size_t t = 0, end = modebuf.length(); t < end; ++t) - { - switch (modebuf[t]) - { - case 'l': - ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l', true)); - continue; - case 'j': - ModeManager::AddChannelMode(new ChannelModeParam("JOINFLOOD", 'j', true)); - continue; - default: - ModeManager::AddChannelMode(new ChannelModeParam("", modebuf[t], true)); - } - } - - sep.GetToken(modebuf); - for (size_t t = 0, end = modebuf.length(); t < end; ++t) - { - switch (modebuf[t]) - { - case 'p': - ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p')); - continue; - case 's': - ModeManager::AddChannelMode(new ChannelMode("SECRET", 's')); - continue; - case 'm': - ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm')); - continue; - case 'n': - ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n')); - continue; - case 't': - ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't')); - continue; - case 'i': - ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i')); - continue; - case 'r': - ModeManager::AddChannelMode(new ChannelModeNoone("REGISTERED", 'r')); - continue; - case 'R': - ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R')); - continue; - case 'c': - ModeManager::AddChannelMode(new ChannelMode("BLOCKCOLOR", 'c')); - continue; - case 'O': - ModeManager::AddChannelMode(new ChannelModeOperOnly("OPERONLY", 'O')); - continue; - case 'A': - ModeManager::AddChannelMode(new ChannelModeOperOnly("ADMINONLY", 'A')); - continue; - case 'Q': - ModeManager::AddChannelMode(new ChannelMode("NOKICK", 'Q')); - continue; - case 'K': - ModeManager::AddChannelMode(new ChannelMode("NOKNOCK", 'K')); - continue; - case 'V': - ModeManager::AddChannelMode(new ChannelMode("NOINVITE", 'V')); - continue; - case 'C': - ModeManager::AddChannelMode(new ChannelMode("NOCTCP", 'C')); - continue; - case 'u': - ModeManager::AddChannelMode(new ChannelMode("AUDITORIUM", 'u')); - continue; - case 'z': - ModeManager::AddChannelMode(new ChannelMode("SSL", 'z')); - continue; - case 'N': - ModeManager::AddChannelMode(new ChannelMode("NONICK", 'N')); - continue; - case 'S': - ModeManager::AddChannelMode(new ChannelMode("STRIPCOLOR", 'S')); - continue; - case 'M': - ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M')); - continue; - case 'T': - ModeManager::AddChannelMode(new ChannelMode("NONOTICE", 'T')); - continue; - case 'G': - ModeManager::AddChannelMode(new ChannelMode("CENSOR", 'G')); - continue; - case 'Z': - ModeManager::AddChannelMode(new ChannelModeUnrealSSL("", 'Z')); - continue; - default: - ModeManager::AddChannelMode(new ChannelMode("", modebuf[t])); - } - } - } - } - - Message::Capab::Run(source, params); - } -}; - struct IRCDMessageChgHost : IRCDMessage { IRCDMessageChgHost(Module *creator) : IRCDMessage(creator, "CHGHOST", 2) { } @@ -1172,6 +1009,7 @@ class ProtoUnreal : public Module /* Core message handlers */ Message::Away message_away; + Message::Capab message_capab; Message::Error message_error; Message::Invite message_invite; Message::Join message_join; @@ -1190,7 +1028,6 @@ class ProtoUnreal : public Module Message::Whois message_whois; /* Our message handlers */ - IRCDMessageCapab message_capab; IRCDMessageChgHost message_chghost; IRCDMessageChgIdent message_chgident; IRCDMessageChgName message_chgname; @@ -1210,44 +1047,6 @@ class ProtoUnreal : public Module bool use_server_side_mlock; - void AddModes() - { - ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0)); - ModeManager::AddChannelMode(new ChannelModeStatus("HALFOP", 'h', '%', 1)); - ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 2)); - /* Unreal sends +q as * and +a as ~ */ - ModeManager::AddChannelMode(new ChannelModeStatus("PROTECT", 'a', '~', 3)); - ModeManager::AddChannelMode(new ChannelModeStatus("OWNER", 'q', '*', 4)); - - /* Add user modes */ - ModeManager::AddUserMode(new UserModeOperOnly("SERV_ADMIN", 'A')); - ModeManager::AddUserMode(new UserMode("BOT", 'B')); - ModeManager::AddUserMode(new UserModeOperOnly("CO_ADMIN", 'C')); - ModeManager::AddUserMode(new UserMode("CENSOR", 'G')); - ModeManager::AddUserMode(new UserModeOperOnly("HIDEOPER", 'H')); - ModeManager::AddUserMode(new UserMode("HIDEIDLE", 'I')); - ModeManager::AddUserMode(new UserModeOperOnly("NETADMIN", 'N')); - ModeManager::AddUserMode(new UserMode("REGPRIV", 'R')); - ModeManager::AddUserMode(new UserModeOperOnly("PROTECTED", 'S')); - ModeManager::AddUserMode(new UserMode("NOCTCP", 'T')); - ModeManager::AddUserMode(new UserMode("WEBTV", 'V')); - ModeManager::AddUserMode(new UserModeOperOnly("WHOIS", 'W')); - ModeManager::AddUserMode(new UserModeOperOnly("ADMIN", 'a')); - ModeManager::AddUserMode(new UserMode("DEAF", 'd')); - ModeManager::AddUserMode(new UserModeOperOnly("GLOBOPS", 'g')); - ModeManager::AddUserMode(new UserModeOperOnly("HELPOP", 'h')); - ModeManager::AddUserMode(new UserMode("INVIS", 'i')); - ModeManager::AddUserMode(new UserModeOperOnly("OPER", 'o')); - ModeManager::AddUserMode(new UserMode("PRIV", 'p')); - ModeManager::AddUserMode(new UserModeOperOnly("GOD", 'q')); - ModeManager::AddUserMode(new UserModeNoone("REGISTERED", 'r')); - ModeManager::AddUserMode(new UserModeOperOnly("SNOMASK", 's')); - ModeManager::AddUserMode(new UserModeNoone("VHOST", 't')); - ModeManager::AddUserMode(new UserMode("WALLOPS", 'w')); - ModeManager::AddUserMode(new UserMode("CLOAK", 'x')); - ModeManager::AddUserMode(new UserModeNoone("SSL", 'z')); - } - public: ProtoUnreal(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR) , EventHook<Event::UserNickChange>(EventHook<Event::UserNickChange>::Priority::FIRST) @@ -1257,6 +1056,7 @@ class ProtoUnreal : public Module , EventHook<Event::MLockEvents>(EventHook<Event::MLockEvents>::Priority::FIRST) , ircd_proto(this) , message_away(this) + , message_capab(this, "PROTOCTL") , message_error(this) , message_invite(this) , message_join(this) @@ -1275,7 +1075,6 @@ class ProtoUnreal : public Module , message_version(this) , message_whois(this) - , message_capab(this) , message_chghost(this) , message_chgident(this) , message_chgname(this) @@ -1295,13 +1094,41 @@ class ProtoUnreal : public Module , message_topic(this) , message_umode2(this) { - - this->AddModes(); } void OnReload(Configuration::Conf *conf) override { use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock"); + + for (int i = 0; i < conf->CountBlock("extban"); ++i) + { + Configuration::Block *extban = conf->GetBlock("extban", i); + Anope::string name = extban->Get<Anope::string>("name"), + type = extban->Get<Anope::string>("type"), + base = extban->Get<Anope::string>("base"), + character = extban->Get<Anope::string>("character"); + + ChannelMode *cm; + + if (character.empty()) + continue; + + if (type == "channel") + cm = new UnrealExtban::ChannelMatcher(name, base, character[0]); + else if (type == "entry") + cm = new UnrealExtban::EntryMatcher(name, base, character[0]); + else if (type == "realname") + cm = new UnrealExtban::RealnameMatcher(name, base, character[0]); + else if (type == "registered") + cm = new UnrealExtban::RegisteredMatcher(name, base, character[0]); + else if (type == "account") + cm = new UnrealExtban::AccountMatcher(name, base, character[0]); + else + continue; + + if (!ModeManager::AddChannelMode(cm)) + delete cm; + } } void OnUserNickChange(User *u, const Anope::string &) override diff --git a/src/bots.cpp b/src/bots.cpp index 697115ea0..205b0841c 100644 --- a/src/bots.cpp +++ b/src/bots.cpp @@ -25,7 +25,15 @@ ServiceBot::ServiceBot(const Anope::string &nnick, const Anope::string &nuser, c this->type = UserType::BOT; this->lastmsg = Anope::CurTime; this->introduced = false; - this->conf = false; + + bi = botinfo.Create(); + bi->bot = this; + + bi->SetNick(nnick); + bi->SetUser(nuser); + bi->SetHost(nhost); + bi->SetRealName(nreal); + bi->SetCreated(Anope::CurTime); Event::OnCreateBot(&Event::CreateBot::OnCreateBot, this); @@ -46,6 +54,9 @@ ServiceBot::ServiceBot(const Anope::string &nnick, const Anope::string &nuser, c ServiceBot::~ServiceBot() { + bi->bot = nullptr; + bi->Delete(); + Event::OnDelBot(&Event::DelBot::OnDelBot, this); // If we're synchronised with the uplink already, send the bot. @@ -219,6 +230,18 @@ ServiceBot* ServiceBot::Find(const Anope::string &nick, bool nick_only) return nullptr; } +void BotInfo::Delete() +{ + if (bot) + { + ServiceBot *b = bot; + bot = nullptr; + delete b; + } + + return Serialize::Object::Delete(); +} + void BotInfo::SetCreated(const time_t &t) { Set(&BotInfoType::created, t); diff --git a/src/channels.cpp b/src/channels.cpp index 7972dca6b..f77f1f4bc 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -306,12 +306,6 @@ void Channel::SetModeInternal(const MessageSource &setter, ChannelMode *ocm, con return; } - if (cm->type == MODE_LIST) - { - ChannelModeList *cml = anope_dynamic_static_cast<ChannelModeList *>(cm); - cml->OnAdd(this, param); - } - MOD_RESULT = Event::OnChannelModeSet(&Event::ChannelModeSet::OnChannelModeSet, this, setter, cm, param); /* Check if we should enforce mlock */ @@ -375,12 +369,6 @@ void Channel::RemoveModeInternal(const MessageSource &setter, ChannelMode *ocm, else this->modes.erase(cm->name); - if (cm->type == MODE_LIST) - { - ChannelModeList *cml = anope_dynamic_static_cast<ChannelModeList *>(cm); - cml->OnDel(this, param); - } - MOD_RESULT = Event::OnChannelModeUnset(&Event::ChannelModeUnset::OnChannelModeUnset, this, setter, cm, param); if (cm->name == "PERM") diff --git a/src/config.cpp b/src/config.cpp index 323a48519..47a9d8580 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -18,6 +18,8 @@ #include "event.h" #include "bots.h" #include "modules.h" +#include "servers.h" +#include "protocol.h" #include "modules/nickserv.h" using namespace Configuration; @@ -323,15 +325,8 @@ Conf::Conf() : Block("") o->SetVhost(vhost); } - for (std::pair<Anope::string, User *> p : UserListByNick) - { - User *u = p.second; - if (u->type != UserType::BOT) - continue; - - ServiceBot *bi = anope_dynamic_static_cast<ServiceBot *>(u); - bi->conf = false; - } + for (BotInfo *bi : Serialize::GetObjects<BotInfo *>(botinfo)) + bi->conf = nullptr; for (int i = 0; i < this->CountBlock("service"); ++i) { Block *service = this->GetBlock("service", i); @@ -349,73 +344,19 @@ Conf::Conf() : Block("") ValidateNotEmpty("service", "gecos", gecos); ValidateNoSpaces("service", "channels", channels); - ServiceBot *bi = ServiceBot::Find(nick, true); - if (!bi) - bi = new ServiceBot(nick, user, host, gecos, modes); - bi->conf = true; - - std::vector<Anope::string> oldchannels = bi->botchannels; - bi->botchannels.clear(); - commasepstream sep(channels); - for (Anope::string token; sep.GetToken(token);) + if (User *u = User::Find(nick, true)) { - bi->botchannels.push_back(token); - size_t ch = token.find('#'); - Anope::string chname, want_modes; - if (ch == Anope::string::npos) - chname = token; - else + if (u->type != UserType::BOT) { - want_modes = token.substr(0, ch); - chname = token.substr(ch); - } - bi->Join(chname); - Channel *c = Channel::Find(chname); - if (!c) - continue; // Can't happen - - c->botchannel = true; - - /* Remove all existing modes */ - ChanUserContainer *cu = c->FindUser(bi); - if (cu != NULL) - for (size_t j = 0; j < cu->status.Modes().length(); ++j) - c->RemoveMode(bi, ModeManager::FindChannelModeByChar(cu->status.Modes()[j]), bi->GetUID()); - /* Set the new modes */ - for (unsigned j = 0; j < want_modes.length(); ++j) - { - ChannelMode *cm = ModeManager::FindChannelModeByChar(want_modes[j]); - if (cm == NULL) - cm = ModeManager::FindChannelModeByChar(ModeManager::GetStatusChar(want_modes[j])); - if (cm && cm->type == MODE_STATUS) - c->SetMode(bi, cm, bi->GetUID()); + u->Kill(Me, "Nickname required by services"); } } - for (unsigned k = 0; k < oldchannels.size(); ++k) - { - size_t ch = oldchannels[k].find('#'); - Anope::string chname = oldchannels[k].substr(ch != Anope::string::npos ? ch : 0); - - bool found = false; - for (unsigned j = 0; j < bi->botchannels.size(); ++j) - { - ch = bi->botchannels[j].find('#'); - Anope::string ochname = bi->botchannels[j].substr(ch != Anope::string::npos ? ch : 0); - if (chname.equals_ci(ochname)) - found = true; - } - - if (found) - continue; + ServiceBot *sb = ServiceBot::Find(nick, true); + if (!sb) + sb = new ServiceBot(nick, user, host, gecos, modes); - Channel *c = Channel::Find(chname); - if (c) - { - c->botchannel = false; - bi->Part(c); - } - } + sb->bi->conf = service; } for (int i = 0; i < this->CountBlock("log"); ++i) @@ -512,6 +453,72 @@ Conf::Conf() : Block("") this->CommandGroups.push_back(gr); } + for (int i = 0; i < this->CountBlock("usermode"); ++i) + { + Block *usermode = this->GetBlock("usermode", i); + + Anope::string nname = usermode->Get<Anope::string>("name"), + character = usermode->Get<Anope::string>("character"); + bool oper_only = usermode->Get<bool>("oper_only"), + setable = usermode->Get<bool>("setable"), + param = usermode->Get<bool>("param"); + + ValidateNotEmpty("usermode", "name", nname); + + if (character.length() != 1) + throw ConfigException("Usermode character length must be 1"); + + Usermode um; + um.name = nname; + um.character = character[0]; + um.param = param; + um.oper_only = oper_only; + um.setable = setable; + + this->Usermodes.push_back(um); + } + + for (int i = 0; i < this->CountBlock("channelmode"); ++i) + { + Block *channelmode = this->GetBlock("channelmode", i); + + Anope::string nname = channelmode->Get<Anope::string>("name"), + character = channelmode->Get<Anope::string>("character"), + status = channelmode->Get<Anope::string>("status"), + param_regex = channelmode->Get<Anope::string>("param_regex"); + bool oper_only = channelmode->Get<bool>("oper_only"), + setable = channelmode->Get<bool>("setable"), + list = channelmode->Get<bool>("list"), + param = channelmode->Get<bool>("param"), + param_unset = channelmode->Get<bool>("param_unset", "yes"); + int level = channelmode->Get<int>("level"); + + ValidateNotEmpty("usermode", "name", nname); + + if (character.length() != 1) + throw ConfigException("Channelmode character length must be 1"); + + if (status.length() > 1) + throw ConfigException("Channelmode status must be at most one character"); + + if (list || !param_regex.empty() || param_unset || !status.empty()) + param = true; + + Channelmode cm; + cm.name = nname; + cm.character = character[0]; + cm.status = !status.empty() ? status[0] : 0; + cm.param_regex = param_regex; + cm.oper_only = oper_only; + cm.setable = setable; + cm.list = list; + cm.param = param; + cm.param_unset = param_unset; + cm.level = level; + + this->Channelmodes.push_back(cm); + } + for (int i = 0; i < this->CountBlock("casemap"); ++i) { Block *casemap = this->GetBlock("casemap", i); @@ -602,6 +609,8 @@ void Conf::Post(Conf *old) if (std::find(old->ModulesAutoLoad.begin(), old->ModulesAutoLoad.end(), this->ModulesAutoLoad[i]) == old->ModulesAutoLoad.end()) ModuleManager::LoadModule(this->ModulesAutoLoad[i], NULL); + ModeManager::Apply(old); + /* Apply opertype changes, as non-conf opers still point to the old oper types */ for (Oper *o : Serialize::GetObjects<Oper *>(operblock)) { @@ -622,6 +631,46 @@ void Conf::Post(Conf *old) } } } + + for (BotInfo *bi : Serialize::GetObjects<BotInfo *>(botinfo)) + { + if (!bi->conf) + { + bi->Delete(); + continue; + } + + for (int i = 0; i < bi->conf->CountBlock("channel"); ++i) + { + Block *channel = bi->conf->GetBlock("channel", i); + + const Anope::string &chname = channel->Get<Anope::string>("name"), + &modes = channel->Get<Anope::string>("modes"); + + bi->bot->Join(chname); + + Channel *c = Channel::Find(chname); + if (!c) + continue; // Can't happen + + c->botchannel = true; + + /* Remove all existing modes */ + ChanUserContainer *cu = c->FindUser(bi->bot); + if (cu != NULL) + for (size_t j = 0; j < cu->status.Modes().length(); ++j) + c->RemoveMode(bi->bot, ModeManager::FindChannelModeByChar(cu->status.Modes()[j]), bi->bot->GetUID()); + /* Set the new modes */ + for (unsigned j = 0; j < modes.length(); ++j) + { + ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[j]); + if (cm == NULL) + cm = ModeManager::FindChannelModeByChar(ModeManager::GetStatusChar(modes[j])); + if (cm && cm->type == MODE_STATUS) + c->SetMode(bi->bot, cm, bi->bot->GetUID()); + } + } + } } Block *Conf::GetModule(Module *m) diff --git a/src/init.cpp b/src/init.cpp index 7e29b43b0..d649a2f6e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -526,6 +526,8 @@ void Anope::Init(int ac, char **av) block = Config->GetBlock("options"); srand(block->Get<unsigned>("seed") ^ time(NULL)); + ModeManager::Apply(nullptr); + /* load modules */ Log() << "Loading modules..."; for (int i = 0; i < Config->CountBlock("module"); ++i) diff --git a/src/modes.cpp b/src/modes.cpp index c0bd79cc7..2ea11d3a3 100644 --- a/src/modes.cpp +++ b/src/modes.cpp @@ -39,9 +39,6 @@ static std::map<Anope::string, UserMode *> UserModesByName; /* Sorted by status */ static std::vector<ChannelModeStatus *> ChannelModesByStatus; -/* Number of generic modes we support */ -unsigned ModeManager::GenericChannelModes = 0, ModeManager::GenericUserModes = 0; - struct StackerInfo { /* Modes to be added */ @@ -127,6 +124,12 @@ Mode::~Mode() bool Mode::CanSet(User *u) const { + if (!setable) + return false; + + if (oper_only) + return u && u->HasMode("OPER"); + return true; } @@ -189,6 +192,11 @@ ChannelModeParam::ChannelModeParam(const Anope::string &cm, char mch, bool ma) : this->type = MODE_PARAM; } +bool ChannelModeParam::IsValid(Anope::string &value) const +{ + return std::regex_search(value.str(), param_validation); +} + ChannelModeStatus::ChannelModeStatus(const Anope::string &mname, char modeChar, char msymbol, short mlevel) : ChannelMode(mname, modeChar), symbol(msymbol), level(mlevel) { this->type = MODE_STATUS; @@ -230,34 +238,6 @@ ChannelMode *ChannelModeVirtual<T>::Wrap(Anope::string ¶m) template class ChannelModeVirtual<ChannelMode>; template class ChannelModeVirtual<ChannelModeList>; -bool UserModeOperOnly::CanSet(User *u) const -{ - return u && u->HasMode("OPER"); -} - -bool UserModeNoone::CanSet(User *u) const -{ - return false; -} - -bool ChannelModeKey::IsValid(Anope::string &value) const -{ - if (!value.empty() && value.find(':') == Anope::string::npos && value.find(',') == Anope::string::npos) - return true; - - return false; -} - -bool ChannelModeOperOnly::CanSet(User *u) const -{ - return u && u->HasMode("OPER"); -} - -bool ChannelModeNoone::CanSet(User *u) const -{ - return false; -} - void StackerInfo::AddMode(Mode *mode, bool set, const Anope::string ¶m) { bool is_param = mode->type == MODE_PARAM; @@ -398,12 +378,6 @@ bool ModeManager::AddUserMode(UserMode *um) if (ModeManager::FindUserModeByName(um->name) != NULL) return false; - if (um->name.empty()) - { - um->name = stringify(++GenericUserModes); - Log() << "ModeManager: Added generic support for user mode " << um->mchar; - } - unsigned want = um->mchar; if (want >= UserModesIdx.size()) UserModesIdx.resize(want + 1); @@ -425,12 +399,6 @@ bool ModeManager::AddChannelMode(ChannelMode *cm) if (ModeManager::FindChannelModeByName(cm->name) != NULL) return false; - if (cm->name.empty()) - { - cm->name = stringify(++GenericChannelModes); - Log() << "ModeManager: Added generic support for channel mode " << cm->mchar; - } - if (cm->mchar) { unsigned want = cm->mchar; @@ -739,6 +707,54 @@ void ModeManager::StackerDel(Mode *m) } } +void ModeManager::Apply(Configuration::Conf *old) +{ + /* XXX remove old modes */ + + for (Configuration::Channelmode &cm : Config->Channelmodes) + { + ChannelMode *mode; + + if (cm.character) + Log(LOG_DEBUG) << "Creating channelmode " << cm.name << " (" << cm.character << ")"; + else + Log(LOG_DEBUG) << "Creating channelmode " << cm.name; + + if (cm.list) + mode = new ChannelModeList(cm.name, cm.character); + else if (cm.status) + mode = new ChannelModeStatus(cm.name, cm.character, cm.status, cm.level); + else if (cm.param) + mode = new ChannelModeParam(cm.name, cm.character, !cm.param_unset); + else + mode = new ChannelMode(cm.name, cm.character); + + mode->SetSetable(cm.setable); + mode->SetOperOnly(cm.oper_only); + + if (!AddChannelMode(mode)) + delete mode; + } + + for (Configuration::Usermode &um : Config->Usermodes) + { + UserMode *mode; + + Log(LOG_DEBUG) << "Creating usermode " << um.name << " (" << um.character << ")"; + + if (um.param) + mode = new UserModeParam(um.name, um.character); + else + mode = new UserMode(um.name, um.character); + + mode->SetSetable(um.setable); + mode->SetOperOnly(um.oper_only); + + if (!AddUserMode(mode)) + delete mode; + } +} + Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh), cidr_len(0) { Anope::string n, u, h; diff --git a/src/servers.cpp b/src/servers.cpp index 394d4d6e8..9f94bc78e 100644 --- a/src/servers.cpp +++ b/src/servers.cpp @@ -48,94 +48,7 @@ Server::Server(Server *up, const Anope::string &sname, unsigned shops, const Ano /* Check to be sure this isn't a juped server */ if (Me == this->uplink && !juped) - { - /* Now do mode related stuff as we know what modes exist .. */ - for (std::pair<Anope::string, User *> p : UserListByNick) - { - User *u = p.second; - if (u->type != UserType::BOT) - continue; - - ServiceBot *bi = anope_dynamic_static_cast<ServiceBot *>(u); - Anope::string modes = !bi->botmodes.empty() ? ("+" + bi->botmodes) : IRCD->DefaultPseudoclientModes; - - bi->SetModesInternal(bi, modes.c_str()); - for (unsigned i = 0; i < bi->botchannels.size(); ++i) - { - size_t h = bi->botchannels[i].find('#'); - if (h == Anope::string::npos) - continue; - Anope::string chname = bi->botchannels[i].substr(h); - Channel *c = Channel::Find(chname); - if (c && c->FindUser(bi)) - { - Anope::string want_modes = bi->botchannels[i].substr(0, h); - for (unsigned j = 0; j < want_modes.length(); ++j) - { - ChannelMode *cm = ModeManager::FindChannelModeByChar(want_modes[j]); - if (cm == NULL) - cm = ModeManager::FindChannelModeByChar(ModeManager::GetStatusChar(want_modes[j])); - if (cm && cm->type == MODE_STATUS) - { - MessageSource ms = bi; - c->SetModeInternal(ms, cm, bi->nick); - } - } - } - } - } - - IRCD->SendBOB(); - - for (unsigned i = 0; i < Me->GetLinks().size(); ++i) - { - Server *s = Me->GetLinks()[i]; - - if (s->juped) - IRCD->SendServer(s); - } - - /* We make the bots go online */ - for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it) - { - User *u = it->second; - - ServiceBot *bi = ServiceBot::Find(u->GetUID()); - if (bi) - { - //XLine x(bi->nick, "Reserved for services"); - //IRCD->SendSQLine(NULL, &x); - } - - IRCD->SendClientIntroduction(u); - if (bi) - bi->introduced = true; - } - - for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it) - { - Channel *c = it->second; - - if (c->users.empty()) - IRCD->SendChannel(c); - else - for (Channel::ChanUserList::const_iterator cit = c->users.begin(), cit_end = c->users.end(); cit != cit_end; ++cit) - IRCD->SendJoin(cit->second->user, c, &cit->second->status); - - for (Channel::ModeList::const_iterator it2 = c->GetModes().begin(); it2 != c->GetModes().end(); ++it2) - { - ChannelMode *cm = ModeManager::FindChannelModeByName(it2->first); - if (!cm || cm->type != MODE_LIST) - continue; - ModeManager::StackerAdd(c->ci->WhoSends(), c, cm, true, it2->second); - } - - if (!c->topic.empty() && !c->topic_setter.empty()) - IRCD->SendTopic(c->ci->WhoSends(), c); - - c->syncing = true; - } - } + Burst(); } Event::OnNewServer(&Event::NewServer::OnNewServer, this); @@ -177,6 +90,60 @@ void Server::Delete(const Anope::string &reason) delete this; } +void Server::Burst() +{ + IRCD->SendBOB(); + + for (unsigned i = 0; i < Me->GetLinks().size(); ++i) + { + Server *s = Me->GetLinks()[i]; + + if (s->juped) + IRCD->SendServer(s); + } + + /* We make the bots go online */ + for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it) + { + User *u = it->second; + + ServiceBot *bi = ServiceBot::Find(u->GetUID()); + if (bi) + { + //XLine x(bi->nick, "Reserved for services"); + //IRCD->SendSQLine(NULL, &x); + } + + IRCD->SendClientIntroduction(u); + if (bi) + bi->introduced = true; + } + + for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it) + { + Channel *c = it->second; + + if (c->users.empty()) + IRCD->SendChannel(c); + else + for (Channel::ChanUserList::const_iterator cit = c->users.begin(), cit_end = c->users.end(); cit != cit_end; ++cit) + IRCD->SendJoin(cit->second->user, c, &cit->second->status); + + for (Channel::ModeList::const_iterator it2 = c->GetModes().begin(); it2 != c->GetModes().end(); ++it2) + { + ChannelMode *cm = ModeManager::FindChannelModeByName(it2->first); + if (!cm || cm->type != MODE_LIST) + continue; + ModeManager::StackerAdd(c->ci->WhoSends(), c, cm, true, it2->second); + } + + if (!c->topic.empty() && !c->topic_setter.empty()) + IRCD->SendTopic(c->ci->WhoSends(), c); + + c->syncing = true; + } +} + const Anope::string &Server::GetName() const { return this->name; |
