mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-27 07:04:57 +01:00
Work on implementing chat
This commit is contained in:
@@ -19,5 +19,10 @@
|
||||
/// If the <see cref="ChatChannel"/> is an admin channel
|
||||
/// </summary>
|
||||
public bool IsAdminChannel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the <see cref="ChatChannel"/> is a watchdog channel
|
||||
/// </summary>
|
||||
public bool IsWatchdogChannel { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace Tgstation.Server.Api.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a chat service provider
|
||||
/// </summary>
|
||||
public enum ChatProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Internet relay chat
|
||||
/// </summary>
|
||||
Irc,
|
||||
/// <summary>
|
||||
/// Superior chat service
|
||||
/// </summary>
|
||||
Discord
|
||||
}
|
||||
}
|
||||
@@ -6,22 +6,10 @@ namespace Tgstation.Server.Api.Models
|
||||
/// <inheritdoc />
|
||||
public sealed class ChatSettings : Internal.ChatSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// If the IRC connection is established
|
||||
/// </summary>
|
||||
[Permissions(DenyWrite = true)]
|
||||
bool IrcConnected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the Discord connection is established
|
||||
/// </summary>
|
||||
[Permissions(DenyWrite = true)]
|
||||
bool DiscordConnected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Channels the Discord bot should listen/announce in
|
||||
/// </summary>
|
||||
[Permissions(WriteRight = ChatSettingsRights.SetChannels)]
|
||||
[Permissions(WriteRight = ChatSettingsRights.WriteChannels)]
|
||||
public List<ChatChannel> Channels { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Tgstation.Server.Api.Rights;
|
||||
|
||||
namespace Tgstation.Server.Api.Models.Internal
|
||||
@@ -8,44 +6,39 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// Manage the server chat bots
|
||||
/// </summary>
|
||||
[Model(RightsType.ChatSettings, RequiresInstance = true)]
|
||||
[Model(RightsType.ChatSettings, RequiresInstance = true, CanCrud = true, ReadRight = ChatSettingsRights.Read)]
|
||||
public class ChatSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// If the IRC client is enabled
|
||||
/// The settings id
|
||||
/// </summary>
|
||||
[Permissions(WriteRight = ChatSettingsRights.SetIrcEnabled)]
|
||||
public bool IrcEnabled { get; set; }
|
||||
[Permissions(DenyWrite = true)]
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The IRC server name
|
||||
/// The name of the connection
|
||||
/// </summary>
|
||||
[Permissions(ReadRight = ChatSettingsRights.SetIrcSettings, WriteRight = ChatSettingsRights.SetIrcSettings)]
|
||||
[Permissions(WriteRight = ChatSettingsRights.WriteName)]
|
||||
[Required]
|
||||
public string IrcHost { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The IRC server port
|
||||
/// If the connection is enabled
|
||||
/// </summary>
|
||||
[Permissions(ReadRight = ChatSettingsRights.SetIrcSettings, WriteRight = ChatSettingsRights.SetIrcSettings)]
|
||||
public ushort IrcPort { get; set; }
|
||||
[Permissions(WriteRight = ChatSettingsRights.WriteEnabled)]
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The IRC server NickServ password
|
||||
/// The <see cref="ChatProvider"/> used for the connection
|
||||
/// </summary>
|
||||
[Permissions(ReadRight = ChatSettingsRights.SetIrcSettings, WriteRight = ChatSettingsRights.SetIrcSettings)]
|
||||
public string IrcNickServPassword { get; set; }
|
||||
[Permissions(WriteRight = ChatSettingsRights.WriteProvider)]
|
||||
public ChatProvider Provider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the Discord bot is enabled
|
||||
/// The information used to connect to the <see cref="Provider"/>
|
||||
/// </summary>
|
||||
[Permissions(WriteRight = ChatSettingsRights.SetDiscordEnabled)]
|
||||
public bool DiscordEnabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Discord bot token
|
||||
/// </summary>
|
||||
[Permissions(ReadRight = ChatSettingsRights.SetDiscordSettings, WriteRight = ChatSettingsRights.SetDiscordSettings)]
|
||||
public string DiscordBotToken { get; set; }
|
||||
[Permissions(ReadRight = ChatSettingsRights.ReadConnectionString, WriteRight = ChatSettingsRights.ReadConnectionString)]
|
||||
[Required]
|
||||
public string ConnectionString { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,24 +13,32 @@ namespace Tgstation.Server.Api.Rights
|
||||
/// </summary>
|
||||
None = 0,
|
||||
/// <summary>
|
||||
/// User can enable/disable the IRC client
|
||||
/// User can change <see cref="Models.Internal.ChatSettings.Enabled"/>
|
||||
/// </summary>
|
||||
SetIrcEnabled = 1,
|
||||
WriteEnabled = 1,
|
||||
/// <summary>
|
||||
/// User can change the IRC settings
|
||||
/// User can change <see cref="Models.Internal.ChatSettings.Provider"/>
|
||||
/// </summary>
|
||||
SetIrcSettings = 2,
|
||||
WriteProvider = 2,
|
||||
/// <summary>
|
||||
/// User can change the chat channels
|
||||
/// User can change <see cref="Models.ChatSettings.Channels"/>
|
||||
/// </summary>
|
||||
SetChannels = 4,
|
||||
WriteChannels = 4,
|
||||
/// <summary>
|
||||
/// User can enable/disable the Discord bot
|
||||
/// User can change <see cref="Models.Internal.ChatSettings.ConnectionString"/>
|
||||
/// </summary>
|
||||
SetDiscordEnabled = 8,
|
||||
WriteConnectionString = 8,
|
||||
/// <summary>
|
||||
/// User can change the Discord settings
|
||||
/// User can read <see cref="Models.Internal.ChatSettings.ConnectionString"/>
|
||||
/// </summary>
|
||||
SetDiscordSettings = 16,
|
||||
ReadConnectionString = 16,
|
||||
/// <summary>
|
||||
/// User can read all chat settings except <see cref="Models.Internal.ChatSettings.ConnectionString"/>
|
||||
/// </summary>
|
||||
Read = 32,
|
||||
/// <summary>
|
||||
/// User can change <see cref="Models.Internal.ChatSettings.Name"/>
|
||||
/// </summary>
|
||||
WriteName = 32
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace Tgstation.Server.Host.Components.Chat
|
||||
{
|
||||
sealed class Channel
|
||||
{
|
||||
public long Id { get; set; }
|
||||
|
||||
public string FriendlyName { get; set; }
|
||||
|
||||
public string ConnectionName { get; set; }
|
||||
|
||||
public bool IsAdminChannel { get; set; }
|
||||
public bool IsPrivateChannel { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Tgstation.Server.Host.Components.Chat
|
||||
{
|
||||
sealed class ChannelMapping
|
||||
{
|
||||
public long ProviderId { get; set; }
|
||||
public long ProviderChannelId { get; set; }
|
||||
public bool IsWatchdogChannel { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,59 +1,175 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Tgstation.Server.Api.Models;
|
||||
using Tgstation.Server.Api.Models.Internal;
|
||||
using Tgstation.Server.Host.Components.Chat.Providers;
|
||||
using Tgstation.Server.Host.Core;
|
||||
|
||||
namespace Tgstation.Server.Host.Components.Chat
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class Chat : IChat
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public bool IrcConnected => throw new System.NotImplementedException();
|
||||
/// <summary>
|
||||
/// The <see cref="IProviderFactory"/> for the <see cref="Chat"/>
|
||||
/// </summary>
|
||||
readonly IProviderFactory providerFactory;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool DiscordConnected => throw new System.NotImplementedException();
|
||||
/// <summary>
|
||||
/// The <see cref="IIOManager"/> for the <see cref="Chat"/>
|
||||
/// </summary>
|
||||
readonly IIOManager ioManager;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task ChangeChannels(IEnumerable<ChatChannel> newChannels, CancellationToken cancellationToken)
|
||||
/// <summary>
|
||||
/// Map of <see cref="IProvider"/>s in use, keyed by <see cref="ChatSettings.Id"/>
|
||||
/// </summary>
|
||||
readonly Dictionary<long, IProvider> providers;
|
||||
|
||||
/// <summary>
|
||||
/// Map of <see cref="Channel.Id"/>s to <see cref="ChannelMapping"/>s
|
||||
/// </summary>
|
||||
readonly Dictionary<long, ChannelMapping> mappedChannels;
|
||||
|
||||
/// <summary>
|
||||
/// Used for remapping <see cref="Channel.Id"/>s
|
||||
/// </summary>
|
||||
long channelIdCounter;
|
||||
|
||||
/// <summary>
|
||||
/// Construct a <see cref="Chat"/>
|
||||
/// </summary>
|
||||
/// <param name="providerFactory">The value of <see cref="providerFactory"/></param>
|
||||
/// <param name="ioManager">The value of <see cref="ioManager"/></param>
|
||||
public Chat(IProviderFactory providerFactory, IIOManager ioManager)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
this.providerFactory = providerFactory ?? throw new ArgumentNullException(nameof(providerFactory));
|
||||
this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
|
||||
|
||||
providers = new Dictionary<long, IProvider>();
|
||||
mappedChannels = new Dictionary<long, ChannelMapping>();
|
||||
channelIdCounter = 1;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task ChangeSettings(Api.Models.Internal.ChatSettings newSettings, CancellationToken cancellationToken)
|
||||
public void Dispose()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
foreach (var I in providers)
|
||||
I.Value.Dispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task ChangeChannels(long connectionId, IEnumerable<Api.Models.ChatChannel> newChannels, CancellationToken cancellationToken)
|
||||
{
|
||||
if (newChannels == null)
|
||||
throw new ArgumentNullException(nameof(newChannels));
|
||||
IProvider provider;
|
||||
lock (providers)
|
||||
if (!providers.TryGetValue(connectionId, out provider))
|
||||
return;
|
||||
var results = await provider.MapChannels(newChannels, cancellationToken).ConfigureAwait(false);
|
||||
if (results == null) //aborted
|
||||
return;
|
||||
var mappings = Enumerable.Zip(newChannels, results, (x, y) => new ChannelMapping
|
||||
{
|
||||
IsWatchdogChannel = x.IsWatchdogChannel,
|
||||
ProviderChannelId = y.Id,
|
||||
ProviderId = connectionId
|
||||
});
|
||||
|
||||
long baseId;
|
||||
lock (this)
|
||||
{
|
||||
baseId = channelIdCounter;
|
||||
channelIdCounter += results.Count;
|
||||
}
|
||||
lock (mappedChannels)
|
||||
{
|
||||
lock (providers)
|
||||
if (!providers.TryGetValue(connectionId, out IProvider verify) || verify != provider) //aborted again
|
||||
return;
|
||||
foreach (var I in mappings)
|
||||
mappedChannels.Add(baseId++, I);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task ChangeSettings(ChatSettings newSettings, CancellationToken cancellationToken)
|
||||
{
|
||||
if (newSettings == null)
|
||||
throw new ArgumentNullException(nameof(newSettings));
|
||||
IProvider provider;
|
||||
lock (providers)
|
||||
{
|
||||
//raw settings changes forces a rebuild of the provider
|
||||
if (providers.TryGetValue(newSettings.Id, out provider))
|
||||
{
|
||||
providers.Remove(newSettings.Id);
|
||||
provider.Dispose();
|
||||
}
|
||||
if (newSettings.Enabled)
|
||||
{
|
||||
provider = providerFactory.CreateProvider(newSettings);
|
||||
providers.Add(newSettings.Id, provider);
|
||||
}
|
||||
}
|
||||
lock (mappedChannels)
|
||||
foreach (var channelId in mappedChannels.Where(x => x.Value.ProviderId == newSettings.Id).Select(x => x.Key))
|
||||
mappedChannels.Remove(channelId);
|
||||
if (newSettings.Enabled)
|
||||
await provider.Connect(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task SendMessage(string message, IEnumerable<long> channelIds, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
if (message == null)
|
||||
throw new ArgumentNullException(nameof(message));
|
||||
if (channelIds == null)
|
||||
throw new ArgumentNullException(nameof(channelIds));
|
||||
|
||||
return Task.WhenAll(channelIds.Select(x =>
|
||||
{
|
||||
ChannelMapping channelMapping;
|
||||
lock(mappedChannels)
|
||||
if (!mappedChannels.TryGetValue(x, out channelMapping))
|
||||
return Task.CompletedTask;
|
||||
IProvider provider;
|
||||
lock (providers)
|
||||
if (!providers.TryGetValue(channelMapping.ProviderId, out provider))
|
||||
return Task.CompletedTask;
|
||||
return provider.SendMessage(channelMapping.ProviderChannelId, message, cancellationToken);
|
||||
}));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task SendWatchdogMessage(string message, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
List<long> wdChannels;
|
||||
lock (mappedChannels) //so it doesn't change while we're using it
|
||||
wdChannels = mappedChannels.Where(x => x.Value.IsWatchdogChannel).Select(x => x.Key).ToList();
|
||||
return SendMessage(message, wdChannels, cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
public Task StartAsync(CancellationToken cancellationToken) => Task.WhenAll(providers.Select(x => x.Value).Select(x => x.Connect(cancellationToken)));
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<IJsonTrackingContext> TrackJsons(string basePath, string channelsJsonName, string commandsJsonName, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
ioManager.ResolvePath(".");
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
public bool Connected(long connectionId)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<IChatJsonTrackingContext> TrackJsons(string basePath, string channelsJsonName, string commandsJsonName, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
lock (providers)
|
||||
return providers.TryGetValue(connectionId, out var provider) && provider.Connected;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,33 +10,31 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
/// <summary>
|
||||
/// For managing connected chat services
|
||||
/// </summary>
|
||||
public interface IChat : IHostedService
|
||||
public interface IChat : IHostedService, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// If the IRC client is connected
|
||||
/// If a given set of <see cref="ChatSettings"/> is connected
|
||||
/// </summary>
|
||||
bool IrcConnected { get; }
|
||||
/// <param name="connectionId">The <see cref="ChatSettings.Id"/> of the connection</param>
|
||||
/// <returns><see langword="true"/> if it is connected, <see langword="false"/> otherwise</returns>
|
||||
bool Connected(long connectionId);
|
||||
|
||||
/// <summary>
|
||||
/// If the Discord client is connected
|
||||
/// </summary>
|
||||
bool DiscordConnected { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Change chat settings
|
||||
/// Change chat settings. If the <see cref="ChatSettings.Id"/> is not currently in use, a new connection will be made instead
|
||||
/// </summary>
|
||||
/// <param name="newSettings">The new <see cref="ChatSettings"/></param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation</returns>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation. Will complete immediately if the <see cref="ChatSettings.Enabled"/> property of <paramref name="newSettings"/> is <see langword="false"/></returns>
|
||||
Task ChangeSettings(ChatSettings newSettings, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Change chat channels
|
||||
/// </summary>
|
||||
/// <param name="connectionId">The <see cref="ChatSettings.Id"/> of the connection</param>
|
||||
/// <param name="newChannels">An <see cref="IEnumerable{T}"/> of the new list of <see cref="Api.Models.ChatChannel"/>s</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation</returns>
|
||||
Task ChangeChannels(IEnumerable<Api.Models.ChatChannel> newChannels, CancellationToken cancellationToken);
|
||||
Task ChangeChannels(long connectionId, IEnumerable<Api.Models.ChatChannel> newChannels, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Send a chat <paramref name="message"/> to a given set of <paramref name="channelIds"/>
|
||||
@@ -63,6 +61,6 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
/// <param name="commandsJsonName">The name of the chat commands json</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in a <see cref="IDisposable"/> tied to the lifetime of the json trackings</returns>
|
||||
Task<IChatJsonTrackingContext> TrackJsons(string basePath, string channelsJsonName, string commandsJsonName, CancellationToken cancellationToken);
|
||||
Task<IJsonTrackingContext> TrackJsons(string basePath, string channelsJsonName, string commandsJsonName, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -5,7 +5,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
/// <summary>
|
||||
/// Represents a tracking of dynamic chat json files
|
||||
/// </summary>
|
||||
public interface IChatJsonTrackingContext : IDisposable
|
||||
public interface IJsonTrackingContext : IDisposable
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Tgstation.Server.Api.Models.Internal;
|
||||
using Tgstation.Server.Host.Components.Chat.Providers;
|
||||
|
||||
namespace Tgstation.Server.Host.Components.Chat
|
||||
{
|
||||
/// <summary>
|
||||
/// Factory for <see cref="IProvider"/>s
|
||||
/// </summary>
|
||||
interface IProviderFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a <see cref="IProvider"/>
|
||||
/// </summary>
|
||||
/// <param name="settings">The <see cref="ChatSettings"/> for the new provider</param>
|
||||
/// <returns>A new <see cref="IProvider"/></returns>
|
||||
IProvider CreateProvider(ChatSettings settings);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
{
|
||||
sealed class Message
|
||||
{
|
||||
string Content { get; set; }
|
||||
User User { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Tgstation.Server.Api.Models;
|
||||
using Tgstation.Server.Host.Components.Chat.Providers;
|
||||
|
||||
namespace Tgstation.Server.Host.Components.Chat
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class ProviderFactory : IProviderFactory
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public IProvider CreateProvider(Api.Models.Internal.ChatSettings settings)
|
||||
{
|
||||
if (settings == null)
|
||||
throw new ArgumentNullException(nameof(settings));
|
||||
switch (settings.Provider)
|
||||
{
|
||||
case ChatProvider.Irc:
|
||||
throw new NotImplementedException();
|
||||
case ChatProvider.Discord:
|
||||
throw new NotImplementedException();
|
||||
default:
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Invalid ChatProvider: {0}", settings.Provider));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// For interacting with a chat service
|
||||
/// </summary>
|
||||
interface IProvider : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// If the <see cref="IProvider"/>
|
||||
/// </summary>
|
||||
bool Connected { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="string"/> that indicates the <see cref="IProvider"/> was mentioned
|
||||
/// </summary>
|
||||
string BotMention { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="Task{TResult}"/> resulting in the next <see cref="Message"/> the <see cref="IProvider"/> recieves or <see langword="null"/> on a disconnect
|
||||
/// </summary>
|
||||
Task<Message> NextMessage { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Attempt to connect the <see cref="IProvider"/>
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in <see langword="true"/> on success, <see langword="false"/> otherwise</returns>
|
||||
Task<bool> Connect(CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Get the <see cref="Channel"/>s for given <paramref name="channels"/>
|
||||
/// </summary>
|
||||
/// <param name="channels">The <see cref="Api.Models.ChatChannel"/>s to map</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in a <see cref="IReadOnlyList{T}"/> of the <see cref="Channel"/>s representing <paramref name="channels"/></returns>
|
||||
Task<IReadOnlyList<Channel>> MapChannels(IEnumerable<Api.Models.ChatChannel> channels, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Send a message to the <see cref="IProvider"/>
|
||||
/// </summary>
|
||||
/// <param name="channelId">The <see cref="Channel.Id"/> to send to</param>
|
||||
/// <param name="message">The message contents</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation</returns>
|
||||
Task SendMessage(long channelId, string message, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -5,7 +5,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
/// <summary>
|
||||
/// Represents a chat message requested by DD
|
||||
/// </summary>
|
||||
sealed class ChatResponse
|
||||
sealed class Response
|
||||
{
|
||||
/// <summary>
|
||||
/// The message string
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Tgstation.Server.Host.Components.Chat
|
||||
{
|
||||
class User
|
||||
{
|
||||
long Id { get; set; }
|
||||
string FriendlyName { get; set; }
|
||||
string Mention { get; set; }
|
||||
Channel channel { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -102,9 +102,9 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
readonly ISession session;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IChatJsonTrackingContext"/> for the <see cref="SessionController"/>
|
||||
/// The <see cref="IJsonTrackingContext"/> for the <see cref="SessionController"/>
|
||||
/// </summary>
|
||||
readonly IChatJsonTrackingContext chatJsonTrackingContext;
|
||||
readonly IJsonTrackingContext chatJsonTrackingContext;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IChat"/> for the <see cref="SessionController"/>
|
||||
@@ -154,7 +154,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
/// <param name="chat">The value of <see cref="chat"/></param>
|
||||
/// <param name="chatJsonTrackingContext">The value of <see cref="chatJsonTrackingContext"/></param>
|
||||
/// <param name="logger">The value of <see cref="logger"/></param>
|
||||
public SessionController(ReattachInformation reattachInformation, ISession session, IByondTopicSender byondTopicSender, IInteropRegistrar interopRegistrar, IChatJsonTrackingContext chatJsonTrackingContext, IChat chat, ILogger<SessionController> logger)
|
||||
public SessionController(ReattachInformation reattachInformation, ISession session, IByondTopicSender byondTopicSender, IInteropRegistrar interopRegistrar, IJsonTrackingContext chatJsonTrackingContext, IChat chat, ILogger<SessionController> logger)
|
||||
{
|
||||
this.chatJsonTrackingContext = chatJsonTrackingContext; //null valid
|
||||
this.reattachInformation = reattachInformation ?? throw new ArgumentNullException(nameof(reattachInformation));
|
||||
|
||||
@@ -539,10 +539,10 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
if (results == null)
|
||||
return;
|
||||
|
||||
List<ChatResponse> responses;
|
||||
List<Response> responses;
|
||||
try
|
||||
{
|
||||
responses = JsonConvert.DeserializeObject<List<ChatResponse>>(results);
|
||||
responses = JsonConvert.DeserializeObject<List<Response>>(results);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ChatSettings.Id"/>
|
||||
/// The <see cref="Api.Models.Internal.ChatSettings.Id"/>
|
||||
/// </summary>
|
||||
public long ChatSettingsId { get; set; }
|
||||
|
||||
|
||||
@@ -5,12 +5,7 @@ namespace Tgstation.Server.Host.Models
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public sealed class ChatSettings : Api.Models.Internal.ChatSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// The row Id
|
||||
/// </summary>
|
||||
public long Id { get; set; }
|
||||
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="Api.Models.Instance.Id"/>
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user