Use case-insensitive comparisons for nicknames and channel names
This commit is contained in:
parent
e4fdf0ac91
commit
f60b3cc988
|
@ -205,7 +205,7 @@ class Connection
|
|||
|
||||
auto newNick = message.parameters[0];
|
||||
|
||||
if(!_server.isNickAvailable(newNick))
|
||||
if(!_server.isNickAvailable(newNick) && newNick.toIRCLower != nick.toIRCLower)
|
||||
{
|
||||
send(Message(_server.name, "433", [nick, newNick, "Nickname already in use"]));
|
||||
return;
|
||||
|
@ -311,7 +311,7 @@ class Connection
|
|||
{
|
||||
sendErrNoSuchChannel(channel);
|
||||
}
|
||||
else if(!channels.canFind!(c => c.name == channel))
|
||||
else if(!_server.canFindChannelByName(channel))
|
||||
{
|
||||
send(Message(_server.name, "442", [nick, channel, "You're not on that channel"], true));
|
||||
}
|
||||
|
@ -347,7 +347,7 @@ class Connection
|
|||
|
||||
if(Server.isValidChannelName(target))
|
||||
{
|
||||
if(!_server.channels.canFind!(c => c.name == target))
|
||||
if(!_server.canFindChannelByName(target))
|
||||
{
|
||||
sendErrNoSuchNick(target);
|
||||
}
|
||||
|
@ -358,7 +358,7 @@ class Connection
|
|||
}
|
||||
else if(Server.isValidNick(target))
|
||||
{
|
||||
if(!_server.connections.canFind!(c => c.nick == target))
|
||||
if(!_server.canFindConnectionByNick(target))
|
||||
{
|
||||
sendErrNoSuchNick(target);
|
||||
}
|
||||
|
@ -366,7 +366,7 @@ class Connection
|
|||
{
|
||||
_server.privmsgToUser(this, target, text);
|
||||
|
||||
auto targetUser = _server.connections.find!(c => c.nick == target)[0];
|
||||
auto targetUser = _server.findConnectionByNick(target)[0];
|
||||
if(targetUser.modes.canFind('a'))
|
||||
{
|
||||
sendRplAway(target, targetUser.awayMessage);
|
||||
|
@ -393,14 +393,11 @@ class Connection
|
|||
return;
|
||||
}
|
||||
|
||||
if(Server.isValidChannelName(target))
|
||||
if(Server.isValidChannelName(target) && _server.canFindChannelByName(target))
|
||||
{
|
||||
if(_server.channels.canFind!(c => c.name == target))
|
||||
{
|
||||
_server.noticeToChannel(this, target, text);
|
||||
}
|
||||
_server.noticeToChannel(this, target, text);
|
||||
}
|
||||
else if(Server.isValidNick(target) && _server.connections.canFind!(c => c.nick == target))
|
||||
else if(Server.isValidNick(target) && _server.canFindConnectionByNick(target))
|
||||
{
|
||||
_server.noticeToUser(this, target, text);
|
||||
}
|
||||
|
@ -417,7 +414,7 @@ class Connection
|
|||
auto mask = message.parameters[0];
|
||||
auto operatorsOnly = message.parameters.length > 1 && message.parameters[1] == "o";
|
||||
|
||||
if(_server.isValidChannelName(mask) && _server.channels.canFind!(c => c.name == mask))
|
||||
if(_server.isValidChannelName(mask) && _server.canFindChannelByName(mask))
|
||||
{
|
||||
_server.whoChannel(this, mask, operatorsOnly);
|
||||
}
|
||||
|
@ -459,7 +456,7 @@ class Connection
|
|||
auto channelName = message.parameters[0];
|
||||
if(message.parameters.length == 1)
|
||||
{
|
||||
if(!_server.channels.canFind!(c => c.name == channelName && (!(c.modes.canFind('s') || c.modes.canFind('p')) || c.members.canFind(this))))
|
||||
if(!_server.channels.canFind!(c => c.name.toIRCLower == channelName.toIRCLower && (!(c.modes.canFind('s') || c.modes.canFind('p')) || c.members.canFind(this))))
|
||||
{
|
||||
//NOTE: The RFCs don't allow ERR_NOSUCHCHANNEL as a response to TOPIC
|
||||
//TODO: If RFC-strictness is off, do send ERR_NOSUCHCHANNEL
|
||||
|
@ -473,12 +470,12 @@ class Connection
|
|||
else
|
||||
{
|
||||
auto newTopic = message.parameters[1];
|
||||
if(!channels.canFind!(c => c.name == channelName))
|
||||
if(!channels.canFind!(c => c.name.toIRCLower == channelName.toIRCLower))
|
||||
{
|
||||
sendErrNotOnChannel(channelName);
|
||||
}
|
||||
//TODO: Allow operators to set flags
|
||||
else if(channels.find!(c => c.name == channelName).map!(c => c.modes.canFind('t') /* && this user isn't an operator */).array[0])
|
||||
else if(channels.find!(c => c.name.toIRCLower == channelName.toIRCLower).map!(c => c.modes.canFind('t') /* && this user isn't an operator */).array[0])
|
||||
{
|
||||
sendErrChanopPrivsNeeded(channelName);
|
||||
}
|
||||
|
@ -505,7 +502,7 @@ class Connection
|
|||
{
|
||||
foreach(channelName; message.parameters[0].split(','))
|
||||
{
|
||||
if(_server.channels.canFind!(c => c.name == channelName && c.visibleTo(this)))
|
||||
if(_server.channels.canFind!(c => c.name.toIRCLower == channelName.toIRCLower && c.visibleTo(this)))
|
||||
{
|
||||
_server.sendChannelNames(this, channelName);
|
||||
}
|
||||
|
@ -545,7 +542,7 @@ class Connection
|
|||
}
|
||||
|
||||
auto targetNick = message.parameters[0];
|
||||
auto targetUserRange = _server.connections.find!(c => c.nick == targetNick);
|
||||
auto targetUserRange = _server.findConnectionByNick(targetNick);
|
||||
if(targetUserRange.empty)
|
||||
{
|
||||
sendErrNoSuchNick(targetNick);
|
||||
|
@ -554,7 +551,7 @@ class Connection
|
|||
auto targetUser = targetUserRange[0];
|
||||
|
||||
auto channelName = message.parameters[1];
|
||||
auto channelRange = _server.channels.find!(c => c.name == channelName);
|
||||
auto channelRange = _server.findChannelByName(channelName);
|
||||
if(channelRange.empty)
|
||||
{
|
||||
_server.invite(this, targetUser.nick, channelName);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
module ircd.helpers;
|
||||
|
||||
import std.range;
|
||||
import std.range : array, empty, front, popFront, save;
|
||||
import std.algorithm : map;
|
||||
|
||||
//Based on std.path.globMatch (https://github.com/dlang/phobos/blob/v2.073.2/std/path.d#L3164)
|
||||
//License: Boost License 1.0 (http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
@ -46,3 +47,26 @@ bool wildcardMatch(string input, string pattern)
|
|||
return input.empty;
|
||||
}
|
||||
|
||||
@safe pure
|
||||
dchar toIRCLower(dchar input)
|
||||
{
|
||||
import std.uni : toLower;
|
||||
switch(input)
|
||||
{
|
||||
case '[':
|
||||
return '{';
|
||||
case ']':
|
||||
return '}';
|
||||
case '\\':
|
||||
return '|';
|
||||
default:
|
||||
return input.toLower;
|
||||
}
|
||||
}
|
||||
|
||||
@safe pure
|
||||
string toIRCLower(string input)
|
||||
{
|
||||
import std.utf : byChar;
|
||||
return input.map!toIRCLower.byChar.array.idup;
|
||||
}
|
||||
|
|
|
@ -98,14 +98,34 @@ class Server
|
|||
return true;
|
||||
}
|
||||
|
||||
Connection[] findConnectionByNick(string nick)
|
||||
{
|
||||
return connections.find!(c => c.nick.toIRCLower == nick.toIRCLower);
|
||||
}
|
||||
|
||||
bool canFindConnectionByNick(string nick)
|
||||
{
|
||||
return !findConnectionByNick(nick).empty;
|
||||
}
|
||||
|
||||
bool isNickAvailable(string nick)
|
||||
{
|
||||
return !connections.canFind!(c => c.nick == nick);
|
||||
return !canFindConnectionByNick(nick);
|
||||
}
|
||||
|
||||
Channel[] findChannelByName(string name)
|
||||
{
|
||||
return channels.find!(c => c.name.toIRCLower == name.toIRCLower);
|
||||
}
|
||||
|
||||
bool canFindChannelByName(string name)
|
||||
{
|
||||
return !findConnectionByNick(name).empty;
|
||||
}
|
||||
|
||||
void join(Connection connection, string channelName)
|
||||
{
|
||||
auto channelRange = channels.find!(c => c.name == channelName);
|
||||
auto channelRange = findChannelByName(channelName);
|
||||
Channel channel;
|
||||
if(channelRange.empty)
|
||||
{
|
||||
|
@ -133,7 +153,7 @@ class Server
|
|||
|
||||
void part(Connection connection, string channelName, string partMessage)
|
||||
{
|
||||
auto channel = connection.channels.array.find!(c => c.name == channelName)[0];
|
||||
auto channel = connection.channels.array.find!(c => c.name.toIRCLower == channelName.toIRCLower)[0];
|
||||
|
||||
foreach(member; channel.members)
|
||||
{
|
||||
|
@ -186,7 +206,7 @@ class Server
|
|||
{
|
||||
//TODO: Check what RFCs say about secret/private channels
|
||||
|
||||
auto channel = channels.find!(c => c.name == channelName)[0];
|
||||
auto channel = findChannelByName(channelName)[0];
|
||||
foreach(c; channel.members.filter!(c => !operatorsOnly || c.isOperator)
|
||||
.filter!(c => c.visibleTo(origin)))
|
||||
{
|
||||
|
@ -210,43 +230,43 @@ class Server
|
|||
|
||||
void privmsgToChannel(Connection sender, string target, string text)
|
||||
{
|
||||
auto channel = channels.find!(c => c.name == target)[0];
|
||||
auto channel = findChannelByName(target)[0];
|
||||
channel.sendPrivMsg(sender, text);
|
||||
}
|
||||
|
||||
void privmsgToUser(Connection sender, string target, string text)
|
||||
{
|
||||
auto user = connections.find!(c => c.nick == target)[0];
|
||||
auto user = findConnectionByNick(target)[0];
|
||||
user.send(Message(sender.mask, "PRIVMSG", [target, text], true));
|
||||
}
|
||||
|
||||
void noticeToChannel(Connection sender, string target, string text)
|
||||
{
|
||||
auto channel = channels.find!(c => c.name == target)[0];
|
||||
auto channel = findChannelByName(target)[0];
|
||||
channel.sendNotice(sender, text);
|
||||
}
|
||||
|
||||
void noticeToUser(Connection sender, string target, string text)
|
||||
{
|
||||
auto user = connections.find!(c => c.nick == target)[0];
|
||||
auto user = findConnectionByNick(target)[0];
|
||||
user.send(Message(sender.mask, "NOTICE", [target, text], true));
|
||||
}
|
||||
|
||||
void sendChannelTopic(Connection origin, string channelName)
|
||||
{
|
||||
auto channel = channels.find!(c => c.name == channelName)[0];
|
||||
auto channel = findChannelByName(channelName)[0];
|
||||
channel.sendTopic(origin);
|
||||
}
|
||||
|
||||
void setChannelTopic(Connection origin, string channelName, string newTopic)
|
||||
{
|
||||
auto channel = channels.find!(c => c.name == channelName)[0];
|
||||
auto channel = findChannelByName(channelName)[0];
|
||||
channel.setTopic(origin, newTopic);
|
||||
}
|
||||
|
||||
void sendChannelNames(Connection connection, string channelName)
|
||||
{
|
||||
auto channel = channels.find!(c => c.name == channelName)[0];
|
||||
auto channel = findChannelByName(channelName)[0];
|
||||
channel.sendNames(connection);
|
||||
}
|
||||
|
||||
|
@ -339,7 +359,7 @@ class Server
|
|||
|
||||
void ison(Connection connection, string[] nicks)
|
||||
{
|
||||
auto reply = nicks.filter!(n => connections.canFind!(u => u.nick == n)).join(' ');
|
||||
auto reply = nicks.filter!(n => canFindConnectionByNick(n)).join(' ');
|
||||
|
||||
connection.send(Message(name, "303", [connection.nick, reply], true));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue