diff --git a/IRCBot.py b/IRCBot.py index 7d15cd4d..df8dce83 100644 --- a/IRCBot.py +++ b/IRCBot.py @@ -65,13 +65,33 @@ class Bot(object): if not next or time_left < next: next = time_left - return next if not next == None and next <= 30 else 30; + if next == None: + return None + if next < 0: + return 0 + return next def call_timers(self): for timer in self.timers[:]: if timer.due(): timer.call() if timer.done(): self.timer_setting_remove(timer) + def next_write(self): + next = None + for server in self.servers.values(): + timeout = server.send_timeout() + if not next or timeout < next: + next = timeout + if next == None: + return None + if next < 0: + return 0 + return next + + def get_poll_timeout(self): + next_timer = self.next_timer() or 30 + next_write = self.next_write() or 30 + return min(next_timer, next_write) def register_read(self, server): self.poll.modify(server.fileno(), select.EPOLLIN) @@ -82,7 +102,7 @@ class Bot(object): select.EPOLLIN|select.EPOLLOUT) def since_last_read(self, server): - return None if not server.last_read else time.time( + return None if not server.last_read else time.monotonic( )-server.last_read def disconnect(self, server): @@ -115,7 +135,7 @@ class Bot(object): def run(self): while self.running: self.lock.acquire() - events = self.poll.poll(self.next_timer()) + events = self.poll.poll(self.get_poll_timeout()) self.call_timers() for fd, event in events: if fd in self.servers: diff --git a/IRCLineHandler.py b/IRCLineHandler.py index 38bf49a0..f67beb58 100644 --- a/IRCLineHandler.py +++ b/IRCLineHandler.py @@ -141,6 +141,9 @@ def handle_353(data): channel.add_user(user) for mode in modes: channel.add_mode(mode, nickname) +@handler(description="on-join user list has finished", default_event=True) +def handle_366(data): + data.server.send_who(data.args[2]) @handler(description="on user joining channel") def handle_JOIN(data): @@ -161,7 +164,6 @@ def handle_JOIN(data): del server.attempted_join[channel.name] bot.events.on("self").on("join").call(channel=channel, server=data.server) - server.send_who(channel.name) channel.send_mode() @handler(description="on user parting channel") diff --git a/IRCServer.py b/IRCServer.py index ee280010..5575e680 100644 --- a/IRCServer.py +++ b/IRCServer.py @@ -30,6 +30,7 @@ class Server(object): self.channel_modes = [] self.channel_types = [] self.last_read = None + self.last_send = None self.attempted_join = {} self.ping_sent = False self.name = None @@ -205,7 +206,7 @@ class Server(object): decoded_lines.append(line) if not decoded_lines: self.disconnect() - self.last_read = time.time() + self.last_read = time.monotonic() self.ping_sent = False return decoded_lines def send(self, data): @@ -217,9 +218,16 @@ class Server(object): print(encoded.decode("utf8")) def _send(self): self.write_buffer = self.write_buffer[self.socket.send( - self.write_buffer):] + self.write_buffer[:512]):] + self.last_send = time.monotonic() def waiting_send(self): - return bool(len(self.write_buffer)) + return bool(len(self.write_buffer)) and self.send_timeout() == 0 + def send_timeout(self): + if self.last_send == None: + return 0 + timeout = (self.last_send)+0.5 + timeout = timeout-time.monotonic() + return max(timeout, 0) def send_user(self, username, realname): self.send("USER %s - - :%s" % (username, realname))