diff --git a/src/Tgstation.Server.Api/Models/ChatChannel.cs b/src/Tgstation.Server.Api/Models/ChatChannel.cs
index a927090029..c7ab3b9b32 100644
--- a/src/Tgstation.Server.Api/Models/ChatChannel.cs
+++ b/src/Tgstation.Server.Api/Models/ChatChannel.cs
@@ -19,5 +19,10 @@
/// If the is an admin channel
///
public bool IsAdminChannel { get; set; }
+
+ ///
+ /// If the is a watchdog channel
+ ///
+ public bool IsWatchdogChannel { get; set; }
}
}
diff --git a/src/Tgstation.Server.Api/Models/ChatProvider.cs b/src/Tgstation.Server.Api/Models/ChatProvider.cs
new file mode 100644
index 0000000000..f41d9de9c5
--- /dev/null
+++ b/src/Tgstation.Server.Api/Models/ChatProvider.cs
@@ -0,0 +1,17 @@
+namespace Tgstation.Server.Api.Models
+{
+ ///
+ /// Represents a chat service provider
+ ///
+ public enum ChatProvider
+ {
+ ///
+ /// Internet relay chat
+ ///
+ Irc,
+ ///
+ /// Superior chat service
+ ///
+ Discord
+ }
+}
diff --git a/src/Tgstation.Server.Api/Models/ChatSettings.cs b/src/Tgstation.Server.Api/Models/ChatSettings.cs
index 2900a7e055..aab5431e9a 100644
--- a/src/Tgstation.Server.Api/Models/ChatSettings.cs
+++ b/src/Tgstation.Server.Api/Models/ChatSettings.cs
@@ -6,22 +6,10 @@ namespace Tgstation.Server.Api.Models
///
public sealed class ChatSettings : Internal.ChatSettings
{
- ///
- /// If the IRC connection is established
- ///
- [Permissions(DenyWrite = true)]
- bool IrcConnected { get; set; }
-
- ///
- /// If the Discord connection is established
- ///
- [Permissions(DenyWrite = true)]
- bool DiscordConnected { get; set; }
-
///
/// Channels the Discord bot should listen/announce in
///
- [Permissions(WriteRight = ChatSettingsRights.SetChannels)]
+ [Permissions(WriteRight = ChatSettingsRights.WriteChannels)]
public List Channels { get; set; }
}
}
diff --git a/src/Tgstation.Server.Api/Models/Internal/ChatSettings.cs b/src/Tgstation.Server.Api/Models/Internal/ChatSettings.cs
index a672895d3c..3357c507b1 100644
--- a/src/Tgstation.Server.Api/Models/Internal/ChatSettings.cs
+++ b/src/Tgstation.Server.Api/Models/Internal/ChatSettings.cs
@@ -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
///
/// Manage the server chat bots
///
- [Model(RightsType.ChatSettings, RequiresInstance = true)]
+ [Model(RightsType.ChatSettings, RequiresInstance = true, CanCrud = true, ReadRight = ChatSettingsRights.Read)]
public class ChatSettings
{
///
- /// If the IRC client is enabled
+ /// The settings id
///
- [Permissions(WriteRight = ChatSettingsRights.SetIrcEnabled)]
- public bool IrcEnabled { get; set; }
+ [Permissions(DenyWrite = true)]
+ public long Id { get; set; }
///
- /// The IRC server name
+ /// The name of the connection
///
- [Permissions(ReadRight = ChatSettingsRights.SetIrcSettings, WriteRight = ChatSettingsRights.SetIrcSettings)]
+ [Permissions(WriteRight = ChatSettingsRights.WriteName)]
[Required]
- public string IrcHost { get; set; }
+ public string Name { get; set; }
///
- /// The IRC server port
+ /// If the connection is enabled
///
- [Permissions(ReadRight = ChatSettingsRights.SetIrcSettings, WriteRight = ChatSettingsRights.SetIrcSettings)]
- public ushort IrcPort { get; set; }
+ [Permissions(WriteRight = ChatSettingsRights.WriteEnabled)]
+ public bool Enabled { get; set; }
///
- /// The IRC server NickServ password
+ /// The used for the connection
///
- [Permissions(ReadRight = ChatSettingsRights.SetIrcSettings, WriteRight = ChatSettingsRights.SetIrcSettings)]
- public string IrcNickServPassword { get; set; }
+ [Permissions(WriteRight = ChatSettingsRights.WriteProvider)]
+ public ChatProvider Provider { get; set; }
///
- /// If the Discord bot is enabled
+ /// The information used to connect to the
///
- [Permissions(WriteRight = ChatSettingsRights.SetDiscordEnabled)]
- public bool DiscordEnabled { get; set; }
-
- ///
- /// The Discord bot token
- ///
- [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; }
}
}
diff --git a/src/Tgstation.Server.Api/Rights/ChatSettingsRights.cs b/src/Tgstation.Server.Api/Rights/ChatSettingsRights.cs
index d27723c28c..e8803311ac 100644
--- a/src/Tgstation.Server.Api/Rights/ChatSettingsRights.cs
+++ b/src/Tgstation.Server.Api/Rights/ChatSettingsRights.cs
@@ -13,24 +13,32 @@ namespace Tgstation.Server.Api.Rights
///
None = 0,
///
- /// User can enable/disable the IRC client
+ /// User can change
///
- SetIrcEnabled = 1,
+ WriteEnabled = 1,
///
- /// User can change the IRC settings
+ /// User can change
///
- SetIrcSettings = 2,
+ WriteProvider = 2,
///
- /// User can change the chat channels
+ /// User can change
///
- SetChannels = 4,
+ WriteChannels = 4,
///
- /// User can enable/disable the Discord bot
+ /// User can change
///
- SetDiscordEnabled = 8,
+ WriteConnectionString = 8,
///
- /// User can change the Discord settings
+ /// User can read
///
- SetDiscordSettings = 16,
+ ReadConnectionString = 16,
+ ///
+ /// User can read all chat settings except
+ ///
+ Read = 32,
+ ///
+ /// User can change
+ ///
+ WriteName = 32
}
}
diff --git a/src/Tgstation.Server.Host/Components/Chat/Channel.cs b/src/Tgstation.Server.Host/Components/Chat/Channel.cs
new file mode 100644
index 0000000000..d9916a1014
--- /dev/null
+++ b/src/Tgstation.Server.Host/Components/Chat/Channel.cs
@@ -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; }
+ }
+}
diff --git a/src/Tgstation.Server.Host/Components/Chat/ChannelMapping.cs b/src/Tgstation.Server.Host/Components/Chat/ChannelMapping.cs
new file mode 100644
index 0000000000..cdf098287a
--- /dev/null
+++ b/src/Tgstation.Server.Host/Components/Chat/ChannelMapping.cs
@@ -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; }
+ }
+}
diff --git a/src/Tgstation.Server.Host/Components/Chat/Chat.cs b/src/Tgstation.Server.Host/Components/Chat/Chat.cs
index 1b5a0fdf09..86cc30b99c 100644
--- a/src/Tgstation.Server.Host/Components/Chat/Chat.cs
+++ b/src/Tgstation.Server.Host/Components/Chat/Chat.cs
@@ -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
{
///
sealed class Chat : IChat
{
- ///
- public bool IrcConnected => throw new System.NotImplementedException();
+ ///
+ /// The for the
+ ///
+ readonly IProviderFactory providerFactory;
- ///
- public bool DiscordConnected => throw new System.NotImplementedException();
+ ///
+ /// The for the
+ ///
+ readonly IIOManager ioManager;
- ///
- public Task ChangeChannels(IEnumerable newChannels, CancellationToken cancellationToken)
+ ///
+ /// Map of s in use, keyed by
+ ///
+ readonly Dictionary providers;
+
+ ///
+ /// Map of s to s
+ ///
+ readonly Dictionary mappedChannels;
+
+ ///
+ /// Used for remapping s
+ ///
+ long channelIdCounter;
+
+ ///
+ /// Construct a
+ ///
+ /// The value of
+ /// The value of
+ 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();
+ mappedChannels = new Dictionary();
+ channelIdCounter = 1;
}
///
- 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();
+ }
+
+ ///
+ public async Task ChangeChannels(long connectionId, IEnumerable 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);
+ }
+ }
+
+ ///
+ 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);
}
///
public Task SendMessage(string message, IEnumerable 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);
+ }));
}
///
public Task SendWatchdogMessage(string message, CancellationToken cancellationToken)
{
- throw new System.NotImplementedException();
+ List 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);
}
///
- public Task StartAsync(CancellationToken cancellationToken)
+ public Task StartAsync(CancellationToken cancellationToken) => Task.WhenAll(providers.Select(x => x.Value).Select(x => x.Connect(cancellationToken)));
+
+ ///
+ public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
+
+ ///
+ public Task TrackJsons(string basePath, string channelsJsonName, string commandsJsonName, CancellationToken cancellationToken)
{
- throw new System.NotImplementedException();
+ ioManager.ResolvePath(".");
+ throw new NotImplementedException();
}
///
- public Task StopAsync(CancellationToken cancellationToken)
+ public bool Connected(long connectionId)
{
- throw new System.NotImplementedException();
- }
-
- ///
- public Task TrackJsons(string basePath, string channelsJsonName, string commandsJsonName, CancellationToken cancellationToken)
- {
- throw new System.NotImplementedException();
+ lock (providers)
+ return providers.TryGetValue(connectionId, out var provider) && provider.Connected;
}
}
}
diff --git a/src/Tgstation.Server.Host/Components/Chat/IChat.cs b/src/Tgstation.Server.Host/Components/Chat/IChat.cs
index f73805eb2b..26eacbfd4f 100644
--- a/src/Tgstation.Server.Host/Components/Chat/IChat.cs
+++ b/src/Tgstation.Server.Host/Components/Chat/IChat.cs
@@ -10,33 +10,31 @@ namespace Tgstation.Server.Host.Components.Chat
///
/// For managing connected chat services
///
- public interface IChat : IHostedService
+ public interface IChat : IHostedService, IDisposable
{
///
- /// If the IRC client is connected
+ /// If a given set of is connected
///
- bool IrcConnected { get; }
+ /// The of the connection
+ /// if it is connected, otherwise
+ bool Connected(long connectionId);
///
- /// If the Discord client is connected
- ///
- bool DiscordConnected { get; }
-
- ///
- /// Change chat settings
+ /// Change chat settings. If the is not currently in use, a new connection will be made instead
///
/// The new
/// The for the operation
- /// A representing the running operation
+ /// A representing the running operation. Will complete immediately if the property of is
Task ChangeSettings(ChatSettings newSettings, CancellationToken cancellationToken);
///
/// Change chat channels
///
+ /// The of the connection
/// An of the new list of s
/// The for the operation
/// A representing the running operation
- Task ChangeChannels(IEnumerable newChannels, CancellationToken cancellationToken);
+ Task ChangeChannels(long connectionId, IEnumerable newChannels, CancellationToken cancellationToken);
///
/// Send a chat to a given set of
@@ -63,6 +61,6 @@ namespace Tgstation.Server.Host.Components.Chat
/// The name of the chat commands json
/// The for the operation
/// A resulting in a tied to the lifetime of the json trackings
- Task TrackJsons(string basePath, string channelsJsonName, string commandsJsonName, CancellationToken cancellationToken);
+ Task TrackJsons(string basePath, string channelsJsonName, string commandsJsonName, CancellationToken cancellationToken);
}
}
\ No newline at end of file
diff --git a/src/Tgstation.Server.Host/Components/Chat/IChatJsonTrackingContext.cs b/src/Tgstation.Server.Host/Components/Chat/IJsonTrackingContext.cs
similarity index 73%
rename from src/Tgstation.Server.Host/Components/Chat/IChatJsonTrackingContext.cs
rename to src/Tgstation.Server.Host/Components/Chat/IJsonTrackingContext.cs
index 8926b33291..5988619602 100644
--- a/src/Tgstation.Server.Host/Components/Chat/IChatJsonTrackingContext.cs
+++ b/src/Tgstation.Server.Host/Components/Chat/IJsonTrackingContext.cs
@@ -5,7 +5,7 @@ namespace Tgstation.Server.Host.Components.Chat
///
/// Represents a tracking of dynamic chat json files
///
- public interface IChatJsonTrackingContext : IDisposable
+ public interface IJsonTrackingContext : IDisposable
{
}
}
\ No newline at end of file
diff --git a/src/Tgstation.Server.Host/Components/Chat/IProviderFactory.cs b/src/Tgstation.Server.Host/Components/Chat/IProviderFactory.cs
new file mode 100644
index 0000000000..b4b47f2d5b
--- /dev/null
+++ b/src/Tgstation.Server.Host/Components/Chat/IProviderFactory.cs
@@ -0,0 +1,18 @@
+using Tgstation.Server.Api.Models.Internal;
+using Tgstation.Server.Host.Components.Chat.Providers;
+
+namespace Tgstation.Server.Host.Components.Chat
+{
+ ///
+ /// Factory for s
+ ///
+ interface IProviderFactory
+ {
+ ///
+ /// Create a
+ ///
+ /// The for the new provider
+ /// A new
+ IProvider CreateProvider(ChatSettings settings);
+ }
+}
diff --git a/src/Tgstation.Server.Host/Components/Chat/Message.cs b/src/Tgstation.Server.Host/Components/Chat/Message.cs
new file mode 100644
index 0000000000..e9b90e6560
--- /dev/null
+++ b/src/Tgstation.Server.Host/Components/Chat/Message.cs
@@ -0,0 +1,8 @@
+namespace Tgstation.Server.Host.Components.Chat.Providers
+{
+ sealed class Message
+ {
+ string Content { get; set; }
+ User User { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Tgstation.Server.Host/Components/Chat/ProviderFactory.cs b/src/Tgstation.Server.Host/Components/Chat/ProviderFactory.cs
new file mode 100644
index 0000000000..b16cd3617c
--- /dev/null
+++ b/src/Tgstation.Server.Host/Components/Chat/ProviderFactory.cs
@@ -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
+{
+ ///
+ sealed class ProviderFactory : IProviderFactory
+ {
+ ///
+ 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));
+ }
+ }
+ }
+}
diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/IProvider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/IProvider.cs
new file mode 100644
index 0000000000..278ffa5813
--- /dev/null
+++ b/src/Tgstation.Server.Host/Components/Chat/Providers/IProvider.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Tgstation.Server.Host.Components.Chat.Providers
+{
+ ///
+ /// For interacting with a chat service
+ ///
+ interface IProvider : IDisposable
+ {
+ ///
+ /// If the
+ ///
+ bool Connected { get; }
+
+ ///
+ /// The that indicates the was mentioned
+ ///
+ string BotMention { get; }
+
+ ///
+ /// Get a resulting in the next the recieves or on a disconnect
+ ///
+ Task NextMessage { get; }
+
+ ///
+ /// Attempt to connect the
+ ///
+ /// The for the operation
+ /// A resulting in on success, otherwise
+ Task Connect(CancellationToken cancellationToken);
+
+ ///
+ /// Get the s for given
+ ///
+ /// The s to map
+ /// The for the operation
+ /// A resulting in a of the s representing
+ Task> MapChannels(IEnumerable channels, CancellationToken cancellationToken);
+
+ ///
+ /// Send a message to the
+ ///
+ /// The to send to
+ /// The message contents
+ /// The for the operation
+ /// A representing the running operation
+ Task SendMessage(long channelId, string message, CancellationToken cancellationToken);
+ }
+}
diff --git a/src/Tgstation.Server.Host/Components/Chat/ChatResponse.cs b/src/Tgstation.Server.Host/Components/Chat/Response.cs
similarity index 93%
rename from src/Tgstation.Server.Host/Components/Chat/ChatResponse.cs
rename to src/Tgstation.Server.Host/Components/Chat/Response.cs
index 67f8cf6782..855752e790 100644
--- a/src/Tgstation.Server.Host/Components/Chat/ChatResponse.cs
+++ b/src/Tgstation.Server.Host/Components/Chat/Response.cs
@@ -5,7 +5,7 @@ namespace Tgstation.Server.Host.Components.Chat
///
/// Represents a chat message requested by DD
///
- sealed class ChatResponse
+ sealed class Response
{
///
/// The message string
diff --git a/src/Tgstation.Server.Host/Components/Chat/User.cs b/src/Tgstation.Server.Host/Components/Chat/User.cs
new file mode 100644
index 0000000000..cc081dfaa9
--- /dev/null
+++ b/src/Tgstation.Server.Host/Components/Chat/User.cs
@@ -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; }
+ }
+}
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/SessionController.cs b/src/Tgstation.Server.Host/Components/Watchdog/SessionController.cs
index 4d61522620..4937f7e170 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/SessionController.cs
+++ b/src/Tgstation.Server.Host/Components/Watchdog/SessionController.cs
@@ -102,9 +102,9 @@ namespace Tgstation.Server.Host.Components.Watchdog
readonly ISession session;
///
- /// The for the
+ /// The for the
///
- readonly IChatJsonTrackingContext chatJsonTrackingContext;
+ readonly IJsonTrackingContext chatJsonTrackingContext;
///
/// The for the
@@ -154,7 +154,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
/// The value of
/// The value of
/// The value of
- public SessionController(ReattachInformation reattachInformation, ISession session, IByondTopicSender byondTopicSender, IInteropRegistrar interopRegistrar, IChatJsonTrackingContext chatJsonTrackingContext, IChat chat, ILogger logger)
+ public SessionController(ReattachInformation reattachInformation, ISession session, IByondTopicSender byondTopicSender, IInteropRegistrar interopRegistrar, IJsonTrackingContext chatJsonTrackingContext, IChat chat, ILogger logger)
{
this.chatJsonTrackingContext = chatJsonTrackingContext; //null valid
this.reattachInformation = reattachInformation ?? throw new ArgumentNullException(nameof(reattachInformation));
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/Watchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/Watchdog.cs
index c0f07beaa5..70ce656dc0 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/Watchdog.cs
+++ b/src/Tgstation.Server.Host/Components/Watchdog/Watchdog.cs
@@ -539,10 +539,10 @@ namespace Tgstation.Server.Host.Components.Watchdog
if (results == null)
return;
- List responses;
+ List responses;
try
{
- responses = JsonConvert.DeserializeObject>(results);
+ responses = JsonConvert.DeserializeObject>(results);
}
catch
{
diff --git a/src/Tgstation.Server.Host/Models/ChatChannel.cs b/src/Tgstation.Server.Host/Models/ChatChannel.cs
index 8f57e1e885..3bd53864fd 100644
--- a/src/Tgstation.Server.Host/Models/ChatChannel.cs
+++ b/src/Tgstation.Server.Host/Models/ChatChannel.cs
@@ -9,7 +9,7 @@
public long Id { get; set; }
///
- /// The
+ /// The
///
public long ChatSettingsId { get; set; }
diff --git a/src/Tgstation.Server.Host/Models/ChatSettings.cs b/src/Tgstation.Server.Host/Models/ChatSettings.cs
index 5d3df56af5..1152181268 100644
--- a/src/Tgstation.Server.Host/Models/ChatSettings.cs
+++ b/src/Tgstation.Server.Host/Models/ChatSettings.cs
@@ -5,12 +5,7 @@ namespace Tgstation.Server.Host.Models
{
///
public sealed class ChatSettings : Api.Models.Internal.ChatSettings
- {
- ///
- /// The row Id
- ///
- public long Id { get; set; }
-
+ {
///
/// The
///