diff --git a/build/Version.props b/build/Version.props
index 7878a900d9..b9cd0eadbd 100644
--- a/build/Version.props
+++ b/build/Version.props
@@ -3,7 +3,7 @@
4.1.0
- 6.0.0
+ 6.1.0
6.0.0
5.0.0
0.4.0
diff --git a/src/Tgstation.Server.Api/Models/ChatChannel.cs b/src/Tgstation.Server.Api/Models/ChatChannel.cs
index d2c38df45d..0039e9bc20 100644
--- a/src/Tgstation.Server.Api/Models/ChatChannel.cs
+++ b/src/Tgstation.Server.Api/Models/ChatChannel.cs
@@ -8,7 +8,8 @@ namespace Tgstation.Server.Api.Models
public class ChatChannel
{
///
- /// The IRC channel name
+ /// The IRC channel name. Also potentially contains the channel passsword (if separated by a colon).
+ /// If multiple copies of the same channel with different keys are added to the server, the one that will be used is undefined.
///
[StringLength(Limits.MaximumIndexableStringLength)]
public string IrcChannel { get; set; }
diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs
index 2b52d7c47f..e4dc424f34 100644
--- a/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs
+++ b/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs
@@ -9,6 +9,7 @@ using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Api.Models;
using Tgstation.Server.Host.Core;
+using Tgstation.Server.Host.Extensions;
using Tgstation.Server.Host.System;
namespace Tgstation.Server.Host.Components.Chat.Providers
@@ -376,52 +377,68 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
}
///
- public override Task> MapChannels(IEnumerable channels, CancellationToken cancellationToken) => Task.Factory.StartNew(() =>
- {
- if (channels.Any(x => x.IrcChannel == null))
- throw new InvalidOperationException("ChatChannel missing IrcChannel!");
- lock (this)
+ public override Task> MapChannels(
+ IEnumerable channels,
+ CancellationToken cancellationToken)
+ => Task.Factory.StartNew(() =>
{
- var hs = new HashSet(); // for unique inserts
- foreach (var I in channels)
- hs.Add(I.IrcChannel);
- var toPart = new List();
- foreach (var I in client.JoinedChannels)
- if (!hs.Remove(I))
- toPart.Add(I);
-
- foreach (var I in toPart)
- client.RfcPart(I, "Pretty nice abscond!");
- foreach (var I in hs)
- client.RfcJoin(I);
-
- return (IReadOnlyCollection)channels.Select(x =>
+ if (channels.Any(x => x.IrcChannel == null))
+ throw new InvalidOperationException("ChatChannel missing IrcChannel!");
+ lock (this)
{
- ulong? id = null;
- if (!channelIdMap.Any(y =>
+ var channelsWithKeys = new Dictionary();
+ var hs = new HashSet(); // for unique inserts
+ foreach (var channel in channels)
{
- if (y.Value != x.IrcChannel)
- return false;
- id = y.Key;
- return true;
- }))
- {
- id = channelIdCounter++;
- channelIdMap.Add(id.Value, x.IrcChannel);
+ var name = channel.GetIrcChannelName();
+ var key = channel.GetIrcChannelKey();
+ if (hs.Add(name) && key != null)
+ channelsWithKeys.Add(name, key);
}
- return new ChannelRepresentation
- {
- RealId = id.Value,
- IsAdminChannel = x.IsAdminChannel == true,
- ConnectionName = address,
- FriendlyName = channelIdMap[id.Value],
- IsPrivateChannel = false,
- Tag = x.Tag
- };
- }).ToList();
- }
- }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current);
+ var toPart = new List();
+ foreach (var activeChannel in client.JoinedChannels)
+ if (!hs.Remove(activeChannel))
+ toPart.Add(activeChannel);
+
+ foreach (var channelToLeave in toPart)
+ client.RfcPart(channelToLeave, "Pretty nice abscond!");
+ foreach (var channelToJoin in hs)
+ if (channelsWithKeys.TryGetValue(channelToJoin, out var key))
+ client.RfcJoin(channelToJoin, key);
+ else
+ client.RfcJoin(channelToJoin);
+
+ return (IReadOnlyCollection)channels
+ .Select(x =>
+ {
+ var channelName = x.GetIrcChannelName();
+ ulong? id = null;
+ if (!channelIdMap.Any(y =>
+ {
+ if (y.Value != channelName)
+ return false;
+ id = y.Key;
+ return true;
+ }))
+ {
+ id = channelIdCounter++;
+ channelIdMap.Add(id.Value, channelName);
+ }
+
+ return new ChannelRepresentation
+ {
+ RealId = id.Value,
+ IsAdminChannel = x.IsAdminChannel == true,
+ ConnectionName = address,
+ FriendlyName = channelIdMap[id.Value],
+ IsPrivateChannel = false,
+ Tag = x.Tag
+ };
+ })
+ .ToList();
+ }
+ }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current);
///
public override Task SendMessage(ulong channelId, string message, CancellationToken cancellationToken) => Task.Factory.StartNew(() =>
diff --git a/src/Tgstation.Server.Host/Extensions/ChatChannelExtensions.cs b/src/Tgstation.Server.Host/Extensions/ChatChannelExtensions.cs
new file mode 100644
index 0000000000..be2afe14bd
--- /dev/null
+++ b/src/Tgstation.Server.Host/Extensions/ChatChannelExtensions.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Tgstation.Server.Api.Models;
+
+namespace Tgstation.Server.Host.Extensions
+{
+ ///
+ /// Extensions for the .
+ ///
+ static class ChatChannelExtensions
+ {
+ ///
+ /// Gets the IRC channel name from a given .
+ ///
+ /// The to retrieve information from.
+ /// The IRC channel name stored in the .
+ public static string GetIrcChannelName(this ChatChannel chatChannel) => GetIrcChannelSplits(chatChannel).First();
+
+ ///
+ /// Gets the IRC channel key from a given .
+ ///
+ /// The to retrieve information from.
+ /// The IRC channel key stored in the if it exists, otherwise.
+ public static string GetIrcChannelKey(this ChatChannel chatChannel)
+ {
+ var splits = GetIrcChannelSplits(chatChannel);
+ if (splits.Count < 2)
+ return null;
+ return splits.Last();
+ }
+
+ ///
+ /// Split a given 's .
+ ///
+ /// The to work with.
+ /// A of the 's separated by the ':' .
+ static IReadOnlyCollection GetIrcChannelSplits(ChatChannel chatChannel)
+ {
+ if (chatChannel == null)
+ throw new ArgumentNullException(nameof(chatChannel));
+
+ if (chatChannel.IrcChannel == null)
+ throw new ArgumentException("IrcChannel must be set!", nameof(chatChannel));
+
+ return chatChannel.IrcChannel.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
+ }
+ }
+}
diff --git a/tests/Tgstation.Server.Tests/VersionsTest.cs b/tests/Tgstation.Server.Tests/VersionsTest.cs
index 81bcc68c41..0bc638dec2 100644
--- a/tests/Tgstation.Server.Tests/VersionsTest.cs
+++ b/tests/Tgstation.Server.Tests/VersionsTest.cs
@@ -60,19 +60,6 @@ namespace Tgstation.Server.Tests
Assert.AreEqual(expected, actual);
}
- [TestMethod]
- public void TestClientVersionFollowingApiVersion()
- {
- var versionString = versionsPropertyGroup.Element(xmlNamespace + "TgsApiVersion").Value + ".0";
- Assert.IsNotNull(versionString);
- Assert.IsTrue(Version.TryParse(versionString, out var apiVersion));
-
- versionString = versionsPropertyGroup.Element(xmlNamespace + "TgsClientVersion").Value + ".0";
- Assert.IsNotNull(versionString);
- Assert.IsTrue(Version.TryParse(versionString, out var clientVersion));
- Assert.IsTrue(clientVersion >= apiVersion);
- }
-
[TestMethod]
public void TestWatchdogVersion()
{