111 lines
3.4 KiB
C#
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");
|
|
}
|
|
}
|