(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.

This commit is contained in:
juanjp600
2019-03-25 10:57:18 -03:00
parent c2e8263927
commit 94c1b29beb
5 changed files with 57 additions and 39 deletions
+32 -14
View File
@@ -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<Decal> decals = new List<Decal>();
private float serverUpdateDelay;
private float remoteWaterVolume, remoteOxygenPercentage;
private List<Vector3> 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<Vector3> newFireSources = new List<Vector3>();
remoteFireSources = new List<Vector3>();
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;
}
}
}
@@ -31,8 +31,8 @@ namespace Barotrauma
GameMain.NetworkMember.CreateEntityEvent(this);
lastSentVolume = waterVolume;
lastSentOxygen = OxygenPercentage;
sendUpdateTimer = NetworkUpdateInterval;
}
sendUpdateTimer = NetConfig.HullUpdateInterval;
}
}
}
@@ -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()
@@ -12,8 +12,6 @@ namespace Barotrauma
{
partial class Hull : MapEntity, ISerializableEntity, IServerSerializable
{
const float NetworkUpdateInterval = 0.5f;
public static List<Hull> hullList = new List<Hull>();
public static List<EntityGrid> EntityGrids { get; } = new List<EntityGrid>();
@@ -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);
@@ -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;