From 5455af24d799afeb69f68b5fc9e215678a5ad44b Mon Sep 17 00:00:00 2001 From: Regalis Date: Thu, 1 Jun 2017 19:37:08 +0300 Subject: [PATCH] Readded spam filter --- Subsurface/Source/Networking/ChatMessage.cs | 56 ++++++++++++++++++--- Subsurface/Source/Networking/Client.cs | 4 ++ Subsurface/Source/Networking/GameServer.cs | 19 ++++--- 3 files changed, 65 insertions(+), 14 deletions(-) diff --git a/Subsurface/Source/Networking/ChatMessage.cs b/Subsurface/Source/Networking/ChatMessage.cs index c2ef0099d..27c0eb21b 100644 --- a/Subsurface/Source/Networking/ChatMessage.cs +++ b/Subsurface/Source/Networking/ChatMessage.cs @@ -134,23 +134,65 @@ namespace Barotrauma.Networking msg.Write(Text); } - static public void ServerRead(NetIncomingMessage msg, Client c) + public static void ServerRead(NetIncomingMessage msg, Client c) { UInt16 ID = msg.ReadUInt16(); string txt = msg.ReadString(); - if (txt.Length > MaxLength) { txt = txt.Substring(0, MaxLength); } - if (NetIdUtils.IdMoreRecent(ID, c.lastSentChatMsgID)) + if (!NetIdUtils.IdMoreRecent(ID, c.lastSentChatMsgID)) return; + + c.lastSentChatMessages.Add(txt); + if (c.lastSentChatMessages.Count > 10) { - //this chat message is new to the server - GameMain.Server.SendChatMessage(txt, null, c); - //GameMain.Server.AddChatMessage(txt, ChatMessageType.Default, c.name); - c.lastSentChatMsgID = ID; + c.lastSentChatMessages.RemoveRange(0, c.lastSentChatMessages.Count-10); } + + + c.lastSentChatMsgID = ID; + + //SPAM FILTER + if (c.ChatSpamTimer > 0.0f) + { + //player has already been spamming, stop again + ChatMessage denyMsg = ChatMessage.Create("", "You have been blocked by the spam filter. Try again after 10 seconds.", ChatMessageType.Server, null); + c.ChatSpamTimer = 10.0f; + GameMain.Server.SendChatMessage(denyMsg, c); + return; + } + + float similarity = 0.0f; + for (int i = 0; i < c.lastSentChatMessages.Count; i++) + { + float closeFactor = 1.0f / (c.lastSentChatMessages.Count - i); + int levenshteinDist = ToolBox.LevenshteinDistance(txt, c.lastSentChatMessages[i]); + similarity += Math.Max((txt.Length - levenshteinDist) / (float)txt.Length * closeFactor, 0.0f); + } + + if (similarity + c.ChatSpamSpeed > 5.0f) + { + c.ChatSpamCount++; + + if (c.ChatSpamCount > 3) + { + //kick for spamming too much + GameMain.Server.KickClient(c); + } + else + { + ChatMessage denyMsg = ChatMessage.Create("", "You have been blocked by the spam filter. Try again after 10 seconds.", ChatMessageType.Server, null); + c.ChatSpamTimer = 10.0f; + GameMain.Server.SendChatMessage(denyMsg, c); + } + return; + } + + c.ChatSpamSpeed += similarity; + + GameMain.Server.SendChatMessage(txt, null, c); } public void ServerWrite(NetOutgoingMessage msg, Client c) diff --git a/Subsurface/Source/Networking/Client.cs b/Subsurface/Source/Networking/Client.cs index bec8eb339..dce365954 100644 --- a/Subsurface/Source/Networking/Client.cs +++ b/Subsurface/Source/Networking/Client.cs @@ -39,6 +39,10 @@ namespace Barotrauma.Networking public List chatMsgQueue = new List(); public UInt16 lastChatMsgQueueID; + + + //latest chat messages sent by this client + public List lastSentChatMessages = new List(); public float ChatSpamSpeed; public float ChatSpamTimer; public int ChatSpamCount; diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index 8f4055560..d84098147 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -1451,7 +1451,17 @@ namespace Barotrauma.Networking if (c.Character == null || !c.inGame) continue; } } - + + public void SendChatMessage(ChatMessage msg, Client recipient) + { + msg.NetStateID = recipient.chatMsgQueue.Count > 0 ? + (ushort)(recipient.chatMsgQueue.Last().NetStateID + 1) : + (ushort)(recipient.lastRecvChatMsgID + 1); + + recipient.chatMsgQueue.Add(msg); + recipient.lastChatMsgQueueID = msg.NetStateID; + } + /// /// Add the message to the chatbox and pass it to all clients who can receive it /// @@ -1628,13 +1638,8 @@ namespace Barotrauma.Networking modifiedMessage, (ChatMessageType)type, senderCharacter); - - chatMsg.NetStateID = client.chatMsgQueue.Count > 0 ? - (ushort)(client.chatMsgQueue.Last().NetStateID + 1) : - (ushort)(client.lastRecvChatMsgID + 1); - client.chatMsgQueue.Add(chatMsg); - client.lastChatMsgQueueID = chatMsg.NetStateID; + SendChatMessage(chatMsg, client); } string myReceivedMessage = message;