Constant error correction + fixed standing catchup

With constant correction, there's little chance for a large difference to build up, so it becomes practically unnoticeable.
Also added a flag which stops the character from updating client-side until the server sends the spawning position.
This commit is contained in:
juanjp600
2017-01-08 12:20:36 -03:00
parent 7dc474dab4
commit 4b868fc09d
2 changed files with 41 additions and 24 deletions

View File

@@ -1222,7 +1222,8 @@ namespace Barotrauma
}
}
if (GameMain.Server != null) return; //the server should not be trying to correct any positions, it's authoritative
if (character != GameMain.NetworkMember.Character || !character.AllowInput)
{
//use simple interpolation for other players' characters and characters that can't move
@@ -1266,6 +1267,16 @@ namespace Barotrauma
PosInfo serverPos = character.MemPos.Last();
if (!character.isSynced)
{
SetPosition(serverPos.Position, false);
Collider.LinearVelocity = Vector2.Zero;
character.MemLocalPos.Clear();
character.LastNetworkUpdateID = serverPos.ID;
character.isSynced = true;
return;
}
int localPosIndex = character.MemLocalPos.FindIndex(m => m.ID == serverPos.ID);
if (localPosIndex > -1)
{
@@ -1274,31 +1285,33 @@ namespace Barotrauma
Vector2 positionError = serverPos.Position - localPos.Position;
float errorMagnitude = positionError.Length();
DebugConsole.NewMessage(positionError.X.ToString()+" "+positionError.Y.ToString(),Color.Red);
if (errorMagnitude > 2.0f)
/*if (errorMagnitude > 8.0f)
{
//predicted position was way off, reset completely
SetPosition(serverPos.Position, false);
//local positions are incorrect now -> just clear the list
character.MemLocalPos.Clear();
}
else if (errorMagnitude > Collider.LinearVelocity.Length() / 10.0f + 0.02f)
{
//our prediction differs from the server position
//-> we need to move the saved local position and all the positions saved after it
else if (errorMagnitude > Collider.LinearVelocity.Length() / 10.0f + 0.02f && false)
{*/
//our prediction differs from the server position
//-> we need to move the saved local position and all the positions saved after it
//(a better way to do this would be to move the character back to
//serverPos and "replay" inputs to see where the character should be now)
for (int i = localPosIndex; i < character.MemLocalPos.Count; i++)
{
character.MemLocalPos[i] =
new PosInfo(
character.MemLocalPos[i].Position + positionError,
character.MemLocalPos[i].Direction,
character.MemLocalPos[i].ID);
}
Collider.SetTransform(character.MemLocalPos.Last().Position, Collider.Rotation);
//(a better way to do this would be to move the character back to
//serverPos and "replay" inputs to see where the character should be now)
for (int i = localPosIndex; i < character.MemLocalPos.Count; i++)
{
character.MemLocalPos[i] =
new PosInfo(
character.MemLocalPos[i].Position + positionError,
character.MemLocalPos[i].Direction,
character.MemLocalPos[i].ID);
}
//Collider.SetTransform(character.MemLocalPos.Last().Position, Collider.Rotation);
Collider.SetTransform(Collider.SimPosition + positionError, Collider.Rotation);
//}
}
if (character.MemLocalPos.Count > 120) character.MemLocalPos.RemoveRange(0, character.MemLocalPos.Count - 120);

View File

@@ -20,11 +20,11 @@ namespace Barotrauma
public static bool DisableControls;
private UInt32 netStateID;
/*private UInt32 netStateID;
public UInt32 NetStateID
{
get { return netStateID; }
}
}*/
[Flags]
private enum InputNetFlags : ushort
@@ -70,6 +70,8 @@ namespace Barotrauma
public List<Item> SpawnItems = new List<Item>();
public bool isSynced = false;
private bool enabled;
public bool Enabled
@@ -96,7 +98,7 @@ namespace Barotrauma
private CharacterInventory inventory;
private UInt32 LastNetworkUpdateID = 0;
public UInt32 LastNetworkUpdateID = 0;
//public int LargeUpdateTimer;
@@ -1312,6 +1314,8 @@ namespace Barotrauma
public virtual void Update(Camera cam, float deltaTime)
{
if (GameMain.Client!=null && this==Controlled && !isSynced) return;
if (!Enabled) return;
PreviousHull = CurrentHull;
@@ -1357,10 +1361,10 @@ namespace Barotrauma
memMousePos.RemoveAt(memMousePos.Count - 1);
TransformCursorPos();
if (dequeuedInput == InputNetFlags.None && Math.Abs(AnimController.Collider.LinearVelocity.X) < 0.005f && Math.Abs(AnimController.Collider.LinearVelocity.Y) < 0.005f)
if (dequeuedInput == InputNetFlags.None && Math.Abs(AnimController.Collider.LinearVelocity.X) < 0.005f && Math.Abs(AnimController.Collider.LinearVelocity.Y) < 0.2f)
{
while (memInput.Count > 5 && memInput[memInput.Count - 1] == 0)
while (memInput.Count > 5 && memInput[memInput.Count - 1] == InputNetFlags.None)
{
//remove inputs where the player is not moving at all
//helps the server catch up, shouldn't affect final position
@@ -1387,7 +1391,7 @@ namespace Barotrauma
if (AnimController.TargetDir == Direction.Left) newInput |= InputNetFlags.FacingLeft;
memInput.Insert(0, newInput);
memMousePos.Insert(0, closestItem!=null ? closestItem.Position : cursorPosition);
memMousePos.Insert(0, /*closestItem!=null ? closestItem.Position : */cursorPosition);
LastNetworkUpdateID++;
if (memInput.Count > 60)
{