diff --git a/paircd/client.py b/paircd/client.py index b7c9550..8190f93 100644 --- a/paircd/client.py +++ b/paircd/client.py @@ -1,6 +1,8 @@ from asyncio import StreamReader, StreamWriter, Queue from dataclasses import dataclass, field +from datetime import datetime from logging import log, INFO +from paircd.reply import RPL_CREATED, RPL_WELCOME, RPL_YOURHOST from paircd.message import Message from typing import Set @@ -35,3 +37,19 @@ class Client: def write_message(self, message: Message) -> None: self.msg_queue.put_nowait(message.encode()) + + def register(self) -> None: + if self.registered: + return + + if not (self.nickname and self.username and self.realname): + return + + self.registered = True + self.log("registered") + + self.write_message(RPL_WELCOME(self.nickname, self.id())) + self.write_message(RPL_YOURHOST(self.nickname, "localhost", "paircd-0.0.1")) + + # TODO: Pull timestamp from Server instance + self.write_message(RPL_CREATED(self.nickname, datetime.utcnow())) diff --git a/paircd/handler/nick.py b/paircd/handler/nick.py index 65d7e5b..f0b319f 100644 --- a/paircd/handler/nick.py +++ b/paircd/handler/nick.py @@ -26,6 +26,4 @@ class NickHandler(CommandHandler): channel = server.get_channel_by_name(channel_name) channel.remove_client_by_nick(client.nickname) - if client.username and client.realname: - client.registered = True - client.log("registered") + client.register() diff --git a/paircd/handler/user.py b/paircd/handler/user.py index 4134890..0f38a99 100644 --- a/paircd/handler/user.py +++ b/paircd/handler/user.py @@ -18,6 +18,4 @@ class UserHandler(CommandHandler): client.username = msg.args[0] client.realname = msg.args[3] - if client.nickname: - client.registered = True - client.log("registered") + client.register() diff --git a/paircd/reply.py b/paircd/reply.py index e902a01..5af2201 100644 --- a/paircd/reply.py +++ b/paircd/reply.py @@ -1,4 +1,4 @@ -from typing import Any, Callable, List, Optional +from typing import Any, Callable, List, Optional, Union from paircd.message import Message @@ -15,7 +15,7 @@ def cmd_fn(cmd: str, tmpl: str) -> Callable: return fn -def reply_fn(cmd: int, tmpl: str) -> Callable: +def reply_fn(cmd: Union[int, str], tmpl: str) -> Callable: def fn(target: str, *args: List[Any]) -> Message: msg = f"{target} {tmpl.format(*args)}" return Message(cmd=str(cmd), args=[msg]) @@ -33,6 +33,9 @@ ERR_NOSUCHNICK = reply_fn(401, "{0} :No such nick/channel") ERR_NOSUCHSERVER = reply_fn(402, "{0}: No such server") # Command responses +RPL_WELCOME = reply_fn("001", "Welcome to the Internet Relay Network {0}") +RPL_YOURHOST = reply_fn("002", "Your host is {0}, running version {1}") +RPL_CREATED = reply_fn("003", "This server was created {0}") RPL_WHOISUSER = reply_fn(311, "{0} {1} {2} * :{3}") RPL_ENDOFWHO = reply_fn(315, "{0} :End of /WHO list") RPL_ENDOFWHOIS = reply_fn(318, "{0} :End of /WHOIS list") diff --git a/paircd/server.py b/paircd/server.py index 22f982e..394be59 100644 --- a/paircd/server.py +++ b/paircd/server.py @@ -1,4 +1,5 @@ from dataclasses import dataclass, field +from datetime import datetime from typing import Dict from paircd.client import Client @@ -9,6 +10,7 @@ from paircd.channel import Channel class Server: clients_by_nick: Dict[str, Client] = field(default_factory=dict) channels_by_name: Dict[str, Channel] = field(default_factory=dict) + create_time: datetime = field(default_factory=datetime.utcnow) def add_client(self, client: Client) -> None: self.clients_by_nick[client.nickname] = client