From c6a92296d4175a2d2276c2d5a46894af3d9085f4 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 6 Sep 2015 16:47:57 -0400 Subject: Allow configuring modes --- data/bahamut.example.conf | 170 +++++++++++++ data/botserv.example.conf | 18 +- data/chanserv.example.conf | 9 - data/example.conf | 25 +- data/global.example.conf | 9 - data/hostserv.example.conf | 9 - data/hybrid.example.conf | 233 +++++++++++++++++ data/inspircd20.example.conf | 540 ++++++++++++++++++++++++++++++++++++++++ data/memoserv.example.conf | 9 - data/ngircd.example.conf | 234 +++++++++++++++++ data/nickserv.example.conf | 9 - data/operserv.example.conf | 9 - data/plexus.example.conf | 294 ++++++++++++++++++++++ data/ratbox.example.conf | 174 +++++++++++++ data/unreal.example.conf | 478 +++++++++++++++++++++++++++++++++++ include/bots.h | 8 +- include/config.h | 35 ++- include/modes.h | 76 +----- include/servers.h | 2 + modules/commands/bs_bot.cpp | 7 +- modules/protocol/bahamut.cpp | 40 --- modules/protocol/charybdis.cpp | 2 + modules/protocol/hybrid.cpp | 49 ---- modules/protocol/inspircd20.cpp | 440 +++++--------------------------- modules/protocol/ngircd.cpp | 47 ---- modules/protocol/plexus.cpp | 60 ----- modules/protocol/ratbox.cpp | 51 ---- modules/protocol/unreal.cpp | 237 +++--------------- src/bots.cpp | 25 +- src/channels.cpp | 12 - src/config.cpp | 189 ++++++++------ src/init.cpp | 2 + src/modes.cpp | 102 ++++---- src/servers.cpp | 143 ++++------- 34 files changed, 2545 insertions(+), 1202 deletions(-) create mode 100644 data/bahamut.example.conf create mode 100644 data/hybrid.example.conf create mode 100644 data/inspircd20.example.conf create mode 100644 data/ngircd.example.conf create mode 100644 data/plexus.example.conf create mode 100644 data/ratbox.example.conf create mode 100644 data/unreal.example.conf 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 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 ModulesAutoLoad; /* After how many characters do we wrap lines? */ unsigned int LineWrap; + std::vector Usermodes; + std::vector 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(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(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(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 chmodes, umodes; - IRCDMessageCapab(Module *creator) : Message::Capab(creator, "CAPAB") { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } void Run(MessageSource &source, const std::vector ¶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(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(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(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 dis