Implement lots of things
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
023e29ab75
commit
a0fbcf83c5
|
@ -4,11 +4,29 @@ namespace IrcStates
|
||||||
{
|
{
|
||||||
public class ChannelUser
|
public class ChannelUser
|
||||||
{
|
{
|
||||||
public List<string> Modes { get; set; }
|
|
||||||
|
|
||||||
public ChannelUser()
|
public ChannelUser()
|
||||||
{
|
{
|
||||||
Modes = new List<string>();
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
@ -28,5 +29,12 @@ namespace IrcStates
|
||||||
? Delegate.CreateDelegate(getType(types.ToArray()), methodInfo)
|
? Delegate.CreateDelegate(getType(types.ToArray()), methodInfo)
|
||||||
: Delegate.CreateDelegate(getType(types.ToArray()), target, 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,10 @@ namespace IrcStates
|
||||||
Raw = new Dictionary<string, string>();
|
Raw = new Dictionary<string, string>();
|
||||||
Modes = 3;
|
Modes = 3;
|
||||||
CaseMapping = Casemap.CaseMapping.Rfc1459;
|
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; }
|
public Dictionary<string, string> Raw { get; set; }
|
||||||
|
@ -35,7 +38,7 @@ namespace IrcStates
|
||||||
public void Parse(IEnumerable<string> tokens)
|
public void Parse(IEnumerable<string> tokens)
|
||||||
{
|
{
|
||||||
if (tokens == null) return;
|
if (tokens == null) return;
|
||||||
|
|
||||||
// remove first and last
|
// remove first and last
|
||||||
tokens = tokens.Skip(1).SkipLast(1);
|
tokens = tokens.Skip(1).SkipLast(1);
|
||||||
|
|
||||||
|
@ -71,8 +74,7 @@ namespace IrcStates
|
||||||
Watch = int.Parse(value, NumberStyles.Integer, CultureInfo.InvariantCulture);
|
Watch = int.Parse(value, NumberStyles.Integer, CultureInfo.InvariantCulture);
|
||||||
break;
|
break;
|
||||||
case "CASEMAPPING":
|
case "CASEMAPPING":
|
||||||
if (Enum.TryParse(value, true, out Casemap.CaseMapping caseMapping))
|
if (Enum.TryParse(value, true, out Casemap.CaseMapping caseMapping)) CaseMapping = caseMapping;
|
||||||
CaseMapping = caseMapping;
|
|
||||||
break;
|
break;
|
||||||
case "CHANTYPES":
|
case "CHANTYPES":
|
||||||
ChanTypes = new List<string> {value};
|
ChanTypes = new List<string> {value};
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace IrcStates
|
namespace IrcStates
|
||||||
{
|
{
|
||||||
|
@ -11,8 +12,10 @@ namespace IrcStates
|
||||||
if (splitVal == null) throw new ArgumentNullException(nameof(splitVal));
|
if (splitVal == null) throw new ArgumentNullException(nameof(splitVal));
|
||||||
|
|
||||||
var split = splitVal.Substring(1).Split(')', 2);
|
var split = splitVal.Substring(1).Split(')', 2);
|
||||||
Modes = new List<string> {split[0]};
|
Modes = new List<string>();
|
||||||
Prefixes = new List<string> {split[1]};
|
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; }
|
public List<string> Modes { get; set; }
|
||||||
|
@ -22,9 +25,10 @@ namespace IrcStates
|
||||||
{
|
{
|
||||||
return FromMode(mode.ToString(CultureInfo.InvariantCulture));
|
return FromMode(mode.ToString(CultureInfo.InvariantCulture));
|
||||||
}
|
}
|
||||||
|
|
||||||
public string FromMode(string mode)
|
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)
|
public string FromPrefix(char prefix)
|
||||||
|
@ -34,7 +38,7 @@ namespace IrcStates
|
||||||
|
|
||||||
public string FromPrefix(string prefix)
|
public string FromPrefix(string prefix)
|
||||||
{
|
{
|
||||||
return Prefixes.Contains(prefix) ? Prefixes[Prefixes.IndexOf(prefix)] : null;
|
return Prefixes.Contains(prefix) ? Modes[Prefixes.IndexOf(prefix)] : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.Serialization;
|
|
||||||
using IrcTokens;
|
using IrcTokens;
|
||||||
|
|
||||||
namespace IrcStates
|
namespace IrcStates
|
||||||
|
@ -210,32 +209,161 @@ namespace IrcStates
|
||||||
|
|
||||||
private Emit HandleSetname(Line line)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
private Emit HandleWhoIsUser(Line line)
|
||||||
|
@ -280,22 +408,63 @@ namespace IrcStates
|
||||||
|
|
||||||
private Emit HandleTopicTime(Line line)
|
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)
|
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)
|
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)
|
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)
|
private Emit HandleNames(Line line)
|
||||||
|
@ -324,10 +493,7 @@ namespace IrcStates
|
||||||
|
|
||||||
var hostmask = new Hostmask(nick.Substring(modes.Length));
|
var hostmask = new Hostmask(nick.Substring(modes.Length));
|
||||||
var nickLower = CaseFold(hostmask.NickName);
|
var nickLower = CaseFold(hostmask.NickName);
|
||||||
if (!Users.ContainsKey(nickLower))
|
if (!Users.ContainsKey(nickLower)) AddUser(hostmask.NickName, nickLower);
|
||||||
{
|
|
||||||
AddUser(hostmask.NickName, nickLower);
|
|
||||||
}
|
|
||||||
|
|
||||||
var user = Users[nickLower];
|
var user = Users[nickLower];
|
||||||
users.Add(user);
|
users.Add(user);
|
||||||
|
@ -339,12 +505,8 @@ namespace IrcStates
|
||||||
if (nickLower == NickNameLower) SelfHostmask(hostmask);
|
if (nickLower == NickNameLower) SelfHostmask(hostmask);
|
||||||
|
|
||||||
foreach (var mode in modes.Select(c => c.ToString(CultureInfo.InvariantCulture)))
|
foreach (var mode in modes.Select(c => c.ToString(CultureInfo.InvariantCulture)))
|
||||||
{
|
|
||||||
if (!channelUser.Modes.Contains(mode))
|
if (!channelUser.Modes.Contains(mode))
|
||||||
{
|
|
||||||
channelUser.Modes.Add(mode);
|
channelUser.Modes.Add(mode);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return emit;
|
return emit;
|
||||||
|
@ -375,9 +537,7 @@ namespace IrcStates
|
||||||
Users.Remove(nickLower);
|
Users.Remove(nickLower);
|
||||||
emit.User = user;
|
emit.User = user;
|
||||||
foreach (var channel in user.Channels.Select(c => Channels[c]))
|
foreach (var channel in user.Channels.Select(c => Channels[c]))
|
||||||
{
|
|
||||||
channel.Users.Remove(user.NickNameLower);
|
channel.Users.Remove(user.NickNameLower);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return emit;
|
return emit;
|
||||||
|
@ -385,7 +545,9 @@ namespace IrcStates
|
||||||
|
|
||||||
private Emit HandleLoggedOut(Line line)
|
private Emit HandleLoggedOut(Line line)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Account = null;
|
||||||
|
SelfHostmask(new Hostmask(line.Params[1]));
|
||||||
|
return new Emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Emit HandleKick(Line line)
|
private Emit HandleKick(Line line)
|
||||||
|
|
|
@ -169,11 +169,9 @@ namespace IrcStates.Tests
|
||||||
var chanUser1 = channel.Users[user.NickNameLower];
|
var chanUser1 = channel.Users[user.NickNameLower];
|
||||||
var chanUser2 = channel.Users[_server.NickNameLower];
|
var chanUser2 = channel.Users[_server.NickNameLower];
|
||||||
|
|
||||||
CollectionAssert.AreEqual(
|
Assert.AreEqual(2, channel.Users.Count);
|
||||||
new Dictionary<string, ChannelUser>
|
CollectionAssert.AreEqual(chanUser1.Modes, channel.Users[user.NickNameLower].Modes);
|
||||||
{
|
CollectionAssert.AreEqual(chanUser2.Modes, channel.Users[_server.NickNameLower].Modes);
|
||||||
{user.NickNameLower, chanUser1}, {_server.NickNameLower, chanUser2}
|
|
||||||
}, channel.Users);
|
|
||||||
CollectionAssert.AreEqual(new List<string> {"o", "v"}, chanUser1.Modes);
|
CollectionAssert.AreEqual(new List<string> {"o", "v"}, chanUser1.Modes);
|
||||||
Assert.AreEqual(channel.NameLower, user.Channels.Single());
|
Assert.AreEqual(channel.NameLower, user.Channels.Single());
|
||||||
}
|
}
|
||||||
|
@ -181,12 +179,12 @@ namespace IrcStates.Tests
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void UserhostInNames()
|
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("user", _server.UserName);
|
||||||
Assert.AreEqual("host", _server.HostName);
|
Assert.AreEqual("host", _server.HostName);
|
||||||
|
|
||||||
var user = _server.Users["other"];
|
var user = _server.Users["other"];
|
||||||
Assert.AreEqual("user2", user.HostName);
|
Assert.AreEqual("user2", user.UserName);
|
||||||
Assert.AreEqual("host2", user.HostName);
|
Assert.AreEqual("host2", user.HostName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue