DiscordChatILink.cs 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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.Dead => _oocChannelId,
  66. ChatChannel.AdminChat => _adminChannelId,
  67. _ => throw new InvalidOperationException("Channel not linked to Discord."),
  68. };
  69. if (channelId == null)
  70. {
  71. // Configuration not set up. Ignore.
  72. return;
  73. }
  74. // @ and < are both problematic for discord due to pinging. / is sanitized solely to kneecap links to murder embeds via blunt force
  75. message = message.Replace("@", "\\@").Replace("<", "\\<").Replace("/", "\\/");
  76. await _discordLink.SendMessageAsync(channelId.Value, $"**{channel.GetString()}**: `{author}`: {message}");
  77. }
  78. }