Unstable 0.16.0.0
This commit is contained in:
@@ -53,7 +53,7 @@ namespace Barotrauma
|
||||
foreach (var activeOrder in ActiveOrders)
|
||||
{
|
||||
if (!(activeOrder?.First is Order order) || activeOrder.Second.HasValue) { continue; }
|
||||
OrderChatMessage.WriteOrder(msg, order, null, order.TargetSpatialEntity, null, 0, order.WallSectionIndex);
|
||||
OrderChatMessage.WriteOrder(msg, order, targetCharacter: null, order.TargetSpatialEntity, orderOption: null, orderPriority: 0, order.WallSectionIndex, isNewOrder: true);
|
||||
bool hasOrderGiver = order.OrderGiver != null;
|
||||
msg.Write(hasOrderGiver);
|
||||
if (hasOrderGiver)
|
||||
|
||||
+1
-34
@@ -348,7 +348,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateCampaignSubs();
|
||||
|
||||
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
|
||||
PendingSubmarineSwitch = null;
|
||||
@@ -399,44 +398,12 @@ namespace Barotrauma
|
||||
Map.OnMissionsSelected += (loc, mission) => { LastUpdateID++; };
|
||||
Reputation.OnAnyReputationValueChanged += () => { LastUpdateID++; };
|
||||
|
||||
UpdateCampaignSubs();
|
||||
|
||||
//increment save ID so clients know they're lacking the most up-to-date save file
|
||||
LastSaveID++;
|
||||
}
|
||||
|
||||
public static void UpdateCampaignSubs()
|
||||
{
|
||||
bool isSubmarineVisible(SubmarineInfo s)
|
||||
=> !GameMain.Server.ServerSettings.HiddenSubs.Any(h
|
||||
=> s.Name.Equals(h, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
List<SubmarineInfo> availableSubs =
|
||||
SubmarineInfo.SavedSubmarines
|
||||
.Where(s =>
|
||||
s.IsCampaignCompatible
|
||||
&& isSubmarineVisible(s))
|
||||
.ToList();
|
||||
|
||||
if (!availableSubs.Any())
|
||||
{
|
||||
//None of the available subs were marked as campaign-compatible, just include all visible subs
|
||||
availableSubs.AddRange(
|
||||
SubmarineInfo.SavedSubmarines
|
||||
.Where(isSubmarineVisible));
|
||||
}
|
||||
|
||||
if (!availableSubs.Any())
|
||||
{
|
||||
//No subs are visible at all! Just make the selected one available
|
||||
availableSubs.Add(GameMain.NetLobbyScreen.SelectedSub);
|
||||
}
|
||||
|
||||
GameMain.NetLobbyScreen.CampaignSubmarines = availableSubs;
|
||||
}
|
||||
|
||||
public bool CanPurchaseSub(SubmarineInfo info)
|
||||
=> info.Price <= Money && GameMain.NetLobbyScreen.CampaignSubmarines.Contains(info);
|
||||
=> info.Price <= Money && GetCampaignSubs().Contains(info);
|
||||
|
||||
public void DiscardClientCharacterData(Client client)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Barotrauma.Networking;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
internal partial class MedicalClinic
|
||||
{
|
||||
private enum RateLimitResult
|
||||
{
|
||||
OK,
|
||||
LimitReached
|
||||
}
|
||||
|
||||
private struct RateLimitInfo
|
||||
{
|
||||
public int Requests;
|
||||
public const int MaxRequests = 5;
|
||||
public DateTimeOffset Expiry;
|
||||
}
|
||||
|
||||
private readonly Dictionary<Client, RateLimitInfo> rateLimits = new Dictionary<Client, RateLimitInfo>();
|
||||
|
||||
public void ServerRead(IReadMessage inc, Client sender)
|
||||
{
|
||||
NetworkHeader header = (NetworkHeader)inc.ReadByte();
|
||||
|
||||
switch (header)
|
||||
{
|
||||
case NetworkHeader.REQUEST_AFFLICTIONS:
|
||||
ProcessRequestedAfflictions(inc, sender);
|
||||
break;
|
||||
case NetworkHeader.REQUEST_PENDING:
|
||||
ProcessRequestedPending(sender);
|
||||
break;
|
||||
case NetworkHeader.ADD_PENDING:
|
||||
ProcessNewAddition(inc, sender);
|
||||
break;
|
||||
case NetworkHeader.REMOVE_PENDING:
|
||||
ProcessNewRemoval(inc, sender);
|
||||
break;
|
||||
case NetworkHeader.HEAL_PENDING:
|
||||
ProcessHealing(sender);
|
||||
break;
|
||||
case NetworkHeader.CLEAR_PENDING:
|
||||
ProcessClearing(sender);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessNewAddition(IReadMessage inc, Client client)
|
||||
{
|
||||
if (CheckRateLimit(client) == RateLimitResult.LimitReached) { return; }
|
||||
|
||||
NetCrewMember newCrewMember = INetSerializableStruct.Read<NetCrewMember>(inc);
|
||||
InsertPendingCrewMember(newCrewMember);
|
||||
ServerSend(newCrewMember, NetworkHeader.ADD_PENDING, DeliveryMethod.Reliable, reponseClient: client);
|
||||
}
|
||||
|
||||
private void ProcessNewRemoval(IReadMessage inc, Client client)
|
||||
{
|
||||
if (CheckRateLimit(client) == RateLimitResult.LimitReached) { return; }
|
||||
|
||||
NetRemovedAffliction removed = INetSerializableStruct.Read<NetRemovedAffliction>(inc);
|
||||
RemovePendingAffliction(removed.CrewMember, removed.Affliction);
|
||||
ServerSend(removed, NetworkHeader.REMOVE_PENDING, DeliveryMethod.Reliable, reponseClient: client);
|
||||
}
|
||||
|
||||
private void ProcessRequestedPending(Client client)
|
||||
{
|
||||
if (CheckRateLimit(client) == RateLimitResult.LimitReached) { return; }
|
||||
|
||||
INetSerializableStruct writeCrewMember = new NetPendingCrew
|
||||
{
|
||||
CrewMembers = PendingHeals.ToArray()
|
||||
};
|
||||
|
||||
ServerSend(writeCrewMember, NetworkHeader.REQUEST_PENDING, DeliveryMethod.Reliable, targetClient: client);
|
||||
}
|
||||
|
||||
private void ProcessHealing(Client client)
|
||||
{
|
||||
if (CheckRateLimit(client) == RateLimitResult.LimitReached) { return; }
|
||||
|
||||
HealRequestResult result = HealAllPending();
|
||||
ServerSend(new NetHealRequest { Result = result }, NetworkHeader.HEAL_PENDING, DeliveryMethod.Reliable, reponseClient: client);
|
||||
}
|
||||
|
||||
private void ProcessClearing(Client client)
|
||||
{
|
||||
if (CheckRateLimit(client) == RateLimitResult.LimitReached) { return; }
|
||||
|
||||
if (!PendingHeals.Any()) { return; }
|
||||
|
||||
ClearPendingHeals();
|
||||
ServerSend(null, NetworkHeader.CLEAR_PENDING, DeliveryMethod.Reliable, reponseClient: client);
|
||||
}
|
||||
|
||||
private void ProcessRequestedAfflictions(IReadMessage inc, Client client)
|
||||
{
|
||||
if (CheckRateLimit(client) == RateLimitResult.LimitReached) { return; }
|
||||
|
||||
NetCrewMember crewMember = INetSerializableStruct.Read<NetCrewMember>(inc);
|
||||
|
||||
CharacterInfo? foundInfo = crewMember.FindCharacterInfo(GetCrewCharacters());
|
||||
|
||||
NetAffliction[] pendingAfflictions = Array.Empty<NetAffliction>();
|
||||
int infoId = 0;
|
||||
|
||||
if (foundInfo is { Character: { CharacterHealth: { } health } })
|
||||
{
|
||||
pendingAfflictions = GetAllAfflictions(health);
|
||||
infoId = foundInfo.GetIdentifierUsingOriginalName();
|
||||
}
|
||||
|
||||
INetSerializableStruct writeCrewMember = new NetCrewMember
|
||||
{
|
||||
CharacterInfoID = infoId,
|
||||
Afflictions = pendingAfflictions
|
||||
};
|
||||
|
||||
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();
|
||||
msg.Write((byte)ServerPacketHeader.MEDICAL);
|
||||
return msg;
|
||||
}
|
||||
|
||||
private void ServerSend(INetSerializableStruct? netStruct, NetworkHeader header, DeliveryMethod deliveryMethod, Client? targetClient = null, Client? reponseClient = null)
|
||||
{
|
||||
if (targetClient is null)
|
||||
{
|
||||
foreach (Client c in GameMain.Server.ConnectedClients)
|
||||
{
|
||||
SendToClient(c);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
SendToClient(targetClient);
|
||||
|
||||
void SendToClient(Client c)
|
||||
{
|
||||
MessageFlag flag = MessageFlag.Announce;
|
||||
if (reponseClient != null && reponseClient == c)
|
||||
{
|
||||
flag = MessageFlag.Response;
|
||||
}
|
||||
|
||||
IWriteMessage msg = StartSending();
|
||||
msg.Write((byte)header);
|
||||
msg.Write((byte)flag);
|
||||
netStruct?.Write(msg);
|
||||
GameMain.Server.ServerPeer.Send(msg, c.Connection, deliveryMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user