implement some stuff
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
b93174070a
commit
023e29ab75
|
@ -6,6 +6,13 @@ namespace IrcStates
|
||||||
{
|
{
|
||||||
public class Channel
|
public class Channel
|
||||||
{
|
{
|
||||||
|
public Channel()
|
||||||
|
{
|
||||||
|
Users = new Dictionary<string, ChannelUser>();
|
||||||
|
ListModes = new Dictionary<string, List<string>>();
|
||||||
|
Modes = new Dictionary<string, string>();
|
||||||
|
}
|
||||||
|
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string NameLower { get; set; }
|
public string NameLower { get; set; }
|
||||||
public Dictionary<string, ChannelUser> Users { get; set; }
|
public Dictionary<string, ChannelUser> Users { get; set; }
|
||||||
|
|
|
@ -5,5 +5,10 @@ namespace IrcStates
|
||||||
public class ChannelUser
|
public class ChannelUser
|
||||||
{
|
{
|
||||||
public List<string> Modes { get; set; }
|
public List<string> Modes { get; set; }
|
||||||
|
|
||||||
|
public ChannelUser()
|
||||||
|
{
|
||||||
|
Modes = new List<string>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,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
|
||||||
{
|
{
|
||||||
|
@ -35,6 +36,9 @@ namespace IrcStates
|
||||||
{
|
{
|
||||||
if (tokens == null) return;
|
if (tokens == null) return;
|
||||||
|
|
||||||
|
// remove first and last
|
||||||
|
tokens = tokens.Skip(1).SkipLast(1);
|
||||||
|
|
||||||
foreach (var token in tokens)
|
foreach (var token in tokens)
|
||||||
{
|
{
|
||||||
var split = token.Split('=', 2);
|
var split = token.Split('=', 2);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
namespace IrcStates
|
namespace IrcStates
|
||||||
{
|
{
|
||||||
|
@ -17,11 +18,20 @@ namespace IrcStates
|
||||||
public List<string> Modes { get; set; }
|
public List<string> Modes { get; set; }
|
||||||
public List<string> Prefixes { get; set; }
|
public List<string> Prefixes { get; set; }
|
||||||
|
|
||||||
|
public string FromMode(char mode)
|
||||||
|
{
|
||||||
|
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) ? Modes[Modes.IndexOf(mode)] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string FromPrefix(char prefix)
|
||||||
|
{
|
||||||
|
return FromPrefix(prefix.ToString(CultureInfo.InvariantCulture));
|
||||||
|
}
|
||||||
|
|
||||||
public string FromPrefix(string prefix)
|
public string FromPrefix(string prefix)
|
||||||
{
|
{
|
||||||
return Prefixes.Contains(prefix) ? Prefixes[Prefixes.IndexOf(prefix)] : null;
|
return Prefixes.Contains(prefix) ? Prefixes[Prefixes.IndexOf(prefix)] : null;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
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
|
||||||
|
@ -103,6 +104,55 @@ namespace IrcStates
|
||||||
return HasChannel(name) ? Channels[name] : null;
|
return HasChannel(name) ? Channels[name] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ChannelUser UserJoin(Channel channel, User user)
|
||||||
|
{
|
||||||
|
var channelUser = new ChannelUser();
|
||||||
|
user.Channels.Add(CaseFold(channel.Name));
|
||||||
|
channel.Users[user.NickNameLower] = channelUser;
|
||||||
|
return channelUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SelfHostmask(Hostmask hostmask)
|
||||||
|
{
|
||||||
|
NickName = hostmask.NickName;
|
||||||
|
if (hostmask.UserName != null) UserName = hostmask.UserName;
|
||||||
|
if (hostmask.HostName != null) HostName = hostmask.HostName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private (Emit, User) UserPart(Line line, string nickName, string channelName, int reasonIndex)
|
||||||
|
{
|
||||||
|
var emit = new Emit();
|
||||||
|
var channelLower = CaseFold(channelName);
|
||||||
|
if (line.Params.Count >= reasonIndex + 1) emit.Text = line.Params[reasonIndex];
|
||||||
|
|
||||||
|
User user = null;
|
||||||
|
if (HasChannel(channelName))
|
||||||
|
{
|
||||||
|
var channel = Channels[channelLower];
|
||||||
|
emit.Channel = channel;
|
||||||
|
var nickLower = CaseFold(nickName);
|
||||||
|
if (HasUser(nickLower))
|
||||||
|
{
|
||||||
|
user = Users[nickLower];
|
||||||
|
user.Channels.Remove(channelLower);
|
||||||
|
channel.Users.Remove(nickLower);
|
||||||
|
if (!user.Channels.Any()) Users.Remove(nickLower);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nickLower == NickNameLower)
|
||||||
|
{
|
||||||
|
Channels.Remove(channelLower);
|
||||||
|
foreach (var userToRemove in channel.Users.Keys.Select(u => Users[u]))
|
||||||
|
{
|
||||||
|
userToRemove.Channels.Remove(channelLower);
|
||||||
|
if (!userToRemove.Channels.Any()) Users.Remove(userToRemove.NickNameLower);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (emit, user);
|
||||||
|
}
|
||||||
|
|
||||||
public List<(Line, Emit)> Recv(byte[] data)
|
public List<(Line, Emit)> Recv(byte[] data)
|
||||||
{
|
{
|
||||||
if (data == null) return null;
|
if (data == null) return null;
|
||||||
|
@ -250,17 +300,87 @@ namespace IrcStates
|
||||||
|
|
||||||
private Emit HandleNames(Line line)
|
private Emit HandleNames(Line line)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var emit = new Emit();
|
||||||
|
var channelLower = CaseFold(line.Params[2]);
|
||||||
|
|
||||||
|
if (!Channels.ContainsKey(channelLower)) return emit;
|
||||||
|
var channel = Channels[channelLower];
|
||||||
|
emit.Channel = channel;
|
||||||
|
var nicknames = line.Params[3].Split(' ', StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
var users = new List<User>();
|
||||||
|
emit.Users = users;
|
||||||
|
|
||||||
|
foreach (var nick in nicknames)
|
||||||
|
{
|
||||||
|
var modes = "";
|
||||||
|
foreach (var c in nick)
|
||||||
|
{
|
||||||
|
var mode = ISupport.Prefix.FromPrefix(c);
|
||||||
|
if (mode != null)
|
||||||
|
modes += mode;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var hostmask = new Hostmask(nick.Substring(modes.Length));
|
||||||
|
var nickLower = CaseFold(hostmask.NickName);
|
||||||
|
if (!Users.ContainsKey(nickLower))
|
||||||
|
{
|
||||||
|
AddUser(hostmask.NickName, nickLower);
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = Users[nickLower];
|
||||||
|
users.Add(user);
|
||||||
|
var channelUser = UserJoin(channel, user);
|
||||||
|
|
||||||
|
if (hostmask.UserName != null) user.UserName = hostmask.UserName;
|
||||||
|
if (hostmask.HostName != null) user.HostName = hostmask.HostName;
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Emit HandleError(Line line)
|
private Emit HandleError(Line line)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Users.Clear();
|
||||||
|
Channels.Clear();
|
||||||
|
return new Emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Emit HandleQuit(Line line)
|
private Emit HandleQuit(Line line)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var emit = new Emit();
|
||||||
|
var nickLower = CaseFold(line.Hostmask.NickName);
|
||||||
|
if (line.Params.Any()) emit.Text = line.Params[0];
|
||||||
|
|
||||||
|
if (nickLower == NickNameLower || line.Source == null)
|
||||||
|
{
|
||||||
|
emit.Self = true;
|
||||||
|
Users.Clear();
|
||||||
|
Channels.Clear();
|
||||||
|
}
|
||||||
|
else if (Users.ContainsKey(nickLower))
|
||||||
|
{
|
||||||
|
var user = Users[nickLower];
|
||||||
|
Users.Remove(nickLower);
|
||||||
|
emit.User = user;
|
||||||
|
foreach (var channel in user.Channels.Select(c => Channels[c]))
|
||||||
|
{
|
||||||
|
channel.Users.Remove(user.NickNameLower);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return emit;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Emit HandleLoggedOut(Line line)
|
private Emit HandleLoggedOut(Line line)
|
||||||
|
@ -270,29 +390,100 @@ namespace IrcStates
|
||||||
|
|
||||||
private Emit HandleKick(Line line)
|
private Emit HandleKick(Line line)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var (emit, kicked) = UserPart(line, line.Params[1], line.Params[0], 2);
|
||||||
|
if (kicked != null)
|
||||||
|
{
|
||||||
|
emit.UserTarget = kicked;
|
||||||
|
if (kicked.NickNameLower == NickNameLower) emit.Self = true;
|
||||||
|
|
||||||
|
var kickerLower = CaseFold(line.Hostmask.NickName);
|
||||||
|
if (kickerLower == NickNameLower) emit.SelfSource = true;
|
||||||
|
|
||||||
|
emit.UserSource = Users.ContainsKey(kickerLower)
|
||||||
|
? Users[kickerLower]
|
||||||
|
: CreateUser(line.Hostmask.NickName, kickerLower);
|
||||||
|
}
|
||||||
|
|
||||||
|
return emit;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Emit HandlePart(Line line)
|
private Emit HandlePart(Line line)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var (emit, user) = UserPart(line, line.Hostmask.NickName, line.Params[0], 1);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
emit.User = user;
|
||||||
|
if (user.NickNameLower == NickNameLower) emit.Self = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return emit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Emit HandleJoin(Line line)
|
private Emit HandleJoin(Line line)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var extended = line.Params.Count == 3;
|
||||||
|
var account = extended ? line.Params[1].Trim('*') : null;
|
||||||
|
var realname = extended ? line.Params[2] : null;
|
||||||
|
var emit = new Emit();
|
||||||
|
|
||||||
|
var channelLower = CaseFold(line.Params[0]);
|
||||||
|
var nickLower = CaseFold(line.Hostmask.NickName);
|
||||||
|
|
||||||
|
// handle own join
|
||||||
|
if (nickLower == NickNameLower)
|
||||||
|
{
|
||||||
|
emit.Self = true;
|
||||||
|
if (!HasChannel(channelLower))
|
||||||
|
{
|
||||||
|
var channel = new Channel();
|
||||||
|
channel.SetName(line.Params[0], channelLower);
|
||||||
|
Channels[channelLower] = channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
SelfHostmask(line.Hostmask);
|
||||||
|
if (extended)
|
||||||
|
{
|
||||||
|
Account = account;
|
||||||
|
RealName = realname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HasChannel(channelLower))
|
||||||
|
{
|
||||||
|
var channel = Channels[channelLower];
|
||||||
|
emit.Channel = channel;
|
||||||
|
|
||||||
|
if (!HasUser(nickLower)) AddUser(line.Hostmask.NickName, nickLower);
|
||||||
|
|
||||||
|
var user = Users[nickLower];
|
||||||
|
emit.User = user;
|
||||||
|
if (line.Hostmask.UserName != null) user.UserName = line.Hostmask.UserName;
|
||||||
|
if (line.Hostmask.HostName != null) user.HostName = line.Hostmask.HostName;
|
||||||
|
if (extended)
|
||||||
|
{
|
||||||
|
user.Account = account;
|
||||||
|
user.RealName = realname;
|
||||||
|
}
|
||||||
|
|
||||||
|
UserJoin(channel, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
return emit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Emit HandleNick(Line line)
|
private Emit HandleNick(Line line)
|
||||||
{
|
{
|
||||||
var nick = line.Params[0];
|
var nick = line.Params[0];
|
||||||
var nickLower = CaseFold(line.Hostmask.NickName);
|
var nickLower = CaseFold(line.Hostmask.NickName);
|
||||||
|
|
||||||
var emit = new Emit();
|
var emit = new Emit();
|
||||||
|
|
||||||
if (Users.ContainsKey(nickLower))
|
if (Users.ContainsKey(nickLower))
|
||||||
{
|
{
|
||||||
var user = Users[nick];
|
var user = Users[nickLower];
|
||||||
|
Users.Remove(nickLower);
|
||||||
emit.User = user;
|
emit.User = user;
|
||||||
|
|
||||||
var oldNickLower = user.NickNameLower;
|
var oldNickLower = user.NickNameLower;
|
||||||
|
@ -301,7 +492,7 @@ namespace IrcStates
|
||||||
Users[newNickLower] = user;
|
Users[newNickLower] = user;
|
||||||
foreach (var channelLower in user.Channels)
|
foreach (var channelLower in user.Channels)
|
||||||
{
|
{
|
||||||
var channel = Channels[channelLower];
|
var channel = Channels[channelLower];
|
||||||
var channelUser = channel.Users[oldNickLower];
|
var channelUser = channel.Users[oldNickLower];
|
||||||
channel.Users.Remove(oldNickLower);
|
channel.Users.Remove(oldNickLower);
|
||||||
channel.Users[newNickLower] = channelUser;
|
channel.Users[newNickLower] = channelUser;
|
||||||
|
@ -310,8 +501,8 @@ namespace IrcStates
|
||||||
|
|
||||||
if (nickLower == NickNameLower)
|
if (nickLower == NickNameLower)
|
||||||
{
|
{
|
||||||
emit.Self = true;
|
emit.Self = true;
|
||||||
NickName = nick;
|
NickName = nick;
|
||||||
NickNameLower = CaseFold(nick);
|
NickNameLower = CaseFold(nick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,10 +511,7 @@ namespace IrcStates
|
||||||
|
|
||||||
private Emit HandleMotd(Line line)
|
private Emit HandleMotd(Line line)
|
||||||
{
|
{
|
||||||
if (line.Command == Numeric.RPL_MOTDSTART)
|
if (line.Command == Numeric.RPL_MOTDSTART) Motd.Clear();
|
||||||
{
|
|
||||||
Motd.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
var emit = new Emit {Text = line.Params[1]};
|
var emit = new Emit {Text = line.Params[1]};
|
||||||
Motd.Add(line.Params[1]);
|
Motd.Add(line.Params[1]);
|
||||||
|
@ -333,7 +521,7 @@ namespace IrcStates
|
||||||
private Emit HandleISupport(Line line)
|
private Emit HandleISupport(Line line)
|
||||||
{
|
{
|
||||||
ISupport = new ISupport();
|
ISupport = new ISupport();
|
||||||
ISupport.Parse(line.Params.Skip(1).SkipLast(1));
|
ISupport.Parse(line.Params);
|
||||||
return new Emit();
|
return new Emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace IrcStates.Tests
|
||||||
Assert.IsTrue(server.Users.ContainsKey("newnickname"));
|
Assert.IsTrue(server.Users.ContainsKey("newnickname"));
|
||||||
Assert.AreEqual("NewNickname", user.NickName);
|
Assert.AreEqual("NewNickname", user.NickName);
|
||||||
Assert.AreEqual("newnickname", user.NickNameLower);
|
Assert.AreEqual("newnickname", user.NickNameLower);
|
||||||
Assert.AreEqual("NewNickName", server.NickName);
|
Assert.AreEqual("NewNickname", server.NickName);
|
||||||
Assert.AreEqual("newnickname", server.NickNameLower);
|
Assert.AreEqual("newnickname", server.NickNameLower);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,6 +100,30 @@ namespace IrcStates.Tests
|
||||||
channel.Users);
|
channel.Users);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void QuitSelf()
|
||||||
|
{
|
||||||
|
_server.Parse(new Line("QUIT :i'm outta here"));
|
||||||
|
Assert.IsFalse(_server.Users.Any());
|
||||||
|
Assert.IsFalse(_server.Channels.Any());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void QuitSelfWithSource()
|
||||||
|
{
|
||||||
|
_server.Parse(new Line(":nickname QUIT :i'm outta here"));
|
||||||
|
Assert.IsFalse(_server.Users.Any());
|
||||||
|
Assert.IsFalse(_server.Channels.Any());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void QuitOther()
|
||||||
|
{
|
||||||
|
_server.Parse(new Line(":other JOIN #chan"));
|
||||||
|
_server.Parse(new Line(":other QUIT :see ya"));
|
||||||
|
Assert.IsFalse(_server.Users.ContainsKey("other"));
|
||||||
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void TopicText()
|
public void TopicText()
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,6 +15,13 @@ namespace IrcStates.Tests
|
||||||
_server.Parse(new Line("001 nickname"));
|
_server.Parse(new Line("001 nickname"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Welcome()
|
||||||
|
{
|
||||||
|
Assert.AreEqual("test", _server.Name);
|
||||||
|
Assert.AreEqual("nickname", _server.NickName);
|
||||||
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void NicknameChange()
|
public void NicknameChange()
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,6 +4,11 @@ namespace IrcStates
|
||||||
{
|
{
|
||||||
public class User
|
public class User
|
||||||
{
|
{
|
||||||
|
public User()
|
||||||
|
{
|
||||||
|
Channels = new HashSet<string>();
|
||||||
|
}
|
||||||
|
|
||||||
public string NickName { get; set; }
|
public string NickName { get; set; }
|
||||||
public string NickNameLower { get; set; }
|
public string NickNameLower { get; set; }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue