aboutsummaryrefslogtreecommitdiff
path: root/modules/channel_op.py
diff options
context:
space:
mode:
Diffstat (limited to 'modules/channel_op.py')
-rw-r--r--modules/channel_op.py103
1 files changed, 76 insertions, 27 deletions
diff --git a/modules/channel_op.py b/modules/channel_op.py
index e7ab7bc9..d37e27b4 100644
--- a/modules/channel_op.py
+++ b/modules/channel_op.py
@@ -26,6 +26,28 @@ class TargetType(enum.Enum):
MASK = 2
ACCOUNT = 3
+def _mlock(s):
+ modes, *args = s.split(" ")
+
+ adds = ""
+ removes = ""
+ add = True
+ for c in modes:
+ if c == "+":
+ add = True
+ elif c == "-":
+ add = False
+ elif add:
+ adds += c
+ else:
+ removes += c
+
+ return (
+ "" if not adds else f"+{''.join(adds)}",
+ "" if not removes else f"-{''.join(removes)}",
+ args
+ )
+
KICK_REASON_SETTING = utils.Setting("default-kick-reason",
"Set the default kick reason", example="have a nice trip")
@@ -33,10 +55,6 @@ BAN_FORMATTING = "${n} = nick, ${u} = username, ${h} = hostname, ${a} = account"
@utils.export("channelset", utils.Setting("ban-format",
"Set ban format (%s)" % BAN_FORMATTING, example="*!${u}@${h}"))
-@utils.export("channelset", utils.Setting("ban-format-account",
- "Set ban format for users with accounts (%s)" % BAN_FORMATTING,
- example="~a:${a}"))
-
@utils.export("serverset", utils.OptionsSetting(
list(QUIET_METHODS.keys()), "quiet-method",
"Set this server's method of muting users"))
@@ -47,6 +65,10 @@ BAN_FORMATTING = "${n} = nick, ${u} = username, ${h} = hostname, ${a} = account"
@utils.export("botset", KICK_REASON_SETTING)
@utils.export("serverset", KICK_REASON_SETTING)
@utils.export("channelset", KICK_REASON_SETTING)
+
+@utils.export("channelset", utils.FunctionSetting(_mlock, "mlock",
+ "Set which modes are locked on and off for the current channel",
+ example="+mnt-z"))
class Module(ModuleManager.BaseModule):
_name = "ChanOp"
@@ -75,23 +97,6 @@ class Module(ModuleManager.BaseModule):
reason = reason or self._kick_reason(server, channel)
channel.send_kicks(nicknames, reason)
- def _format_hostmask(self, user, s):
- vars = {}
- vars["n"] = vars["nickname"] = user.nickname
- vars["u"] = vars["username"] = user.username
- vars["h"] = vars["hostname"] = user.hostname
- vars["a"] = vars["account"] = user.account or ""
- return utils.parse.format_token_replace(s, vars)
- def _get_hostmask(self, channel, user):
- if not user.account == None:
- account_format = channel.get_setting("ban-format-account", None)
- if not account_format == None:
- return self._format_hostmask(user, account_format)
-
- format = channel.get_setting("ban-format", "*!${u}@${h}")
- return self._format_hostmask(user, format)
-
-
@utils.hook("received.command.topic")
@utils.kwarg("require_mode", "o")
@utils.kwarg("require_access", "low,topic")
@@ -209,7 +214,8 @@ class Module(ModuleManager.BaseModule):
elif flag == "V" and identified:
modes.append(("v", user.nickname))
elif flag == "b":
- modes.append(("b", self._get_hostmask(channel, user)))
+ mask = self.exports.get("ban-mask")(server, channel, user)
+ modes.append(("b", mask))
kick_reason = "User is banned from this channel"
new_modes = []
@@ -394,15 +400,16 @@ class Module(ModuleManager.BaseModule):
elif spec[2][0] in ["user", "cuser"]:
users = [spec[2][1]]
elif spec[2][0] == "word":
- masks = [spec[2][1]]
+ args = [spec[2][1]]
target_type, mode, prefix = self._find_mode(type, server)
if users:
if target_type == TargetType.MASK:
- args = [self._get_hostmask(spec[0], u) for u in users]
+ mask_f = self.exports.get("ban-mask")
+ args = [mask_f(server, spec[0], u) for u in users]
elif target_type == TargetType.NICKNAME:
args = [
- u.nickname for u in users if not spec[0].has_mode(u, mode)]
+ u.nickname for u in users if not spec[0].has_umode(u, mode)]
elif target_type == TargetType.ACCOUNT:
args = [u.account for u in users if not u.account == None]
@@ -428,7 +435,9 @@ class Module(ModuleManager.BaseModule):
users = args = []
if event["spec"][1][0] == "user":
- masks = [self._get_hostmask(event["spec"][0], event["spec"][1][1])]
+ mask_f = self.exports.get("ban-mask")
+ masks = [
+ mask_f(event["server"], event["spec"][0], event["spec"][1][1])]
elif event["spec"][1][0] == "word":
masks = self._list_query_event(event["spec"][0],
event["spec"][1][1], mode, prefix)
@@ -457,7 +466,7 @@ class Module(ModuleManager.BaseModule):
_, mode, _ = self._find_mode(
event["hook"].get_kwarg("type"), event["server"])
valid_nicks = [
- u.nickname for u in users if event["spec"][0].has_mode(u, mode)]
+ u.nickname for u in users if event["spec"][0].has_umode(u, mode)]
if valid_nicks:
event["spec"][0].send_modes([(mode, a) for a in valid_nicks], False)
@@ -489,3 +498,43 @@ class Module(ModuleManager.BaseModule):
if modes:
event["spec"][0].send_modes(modes, False)
+
+ @utils.hook("received.324")
+ @utils.hook("received.mode.channel")
+ def on_modes(self, event):
+ mlock = event["channel"].get_setting("mlock", None)
+ if mlock:
+ changes_adds = ""
+ changes_removes = ""
+ changes_args = []
+ adds, removes, args = mlock
+ args = args.copy() # cached settings objects are mutable
+
+ for mode in adds[1:]:
+ if not event["channel"].has_mode(mode):
+ if (mode in event["server"].channel_list_modes or
+ mode in event["server"].channel_parametered_modes or
+ mode in event["server"].channel_setting_modes):
+ changes_adds += mode
+ changes_args.append(args.pop(0))
+ elif mode in event["server"].channel_modes:
+ changes_adds += mode
+
+ for mode in removes[1:]:
+ if event["channel"].has_mode(mode):
+ if (mode in event["server"].channel_list_modes or
+ mode in event["server"].channel_parametered_modes):
+ changes_removes += mode
+ changes_args.append(args.pop(0))
+ elif (mode in event["server"].channel_setting_modes or
+ mode in event["server"].channel_modes):
+ changes_removes += mode
+
+ out = ""
+ if changes_adds:
+ out += f"+{changes_adds}"
+ if changes_removes:
+ out += f"-{changes_removes}"
+
+ if out:
+ event["channel"].send_mode(out, changes_args)