Files
tbd-station-14/Content.Server/Discord/DiscordLink/DiscordChatLink.cs

111 lines
3.4 KiB
C#

using Content.Server.Chat.Managers;
using Content.Shared.CCVar;
using Content.Shared.Chat;
using NetCord.Gateway;
using Robust.Shared.Asynchronous;
using Robust.Shared.Configuration;
namespace Content.Server.Discord.DiscordLink;
public sealed class DiscordChatLink : IPostInjectInit
{
[Dependency] private readonly DiscordLink _discordLink = default!;
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
[Dependency] private readonly IChatManager _chatManager = default!;
[Dependency] private readonly ITaskManager _taskManager = default!;
[Dependency] private readonly ILogManager _logManager = default!;
private ISawmill _sawmill = default!;
private ulong? _oocChannelId;
private ulong? _adminChannelId;
public void Initialize()
{
_discordLink.OnMessageReceived += OnMessageReceived;
_configurationManager.OnValueChanged(CCVars.OocDiscordChannelId, OnOocChannelIdChanged, true);
_configurationManager.OnValueChanged(CCVars.AdminChatDiscordChannelId, OnAdminChannelIdChanged, true);
}
public void Shutdown()
{
_discordLink.OnMessageReceived -= OnMessageReceived;
_configurationManager.UnsubValueChanged(CCVars.OocDiscordChannelId, OnOocChannelIdChanged);
_configurationManager.UnsubValueChanged(CCVars.AdminChatDiscordChannelId, OnAdminChannelIdChanged);
}
private void OnOocChannelIdChanged(string channelId)
{
if (string.IsNullOrEmpty(channelId))
{
_oocChannelId = null;
return;
}
_oocChannelId = ulong.Parse(channelId);
}
private void OnAdminChannelIdChanged(string channelId)
{
if (string.IsNullOrEmpty(channelId))
{
_adminChannelId = null;
return;
}
_adminChannelId = ulong.Parse(channelId);
}
private void OnMessageReceived(Message message)
{
if (message.Author.IsBot)
return;
var contents = message.Content.ReplaceLineEndings(" ");
if (message.ChannelId == _oocChannelId)
{
_taskManager.RunOnMainThread(() => _chatManager.SendHookOOC(message.Author.Username, contents));
}
else if (message.ChannelId == _adminChannelId)
{
_taskManager.RunOnMainThread(() => _chatManager.SendHookAdmin(message.Author.Username, contents));
}
}
public async void SendMessage(string message, string author, ChatChannel channel)
{
var channelId = channel switch
{
ChatChannel.OOC => _oocChannelId,
ChatChannel.AdminChat => _adminChannelId,
_ => throw new InvalidOperationException("Channel not linked to Discord."),
};
if (channelId == null)
{
// Configuration not set up. Ignore.
return;
}
// @ and < are both problematic for discord due to pinging. / is sanitized solely to kneecap links to murder embeds via blunt force
message = message.Replace("@", "\\@").Replace("<", "\\<").Replace("/", "\\/");
try
{
await _discordLink.SendMessageAsync(channelId.Value, $"**{channel.GetString()}**: `{author}`: {message}");
}
catch (Exception e)
{
_sawmill.Error($"Error while sending Discord message: {e}");
}
}
void IPostInjectInit.PostInject()
{
_sawmill = _logManager.GetSawmill("discord.chat");
}
}