diff --git a/src/DMAPI/tgs.dm b/src/DMAPI/tgs.dm index 05a4b3e9a5..c96d7500b9 100644 --- a/src/DMAPI/tgs.dm +++ b/src/DMAPI/tgs.dm @@ -100,6 +100,7 @@ var/connection_name //the name of the configured chat connection var/is_admin_channel //if the server operator has marked this channel for game admins only var/is_private_channel //if this is a private chat channel + var/tag //user defined string associated with channel //represents a chat user /datum/tgs_chat_user diff --git a/src/DMAPI/tgs/v4/api.dm b/src/DMAPI/tgs/v4/api.dm index c24691e150..29cea8ab8b 100644 --- a/src/DMAPI/tgs/v4/api.dm +++ b/src/DMAPI/tgs/v4/api.dm @@ -291,7 +291,8 @@ channel.friendly_name = channel_json["friendlyName"] channel.connection_name = channel_json["connectionName"] channel.is_admin_channel = channel_json["isAdminChannel"] - channel.is_private_channel = channel_json["isPrivateChannel"] || FALSE + channel.is_private_channel = channel_json["isPrivateChannel"] + channel.tag = channel_json["tag"] return channel /* diff --git a/src/Tgstation.Server.Api/Models/ChatChannel.cs b/src/Tgstation.Server.Api/Models/ChatChannel.cs index 5b64376bf5..36cddd706f 100644 --- a/src/Tgstation.Server.Api/Models/ChatChannel.cs +++ b/src/Tgstation.Server.Api/Models/ChatChannel.cs @@ -34,5 +34,10 @@ namespace Tgstation.Server.Api.Models /// [Required] public bool? IsUpdatesChannel { get; set; } + + /// + /// A custom tag users can define to group channels together + /// + public string Tag { get; set; } } } diff --git a/src/Tgstation.Server.Host/Components/Chat/Channel.cs b/src/Tgstation.Server.Host/Components/Chat/Channel.cs index 07111826d8..0e3c4afe65 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Channel.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Channel.cs @@ -44,5 +44,10 @@ namespace Tgstation.Server.Host.Components.Chat /// If this is a 1-to-1 chat channel /// public bool IsPrivate { get; set; } + + /// + /// For user use + /// + public string Tag { get; set; } } } diff --git a/src/Tgstation.Server.Host/Components/Chat/Chat.cs b/src/Tgstation.Server.Host/Components/Chat/Chat.cs index 983155cad5..1a48978243 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Chat.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Chat.cs @@ -165,13 +165,15 @@ namespace Tgstation.Server.Host.Components.Chat async Task ProcessMessage(IProvider provider, Message message, CancellationToken cancellationToken) { //map the channel if it's private and we haven't seen it - if (message.User.Channel.IsPrivate) - lock (providers) + lock (providers) + { + var providerId = providers.Where(x => x.Value == provider).Select(x => x.Key).First(); + var enumerable = mappedChannels.Where(x => x.Value.ProviderId == providerId && x.Value.ProviderChannelId == message.User.Channel.RealId); + if (message.User.Channel.IsPrivate) lock (mappedChannels) { if (!provider.Connected) return; - var enumerable = mappedChannels.Where(x => x.Value.ProviderChannelId == message.User.Channel.RealId); if (!enumerable.Any()) { ulong newId; @@ -181,7 +183,7 @@ namespace Tgstation.Server.Host.Components.Chat { IsWatchdogChannel = false, ProviderChannelId = message.User.Channel.RealId, - ProviderId = providers.Where(x => x.Value == provider).Select(x => x.Key).First(), + ProviderId = providerId, Channel = message.User.Channel }); message.User.Channel.RealId = newId; @@ -189,6 +191,14 @@ namespace Tgstation.Server.Host.Components.Chat else message.User.Channel.RealId = enumerable.First().Key; } + else + { + //need to add tag and isAdminChannel + var mapping = enumerable.First().Value; + message.User.Channel.Tag = mapping.Channel.Tag; + message.User.Channel.IsAdmin = mapping.Channel.IsAdmin; + } + } var splits = new List(message.Content.Trim().Split(' ')); var address = splits[0]; @@ -249,7 +259,7 @@ namespace Tgstation.Server.Host.Components.Chat { var helpHandler = await GetCommand(splits[0].ToUpperInvariant()).ConfigureAwait(false); if (helpHandler != default) - helpText = String.Format(CultureInfo.InvariantCulture, "{0}: {1}", helpHandler.Name, helpHandler.HelpText); + helpText = String.Format(CultureInfo.InvariantCulture, "{0}: {1}{2}", helpHandler.Name, helpHandler.HelpText, helpHandler.AdminOnly ? " - May only be used in admin channels" : String.Empty); else helpText = UnknownCommandMessage; } @@ -258,6 +268,13 @@ namespace Tgstation.Server.Host.Components.Chat } var commandHandler = await GetCommand(command).ConfigureAwait(false); + + if (commandHandler.AdminOnly && !message.User.Channel.IsAdmin) + { + await SendMessage("Use this command in an admin channel!", new List { message.User.Channel.RealId }, cancellationToken).ConfigureAwait(false); + return; + } + if (commandHandler == default) { await SendMessage(UnknownCommandMessage, new List { message.User.Channel.RealId }, cancellationToken).ConfigureAwait(false); diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs index 1738af477b..fe4ade8202 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs @@ -91,10 +91,10 @@ namespace Tgstation.Server.Host.Components.Chat.Providers Channel = new Channel { RealId = e.Channel.Id, - IsAdmin = false, IsPrivate = true, ConnectionName = pm ? e.Author.Username : (e.Channel as ITextChannel)?.Guild.Name ?? "UNKNOWN", FriendlyName = e.Channel.Name + //isAdmin and Tag populated by manager }, FriendlyName = e.Author.Username, Mention = NormalizeMention(e.Author.Mention) @@ -176,7 +176,8 @@ namespace Tgstation.Server.Host.Components.Chat.Providers IsAdmin = channel.IsAdminChannel == true, ConnectionName = discordChannel.Guild.Name, FriendlyName = discordChannel.Name, - IsPrivate = false + IsPrivate = false, + Tag = channel.Tag }; }; diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs index 1e4f39d80d..72af093b06 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs @@ -160,23 +160,31 @@ namespace Tgstation.Server.Host.Components.Chat.Providers var username = e.Data.Nick; var channelName = isPrivate ? username : e.Data.Channel; - ulong channelId = 0; - lock (this) + + ulong MapAndGetChannelId(Dictionary dicToCheck) { - var dicToCheck = isPrivate ? queryChannelIdMap : channelIdMap; + ulong? resultId = null; if (!dicToCheck.Any(x => { if (x.Value != channelName) return false; - channelId = x.Key; + resultId = x.Key; return true; })) { - channelId = ++channelIdCounter; - dicToCheck.Add(channelId, channelName); - if (isPrivate) - channelIdMap.Add(channelId, null); + resultId = ++channelIdCounter; + dicToCheck.Add(resultId.Value, channelName); + if (dicToCheck == queryChannelIdMap) + channelIdMap.Add(resultId.Value, null); } + return resultId.Value; + }; + + ulong userId, channelId; + lock (this) + { + userId = MapAndGetChannelId(queryChannelIdMap); + channelId = isPrivate ? userId : MapAndGetChannelId(channelIdMap); } var message = new Message @@ -186,14 +194,14 @@ namespace Tgstation.Server.Host.Components.Chat.Providers { Channel = new Channel { - IsAdmin = false, ConnectionName = address, FriendlyName = isPrivate ? String.Format(CultureInfo.InvariantCulture, "PM: {0}", channelName) : channelName, RealId = channelId, IsPrivate = isPrivate + //isAdmin and Tag populated by manager }, FriendlyName = username, - RealId = channelId, + RealId = userId, Mention = username } }; @@ -368,7 +376,8 @@ namespace Tgstation.Server.Host.Components.Chat.Providers IsAdmin = x.IsAdminChannel == true, ConnectionName = address, FriendlyName = channelIdMap[id], - IsPrivate = false + IsPrivate = false, + Tag = x.Tag }; }).ToList(); } diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs index 0c6b7920fb..f0fb73e42a 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs @@ -18,6 +18,9 @@ namespace Tgstation.Server.Host.Components.Chat.Providers /// TaskCompletionSource nextMessage; + /// + /// Construct a + /// protected Provider() { messageQueue = new Queue();