forked from lesderid/salty-ircd
Implement WHOIS
This commit is contained in:
parent
132c0229a7
commit
0ac5cc07ba
|
@ -7,6 +7,7 @@ import std.range;
|
|||
import std.conv;
|
||||
import std.socket;
|
||||
import std.utf;
|
||||
import std.datetime;
|
||||
|
||||
import vibe.core.core;
|
||||
import vibe.stream.operations;
|
||||
|
@ -28,6 +29,12 @@ class Connection
|
|||
string hostname;
|
||||
char[] modes;
|
||||
|
||||
SysTime lastMessageTime;
|
||||
|
||||
string awayMessage;
|
||||
|
||||
bool connected;
|
||||
|
||||
@property auto channels() { return _server.channels.filter!(c => c.members.canFind(this)); }
|
||||
|
||||
@property string mask() { return nick ~ "!" ~ user ~ "@" ~ hostname; }
|
||||
|
@ -35,10 +42,6 @@ class Connection
|
|||
@property bool isOperator() { return modes.canFind('o') || modes.canFind('O'); }
|
||||
@property string servername() { return _server.name; } //TODO: Support server linking
|
||||
|
||||
string awayMessage;
|
||||
|
||||
bool connected;
|
||||
|
||||
this(TCPConnection connection, Server server)
|
||||
{
|
||||
_connection = connection;
|
||||
|
@ -104,6 +107,13 @@ class Connection
|
|||
continue;
|
||||
}
|
||||
|
||||
//NOTE: The RFCs don't specify what 'being idle' means
|
||||
// We assume that it's sending any message that isn't a PING/PONG.
|
||||
if(message.command != "PING" && message.command != "PONG")
|
||||
{
|
||||
lastMessageTime = Clock.currTime;
|
||||
}
|
||||
|
||||
writeln("C> " ~ message.toString);
|
||||
|
||||
//TODO: If RFC-strictness is off, ignore case
|
||||
|
@ -185,6 +195,10 @@ class Connection
|
|||
if(!registered) sendErrNotRegistered();
|
||||
else onIson(message);
|
||||
break;
|
||||
case "WHOIS":
|
||||
if(!registered) sendErrNotRegistered();
|
||||
else onWhois(message);
|
||||
break;
|
||||
default:
|
||||
writeln("unknown command '", message.command, "'");
|
||||
send(Message(_server.name, "421", [nick, message.command, "Unknown command"]));
|
||||
|
@ -658,6 +672,33 @@ class Connection
|
|||
_server.ison(this, message.parameters[0].split);
|
||||
}
|
||||
|
||||
void onWhois(Message message)
|
||||
{
|
||||
if(message.parameters.length < 1)
|
||||
{
|
||||
sendErrNoNickGiven();
|
||||
return;
|
||||
}
|
||||
else if(message.parameters.length > 1)
|
||||
{
|
||||
notImplemented("forwarding WHOIS to another server");
|
||||
return;
|
||||
}
|
||||
|
||||
auto mask = message.parameters[0];
|
||||
//TODO: Support user masks
|
||||
if(!_server.canFindConnectionByNick(mask) || !_server.findConnectionByNick(mask)[0].visibleTo(this))
|
||||
{
|
||||
sendErrNoSuchNick(mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
_server.whois(this, mask);
|
||||
}
|
||||
|
||||
send(Message(_server.name, "318", [nick, mask, "End of WHOIS list"], true));
|
||||
}
|
||||
|
||||
void sendWhoReply(string channel, Connection user, uint hopCount)
|
||||
{
|
||||
auto flags = user.modes.canFind('a') ? "G" : "H";
|
||||
|
|
|
@ -26,6 +26,7 @@ class Server
|
|||
enum versionString = "salty-ircd-" ~ packageVersion;
|
||||
|
||||
string name;
|
||||
enum string info = "A salty-ircd server"; //TODO: Make server info configurable
|
||||
|
||||
string motd;
|
||||
|
||||
|
@ -364,6 +365,24 @@ class Server
|
|||
connection.send(Message(name, "303", [connection.nick, reply], true));
|
||||
}
|
||||
|
||||
void whois(Connection connection, string mask)
|
||||
{
|
||||
auto user = findConnectionByNick(mask)[0];
|
||||
|
||||
connection.send(Message(name, "311", [connection.nick, user.nick, user.user, user.hostname, "*", user.hostname], true));
|
||||
//TODO: Send information about the user's actual server (which is not necessarily this one)
|
||||
connection.send(Message(name, "312", [connection.nick, user.nick, name, info], true));
|
||||
if(user.isOperator)
|
||||
{
|
||||
connection.send(Message(name, "313", [connection.nick, user.nick, "is an IRC operator"], true));
|
||||
}
|
||||
auto idleSeconds = (Clock.currTime - user.lastMessageTime).total!"seconds";
|
||||
connection.send(Message(name, "317", [connection.nick, user.nick, idleSeconds.to!string, "seconds idle"], true));
|
||||
//TODO: Prepend nick prefix (i.e. '@' or '+') when applicable
|
||||
auto userChannels = user.channels.map!(c => c.name).join(' ');
|
||||
connection.send(Message(name, "319", [connection.nick, user.nick, userChannels], true));
|
||||
}
|
||||
|
||||
void listen(ushort port = 6667)
|
||||
{
|
||||
listenTCP(port, &acceptConnection);
|
||||
|
|
Loading…
Reference in New Issue