DiscordChatILink.cs 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. using System.Threading.Tasks;
  2. using Content.Server.Chat.Managers;
  3. using Content.Shared.CCVar;
  4. using Content.Shared.Chat;
  5. using Discord.WebSocket;
  6. using Robust.Shared.Asynchronous;
  7. using Robust.Shared.Configuration;
  8. namespace Content.Server.Discord.DiscordLink;
  9. public sealed class DiscordChatLink
  10. {
  11. [Dependency] private DiscordLink _discordLink = default!;
  12. [Dependency] private IConfigurationManager _configurationManager = default!;
  13. [Dependency] private readonly IChatManager _chatManager = default!;
  14. [Dependency] private readonly ITaskManager _taskManager = default!;
  15. private ulong? _oocChannelId;
  16. private ulong? _adminChannelId;
  17. public void Initialize()
  18. {
  19. _discordLink.OnMessageReceived += OnMessageReceived;
  20. _configurationManager.OnValueChanged(CCVars.OocDiscordChannelId, OnOocChannelIdChanged, true);
  21. _configurationManager.OnValueChanged(CCVars.AdminChatDiscordChannelId, OnAdminChannelIdChanged, true);
  22. }
  23. public void Shutdown()
  24. {
  25. _discordLink.OnMessageReceived -= OnMessageReceived;
  26. _configurationManager.UnsubValueChanged(CCVars.OocDiscordChannelId, OnOocChannelIdChanged);
  27. _configurationManager.UnsubValueChanged(CCVars.AdminChatDiscordChannelId, OnAdminChannelIdChanged);
  28. }
  29. private void OnOocChannelIdChanged(string channelId)
  30. {
  31. if (string.IsNullOrEmpty(channelId))
  32. {
  33. _oocChannelId = null;
  34. return;
  35. }
  36. _oocChannelId = ulong.Parse(channelId);
  37. }
  38. private void OnAdminChannelIdChanged(string channelId)
  39. {
  40. if (string.IsNullOrEmpty(channelId))
  41. {
  42. _adminChannelId = null;
  43. return;
  44. }
  45. _adminChannelId = ulong.Parse(channelId);
  46. }
  47. private void OnMessageReceived(SocketMessage message)
  48. {
  49. if (message.Author.IsBot)
  50. return;
  51. if (message.Channel.Id == _oocChannelId)
  52. {
  53. _taskManager.RunOnMainThread(() => _chatManager.SendHookOOC(message.Author.Username, message.Content));
  54. }
  55. else if (message.Channel.Id == _adminChannelId)
  56. {
  57. _taskManager.RunOnMainThread(() => _chatManager.SendHookAdmin(message.Author.Username, message.Content));
  58. }
  59. }
  60. public async Task SendMessage(string message, string author, ChatChannel channel)
  61. {
  62. var channelId = channel switch
  63. {
  64. ChatChannel.OOC => _oocChannelId,
  65. ChatChannel.AdminChat => _adminChannelId,
  66. _ => throw new InvalidOperationException("Channel not linked to Discord."),
  67. };
  68. if (channelId == null)
  69. {
  70. // Configuration not set up. Ignore.
  71. return;
  72. }
  73. // @ and < are both problematic for discord due to pinging. / is sanitized solely to kneecap links to murder embeds via blunt force
  74. message = message.Replace("@", "\\@").Replace("<", "\\<").Replace("/", "\\/");
  75. await _discordLink.SendMessageAsync(channelId.Value, $"**{channel.GetString()}**: `{author}`: {message}");
  76. }
  77. }