Implement lots of things
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Ben Harris 2020-05-14 02:10:04 -04:00
parent 023e29ab75
commit a0fbcf83c5
Signed by: ben
GPG Key ID: 4E0AF802FFF7960C
6 changed files with 231 additions and 39 deletions

View File

@ -4,11 +4,29 @@ namespace IrcStates
{
public class ChannelUser
{
public List<string> Modes { get; set; }
public ChannelUser()
{
Modes = new List<string>();
}
public List<string> Modes { get; set; }
protected bool Equals(ChannelUser other)
{
return other != null && Equals(Modes, other.Modes);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((ChannelUser) obj);
}
public override int GetHashCode()
{
return Modes != null ? Modes.GetHashCode() : 0;
}
}
}

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
@ -28,5 +29,12 @@ namespace IrcStates
? Delegate.CreateDelegate(getType(types.ToArray()), methodInfo)
: Delegate.CreateDelegate(getType(types.ToArray()), target, methodInfo);
}
public static void Update<TKey, TValue>(this Dictionary<TKey, TValue> dict, Dictionary<TKey, TValue> other)
{
if (dict == null || other == null || !other.Any()) return;
foreach (var (key, value) in other) dict[key] = value;
}
}
}

View File

@ -14,7 +14,10 @@ namespace IrcStates
Raw = new Dictionary<string, string>();
Modes = 3;
CaseMapping = Casemap.CaseMapping.Rfc1459;
// TODO: add remaining defaults, change properties to normal members as needed
Prefix = new ISupportPrefix("(ov)@+");
ChanModes = new ISupportChanModes("b,k,l,imnpst");
StatusMsg = new List<string>();
Whox = false;
}
public Dictionary<string, string> Raw { get; set; }
@ -35,7 +38,7 @@ namespace IrcStates
public void Parse(IEnumerable<string> tokens)
{
if (tokens == null) return;
// remove first and last
tokens = tokens.Skip(1).SkipLast(1);
@ -71,8 +74,7 @@ namespace IrcStates
Watch = int.Parse(value, NumberStyles.Integer, CultureInfo.InvariantCulture);
break;
case "CASEMAPPING":
if (Enum.TryParse(value, true, out Casemap.CaseMapping caseMapping))
CaseMapping = caseMapping;
if (Enum.TryParse(value, true, out Casemap.CaseMapping caseMapping)) CaseMapping = caseMapping;
break;
case "CHANTYPES":
ChanTypes = new List<string> {value};

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace IrcStates
{
@ -11,8 +12,10 @@ namespace IrcStates
if (splitVal == null) throw new ArgumentNullException(nameof(splitVal));
var split = splitVal.Substring(1).Split(')', 2);
Modes = new List<string> {split[0]};
Prefixes = new List<string> {split[1]};
Modes = new List<string>();
Modes.AddRange(split[0].Select(c => c.ToString(CultureInfo.InvariantCulture)));
Prefixes = new List<string>();
Prefixes.AddRange(split[1].Select(c => c.ToString(CultureInfo.InvariantCulture)));
}
public List<string> Modes { get; set; }
@ -22,9 +25,10 @@ namespace IrcStates
{
return FromMode(mode.ToString(CultureInfo.InvariantCulture));
}
public string FromMode(string mode)
{
return Modes.Contains(mode) ? Modes[Modes.IndexOf(mode)] : null;
return Modes.Contains(mode) ? Prefixes[Modes.IndexOf(mode)] : null;
}
public string FromPrefix(char prefix)
@ -34,7 +38,7 @@ namespace IrcStates
public string FromPrefix(string prefix)
{
return Prefixes.Contains(prefix) ? Prefixes[Prefixes.IndexOf(prefix)] : null;
return Prefixes.Contains(prefix) ? Modes[Prefixes.IndexOf(prefix)] : null;
}
}
}

View File

