forked from lesderid/salty-ircd
Implement channel key and user limit management
This commit is contained in:
parent
f50f602eea
commit
6a6006c2c5
|
@ -2,6 +2,7 @@ module ircd.channel;
|
|||
|
||||
import std.algorithm;
|
||||
import std.string;
|
||||
import std.typecons : Nullable;
|
||||
|
||||
import ircd.connection;
|
||||
import ircd.server;
|
||||
|
@ -18,8 +19,8 @@ class Channel
|
|||
char[][Connection] memberModes;
|
||||
string[][char] maskLists;
|
||||
|
||||
string key; //TODO: Fully implement key
|
||||
//TODO: Implement member limit (+l)
|
||||
string key;
|
||||
Nullable!uint userLimit;
|
||||
|
||||
private Server _server;
|
||||
|
||||
|
@ -136,17 +137,27 @@ class Channel
|
|||
|
||||
void sendModes(Connection user)
|
||||
{
|
||||
auto specialModes = "";
|
||||
string[] specialModeParameters;
|
||||
|
||||
if(members.canFind(user) && key !is null)
|
||||
{
|
||||
user.send(Message(_server.name, "324", [user.nick, name, "+" ~ modes.idup ~ "k", key]));
|
||||
specialModes ~= "k";
|
||||
specialModeParameters ~= key;
|
||||
}
|
||||
else
|
||||
|
||||
if(members.canFind(user) && !userLimit.isNull)
|
||||
{
|
||||
user.send(Message(_server.name, "324", [user.nick, name, "+" ~ modes.idup]));
|
||||
import std.conv : to;
|
||||
|
||||
specialModes ~= "l";
|
||||
specialModeParameters ~= userLimit.to!string;
|
||||
}
|
||||
|
||||
user.send(Message(_server.name, "324", [user.nick, name, "+" ~ modes.idup ~ specialModes] ~ specialModeParameters));
|
||||
}
|
||||
|
||||
bool setMemberMode(Connection setter, Connection target, char mode)
|
||||
bool setMemberMode(Connection target, char mode)
|
||||
{
|
||||
if(memberModes[target].canFind(mode))
|
||||
{
|
||||
|
@ -157,7 +168,7 @@ class Channel
|
|||
return true;
|
||||
}
|
||||
|
||||
bool unsetMemberMode(Connection setter, Connection target, char mode)
|
||||
bool unsetMemberMode(Connection target, char mode)
|
||||
{
|
||||
if(!memberModes[target].canFind(mode))
|
||||
{
|
||||
|
@ -172,7 +183,7 @@ class Channel
|
|||
return true;
|
||||
}
|
||||
|
||||
bool setMode(Connection setter, char mode)
|
||||
bool setMode(char mode)
|
||||
{
|
||||
if(modes.canFind(mode))
|
||||
{
|
||||
|
@ -184,7 +195,7 @@ class Channel
|
|||
return true;
|
||||
}
|
||||
|
||||
bool unsetMode(Connection setter, char mode)
|
||||
bool unsetMode(char mode)
|
||||
{
|
||||
if(!modes.canFind(mode))
|
||||
{
|
||||
|
@ -199,7 +210,7 @@ class Channel
|
|||
return true;
|
||||
}
|
||||
|
||||
bool addMaskListEntry(Connection origin, string mask, char mode)
|
||||
bool addMaskListEntry(string mask, char mode)
|
||||
{
|
||||
if(maskLists[mode].canFind!(m => m.toIRCLower == mask.toIRCLower))
|
||||
{
|
||||
|
@ -211,7 +222,7 @@ class Channel
|
|||
return true;
|
||||
}
|
||||
|
||||
bool removeMaskListEntry(Connection origin, string mask, char mode)
|
||||
bool removeMaskListEntry(string mask, char mode)
|
||||
{
|
||||
if(!maskLists[mode].canFind!(m => m.toIRCLower == mask.toIRCLower))
|
||||
{
|
||||
|
@ -253,6 +264,42 @@ class Channel
|
|||
connection.send(Message(_server.name, "347", [connection.nick, name, "End of channel invite list"], true));
|
||||
}
|
||||
|
||||
bool setKey(string key)
|
||||
{
|
||||
this.key = key;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool unsetKey(string key)
|
||||
{
|
||||
if(this.key != key)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
this.key = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void setUserLimit(uint userLimit)
|
||||
{
|
||||
this.userLimit = userLimit;
|
||||
}
|
||||
|
||||
bool unsetUserLimit()
|
||||
{
|
||||
if(userLimit.isNull)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
userLimit.nullify();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
string prefixedNick(Connection member)
|
||||
{
|
||||
if(memberModes[member].canFind('o'))
|
||||
|
|
|
@ -975,9 +975,9 @@ Lforeach:
|
|||
break Lforeach;
|
||||
}
|
||||
|
||||
auto success = false;
|
||||
if(add) success = channel.setMemberMode(this, member, mode);
|
||||
else success = channel.unsetMemberMode(this, member, mode);
|
||||
bool success;
|
||||
if(add) success = channel.setMemberMode(member, mode);
|
||||
else success = channel.unsetMemberMode(member, mode);
|
||||
if(success)
|
||||
{
|
||||
processedModes ~= mode;
|
||||
|
@ -1000,24 +1000,74 @@ Lforeach:
|
|||
break Lforeach;
|
||||
}
|
||||
|
||||
auto success = false;
|
||||
if(add) success = channel.addMaskListEntry(this, mask, mode);
|
||||
else success = channel.removeMaskListEntry(this, mask, mode);
|
||||
bool success;
|
||||
if(add) success = channel.addMaskListEntry(mask, mode);
|
||||
else success = channel.removeMaskListEntry(mask, mode);
|
||||
if(success)
|
||||
{
|
||||
processedModes ~= mode;
|
||||
processedParameters ~= mask;
|
||||
}
|
||||
break;
|
||||
case 'k': //TODO: Implement channel key
|
||||
if(i + 1 == message.parameters.length)
|
||||
{
|
||||
//TODO: Figure out what to do when we need more mode parameters
|
||||
break Lforeach;
|
||||
}
|
||||
auto key = message.parameters[++i];
|
||||
|
||||
bool success;
|
||||
if(add) success = channel.setKey(key);
|
||||
else success = channel.unsetKey(key);
|
||||
if(success)
|
||||
{
|
||||
processedModes ~= mode;
|
||||
processedParameters ~= key;
|
||||
}
|
||||
break;
|
||||
case 'l': //TODO: Implement user limit
|
||||
if(add)
|
||||
{
|
||||
if(i + 1 == message.parameters.length)
|
||||
{
|
||||
//TODO: Figure out what to do when we need more mode parameters
|
||||
break Lforeach;
|
||||
}
|
||||
|
||||
auto limitString = message.parameters[++i];
|
||||
uint limit = 0;
|
||||
try
|
||||
{
|
||||
limit = limitString.to!uint;
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
break Lforeach;
|
||||
}
|
||||
|
||||
channel.setUserLimit(limit);
|
||||
|
||||
processedModes ~= mode;
|
||||
processedParameters ~= limitString;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(channel.unsetUserLimit())
|
||||
{
|
||||
processedModes ~= mode;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'i': //TODO: Implement invite-only channels
|
||||
case 'm': //TODO: Implement channel moderation
|
||||
case 'n': //TODO: Implement the no messages from clients on the outside flag
|
||||
case 'p':
|
||||
case 's':
|
||||
case 't':
|
||||
auto success = false;
|
||||
if(add) channel.setMode(this, mode);
|
||||
else channel.unsetMode(this, mode);
|
||||
bool success;
|
||||
if(add) channel.setMode(mode);
|
||||
else channel.unsetMode(mode);
|
||||
if(success)
|
||||
{
|
||||
processedModes ~= mode;
|
||||
|
|
Loading…
Reference in New Issue