From 94c1b29beb91283e9e5c935200e74bcade7f8045 Mon Sep 17 00:00:00 2001 From: juanjp600 Date: Mon, 25 Mar 2019 10:57:18 -0300 Subject: [PATCH] (9a13b4418) Hull syncing fixes: - Don't let clients decrease the size of FireSources below zero. May happen because clients are allowed to predict changes in the size (correcting the values when receiving updates from the server), but not remove the fires if their size is too small. - When using the fire/water command, the clients used to simply discard hull updates from the server if fire/water had been edited within 0.5 seconds (to prevent the state from reverting back to previous one when receiving an update). This occasionally caused the fires/water to get out of sync if the server didn't send additional updates after the 0.5 delay. Now the clients will simply correct the hull to the last known server state after the 0.5 second delay. --- .../BarotraumaClient/Source/Map/Hull.cs | 46 +++++++++++++------ .../BarotraumaServer/Source/Map/Hull.cs | 4 +- .../BarotraumaShared/Source/Map/FireSource.cs | 38 +++++++-------- .../BarotraumaShared/Source/Map/Hull.cs | 6 +-- .../Source/Networking/NetConfig.cs | 2 +- 5 files changed, 57 insertions(+), 39 deletions(-) diff --git a/Barotrauma/BarotraumaClient/Source/Map/Hull.cs b/Barotrauma/BarotraumaClient/Source/Map/Hull.cs index 609974556..8dc7700f0 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Hull.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Hull.cs @@ -1,13 +1,13 @@ using Barotrauma.Networking; using Barotrauma.Particles; using Barotrauma.Sounds; +using Lidgren.Network; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; using System; using System.Collections.Generic; -using Microsoft.Xna.Framework.Input; using System.Linq; -using Lidgren.Network; namespace Barotrauma { @@ -18,6 +18,8 @@ namespace Barotrauma private List decals = new List(); private float serverUpdateDelay; + private float remoteWaterVolume, remoteOxygenPercentage; + private List remoteFireSources; private bool networkUpdatePending; private float networkUpdateTimer; @@ -138,6 +140,10 @@ namespace Barotrauma partial void UpdateProjSpecific(float deltaTime, Camera cam) { serverUpdateDelay -= deltaTime; + if (serverUpdateDelay <= 0.0f) + { + ApplyRemoteState(); + } if (networkUpdatePending) { @@ -546,18 +552,18 @@ namespace Barotrauma public void ClientRead(ServerNetObject type, NetBuffer message, float sendingTime) { - float newWaterVolume = message.ReadRangedSingle(0.0f, 1.5f, 8) * Volume; - float newOxygenPercentage = message.ReadRangedSingle(0.0f, 100.0f, 8); + remoteWaterVolume = message.ReadRangedSingle(0.0f, 1.5f, 8) * Volume; + remoteOxygenPercentage = message.ReadRangedSingle(0.0f, 100.0f, 8); bool hasFireSources = message.ReadBoolean(); int fireSourceCount = 0; - List newFireSources = new List(); + remoteFireSources = new List(); if (hasFireSources) { fireSourceCount = message.ReadRangedInteger(0, 16); for (int i = 0; i < fireSourceCount; i++) { - newFireSources.Add(new Vector3( + remoteFireSources.Add(new Vector3( MathHelper.Clamp(message.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f), MathHelper.Clamp(message.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f), message.ReadRangedSingle(0.0f, 1.0f, 8))); @@ -566,15 +572,25 @@ namespace Barotrauma if (serverUpdateDelay > 0.0f) { return; } - WaterVolume = newWaterVolume; - OxygenPercentage = newOxygenPercentage; - - for (int i = 0; i < fireSourceCount; i++) + ApplyRemoteState(); + } + + private void ApplyRemoteState() + { + if (remoteFireSources == null) + { + return; + } + + WaterVolume = remoteWaterVolume; + OxygenPercentage = remoteOxygenPercentage; + + for (int i = 0; i < remoteFireSources.Count; i++) { Vector2 pos = new Vector2( - rect.X + rect.Width * newFireSources[i].X, - rect.Y - rect.Height + (rect.Height * newFireSources[i].Y)); - float size = newFireSources[i].Z * rect.Width; + rect.X + rect.Width * remoteFireSources[i].X, + rect.Y - rect.Height + (rect.Height * remoteFireSources[i].Y)); + float size = remoteFireSources[i].Z * rect.Width; var newFire = i < FireSources.Count ? FireSources[i] : @@ -590,7 +606,7 @@ namespace Barotrauma } } - for (int i = FireSources.Count - 1; i >= fireSourceCount; i--) + for (int i = FireSources.Count - 1; i >= remoteFireSources.Count; i--) { FireSources[i].Remove(); if (i < FireSources.Count) @@ -598,6 +614,8 @@ namespace Barotrauma FireSources.RemoveAt(i); } } + + remoteFireSources = null; } } } diff --git a/Barotrauma/BarotraumaServer/Source/Map/Hull.cs b/Barotrauma/BarotraumaServer/Source/Map/Hull.cs index 907ba6f45..5f9257b42 100644 --- a/Barotrauma/BarotraumaServer/Source/Map/Hull.cs +++ b/Barotrauma/BarotraumaServer/Source/Map/Hull.cs @@ -31,8 +31,8 @@ namespace Barotrauma GameMain.NetworkMember.CreateEntityEvent(this); lastSentVolume = waterVolume; lastSentOxygen = OxygenPercentage; - sendUpdateTimer = NetworkUpdateInterval; - } + sendUpdateTimer = NetConfig.HullUpdateInterval; + } } } diff --git a/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs b/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs index a51330613..c252c399a 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs @@ -175,12 +175,11 @@ namespace Barotrauma LimitSize(); UpdateProjSpecific(growModifier); - -#if CLIENT - if (GameMain.Client != null) return; -#endif - - if (size.X < 1.0f) Remove(); + + if (size.X < 1.0f && (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)) + { + Remove(); + } } partial void UpdateProjSpecific(float growModifier); @@ -285,6 +284,7 @@ namespace Barotrauma spawnPos, speed, 0.0f, hull); } #endif + extinguishAmount = Math.Min(size.X, extinguishAmount); position.X += extinguishAmount / 2.0f; size.X -= extinguishAmount; @@ -292,11 +292,10 @@ namespace Barotrauma //evaporate some of the water hull.WaterVolume -= extinguishAmount; -#if CLIENT - if (GameMain.Client != null) return; -#endif - - if (size.X < 1.0f) Remove(); + if (size.X < 1.0f && (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)) + { + Remove(); + } } public void Extinguish(float deltaTime, float amount) @@ -315,22 +314,25 @@ namespace Barotrauma spawnPos, speed, 0.0f, hull); } #endif + extinguishAmount = Math.Min(size.X, extinguishAmount); position.X += extinguishAmount / 2.0f; size.X -= extinguishAmount; hull.WaterVolume -= extinguishAmount; - -#if CLIENT - if (GameMain.Client != null) return; -#endif - - if (size.X < 1.0f) Remove(); + + if (size.X < 1.0f && (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)) + { + Remove(); + } } public void Extinguish(float deltaTime, float amount, Vector2 worldPosition) { - if (IsInDamageRange(worldPosition, 100.0f)) Extinguish(deltaTime, amount); + if (IsInDamageRange(worldPosition, 100.0f)) + { + Extinguish(deltaTime, amount); + } } public void Remove() diff --git a/Barotrauma/BarotraumaShared/Source/Map/Hull.cs b/Barotrauma/BarotraumaShared/Source/Map/Hull.cs index b624bb247..da308afe7 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Hull.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Hull.cs @@ -12,8 +12,6 @@ namespace Barotrauma { partial class Hull : MapEntity, ISerializableEntity, IServerSerializable { - const float NetworkUpdateInterval = 0.5f; - public static List hullList = new List(); public static List EntityGrids { get; } = new List(); @@ -21,7 +19,7 @@ namespace Barotrauma public static bool EditWater, EditFire; public const float OxygenDistributionSpeed = 500.0f; - public const float OxygenDetoriationSpeed = 0.3f; + public const float OxygenDeteriorationSpeed = 0.3f; public const float OxygenConsumptionSpeed = 1000.0f; public const int WaveWidth = 32; @@ -416,7 +414,7 @@ namespace Barotrauma { UpdateProjSpecific(deltaTime, cam); - Oxygen -= OxygenDetoriationSpeed * deltaTime; + Oxygen -= OxygenDeteriorationSpeed * deltaTime; FireSource.UpdateAll(FireSources, deltaTime); diff --git a/Barotrauma/BarotraumaShared/Source/Networking/NetConfig.cs b/Barotrauma/BarotraumaShared/Source/Networking/NetConfig.cs index 2e2d01dc0..219b4d55e 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/NetConfig.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/NetConfig.cs @@ -35,8 +35,8 @@ namespace Barotrauma.Networking public const float DeleteDisconnectedTime = 20.0f; public const float ItemConditionUpdateInterval = 0.15f; - public const float LevelObjectUpdateInterval = 0.5f; + public const float HullUpdateInterval = 0.5f; public const int MaxEventPacketsPerUpdate = 4;