From 5ab43b475bcb05626c0d6e37e6f97d6da2b24781 Mon Sep 17 00:00:00 2001 From: DeinFreund Date: Wed, 17 Oct 2018 15:48:56 +0200 Subject: [PATCH 1/3] discord relay uses nicknames over usernames, allow zkls users to mention discord users by nick, disallow mentioning roles like [at]everyone --- ZkLobbyServer/DiscordRelaySource.cs | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/ZkLobbyServer/DiscordRelaySource.cs b/ZkLobbyServer/DiscordRelaySource.cs index 05f7ad5d47..ac34a0ddd2 100644 --- a/ZkLobbyServer/DiscordRelaySource.cs +++ b/ZkLobbyServer/DiscordRelaySource.cs @@ -22,6 +22,11 @@ private static string GetName(IUser user) return user.Username + "#" + user.Discriminator; } + private static string ReplaceMention(string message, MatchEvaluator replace) + { + return Regex.Replace(message, "<@!{0,1}([0-9]+)>", replace); + } + public DiscordRelaySource(DiscordSocketClient client, ulong serverID, SaySource source) { discord = client; @@ -50,13 +55,24 @@ public void SetTopic(string channel, string topic) } } - public void SendMessage(ChatRelayMessage m) { try { if (m.Source != source) { + //Translate mentions of nicknames to discord mentions + var userIdsByNickname = discord.GetGuild(serverID).Users.ToDictionary(x => x.Nickname, x => x.Id); + userIdsByNickname.ForEach((pair) => m.Message = m.Message.Replace(pair.Key, string.Format("<@{0}>", pair.Value))); + + //Block any mentions of an entire role via ID + var roleIds = discord.GetGuild(serverID).Roles.Select(x => x.Id.ToString()).ToList(); + m.Message = ReplaceMention(m.Message, match => roleIds.Contains(match.Groups[1].Value) ? "" : match.Groups[1].Value); + + //Block any mentions of an entire role via Name + var roleNames = discord.GetGuild(serverID).Roles.Select(x => x.Name).ToList(); + roleNames.ForEach(role => m.Message = m.Message.Replace(string.Format("@{0}", role), "")); + if (m.User != GlobalConst.NightwatchName) GetChannel(m.Channel)?.SendMessageAsync($"<{m.User}> {m.Message}"); // don't relay extra "nightwatch" if it is self relay else GetChannel(m.Channel)?.SendMessageAsync(m.Message); @@ -81,18 +97,18 @@ public void SendPm(string user, string message) } - private static string TranslateMentions(SocketMessage msg) + private string TranslateMentions(SocketMessage msg) { var text = msg.Content; if (string.IsNullOrEmpty(text)) return string.Empty; - return Regex.Replace(text, "<@([0-9]+)>", + return ReplaceMention(text, m => { var mentionedId = m.Groups[1].Value; var user = msg.MentionedUsers.FirstOrDefault(x => x.Id.ToString() == mentionedId); - if (user != null) return user.Username; + if (user != null) return discord.GetGuild(serverID).Users.FirstOrDefault(x => x.Id == user.Id)?.Nickname ?? user.Username; var channel = msg.MentionedChannels.FirstOrDefault(x => x.Id.ToString() == mentionedId); if (channel != null) return channel.Name; From aa8391cb48e1b5e1a638f04547b9d3ff67c48a16 Mon Sep 17 00:00:00 2001 From: DeinFreund Date: Wed, 17 Oct 2018 16:10:35 +0200 Subject: [PATCH 2/3] iterate over words instead of users, this should make this pr slightly less terrible --- ZkLobbyServer/DiscordRelaySource.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ZkLobbyServer/DiscordRelaySource.cs b/ZkLobbyServer/DiscordRelaySource.cs index ac34a0ddd2..3771353e10 100644 --- a/ZkLobbyServer/DiscordRelaySource.cs +++ b/ZkLobbyServer/DiscordRelaySource.cs @@ -62,8 +62,9 @@ public void SendMessage(ChatRelayMessage m) if (m.Source != source) { //Translate mentions of nicknames to discord mentions - var userIdsByNickname = discord.GetGuild(serverID).Users.ToDictionary(x => x.Nickname, x => x.Id); - userIdsByNickname.ForEach((pair) => m.Message = m.Message.Replace(pair.Key, string.Format("<@{0}>", pair.Value))); + var userIdsByNickname = discord.GetGuild(serverID).Users.ToDictionary(x => x.Nickname, x => x.Id.ToString(), StringComparer.OrdinalIgnoreCase); + m.Message = Regex.Replace(m.Message, "(\\w+)", match => userIdsByNickname.ContainsKey(match.Groups[1].Value) ? + string.Format("<@{0}>", userIdsByNickname[match.Groups[1].Value]) : match.Groups[1].Value); //Block any mentions of an entire role via ID var roleIds = discord.GetGuild(serverID).Roles.Select(x => x.Id.ToString()).ToList(); From b2e9eac5b12447e6d073ad2907374c0d1b78ba24 Mon Sep 17 00:00:00 2001 From: DeinFreund Date: Wed, 17 Oct 2018 16:47:47 +0200 Subject: [PATCH 3/3] Use sprung's suggestion and only remove @ from roles --- ZkLobbyServer/DiscordRelaySource.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ZkLobbyServer/DiscordRelaySource.cs b/ZkLobbyServer/DiscordRelaySource.cs index 3771353e10..1220dedb29 100644 --- a/ZkLobbyServer/DiscordRelaySource.cs +++ b/ZkLobbyServer/DiscordRelaySource.cs @@ -72,7 +72,7 @@ public void SendMessage(ChatRelayMessage m) //Block any mentions of an entire role via Name var roleNames = discord.GetGuild(serverID).Roles.Select(x => x.Name).ToList(); - roleNames.ForEach(role => m.Message = m.Message.Replace(string.Format("@{0}", role), "")); + roleNames.ForEach(role => m.Message = m.Message.Replace(string.Format("@{0}", role), string.Format(" {0}", role))); if (m.User != GlobalConst.NightwatchName) GetChannel(m.Channel)?.SendMessageAsync($"<{m.User}> {m.Message}"); // don't relay extra "nightwatch" if it is self relay @@ -142,4 +142,4 @@ private SocketTextChannel GetChannel(string name) return discord?.GetGuild(serverID)?.TextChannels.FirstOrDefault(x => x.Name == name); } } -} \ No newline at end of file +}