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
@@ -1,6 +1,7 @@
using Barotrauma.Networking;
using System.Linq;
using System.Xml.Linq;
using Barotrauma.Items.Components;
namespace Barotrauma
{
@@ -88,5 +89,16 @@ namespace Barotrauma
{
GameServer.Log($"{GameServer.CharacterLogName(this)} has gained the talent '{talentPrefab.DisplayName}'", ServerLog.MessageType.Talent);
}
private void SyncInGameEditables(Item item)
{
foreach (ItemComponent itemComponent in item.Components)
{
foreach (var serializableProperty in SerializableProperty.GetProperties<InGameEditable>(itemComponent))
{
GameMain.Server.CreateEntityEvent(item, new Item.ChangePropertyEventData(serializableProperty, itemComponent));
}
}
}
}
}
@@ -431,21 +431,33 @@ namespace Barotrauma
tempBuffer.WriteSingle(SimPosition.Y);
float MaxVel = NetConfig.MaxPhysicsBodyVelocity;
AnimController.Collider.LinearVelocity = new Vector2(
MathHelper.Clamp(AnimController.Collider.LinearVelocity.X, -MaxVel, MaxVel),
MathHelper.Clamp(AnimController.Collider.LinearVelocity.Y, -MaxVel, MaxVel));
NetConfig.Quantize(AnimController.Collider.LinearVelocity.X, -MaxVel, MaxVel, 12),
NetConfig.Quantize(AnimController.Collider.LinearVelocity.Y, -MaxVel, MaxVel, 12));
tempBuffer.WriteRangedSingle(AnimController.Collider.LinearVelocity.X, -MaxVel, MaxVel, 12);
tempBuffer.WriteRangedSingle(AnimController.Collider.LinearVelocity.Y, -MaxVel, MaxVel, 12);
bool fixedRotation = AnimController.Collider.FarseerBody.FixedRotation || !AnimController.Collider.PhysEnabled;
AnimController.TargetMovement = new Vector2(
NetConfig.Quantize(AnimController.TargetMovement.X, -Ragdoll.MAX_SPEED, Ragdoll.MAX_SPEED, 12),
NetConfig.Quantize(AnimController.TargetMovement.Y, -Ragdoll.MAX_SPEED, Ragdoll.MAX_SPEED, 12));
tempBuffer.WriteRangedSingle(AnimController.TargetMovement.X, -Ragdoll.MAX_SPEED, Ragdoll.MAX_SPEED, 12);
tempBuffer.WriteRangedSingle(AnimController.TargetMovement.Y, -Ragdoll.MAX_SPEED, Ragdoll.MAX_SPEED, 12);
bool fixedRotation = AnimController.Collider.FarseerBody.FixedRotation;
tempBuffer.WriteBoolean(fixedRotation);
if (!fixedRotation)
{
tempBuffer.WriteSingle(AnimController.Collider.Rotation);
float MaxAngularVel = NetConfig.MaxPhysicsBodyAngularVelocity;
AnimController.Collider.AngularVelocity = NetConfig.Quantize(AnimController.Collider.AngularVelocity, -MaxAngularVel, MaxAngularVel, 8);
AnimController.Collider.AngularVelocity =
AnimController.Collider.PhysEnabled ?
0.0f :
NetConfig.Quantize(AnimController.Collider.AngularVelocity, -MaxAngularVel, MaxAngularVel, 8);
tempBuffer.WriteRangedSingle(MathHelper.Clamp(AnimController.Collider.AngularVelocity, -MaxAngularVel, MaxAngularVel), -MaxAngularVel, MaxAngularVel, 8);
}
tempBuffer.WriteBoolean(AnimController.IgnorePlatforms);
bool writeStatus = healthUpdateTimer <= 0.0f;
tempBuffer.WriteBoolean(writeStatus);
if (writeStatus)
@@ -0,0 +1,70 @@
using Barotrauma.Networking;
using System.Collections.Generic;
using System.Linq;
namespace Barotrauma
{
partial class Limb : ISerializableEntity, ISpatialEntity
{
/// <summary>
/// An invisible "ghost body" used for doing lag compensation server side by allowing clients' shots to hit bodies at the positions where
/// they "used to be" back when the client fired a weapon.
/// </summary>
public PhysicsBody LagCompensatedBody { get; private set; }
/// <summary>
/// A queue of past positions of the limb.
/// </summary>
public Queue<PosInfo> MemState { get; } = new Queue<PosInfo>();
partial void InitProjSpecific(ContentXElement element)
{
LagCompensatedBody = new PhysicsBody(Params, findNewContacts: false)
{
BodyType = FarseerPhysics.BodyType.Static,
CollisionCategories = Physics.CollisionLagCompensationBody,
CollidesWith = Physics.CollisionNone,
UserData = this
};
}
partial void UpdateProjSpecific(float deltaTime)
{
if (GameMain.Server == null) { return; }
MemState.Enqueue(new PosInfo(body.SimPosition, body.Rotation, body.LinearVelocity, body.AngularVelocity, (float)Timing.TotalTime));
//clear old states
while (
MemState.Any() &&
MemState.Peek().Timestamp < Timing.TotalTime - GameMain.Server.ServerSettings.MaxLagCompensationSeconds)
{
MemState.Dequeue();
}
}
public static void SetLagCompensatedBodyPositions(Client client)
{
if (GameMain.Server == null) { return; }
//convert from milliseconds to seconds, assume latency is symmetrical (time from client to server is half of the roundtrip time / ping)
float latency = client.Ping / 1000.0f / 2;
float time = (float)Timing.TotalTime - MathUtils.Min(latency, GameMain.Server.ServerSettings.MaxLagCompensationSeconds);
foreach (var character in Character.CharacterList)
{
foreach (var limb in character.AnimController.Limbs)
{
if (limb.body.Enabled == false || limb.IgnoreCollisions) { continue; }
var matchingState = limb.MemState.FirstOrDefault(l => l.Timestamp <= time);
if (matchingState == null) { continue; }
limb.LagCompensatedBody.SetTransformIgnoreContacts(matchingState.Position, matchingState.Rotation ?? 0.0f);
}
}
}
partial void RemoveProjSpecific()
{
LagCompensatedBody.Remove();
}
}
}