v1.1.19.3 (Treacherous Tides Hotfix 2)

This commit is contained in:
Regalis11
2023-10-30 17:38:29 +02:00
parent b968376247
commit a8f9c97dda
38 changed files with 517 additions and 256 deletions
@@ -80,58 +80,10 @@ namespace Barotrauma.Networking
{
c.LastSentChatMessages.RemoveRange(0, c.LastSentChatMessages.Count - 10);
}
float similarity = 0.0f;
for (int i = 0; i < c.LastSentChatMessages.Count; i++)
{
float closeFactor = 1.0f / (c.LastSentChatMessages.Count - i);
if (string.IsNullOrEmpty(txt))
{
similarity += closeFactor;
}
else
{
int levenshteinDist = ToolBox.LevenshteinDistance(txt, c.LastSentChatMessages[i]);
similarity += Math.Max((txt.Length - levenshteinDist) / (float)txt.Length * closeFactor, 0.0f);
}
}
//order/report messages can be sent a little faster than normal messages without triggering the spam filter
if (orderMsg != null)
{
similarity *= 0.25f;
}
bool isSpamExempt = RateLimiter.IsExempt(c);
if (similarity + c.ChatSpamSpeed > 5.0f && !isSpamExempt)
{
GameMain.Server.KarmaManager.OnSpamFilterTriggered(c);
c.ChatSpamCount++;
if (c.ChatSpamCount > 3)
{
//kick for spamming too much
GameMain.Server.KickClient(c, TextManager.Get("SpamFilterKicked").Value);
}
else
{
ChatMessage denyMsg = Create("", TextManager.Get("SpamFilterBlocked").Value, ChatMessageType.Server, null);
c.ChatSpamTimer = 10.0f;
GameMain.Server.SendDirectChatMessage(denyMsg, c);
}
return;
}
c.ChatSpamSpeed += similarity + 0.5f;
if (c.ChatSpamTimer > 0.0f && !isSpamExempt)
{
ChatMessage denyMsg = Create("", TextManager.Get("SpamFilterBlocked").Value, ChatMessageType.Server, null);
c.ChatSpamTimer = 10.0f;
GameMain.Server.SendDirectChatMessage(denyMsg, c);
return;
}
//order/report messages can be sent a little faster than normal messages without triggering the spam filter;
float similarityMultiplier = orderMsg != null ? 0.25f : 1.0f;
HandleSpamFilter(c, txt, out bool flaggedAsSpam, similarityMultiplier);
if (flaggedAsSpam) { return; }
if (type == ChatMessageType.Order)
{
@@ -177,6 +129,65 @@ namespace Barotrauma.Networking
}
}
/// <summary>
/// Increase the client's chat spam speed and check whether the spam filter should kick in
/// </summary>
public static void HandleSpamFilter(Client c, string messageText, out bool flaggedAsSpam, float similarityMultiplier = 1.0f)
{
float similarity = 0.0f;
for (int i = 0; i < c.LastSentChatMessages.Count; i++)
{
float closeFactor = 1.0f / (c.LastSentChatMessages.Count - i);
if (string.IsNullOrEmpty(messageText))
{
similarity += closeFactor;
}
else
{
int levenshteinDist = ToolBox.LevenshteinDistance(messageText, c.LastSentChatMessages[i]);
similarity += Math.Max((messageText.Length - levenshteinDist) / (float)messageText.Length * closeFactor, 0.0f);
}
}
similarity *= similarityMultiplier;
bool isSpamExempt = RateLimiter.IsExempt(c);
if (similarity + c.ChatSpamSpeed > 5.0f && !isSpamExempt)
{
GameMain.Server.KarmaManager.OnSpamFilterTriggered(c);
c.ChatSpamCount++;
if (c.ChatSpamCount > 3)
{
//kick for spamming too much
GameMain.Server.KickClient(c, TextManager.Get("SpamFilterKicked").Value);
}
else
{
ChatMessage denyMsg = Create("", TextManager.Get("SpamFilterBlocked").Value, ChatMessageType.Server, null);
c.ChatSpamTimer = 10.0f;
GameMain.Server.SendDirectChatMessage(denyMsg, c);
}
flaggedAsSpam = true;
return;
}
c.ChatSpamSpeed += similarity + 0.5f;
if (c.ChatSpamTimer > 0.0f && !isSpamExempt)
{
ChatMessage denyMsg = Create("", TextManager.Get("SpamFilterBlocked").Value, ChatMessageType.Server, null);
c.ChatSpamTimer = 10.0f;
GameMain.Server.SendDirectChatMessage(denyMsg, c);
flaggedAsSpam = true;
return;
}
flaggedAsSpam = false;
}
public int EstimateLengthBytesServer(Client c)
{
int length = 1 + //(byte)ServerNetObject.CHAT_MESSAGE
@@ -369,6 +369,9 @@ namespace Barotrauma.Networking
if (!character.ClientDisconnected) { continue; }
Client owner = connectedClients.Find(c => (c.Character == null || c.Character == character) && character.IsClientOwner(c));
bool canOwnerTakeControl =
owner != null && owner.InGame && !owner.NeedsMidRoundSync &&
(!ServerSettings.AllowSpectating || !owner.SpectateOnly);
if (!character.IsDead)
{
character.KillDisconnectedTimer += deltaTime;
@@ -379,18 +382,19 @@ namespace Barotrauma.Networking
character.Kill(CauseOfDeathType.Disconnected, null);
continue;
}
if (owner != null && owner.InGame && !owner.NeedsMidRoundSync &&
(!ServerSettings.AllowSpectating || !owner.SpectateOnly))
if (canOwnerTakeControl)
{
SetClientCharacter(owner, character);
}
}
else if (owner != null &&
else if (canOwnerTakeControl &&
character.CauseOfDeath?.Type == CauseOfDeathType.Disconnected &&
character.CharacterHealth.VitalityDisregardingDeath > 0)
{
//create network event immediately to ensure the character is revived client-side
//before the client gains control of it (normally status events are created periodically)
character.Revive(removeAfflictions: false, createNetworkEvent: true);
SetClientCharacter(owner, character);
character.Revive(removeAfflictions: false);
}
}
@@ -345,9 +345,15 @@ namespace Barotrauma
sender.SetVote(voteType, client);
if (client?.Character != null)
{
GameMain.Server.SendChatMessage(
TextManager.GetWithVariable("traitor.blamebutton.dialog", "[name]", client.Character.DisplayName).Value,
ChatMessageType.Radio, senderClient: sender, senderCharacter: sender.Character);
string msg = TextManager.GetWithVariable("traitor.blamebutton.dialog", "[name]", client.Character.DisplayName).Value;
ChatMessage.HandleSpamFilter(sender, msg, out bool flaggedAsSpam);
if (!flaggedAsSpam)
{
GameMain.Server.SendChatMessage(
msg,
ChatMessageType.Radio, senderClient: sender, senderCharacter: sender.Character);
sender.LastSentChatMessages.Add(msg);
}
}
}
break;