Implement PRIVMSG

This commit is contained in:
Les De Ridder 2017-03-15 22:35:15 +01:00
parent c157a1e7a6
commit dfe9e65786
No known key found for this signature in database
GPG Key ID: 5EC132DFA85DB372
4 changed files with 88 additions and 2 deletions

View File

@ -37,4 +37,12 @@ class Channel
connection.send(Message(_server.name, "353", [connection.nick, channelType, name, members.map!(m => m.nick).join(' ')], true));
connection.send(Message(_server.name, "366", [connection.nick, name, "End of NAMES list"], true));
}
void sendPrivMsg(Connection sender, string text)
{
foreach(member; members.filter!(m => m.nick != sender.nick))
{
member.send(Message(sender.mask, "PRIVMSG", [name, text], true));
}
}
}

View File

@ -118,6 +118,9 @@ class Connection
case "PART":
onPart(message);
break;
case "PRIVMSG":
onPrivMsg(message);
break;
default:
writeln("unknown command '", message.command, "'");
send(Message(_server.name, "421", [nick, message.command, "Unknown command"]));
@ -176,7 +179,7 @@ class Connection
auto channel = message.parameters[0];
if(!Server.isValidChannelName(channel))
{
send(Message(_server.name, "403", [nick, channel, "No such channel"], true));
sendErrNoSuchChannel(channel);
}
else
{
@ -191,7 +194,7 @@ class Connection
auto channel = message.parameters[0];
if(!Server.isValidChannelName(channel))
{
send(Message(_server.name, "403", [nick, channel, "No such channel"], true));
sendErrNoSuchChannel(channel);
}
else if(!channels.canFind!(c => c.name == channel))
{
@ -210,6 +213,62 @@ class Connection
}
}
void onPrivMsg(Message message)
{
//TODO: Support special message targets
auto target = message.parameters[0];
auto text = message.parameters[1];
if(message.parameters.length == 0)
{
send(Message(_server.name, "411", [nick, "No recipient given (PRIVMSG)"], true));
return;
}
if(message.parameters.length == 1)
{
send(Message(_server.name, "412", [nick, "No text to send"], true));
return;
}
if(Server.isValidChannelName(target))
{
if(!_server.channels.canFind!(c => c.name == target))
{
sendErrNoSuchNick(target);
}
else
{
_server.sendToChannel(this, target, text);
}
}
else if(Server.isValidNick(target))
{
if(!_server.connections.canFind!(c => c.nick == target))
{
sendErrNoSuchNick(target);
}
else
{
_server.sendToUser(this, target, text);
}
}
else
{
//is this the right response?
sendErrNoSuchNick(target);
}
}
void sendErrNoSuchChannel(string name)
{
send(Message(_server.name, "403", [nick, name, "No such channel"], true));
}
void sendErrNoSuchNick(string name)
{
send(Message(_server.name, "401", [nick, name, "No such nick/channel"], true));
}
string getHost()
{
auto address = parseAddress(_connection.peerAddress);

View File

@ -24,6 +24,7 @@ struct Message
line = line[prefix.length + 1 .. $];
}
//stop early when no space character can be found (message without parameters)
if(!line.canFind(' '))
{
return Message(prefix, line, [], false);

View File

@ -58,6 +58,12 @@ class Server
return (name.startsWith('#') || name.startsWith('&')) && name.length <= 200;
}
static bool isValidNick(string name)
{
//TODO: Use the real rules
return !name.startsWith('#') && !name.startsWith('&') && name.length <= 9;
}
void join(Connection connection, string channelName)
{
auto channelRange = channels.find!(c => c.name == channelName);
@ -132,6 +138,18 @@ class Server
}
}
void sendToChannel(Connection sender, string target, string text)
{
auto channel = channels.find!(c => c.name == target)[0];
channel.sendPrivMsg(sender, text);
}
void sendToUser(Connection sender, string target, string text)
{
auto user = connections.find!(c => c.nick == target)[0];
user.send(Message(sender.mask, "PRIVMSG", [target, text], true));
}
void listen(ushort port = 6667)
{
listenTCP(port, &acceptConnection);