Implement KICK

This commit is contained in:
Les De Ridder 2017-04-30 22:41:48 +02:00
parent 3c43cfa64b
commit 4fa71ee798
No known key found for this signature in database
GPG Key ID: 5EC132DFA85DB372
3 changed files with 112 additions and 25 deletions

View File

@ -36,6 +36,24 @@ class Channel
}
}
void part(Connection connection, string partMessage)
{
foreach(member; members)
{
if(partMessage !is null)
{
member.send(Message(connection.mask, "PART", [name, partMessage], true));
}
else
{
member.send(Message(connection.mask, "PART", [name]));
}
}
members = members.remove!(m => m == connection);
memberModes.remove(connection);
}
void sendNames(Connection connection, bool sendRplEndOfNames = true)
{
string channelType;
@ -63,16 +81,6 @@ class Channel
}
}
string prefixedNick(Connection member)
{
if(memberModes[member].canFind('o'))
{
return '@' ~ member.nick;
}
return member.nick;
}
void sendPrivMsg(Connection sender, string text)
{
foreach(member; members.filter!(m => m.nick != sender.nick))
@ -111,6 +119,27 @@ class Channel
}
}
void kick(Connection kicker, Connection user, string comment)
{
foreach(member; members)
{
member.send(Message(kicker.mask, "KICK", [name, user.nick, comment], true));
}
members = members.remove!(m => m == user);
memberModes.remove(user);
}
string prefixedNick(Connection member)
{
if(memberModes[member].canFind('o'))
{
return '@' ~ member.nick;
}
return member.nick;
}
bool visibleTo(Connection connection)
{
return members.canFind(connection) || !modes.canFind('s') && !modes.canFind('p');

View File

@ -213,6 +213,9 @@ class Connection
case "KILL":
onKill(message);
break;
case "KICK":
onKick(message);
break;
default:
writeln("unknown command '", message.command, "'");
send(Message(_server.name, "421", [nick, message.command, "Unknown command"]));
@ -739,6 +742,60 @@ class Connection
_server.kill(this, nick, comment);
}
void onKick(Message message)
{
if(message.parameters.length < 2)
{
sendErrNeedMoreParams(message.command);
return;
}
auto channelList = message.parameters[0].split(',');
auto userList = message.parameters[1].split(',');
auto comment = message.parameters.length > 2 ? message.parameters[2] : nick;
if(channelList.length != 1 && channelList.length != userList.length)
{
//TODO: Figure out what the right error is here
sendErrNeedMoreParams(message.command);
return;
}
foreach(i, nick; userList)
{
auto channelName = channelList[0];
if(channelList.length != 1)
{
channelName = channelList[i];
}
if(!_server.canFindChannelByName(channelName))
{
sendErrNoSuchChannel(channelName);
}
else
{
auto channel = _server.findChannelByName(channelName)[0];
if(!channel.members.canFind(this))
{
sendErrNotOnChannel(channelName);
}
else if(!channel.memberModes[this].canFind('o'))
{
sendErrChanopPrivsNeeded(channelName);
}
else if(!channel.members.canFind!(m => m.nick.toIRCLower == nick.toIRCLower))
{
sendErrUserNotInChannel(nick, channelName);
}
else
{
_server.kick(this, channelName, nick, comment);
}
}
}
}
void sendWhoReply(string channel, Connection user, uint hopCount)
{
auto flags = user.modes.canFind('a') ? "G" : "H";
@ -789,6 +846,11 @@ class Connection
send(Message(_server.name, "431", [nick, "No nickname given"], true));
}
void sendErrUserNotInChannel(string otherNick, string channel)
{
send(Message(_server.name, "441", [nick, otherNick, channel, "They aren't on that channel"], true));
}
void sendErrNotOnChannel(string channel)
{
send(Message(_server.name, "442", [nick, channel, "You're not on that channel"], true));

View File

@ -156,21 +156,9 @@ class Server
{
auto channel = connection.channels.array.find!(c => c.name.toIRCLower == channelName.toIRCLower)[0];
foreach(member; channel.members)
{
if(partMessage !is null)
{
member.send(Message(connection.mask, "PART", [channelName, partMessage], true));
}
else
{
member.send(Message(connection.mask, "PART", [channelName]));
}
}
channel.part(connection, partMessage);
channel.members = channel.members.remove!(m => m == connection);
if(channel.members.length == 0)
if(channel.members.empty)
{
channels = channels.remove!(c => c == channel);
}
@ -183,7 +171,7 @@ class Server
{
peers ~= channel.members;
channel.members = channel.members.remove!(m => m == connection);
if(channel.members.length == 0)
if(channel.members.empty)
{
channels = channels.remove!(c => c == channel);
}
@ -397,6 +385,14 @@ class Server
user.closeConnection();
}
void kick(Connection kicker, string channelName, string nick, string comment)
{
auto channel = findChannelByName(channelName)[0];
auto user = findConnectionByNick(nick)[0];
channel.kick(kicker, user, comment);
}
void listen(ushort port = 6667)
{
listenTCP(port, &acceptConnection);