From f40e2acdd83314136ff463b08a67b41ac42e0cd3 Mon Sep 17 00:00:00 2001 From: Morbo <14136326+Morb0@users.noreply.github.com> Date: Fri, 11 Feb 2022 00:09:44 +0300 Subject: [PATCH] Add Discord round start notifications (#95) * Add new round Discord role alert * Add russian locale for Discord alert * Make Discord role id var optional * Rename new_round ccvars to just round --- .../GameTicking/GameTicker.CVars.cs | 8 +++ .../GameTicking/GameTicker.RoundFlow.cs | 1 + .../GameTicking/GameTicket.Discord.cs | 64 +++++++++++++++++++ Content.Shared/CCVar/CCVars.cs | 6 ++ .../en-US/game-ticking/discord-round.ftl | 1 + .../ru-RU/game-ticking/discord-round.ftl | 1 + 6 files changed, 81 insertions(+) create mode 100644 Content.Server/GameTicking/GameTicket.Discord.cs create mode 100644 Resources/Locale/en-US/game-ticking/discord-round.ftl create mode 100644 Resources/Locale/ru-RU/game-ticking/discord-round.ftl diff --git a/Content.Server/GameTicking/GameTicker.CVars.cs b/Content.Server/GameTicking/GameTicker.CVars.cs index 94e081cfe5..c2b16922cf 100644 --- a/Content.Server/GameTicking/GameTicker.CVars.cs +++ b/Content.Server/GameTicking/GameTicker.CVars.cs @@ -27,6 +27,12 @@ namespace Content.Server.GameTicking [ViewVariables] public float MaxStationOffset { get; private set; } = 0f; + [ViewVariables] + public string DiscordWebhook { get; private set; } = ""; + + [ViewVariables] + public string DiscordRoleId { get; private set; } = ""; + private void InitializeCVars() { _configurationManager.OnValueChanged(CCVars.GameLobbyEnabled, value => LobbyEnabled = value, true); @@ -37,6 +43,8 @@ namespace Content.Server.GameTicking _configurationManager.OnValueChanged(CCVars.StationOffset, value => StationOffset = value, true); _configurationManager.OnValueChanged(CCVars.StationRotation, value => StationRotation = value, true); _configurationManager.OnValueChanged(CCVars.MaxStationOffset, value => MaxStationOffset = value, true); + _configurationManager.OnValueChanged(CCVars.DiscordRoundWebhook, value => DiscordWebhook = value, true); + _configurationManager.OnValueChanged(CCVars.DiscordRoundRoleId, value => DiscordRoleId = value, true); } } } diff --git a/Content.Server/GameTicking/GameTicker.RoundFlow.cs b/Content.Server/GameTicking/GameTicker.RoundFlow.cs index 2d37e8b680..02c847b294 100644 --- a/Content.Server/GameTicking/GameTicker.RoundFlow.cs +++ b/Content.Server/GameTicking/GameTicker.RoundFlow.cs @@ -449,6 +449,7 @@ namespace Content.Server.GameTicking Logger.InfoS("ticker", "Restarting round!"); SendServerMessage(Loc.GetString("game-ticker-restart-round")); + SendDiscordNewRoundAlert(); RoundNumberMetric.Inc(); diff --git a/Content.Server/GameTicking/GameTicket.Discord.cs b/Content.Server/GameTicking/GameTicket.Discord.cs new file mode 100644 index 0000000000..511ccd3744 --- /dev/null +++ b/Content.Server/GameTicking/GameTicket.Discord.cs @@ -0,0 +1,64 @@ + +using System.Net.Http; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Content.Server.GameTicking +{ + public partial class GameTicker + { + private readonly HttpClient _httpClient = new(); + + private async void SendDiscordNewRoundAlert() + { + var sendsWebhook = DiscordWebhook != string.Empty; + if (sendsWebhook) + { + WebhookPayload payload; + + if (DiscordRoleId != string.Empty) + { + payload = new WebhookPayload() + { + Content = $"<@&{DiscordRoleId}> {Loc.GetString("discord-round-new")}", + AllowedMentions = new Dictionary + { + { "roles", new []{ DiscordRoleId } } + }, + }; + } + else + { + payload = new WebhookPayload() + { + Content = Loc.GetString("discord-round-new"), + }; + } + + var request = await _httpClient.PostAsync(DiscordWebhook, + new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json")); + + var content = await request.Content.ReadAsStringAsync(); + if (!request.IsSuccessStatusCode) + { + Logger.ErrorS("ticker", $"Discord returned bad status code when posting message: {request.StatusCode}\nResponse: {content}"); + return; + } + } + } + + private struct WebhookPayload + { + [JsonPropertyName("content")] + public string Content { get; set; } = ""; + + [JsonPropertyName("allowed_mentions")] + public Dictionary AllowedMentions { get; set; } = + new() + { + { "parse", Array.Empty() } + }; + } + } +} diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index 51352e71f3..1a24e702dd 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -161,6 +161,12 @@ namespace Content.Shared.CCVar public static readonly CVarDef DiscordAHelpWebhook = CVarDef.Create("discord.ahelp_webhook", string.Empty, CVar.SERVERONLY); + public static readonly CVarDef DiscordRoundWebhook = + CVarDef.Create("discord.round_webhook", string.Empty, CVar.SERVERONLY); + + public static readonly CVarDef DiscordRoundRoleId = + CVarDef.Create("discord.round_roleid", string.Empty, CVar.SERVERONLY); + /* * Suspicion */ diff --git a/Resources/Locale/en-US/game-ticking/discord-round.ftl b/Resources/Locale/en-US/game-ticking/discord-round.ftl new file mode 100644 index 0000000000..486f752146 --- /dev/null +++ b/Resources/Locale/en-US/game-ticking/discord-round.ftl @@ -0,0 +1 @@ +discord-round-new = New round started! diff --git a/Resources/Locale/ru-RU/game-ticking/discord-round.ftl b/Resources/Locale/ru-RU/game-ticking/discord-round.ftl new file mode 100644 index 0000000000..82e17d813f --- /dev/null +++ b/Resources/Locale/ru-RU/game-ticking/discord-round.ftl @@ -0,0 +1 @@ +discord-round-new = Новый раунд начался!