about summary refs log tree commit diff
path: root/IrcStates/Server.cs
diff options
context:
space:
mode:
Diffstat (limited to 'IrcStates/Server.cs')
-rw-r--r--IrcStates/Server.cs206
1 files changed, 184 insertions, 22 deletions
diff --git a/IrcStates/Server.cs b/IrcStates/Server.cs
index ea7dd9e..d9022a0 100644
--- a/IrcStates/Server.cs
+++ b/IrcStates/Server.cs
@@ -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)