From 56ca3205bbf9f659e22e0a8fb250cc2cab1176bb Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Wed, 18 Jul 2018 12:47:28 -0400 Subject: [PATCH] WIP IrcProvider --- .../Chat/Providers/IrcPasswordType.cs | 9 + .../Components/Chat/Providers/IrcProvider.cs | 175 ++++++++++++++++++ src/Tgstation.Server.Host/Core/Application.cs | 4 + .../Core/IApplication.cs | 5 + 4 files changed, 193 insertions(+) create mode 100644 src/Tgstation.Server.Host/Components/Chat/Providers/IrcPasswordType.cs create mode 100644 src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/IrcPasswordType.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/IrcPasswordType.cs new file mode 100644 index 0000000000..38181f9f99 --- /dev/null +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/IrcPasswordType.cs @@ -0,0 +1,9 @@ +namespace Tgstation.Server.Host.Components.Chat.Providers +{ + enum IrcPasswordType + { + Server, + Sasl, + NickServ + } +} diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs new file mode 100644 index 0000000000..49410fc57d --- /dev/null +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs @@ -0,0 +1,175 @@ +using Meebey.SmartIrc4net; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Threading; +using System.Threading.Tasks; +using Tgstation.Server.Api.Models; +using Tgstation.Server.Host.Core; + +namespace Tgstation.Server.Host.Components.Chat.Providers +{ + /// + /// for internet relay chat + /// + sealed class IrcProvider : IProvider + { + /// + public bool Connected => throw new NotImplementedException(); + + /// + public string BotMention => throw new NotImplementedException(); + + /// + /// The for the + /// + readonly ILogger logger; + + /// + /// The client + /// + readonly IrcFeatures client; + + /// + /// Address of the server to connect to + /// + readonly string address; + /// + /// Port of the server to connect to + /// + readonly ushort port; + /// + /// IRC nickname + /// + readonly string nickname; + /// + /// Password which will used for authentication + /// + readonly string password; + /// + /// The of + /// + readonly IrcPasswordType? passwordType; + + /// + /// Construct an + /// + /// The value of logger + /// The to get the from + /// The value of + /// The value of + /// The value of + /// The value of + /// The value of + /// If should be used + public IrcProvider(ILogger logger, IApplication application, string address, ushort port, string nickname, string password, IrcPasswordType? passwordType, bool useSsl) + { + this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); + if (application == null) + throw new ArgumentNullException(nameof(application)); + + this.address = address ?? throw new ArgumentNullException(nameof(address)); + this.port = port; + this.nickname = nickname ?? throw new ArgumentNullException(nameof(nickname)); + + if (passwordType.HasValue && password == null) + throw new ArgumentNullException(nameof(password)); + + if(password != null && !passwordType.HasValue) + throw new ArgumentNullException(nameof(passwordType)); + + this.password = password; + this.passwordType = passwordType; + + client = new IrcFeatures + { + SupportNonRfc = true, + CtcpUserInfo = "You are going to play. And I am going to watch. And everything will be just fine...", + AutoRejoin = true, + AutoRejoinOnKick = true, + AutoRelogin = true, + AutoRetry = true, + AutoRetryLimit = 5, + AutoRetryDelay = 5, + ActiveChannelSyncing = true, + AutoNickHandling = true, + CtcpVersion = application.VersionString, + UseSsl = useSsl, + ValidateServerCertificate = useSsl, + }; + + client.OnChannelMessage += Client_OnChannelMessage; + client.OnQueryMessage += Client_OnQueryMessage; + } + + void Client_OnQueryMessage(object sender, IrcEventArgs e) + { + throw new NotImplementedException(); + } + + void Client_OnChannelMessage(object sender, IrcEventArgs e) + { + throw new NotImplementedException(); + } + + /// + public void Dispose() => Disconnect(default).Wait(); //not actually a task so whatever + + /// + public Task Connect(CancellationToken cancellationToken) => Task.Factory.StartNew(() => + { + try + { + client.Connect(address, port); + + cancellationToken.ThrowIfCancellationRequested(); + + if (passwordType == IrcPasswordType.Sasl) + { + //TODO + } + + if (passwordType == IrcPasswordType.Server) + client.Login(nickname, nickname, 0, nickname, password); + else + client.Login(nickname, nickname); + + if (passwordType == IrcPasswordType.NickServ) + { + cancellationToken.ThrowIfCancellationRequested(); + client.SendMessage(SendType.Message, "NickServ", String.Format(CultureInfo.InvariantCulture, "IDENTIFY {0}", password)); + } + } + catch(Exception e) + { + logger.LogWarning("Unable to connect to IRC: {0}", e); + } + return true; + }, cancellationToken,TaskCreationOptions.LongRunning, TaskScheduler.Current); + + /// + public Task Disconnect(CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + /// + public Task> MapChannels(IEnumerable channels, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + /// + public Task NextMessage(CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + /// + public Task SendMessage(ulong channelId, string message, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Tgstation.Server.Host/Core/Application.cs b/src/Tgstation.Server.Host/Core/Application.cs index 963b22e98a..cd8c07c453 100644 --- a/src/Tgstation.Server.Host/Core/Application.cs +++ b/src/Tgstation.Server.Host/Core/Application.cs @@ -30,6 +30,9 @@ namespace Tgstation.Server.Host.Core /// public Version Version { get; } + /// + public string VersionString { get; } + /// /// The for the /// @@ -56,6 +59,7 @@ namespace Tgstation.Server.Host.Core this.hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment)); Version = Assembly.GetExecutingAssembly().GetName().Version; + VersionString = String.Format(CultureInfo.InvariantCulture, "/tg/station server v{0}", Version); } /// diff --git a/src/Tgstation.Server.Host/Core/IApplication.cs b/src/Tgstation.Server.Host/Core/IApplication.cs index eed6769ab3..b00ae8a3b9 100644 --- a/src/Tgstation.Server.Host/Core/IApplication.cs +++ b/src/Tgstation.Server.Host/Core/IApplication.cs @@ -7,6 +7,11 @@ namespace Tgstation.Server.Host.Core /// public interface IApplication { + /// + /// A more verbose version of + /// + string VersionString { get; } + /// /// The version of the ///