From f582756a32ea4470bd0978d6258be92ec40cef43 Mon Sep 17 00:00:00 2001 From: Forest Belton <65484+forestbelton@users.noreply.github.com> Date: Tue, 22 Jun 2021 02:40:55 -0400 Subject: [PATCH] Make first user in channel an operator --- paircd/channel.py | 16 +++++++++++----- paircd/handler/join.py | 6 ++++-- paircd/handler/who.py | 13 +++++++++---- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/paircd/channel.py b/paircd/channel.py index a14f8f9..c573f0b 100644 --- a/paircd/channel.py +++ b/paircd/channel.py @@ -1,6 +1,6 @@ -from asyncio import Queue +from collections import defaultdict from dataclasses import dataclass, field -from typing import Dict, List +from typing import Dict, Set from paircd.client import Client from paircd.message import Message @@ -11,13 +11,16 @@ class Channel: name: str topic: str = "" clients_by_nick: Dict[str, Client] = field(default_factory=dict) - msg_queue: Queue = field(default_factory=Queue) + modes_by_nick: Dict[str, Set[str]] = field(default_factory=lambda: defaultdict(set)) def add_client(self, client: Client) -> None: self.clients_by_nick[client.nickname] = client + if len(self.clients_by_nick) == 1: + self.modes_by_nick[client.nickname].add("@") def remove_client_by_nick(self, nick: str) -> None: del self.clients_by_nick[nick] + del self.modes_by_nick[nick] def write_message(self, msg: Message) -> None: for client in self.clients_by_nick.values(): @@ -26,5 +29,8 @@ class Channel: continue client.write_message(msg) - def get_modes(self) -> List[str]: - return [] + def get_modes(self) -> Set[str]: + return set() + + def get_user_modes_by_nick(self, nick: str) -> Set[str]: + return self.modes_by_nick[nick] diff --git a/paircd/handler/join.py b/paircd/handler/join.py index ae9174a..07ebcc3 100644 --- a/paircd/handler/join.py +++ b/paircd/handler/join.py @@ -36,8 +36,10 @@ class JoinHandler(CommandHandler): RPL_TOPIC(client.nickname, channel_name, channel.topic) ) - client.log("TODO: implement user channel modes", level=logging.WARN) - channel_members = list(channel.clients_by_nick.keys()) + channel_members = [ + f"{''.join(channel.get_user_modes_by_nick(member))}{member}" + for member in channel.clients_by_nick.keys() + ] client.write_message( # "=" means public channel (ref: https://modern.ircdocs.horse/#rplnamreply-353) RPL_NAMREPLY(client.nickname, "=", channel_name, " ".join(channel_members)) diff --git a/paircd/handler/who.py b/paircd/handler/who.py index 8fd81f7..294c924 100644 --- a/paircd/handler/who.py +++ b/paircd/handler/who.py @@ -1,4 +1,5 @@ import logging +from paircd.channel import Channel from paircd.reply import RPL_ENDOFWHO, RPL_WHOREPLY from paircd.client import Client @@ -25,19 +26,23 @@ class WhoHandler(CommandHandler): channel = server.get_channel_by_name(name) for member in channel.clients_by_nick.values(): - self.who_reply(client, name, member) + self.who_reply(client, channel, member) self.who_end(client, name) - def who_reply(self, client: Client, channel_name: str, member: Client) -> None: + def who_reply(self, client: Client, channel: Channel, member: Client) -> None: + modes = "H" # H = here, G = gone + for mode in channel.get_user_modes_by_nick(member.nickname): + modes += mode + msg = RPL_WHOREPLY( client.nickname, - channel_name, + channel.name, member.username, member.hostname, "localhost", # server member.nickname, # TODO: Implement - "H", # H = here, G = gone + modes, "0", # hop count member.realname, )