summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2015-09-06 16:47:57 -0400
committerAdam <Adam@anope.org>2015-09-06 16:48:25 -0400
commitc6a92296d4175a2d2276c2d5a46894af3d9085f4 (patch)
tree8e6dfe9fd21825f53a1e32641bc71e701e6c853e
parent263dc290d296af2fcdf7f8a9f04735935e9c2580 (diff)
Allow configuring modes
-rw-r--r--data/bahamut.example.conf170
-rw-r--r--data/botserv.example.conf18
-rw-r--r--data/chanserv.example.conf9
-rw-r--r--data/example.conf25
-rw-r--r--data/global.example.conf9
-rw-r--r--data/hostserv.example.conf9
-rw-r--r--data/hybrid.example.conf233
-rw-r--r--data/inspircd20.example.conf540
-rw-r--r--data/memoserv.example.conf9
-rw-r--r--data/ngircd.example.conf234
-rw-r--r--data/nickserv.example.conf9
-rw-r--r--data/operserv.example.conf9
-rw-r--r--data/plexus.example.conf294
-rw-r--r--data/ratbox.example.conf174
-rw-r--r--data/unreal.example.conf478
-rw-r--r--include/bots.h8
-rw-r--r--include/config.h35
-rw-r--r--include/modes.h76
-rw-r--r--include/servers.h2
-rw-r--r--modules/commands/bs_bot.cpp7
-rw-r--r--modules/protocol/bahamut.cpp40
-rw-r--r--modules/protocol/charybdis.cpp2
-rw-r--r--modules/protocol/hybrid.cpp49
-rw-r--r--modules/protocol/inspircd20.cpp440
-rw-r--r--modules/protocol/ngircd.cpp47
-rw-r--r--modules/protocol/plexus.cpp60
-rw-r--r--modules/protocol/ratbox.cpp51
-rw-r--r--modules/protocol/unreal.cpp237
-rw-r--r--src/bots.cpp25
-rw-r--r--src/channels.cpp12
-rw-r--r--src/config.cpp189
-rw-r--r--src/init.cpp2
-rw-r--r--src/modes.cpp102
-rw-r--r--src/servers.cpp143
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> &params) 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> &params) 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 &param)
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 &param)
{
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;