@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.Serialization;
using IrcTokens;
namespace IrcStates
@ -210,32 +209,161 @@ namespace IrcStates
private Emit HandleSetname(Line line)
{
throw new NotImplementedException();
var emit = new Emit();
var realname = line.Params[0];
var nicknameLower = CaseFold(line.Hostmask.NickName);
if (nicknameLower == NickNameLower)
{
emit.Self = true;
RealName = realname;
}
if (Users.ContainsKey(nicknameLower))
{
var user = Users[nicknameLower];
emit.User = user;
user.RealName = realname;
}
return emit;
}
private Emit HandleAway(Line line)
{
throw new NotImplementedException();
var emit = new Emit();
var away = line.Params.FirstOrDefault();
var nicknameLower = CaseFold(line.Hostmask.NickName);
if (nicknameLower == NickNameLower)
{
emit.Self = true;
Away = away;
}
if (Users.ContainsKey(nicknameLower))
{
var user = Users[nicknameLower];
emit.User = user;
user.Away = away;
}
return emit;
}
private Emit HandleAccount(Line line)
{
throw new NotImplementedException();
var emit = new Emit();
var account = line.Params[0].Trim('*');
var nicknameLower = CaseFold(line.Hostmask.NickName);
if (nicknameLower == NickNameLower)
{
emit.Self = true;
Account = account;
}
if (Users.ContainsKey(nicknameLower))
{
var user = Users[nicknameLower];
emit.User = user;
user.Account = account;
}
return emit;
}
private Emit HandleCap(Line line)
{
throw new NotImplementedException();
HasCap = true;
var subcommand = line.Params[1].ToUpperInvariant();
var multiline = line.Params[2] == "*";
var caps = line.Params[multiline ? 3 : 2];
var tokens = new Dictionary<string, string>();
var tokensStr = new List<string>();
foreach (var cap in caps.Split(' ', StringSplitOptions.RemoveEmptyEntries))
{
tokensStr.Add(cap);
var kv = cap.Split('=', 2);
tokens[kv[0]] = kv.Length > 1 ? kv[1] : string.Empty;
}
var emit = new Emit();
emit.Subcommand = subcommand;
emit.Finished = !multiline;
emit.Tokens = tokensStr;
switch (subcommand)
{
case "LS":
TempCaps = tokens;
if (!multiline)
{
AvailableCaps = TempCaps;
TempCaps.Clear();
}
break;
case "NEW":
AvailableCaps.Update(tokens);
break;
case "DEL":
foreach (var key in tokens.Keys.Where(key => AvailableCaps.ContainsKey(key)))
{
AvailableCaps.Remove(key);
if (AgreedCaps.Contains(key)) AgreedCaps.Remove(key);
}
break;
case "ACK":
foreach (var key in tokens.Keys)
if (key.StartsWith('-'))
{
var k = key.Substring(1);
if (AgreedCaps.Contains(k)) AgreedCaps.Remove(k);
}
else if (!AgreedCaps.Contains(key) && !AvailableCaps.ContainsKey(key))
{
AgreedCaps.Add(key);
}
break;
}
return emit;
}
private Emit HandleLoggedIn(Line line)
{
throw new NotImplementedException();
SelfHostmask(new Hostmask(line.Params[1]));
Account = line.Params[2];
return new Emit();
}
private Emit HandleChghost(Line line)
{
throw new NotImplementedException();
var emit = new Emit();
var username = line.Params[0];
var hostname = line.Params[1];
var nicknameLower = CaseFold(line.Hostmask.NickName);
if (nicknameLower == NickNameLower)
{
emit.Self = true;
UserName = username;
HostName = hostname;
}
if (Users.ContainsKey(nicknameLower))
{
var user = Users[nicknameLower];
emit.User = user;
user.UserName = username;
user.HostName = hostname;
}
return emit;
}
private Emit HandleWhoIsUser(Line line)
@ -280,22 +408,63 @@ namespace IrcStates
private Emit HandleTopicTime(Line line)
{
throw new NotImplementedException();
var emit = new Emit();
var channelLower = CaseFold(line.Params[1]);
if (Channels.ContainsKey(channelLower))
{
var channel = Channels[channelLower];
emit.Channel = channel;
channel.TopicSetter = line.Params[2];
channel.TopicTime = DateTimeOffset
.FromUnixTimeSeconds(int.Parse(line.Params[3], CultureInfo.InvariantCulture)).DateTime;
}
return emit;
}
private Emit HandleTopicNumeric(Line line)
{
throw new NotImplementedException();
var emit = new Emit();
var channelLower = CaseFold(line.Params[1]);
if (Channels.ContainsKey(channelLower))
{
var channel = Channels[channelLower];
emit.Channel = channel;
Channels[channelLower].Topic = line.Params[2];
}
return emit;
}
private Emit HandleTopic(Line line)
{
throw new NotImplementedException();
var emit = new Emit();
var channelLower = CaseFold(line.Params[0]);
if (Channels.ContainsKey(channelLower))
{
var channel = Channels[channelLower];
emit.Channel = channel;
channel.Topic = line.Params[1];
channel.TopicSetter = line.Hostmask.ToString();
channel.TopicTime = DateTime.UtcNow;
}
return emit;
}
private Emit HandleCreationTime(Line line)
{
throw new NotImplementedException();
var emit = new Emit();
var channelLower = CaseFold(line.Params[1]);
if (Channels.ContainsKey(channelLower))
{
var channel = Channels[channelLower];
emit.Channel = channel;
channel.Created = DateTimeOffset
.FromUnixTimeSeconds(int.Parse(line.Params[2], CultureInfo.InvariantCulture)).DateTime;
}
return emit;
}
private Emit HandleNames(Line line)
@ -324,10 +493,7 @@ namespace IrcStates
var hostmask = new Hostmask(nick.Substring(modes.Length));
var nickLower = CaseFold(hostmask.NickName);
if (!Users.ContainsKey(nickLower))
{
AddUser(hostmask.NickName, nickLower);
}
if (!Users.ContainsKey(nickLower)) AddUser(hostmask.NickName, nickLower);
var user = Users[nickLower];
users.Add(user);
@ -339,12 +505,8 @@ namespace IrcStates
if (nickLower == NickNameLower) SelfHostmask(hostmask);
foreach (var mode in modes.Select(c => c.ToString(CultureInfo.InvariantCulture)))
{
if (!channelUser.Modes.Contains(mode))
{
channelUser.Modes.Add(mode);
}
}
}
return emit;
@ -375,9 +537,7 @@ namespace IrcStates
Users.Remove(nickLower);
emit.User = user;
foreach (var channel in user.Channels.Select(c => Channels[c]))
{
channel.Users.Remove(user.NickNameLower);
}
}
return emit;
@ -385,7 +545,9 @@ namespace IrcStates
private Emit HandleLoggedOut(Line line)
{
throw new NotImplementedException();
Account = null;
SelfHostmask(new Hostmask(line.Params[1]));
return new Emit();
}
private Emit HandleKick(Line line)

