From 7f98ba8310b8d48ee28f3fe90c99845b80edcf2b Mon Sep 17 00:00:00 2001 From: jesopo Date: Mon, 17 Feb 2020 15:16:00 +0000 Subject: [PATCH] send multiple KICKs in the same line when possible --- modules/channel_op.py | 13 ++++++------- src/IRCChannel.py | 12 ++++++++++-- src/IRCServer.py | 1 + src/core_modules/line_handler/core.py | 7 +++++++ 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/modules/channel_op.py b/modules/channel_op.py index e87fc6b9..6bbedf5e 100644 --- a/modules/channel_op.py +++ b/modules/channel_op.py @@ -55,9 +55,9 @@ class Module(ModuleManager.BaseModule): server.get_setting("default-kick-reason", self.bot.get_setting("default-kick-reson", KICK_REASON))) - def _kick(self, server, channel, target_user, reason): + def _kick(self, server, channel, nicknames, reason): reason = reason or self._kick_reason(server, channel) - channel.send_kick(target_user.nickname, reason) + channel.send_kicks(nicknames, reason) @utils.hook("received.command.kick") @utils.hook("received.command.k", alias_of="kick") @@ -66,8 +66,8 @@ class Module(ModuleManager.BaseModule): @utils.kwarg("help", "Kick a user from a channel") @utils.spec("!<#channel>r~channel !cuser ?string") def kick(self, event): - self._kick(event["server"], event["spec"][0], event["spec"][1], - event["spec"][2]) + self._kick(event["server"], event["spec"][0], + [event["spec"][1].nickname], event["spec"][2]) def _format_hostmask(self, user, s): vars = {} @@ -143,9 +143,8 @@ class Module(ModuleManager.BaseModule): users = event["spec"][2][1] else: users = [event["spec"][2][1]] - for user in users: - self._kick(event["server"], event["spec"][0], user, - event["spec"][3]) + self._kick(event["server"], event["spec"][0], + [u.nickname for u in users], event["spec"][3]) @utils.hook("received.command.op") @utils.hook("received.command.up", alias_of="op") diff --git a/src/IRCChannel.py b/src/IRCChannel.py index fc1317df..5848646a 100644 --- a/src/IRCChannel.py +++ b/src/IRCChannel.py @@ -215,17 +215,25 @@ class Channel(IRCObject.Object): def send_tagmsg(self, tags: dict): return self.server.send_tagmsg(self.name, tags) + def _chunks(self, n: int, l: typing.List[str]): + return [l[i:i+n] for i in range(0, len(l), n)] + def send_mode(self, mode: str=None, target: typing.List[str]=None): return self.server.send_mode(self.name, mode, target) def send_modes(self, mode: str, add: bool, args: typing.List[str]): chunk_n = int(self.server.isupport.get("MODES", "3") or "6") - chunks = [args[i:i+chunk_n] for i in range(0, len(args), chunk_n)] - for chunk in chunks: + for chunk in self._chunks(chunk_n, args): mode_str = "%s%s" % ("+" if add else "-", mode*len(chunk)) self.server.send_mode(self.name, mode_str, chunk) def send_kick(self, target: str, reason: str=None): return self.server.send_kick(self.name, target, reason) + def send_kicks(self, targets: typing.List[str], reason: str=None): + chunk_n = self.server.targmax.get("KICK", 1) + for chunk in self._chunks(chunk_n, targets): + chan_str = ",".join([self.name]*len(chunk)) + self.server.send_kick(chan_str, ",".join(chunk), reason) + def send_ban(self, hostmask: str): return self.server.send_mode(self.name, "+b", [hostmask]) def send_unban(self, hostmask: str): diff --git a/src/IRCServer.py b/src/IRCServer.py index 3549981b..bf25f494 100644 --- a/src/IRCServer.py +++ b/src/IRCServer.py @@ -62,6 +62,7 @@ class Server(IRCObject.Object): self.channel_types = ["#"] self.case_mapping = "rfc1459" self.statusmsg = [] # type: typing.List[str] + self.targmax = {} self.motd_lines = [] # type: typing.List[str] self.motd_done = False diff --git a/src/core_modules/line_handler/core.py b/src/core_modules/line_handler/core.py index c72bcb77..a7075613 100644 --- a/src/core_modules/line_handler/core.py +++ b/src/core_modules/line_handler/core.py @@ -61,6 +61,13 @@ def handle_005(events, event): list_numeric = qiuet.get(2, "367") # RPL_BANLIST end_numeric = quiet.get(3, "368") # RPL_ENDOFBANLIST event["server"].quiet = [quiet[0], prefix, list_numeric, end_numeric] + if "TARGMAX" in isupport: + targmax = {} + for piece in isupport["TARGMAX"].split(","): + cmd, _, n = piece.partition(":") + if n: + targmax[cmd] = int(n) + event["server"].targmax = targmax events.on("received.005").call(isupport=isupport, server=event["server"])