Build 1.1.4.0

This commit is contained in:
Markus Isberg
2023-03-31 18:40:44 +03:00
parent efba17e0ff
commit 9470edead3
483 changed files with 17487 additions and 8548 deletions
@@ -11,20 +11,15 @@ namespace Barotrauma
{
internal partial class MedicalClinic
{
private enum RateLimitResult
{
OK,
LimitReached
}
// allow 10 requests per 5 seconds, announce to chat if the limit is reached
private readonly RateLimiter rateLimiter = new(
maxRequests: 10,
expiryInSeconds: 5,
punishmentRules: (RateLimitAction.OnLimitReached, RateLimitPunishment.Announce));
private struct RateLimitInfo
{
public int Requests;
public const int MaxRequests = 10;
public DateTimeOffset Expiry;
}
private readonly record struct AfflictionSubscriber(Client Subscriber, CharacterInfo Target, DateTimeOffset Expiry);
private readonly Dictionary<Client, RateLimitInfo> rateLimits = new Dictionary<Client, RateLimitInfo>();
private readonly List<AfflictionSubscriber> afflictionSubscribers = new();
public void ServerRead(IReadMessage inc, Client sender)
{
@@ -35,6 +30,9 @@ namespace Barotrauma
case NetworkHeader.ADD_EVERYTHING_TO_PENDING:
ProcessAddEverything(sender);
break;
case NetworkHeader.UNSUBSCRIBE_ME:
RemoveClientSubscription(sender);
break;
case NetworkHeader.REQUEST_AFFLICTIONS:
ProcessRequestedAfflictions(inc, sender);
break;
@@ -58,7 +56,7 @@ namespace Barotrauma
private void ProcessNewAddition(IReadMessage inc, Client client)
{
if (CheckRateLimit(client) == RateLimitResult.LimitReached) { return; }
if (rateLimiter.IsLimitReached(client)) { return; }
NetCrewMember newCrewMember = INetSerializableStruct.Read<NetCrewMember>(inc);
InsertPendingCrewMember(newCrewMember);
@@ -67,14 +65,25 @@ namespace Barotrauma
private void ProcessAddEverything(Client client)
{
if (CheckRateLimit(client) == RateLimitResult.LimitReached) { return; }
if (rateLimiter.IsLimitReached(client)) { return; }
AddEverythingToPending();
ServerSend(PendingHeals.ToNetCollection(), NetworkHeader.ADD_PENDING, DeliveryMethod.Reliable, reponseClient: client);
}
private void RemoveClientSubscription(Client client)
{
foreach (AfflictionSubscriber sub in afflictionSubscribers.ToList())
{
if (sub.Subscriber == client || sub.Expiry < DateTimeOffset.Now)
{
afflictionSubscribers.Remove(sub);
}
}
}
private void ProcessNewRemoval(IReadMessage inc, Client client)
{
if (CheckRateLimit(client) == RateLimitResult.LimitReached) { return; }
if (rateLimiter.IsLimitReached(client)) { return; }
NetRemovedAffliction removed = INetSerializableStruct.Read<NetRemovedAffliction>(inc);
RemovePendingAffliction(removed.CrewMember, removed.Affliction);
@@ -83,14 +92,14 @@ namespace Barotrauma
private void ProcessRequestedPending(Client client)
{
if (CheckRateLimit(client) == RateLimitResult.LimitReached) { return; }
if (rateLimiter.IsLimitReached(client)) { return; }
ServerSend(PendingHeals.ToNetCollection(), NetworkHeader.REQUEST_PENDING, DeliveryMethod.Reliable, targetClient: client);
}
private void ProcessHealing(Client client)
{
if (CheckRateLimit(client) == RateLimitResult.LimitReached) { return; }
if (rateLimiter.IsLimitReached(client)) { return; }
HealRequestResult result = HealAllPending(client: client);
ServerSend(new NetHealRequest { Result = result }, NetworkHeader.HEAL_PENDING, DeliveryMethod.Reliable, reponseClient: client);
@@ -98,7 +107,7 @@ namespace Barotrauma
private void ProcessClearing(Client client)
{
if (CheckRateLimit(client) == RateLimitResult.LimitReached) { return; }
if (rateLimiter.IsLimitReached(client)) { return; }
if (!PendingHeals.Any()) { return; }
@@ -108,7 +117,7 @@ namespace Barotrauma
private void ProcessRequestedAfflictions(IReadMessage inc, Client client)
{
if (CheckRateLimit(client) == RateLimitResult.LimitReached) { return; }
if (rateLimiter.IsLimitReached(client)) { return; }
NetCrewMember crewMember = INetSerializableStruct.Read<NetCrewMember>(inc);
@@ -129,35 +138,17 @@ namespace Barotrauma
Afflictions = pendingAfflictions
};
if (foundInfo is not null)
{
RemoveClientSubscription(client);
// the client subscribes to the afflictions of the crew member for the next minute
afflictionSubscribers.Add(new AfflictionSubscriber(client, foundInfo, DateTimeOffset.Now.AddMinutes(1)));
}
ServerSend(writeCrewMember, NetworkHeader.REQUEST_AFFLICTIONS, DeliveryMethod.Unreliable, client);
}
private RateLimitResult CheckRateLimit(Client client)
{
if (rateLimits.TryGetValue(client, out RateLimitInfo rateLimitInfo))
{
if (rateLimitInfo.Expiry < DateTimeOffset.Now)
{
rateLimitInfo.Expiry = DateTimeOffset.Now.AddSeconds(5);
rateLimitInfo.Requests = 1;
}
else
{
if (rateLimitInfo.Requests > RateLimitInfo.MaxRequests) { return RateLimitResult.LimitReached; }
rateLimitInfo.Requests++;
}
rateLimits[client] = rateLimitInfo;
}
else
{
rateLimits.Add(client, new RateLimitInfo { Requests = 1, Expiry = DateTimeOffset.Now.AddSeconds(5) });
}
return RateLimitResult.OK;
}
private IWriteMessage StartSending()
{
IWriteMessage msg = new WriteOnlyMessage();