View File

@ -169,11 +169,9 @@ namespace IrcStates.Tests
var chanUser1 = channel.Users[user.NickNameLower];
var chanUser2 = channel.Users[_server.NickNameLower];
CollectionAssert.AreEqual(
new Dictionary<string, ChannelUser>
{
{user.NickNameLower, chanUser1}, {_server.NickNameLower, chanUser2}
}, channel.Users);
Assert.AreEqual(2, channel.Users.Count);
CollectionAssert.AreEqual(chanUser1.Modes, channel.Users[user.NickNameLower].Modes);
CollectionAssert.AreEqual(chanUser2.Modes, channel.Users[_server.NickNameLower].Modes);
CollectionAssert.AreEqual(new List<string> {"o", "v"}, chanUser1.Modes);
Assert.AreEqual(channel.NameLower, user.Channels.Single());
}
@ -181,12 +179,12 @@ namespace IrcStates.Tests
[TestMethod]
public void UserhostInNames()
{
_server.Parse(new Line("353 * * #chan :nickname!user@host other@user2@host2"));
_server.Parse(new Line("353 * * #chan :nickname!user@host other!user2@host2"));
Assert.AreEqual("user", _server.UserName);
Assert.AreEqual("host", _server.HostName);
var user = _server.Users["other"];
Assert.AreEqual("user2", user.HostName);
Assert.AreEqual("user2", user.UserName);
Assert.AreEqual("host2", user.HostName);
}