diff options
Diffstat (limited to 'modules/channel_op.py')
| -rw-r--r-- | modules/channel_op.py | 103 |
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) |
