Merge remote-tracking branch 'upstream/master' into develop

This commit is contained in:
EvilFactory
2024-12-11 10:44:53 -03:00
257 changed files with 4793 additions and 1653 deletions
@@ -93,6 +93,10 @@ namespace Barotrauma.Networking
return cursorPositionError *= 0.7f;
}
/// <summary>
/// Quantizes the value so it's "as accurate as it can be" when the value is represented using the specified number of bits.
/// Relevant e.g. when writing float values into network messages using some specific number of bits.
/// </summary>
public static Vector2 Quantize(Vector2 value, float min, float max, int numberOfBits)
{
return new Vector2(
@@ -100,15 +104,21 @@ namespace Barotrauma.Networking
Quantize(value.Y, min, max, numberOfBits));
}
/// <summary>
/// Quantizes the value so it's "as accurate as it can be" when the value is represented using the specified number of bits.
/// Relevant e.g. when writing float values into network messages using some specific number of bits.
/// </summary>
public static float Quantize(float value, float min, float max, int numberOfBits)
{
float step = (max - min) / (1 << (numberOfBits + 1));
value = MathHelper.Clamp(value, min, max);
float step = (max - min) / ((1 << numberOfBits) - 1);
if (Math.Abs(value) < step + 0.00001f)
{
return 0.0f;
}
return MathUtils.RoundTowardsClosest(MathHelper.Clamp(value, min, max), step);
return MathUtils.RoundTowardsClosest(value - min, step) + min;
}
}
}
@@ -1,9 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Barotrauma.Networking
{
class EntityEventException : Exception
{
public readonly Entity Entity;
public EntityEventException(string errorMessage, Entity causingEntity, Exception innerException = null) : base(errorMessage, innerException)
{
Entity = causingEntity;
}
}
abstract class NetEntityEventManager
{
public const int MaxEventBufferLength = 1024;
@@ -29,7 +38,7 @@ namespace Barotrauma.Networking
}
catch (Exception exception)
{
DebugConsole.ThrowError("Failed to write an event for the entity \"" + e.Entity + "\"", exception);
DebugConsole.ThrowError($"Failed to write an event (ID: {e.ID}) for the entity \"{e.Entity}\"", exception, contentPackage: e.Entity?.ContentPackage);
GameAnalyticsManager.AddErrorEventOnce("NetEntityEventManager.Write:WriteFailed" + e.Entity.ToString(),
GameAnalyticsManager.ErrorSeverity.Error,
"Failed to write an event for the entity \"" + e.Entity + "\"\n" + exception.StackTrace.CleanupStackTrace());
@@ -37,7 +46,8 @@ namespace Barotrauma.Networking
//write an empty event to avoid messing up IDs
//(otherwise the clients might read the next event in the message and think its ID
//is consecutive to the previous one, even though we skipped over this broken event)
tempBuffer.WriteUInt16(Entity.NullEntityID);
tempBuffer.WriteUInt16(Entity.NullEntityID);
tempBuffer.WriteVariableUInt32(0); //size of the event
eventCount++;
continue;
}
@@ -31,7 +31,7 @@ namespace Barotrauma.Networking
/// </summary>
public OrderChatMessage(Order order, Character targetCharacter, Character sender, bool isNewOrder = true)
: this(order,
order?.GetChatMessage(targetCharacter?.Name,
order?.GetChatMessage(targetCharacter?.DisplayName,
(order.TargetEntity as Hull ?? sender?.CurrentHull)?.DisplayName?.Value,
givingOrderToSelf: targetCharacter == sender, orderOption: order.Option, isNewOrder: isNewOrder),
targetCharacter, sender, isNewOrder)
@@ -51,7 +51,7 @@ namespace Barotrauma.Networking
=> entity switch
{
null => null,
Character character => character.Name,
Character character => character.DisplayName,
Item it => it.Name,
_ => throw new ArgumentException("Entity is not a character or item", nameof(entity))
};
@@ -36,6 +36,7 @@ namespace Barotrauma.Networking
public enum RespawnMode
{
None,
MidRound,
BetweenRounds,
Permadeath,
@@ -420,6 +421,19 @@ namespace Barotrauma.Networking
set { tickRate = MathHelper.Clamp(value, 1, 60); }
}
private int maxLagCompensation = 150;
[Serialize(150, IsPropertySaveable.Yes, description:
"Maximum amount of lag compensation for firing weapons, in milliseconds. " +
"E.g. when a client fires a gun, the server will be notified about it with some latency, and checks if it hit anything in the past (at the time the shot was taken), up to this limit. " +
"The largest allowed lag compensation is 500 milliseconds.")]
public int MaxLagCompensation
{
get { return maxLagCompensation; }
set { maxLagCompensation = MathHelper.Clamp(value, 0, 500); }
}
public float MaxLagCompensationSeconds => maxLagCompensation / 1000.0f;
[Serialize(true, IsPropertySaveable.Yes, description: "Do clients need to be authenticated (e.g. based on Steam ID or an EGS ownership token). Can be disabled if you for example want to play the game in a local network without a connection to external services.")]
public bool RequireAuthentication
{