diff --git a/source/ircd/connection.d b/source/ircd/connection.d index 4f56fbe..34714f7 100644 --- a/source/ircd/connection.d +++ b/source/ircd/connection.d @@ -157,6 +157,10 @@ class Connection if(!registered) sendErrNotRegistered(); else onNames(message); break; + case "LIST": + if(!registered) sendErrNotRegistered(); + else onList(message); + break; default: writeln("unknown command '", message.command, "'"); send(Message(_server.name, "421", [nick, message.command, "Unknown command"])); @@ -481,6 +485,25 @@ class Connection } } + void onList(Message message) + { + if(message.parameters.length > 1) + { + notImplemented("forwarding LIST to another server"); + return; + } + + if(message.parameters.length == 0) + { + _server.sendFullList(this); + } + else + { + auto channelNames = message.parameters[0].split(','); + _server.sendPartialList(this, channelNames); + } + } + void sendWhoReply(string channel, Connection user, uint hopCount) { auto flags = user.modes.canFind('a') ? "G" : "H"; @@ -495,6 +518,16 @@ class Connection send(Message(_server.name, "301", [nick, target, message], true)); } + void sendRplList(string channelName, ulong visibleCount, string topic) + { + send(Message(_server.name, "322", [nick, channelName, visibleCount.to!string, topic], true)); + } + + void sendRplListEnd() + { + send(Message(_server.name, "323", [nick, "End of LIST"], true)); + } + void sendRplEndOfNames(string channelName) { send(Message(_server.name, "366", [nick, channelName, "End of NAMES list"], true)); diff --git a/source/ircd/server.d b/source/ircd/server.d index f509c86..fa5df94 100644 --- a/source/ircd/server.d +++ b/source/ircd/server.d @@ -233,6 +233,24 @@ class Server connection.sendRplEndOfNames("*"); } + void sendFullList(Connection connection) + { + foreach(channel; channels.filter!(c => c.visibleTo(connection))) + { + connection.sendRplList(channel.name, channel.members.filter!(m => m.visibleTo(connection)).array.length, channel.topic); + } + connection.sendRplListEnd(); + } + + void sendPartialList(Connection connection, string[] channelNames) + { + foreach(channel; channels.filter!(c => channelNames.canFind(c.name) && c.visibleTo(connection))) + { + connection.sendRplList(channel.name, channel.members.filter!(m => m.visibleTo(connection)).array.length, channel.topic); + } + connection.sendRplListEnd(); + } + void listen(ushort port = 6667) { listenTCP(port, &acceptConnection);