156 lines
4.7 KiB
C#
156 lines
4.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Reflection.Metadata.Ecma335;
|
|
using IrcTokens;
|
|
|
|
namespace IrcStates
|
|
{
|
|
public class Server
|
|
{
|
|
public const string WhoType = "525"; // randomly generated
|
|
private readonly StatefulDecoder _decoder;
|
|
|
|
private Dictionary<string, string> TempCaps;
|
|
|
|
public Server(string name)
|
|
{
|
|
Name = name;
|
|
Registered = false;
|
|
Modes = new List<string>();
|
|
Motd = new List<string>();
|
|
_decoder = new StatefulDecoder();
|
|
Users = new Dictionary<string, User>();
|
|
Channels = new Dictionary<string, Channel>();
|
|
ISupport = new ISupport();
|
|
HasCap = false;
|
|
TempCaps = new Dictionary<string, string>();
|
|
AvailableCaps = new Dictionary<string, string>();
|
|
AgreedCaps = new List<string>();
|
|
RegisterHandlersByAttribute();
|
|
}
|
|
|
|
private void RegisterHandlersByAttribute()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public string Name { get; set; }
|
|
public string NickName { get; set; }
|
|
public string NickNameLower { get; set; }
|
|
public string UserName { get; set; }
|
|
public string HostName { get; set; }
|
|
public string RealName { get; set; }
|
|
public string Account { get; set; }
|
|
public string Away { get; set; }
|
|
|
|
public bool Registered { get; set; }
|
|
public List<string> Modes { get; set; }
|
|
public List<string> Motd { get; set; }
|
|
public Dictionary<string, User> Users { get; set; }
|
|
public Dictionary<string, Channel> Channels { get; set; }
|
|
public Dictionary<string, string> AvailableCaps { get; set; }
|
|
public List<string> AgreedCaps { get; set; }
|
|
|
|
public ISupport ISupport { get; set; }
|
|
public bool HasCap { get; set; }
|
|
|
|
public delegate Emit MessageHandler(Server server, Line line);
|
|
private Dictionary<string, List<MessageHandler>> Handlers { get; set; }
|
|
|
|
public override string ToString()
|
|
{
|
|
return $"Server(name={Name})";
|
|
}
|
|
|
|
public List<(Line, Emit)> Recv(byte[] data)
|
|
{
|
|
if (data == null) return null;
|
|
|
|
var lines = _decoder.Push(data, data.Length);
|
|
if (lines == null) throw new ServerDisconnectedException();
|
|
|
|
return lines.Select(l => (l, ParseTokens(l))).ToList();
|
|
}
|
|
|
|
public Emit Parse(Line line)
|
|
{
|
|
if (line == null || !Handlers.ContainsKey(line.Command)) return null;
|
|
var ret = new Emit();
|
|
|
|
var handlers = Handlers[line.Command]
|
|
.Select(callback => callback(this, line))
|
|
.Where(emit => emit != null);
|
|
|
|
foreach (var emit in handlers)
|
|
{
|
|
emit.Command = line.Command;
|
|
ret = emit;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
public string CaseFold(string str)
|
|
{
|
|
return Casemap.CaseFold(ISupport.CaseMapping, str);
|
|
}
|
|
|
|
public bool CaseFoldEquals(string s1, string s2)
|
|
{
|
|
return CaseFold(s1) == CaseFold(s2);
|
|
}
|
|
|
|
public bool IsMe(string nickname)
|
|
{
|
|
return CaseFold(nickname) == NickNameLower;
|
|
}
|
|
|
|
public bool HasUser(string nickname)
|
|
{
|
|
return Users.ContainsKey(CaseFold(nickname));
|
|
}
|
|
|
|
private void AddUser(string nickname, string nicknameLower)
|
|
{
|
|
var user = CreateUser(nickname, nicknameLower);
|
|
Users[nicknameLower] = user;
|
|
}
|
|
|
|
private User CreateUser(string nickname, string nicknameLower)
|
|
{
|
|
var user = new User();
|
|
user.SetNickName(nickname, nicknameLower);
|
|
return user;
|
|
}
|
|
|
|
public bool IsChannel(string target)
|
|
{
|
|
return !string.IsNullOrEmpty(target) &&
|
|
ISupport.ChanTypes.Contains(target[0].ToString(CultureInfo.InvariantCulture));
|
|
}
|
|
|
|
public bool HasChannel(string name)
|
|
{
|
|
return Channels.ContainsKey(CaseFold(name));
|
|
}
|
|
|
|
public Channel GetChannel(string name)
|
|
{
|
|
return HasChannel(name) ? Channels[name] : null;
|
|
}
|
|
|
|
[Handles(Numeric.RPL_WELCOME)]
|
|
private Emit HandleWelcome(Line line)
|
|
{
|
|
NickName = line.Params[0];
|
|
NickNameLower = CaseFold(line.Params[0]);
|
|
Registered = true;
|
|
return new Emit();
|
|
}
|
|
|
|
}
|
|
}
|