Using Levenshtein distance to measure the similarity of chat messages, (float)0.0 -> 0.0f

This commit is contained in:
Regalis
2016-08-28 16:53:24 +03:00
parent e2885a912d
commit fe8cce1723
3 changed files with 71 additions and 14 deletions
+5
View File
@@ -30,6 +30,11 @@ namespace Barotrauma.Networking
public string version; public string version;
public bool inGame; public bool inGame;
public List<string> ChatMessages = new List<string>();
public float ChatSpamSpeed;
public float ChatSpamTimer;
public int ChatSpamCount;
private List<Client> kickVoters; private List<Client> kickVoters;
public bool ReadyToStart; public bool ReadyToStart;
+2 -2
View File
@@ -664,8 +664,8 @@ namespace Barotrauma.Networking
break; break;
case (byte)PacketTypes.Chatmessage: case (byte)PacketTypes.Chatmessage:
//ChatMessageType messageType = (ChatMessageType)inc.ReadByte(); //ChatMessageType messageType = (ChatMessageType)inc.ReadByte();
var chatMsg = ChatMessage.ReadNetworkMessage(inc);
AddChatMessage(ChatMessage.ReadNetworkMessage(inc)); AddChatMessage(chatMsg);
break; break;
case (byte)PacketTypes.NetworkEvent: case (byte)PacketTypes.NetworkEvent:
//read the data from the message and update client state accordingly //read the data from the message and update client state accordingly
+63 -11
View File
@@ -346,6 +346,9 @@ namespace Barotrauma.Networking
if (c.FileStreamSender != null) UpdateFileTransfer(c, deltaTime); if (c.FileStreamSender != null) UpdateFileTransfer(c, deltaTime);
c.ReliableChannel.Update(deltaTime); c.ReliableChannel.Update(deltaTime);
//slowly reset spam timers
c.ChatSpamTimer = Math.Max(0.0f, c.ChatSpamTimer - deltaTime);
} }
NetIncomingMessage inc = null; NetIncomingMessage inc = null;
@@ -1428,6 +1431,7 @@ namespace Barotrauma.Networking
private void ReadChatMessage(NetIncomingMessage inc) private void ReadChatMessage(NetIncomingMessage inc)
{ {
Client sender = connectedClients.Find(x => x.Connection == inc.SenderConnection);
ChatMessage message = ChatMessage.ReadNetworkMessage(inc); ChatMessage message = ChatMessage.ReadNetworkMessage(inc);
List<Client> recipients = new List<Client>(); List<Client> recipients = new List<Client>();
@@ -1455,19 +1459,64 @@ namespace Barotrauma.Networking
recipients.Add(c); recipients.Add(c);
} }
//SPAM FILTER
if (sender.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);
sender.ChatSpamTimer = 10.0f;
SendChatMessage(denyMsg, sender);
return;
}
float similarity = 0;
similarity += sender.ChatSpamSpeed; //the faster messages are being sent, the faster the filter will block
for (int i = 0; i < sender.ChatMessages.Count; i++)
{
float closeFactor = 1.0f / (20.0f - i);
int levenshteinDist = ToolBox.LevenshteinDistance(message.Text, sender.ChatMessages[i]);
similarity += Math.Max((message.Text.Length - levenshteinDist) / message.Text.Length * closeFactor, 0.0f);
}
if (similarity > 6.0f)
{
sender.ChatSpamCount++;
if (sender.ChatSpamCount > 3)
{
//kick for spamming too much
KickClient(sender, false);
}
else
{
ChatMessage denyMsg = ChatMessage.Create("", "You have been blocked by the spam filter. Try again after 10 seconds.", ChatMessageType.Server, null);
sender.ChatSpamTimer = 10.0f;
SendChatMessage(denyMsg, sender);
}
return;
}
sender.ChatMessages.Add(message.Text);
if (sender.ChatMessages.Count > 20)
{
sender.ChatMessages.RemoveAt(0);
}
AddChatMessage(message); AddChatMessage(message);
sender.ChatSpamSpeed += 5.0f;
foreach (Client c in recipients) foreach (Client c in recipients)
{ {
ReliableMessage msg = c.ReliableChannel.CreateMessage(); ReliableMessage msg = c.ReliableChannel.CreateMessage();
msg.InnerMessage.Write((byte)PacketTypes.Chatmessage); msg.InnerMessage.Write((byte)PacketTypes.Chatmessage);
//msg.InnerMessage.Write((byte)type);
//msg.InnerMessage.Write(message);
message.WriteNetworkMessage(msg.InnerMessage); message.WriteNetworkMessage(msg.InnerMessage);
c.ReliableChannel.SendMessage(msg, c.Connection); c.ReliableChannel.SendMessage(msg, c.Connection);
} }
} }
public override void SendChatMessage(string message, ChatMessageType? type = null) public override void SendChatMessage(string message, ChatMessageType? type = null)
@@ -1526,18 +1575,21 @@ namespace Barotrauma.Networking
SendChatMessage(chatMessage, recipients); SendChatMessage(chatMessage, recipients);
} }
public void SendChatMessage(ChatMessage chatMessage, Client recipient)
{
ReliableMessage msg = recipient.ReliableChannel.CreateMessage();
msg.InnerMessage.Write((byte)PacketTypes.Chatmessage);
chatMessage.WriteNetworkMessage(msg.InnerMessage);
recipient.ReliableChannel.SendMessage(msg, recipient.Connection);
}
public void SendChatMessage(ChatMessage chatMessage, List<Client> recipients) public void SendChatMessage(ChatMessage chatMessage, List<Client> recipients)
{ {
foreach (Client c in recipients) foreach (Client recipient in recipients)
{ {
ReliableMessage msg = c.ReliableChannel.CreateMessage(); SendChatMessage(chatMessage, recipient);
msg.InnerMessage.Write((byte)PacketTypes.Chatmessage);
//msg.InnerMessage.Write((byte)type);
//msg.InnerMessage.Write(message);
chatMessage.WriteNetworkMessage(msg.InnerMessage);
c.ReliableChannel.SendMessage(msg, c.Connection);
} }
} }