Server doesn't send character position updates to far-away clients, clients disable characters if they haven't received position updates in a while

This commit is contained in:
Regalis
2017-02-07 18:59:25 +02:00
parent b98ebe6e21
commit d46207916f
6 changed files with 48 additions and 88 deletions
+5 -5
View File
@@ -33,16 +33,16 @@ namespace Barotrauma
public override void Update(Camera cam, float deltaTime) public override void Update(Camera cam, float deltaTime)
{ {
if (!Enabled) return;
base.Update(cam, deltaTime); base.Update(cam, deltaTime);
float dist = Vector2.Distance(cam.WorldViewCenter, WorldPosition); if (!Enabled) return;
if (dist > 8000.0f)
float dist = Vector2.DistanceSquared(cam.WorldViewCenter, WorldPosition);
if (dist > 8000.0f * 8000.0f)
{ {
AnimController.SimplePhysicsEnabled = true; AnimController.SimplePhysicsEnabled = true;
} }
else if (dist < 7000.0f) else if (dist < 7000.0f * 7000.0f)
{ {
AnimController.SimplePhysicsEnabled = false; AnimController.SimplePhysicsEnabled = false;
} }
@@ -1125,14 +1125,14 @@ namespace Barotrauma
public void SetPosition(Vector2 simPosition, bool lerp = false) public void SetPosition(Vector2 simPosition, bool lerp = false)
{ {
Vector2 moveAmount = simPosition - Collider.SimPosition; Vector2 limbMoveAmount = simPosition - MainLimb.SimPosition;
Collider.SetTransform(simPosition, Collider.Rotation); Collider.SetTransform(simPosition, Collider.Rotation);
foreach (Limb limb in Limbs) foreach (Limb limb in Limbs)
{ {
//check visibility from the new position of the collider to the new position of this limb //check visibility from the new position of the collider to the new position of this limb
Vector2 movePos = limb.SimPosition + moveAmount; Vector2 movePos = limb.SimPosition + limbMoveAmount;
TrySetLimbPosition(limb, simPosition, movePos, lerp); TrySetLimbPosition(limb, simPosition, movePos, lerp);
} }
@@ -1160,7 +1160,7 @@ namespace Barotrauma
if (lerp) if (lerp)
{ {
limb.body.TargetPosition = movePos; limb.body.TargetPosition = movePos;
limb.body.MoveToTargetPosition(Vector2.DistanceSquared(limb.SimPosition, movePos) < 100.0f); limb.body.MoveToTargetPosition(true);
} }
else else
{ {
@@ -1179,7 +1179,7 @@ namespace Barotrauma
protected void CheckDistFromCollider() protected void CheckDistFromCollider()
{ {
float allowedDist = Math.Max(Math.Max(Collider.radius, Collider.width), Collider.height) * 2.0f; float allowedDist = Math.Max(Math.Max(Collider.radius, Collider.width), Collider.height) * 2.0f;
float resetDist = allowedDist * 10.0f; float resetDist = allowedDist * 5.0f;
float distSqrd = Vector2.DistanceSquared(Collider.SimPosition, MainLimb.SimPosition); float distSqrd = Vector2.DistanceSquared(Collider.SimPosition, MainLimb.SimPosition);
+25 -4
View File
@@ -107,7 +107,7 @@ namespace Barotrauma
public UInt16 LastNetworkUpdateID = 0; public UInt16 LastNetworkUpdateID = 0;
//public int LargeUpdateTimer; protected float lastRecvPositionUpdateTime;
public readonly Dictionary<string, ObjectProperty> Properties; public readonly Dictionary<string, ObjectProperty> Properties;
public Dictionary<string, ObjectProperty> ObjectProperties public Dictionary<string, ObjectProperty> ObjectProperties
@@ -1331,7 +1331,7 @@ namespace Barotrauma
public virtual void Update(Camera cam, float deltaTime) public virtual void Update(Camera cam, float deltaTime)
{ {
if (GameMain.Client!=null && this==Controlled && !isSynced) return; if (GameMain.Client != null && this == Controlled && !isSynced) return;
if (!Enabled) return; if (!Enabled) return;
@@ -1360,7 +1360,22 @@ namespace Barotrauma
if (this != Character.Controlled) if (this != Character.Controlled)
{ {
if (GameMain.Server != null && !(this is AICharacter)) if (GameMain.Client != null)
{
//freeze AI characters if more than 1 seconds have passed since last update from the server
if (lastRecvPositionUpdateTime < NetTime.Now - 1.0f)
{
AnimController.Frozen = true;
memPos.Clear();
//hide after 2 seconds
if (lastRecvPositionUpdateTime < NetTime.Now - 2.0f)
{
Enabled = false;
return;
}
}
}
else if (GameMain.Server != null && !(this is AICharacter))
{ {
if (!AllowInput) if (!AllowInput)
{ {
@@ -1447,8 +1462,9 @@ namespace Barotrauma
memInput.RemoveRange(60, memInput.Count - 60); memInput.RemoveRange(60, memInput.Count - 60);
} }
} }
else //this == Character.Controlled && GameMain.Client == null else
{ {
//this == Character.Controlled && GameMain.Client == null
AnimController.Frozen = false; AnimController.Frozen = false;
} }
@@ -2247,6 +2263,11 @@ namespace Barotrauma
case ServerNetObject.ENTITY_POSITION: case ServerNetObject.ENTITY_POSITION:
bool facingRight = AnimController.Dir > 0.0f; bool facingRight = AnimController.Dir > 0.0f;
lastRecvPositionUpdateTime = (float)NetTime.Now;
AnimController.Frozen = false;
Enabled = true;
UInt16 networkUpdateID = 0; UInt16 networkUpdateID = 0;
if (msg.ReadBoolean()) if (msg.ReadBoolean())
{ {
@@ -44,10 +44,6 @@ namespace Barotrauma
{ {
radarPosition = monster.Position; radarPosition = monster.Position;
} }
else if (GameMain.Client == null)
{ Vector2 diff = monster.WorldPosition - Submarine.MainSub.WorldPosition;
monster.Enabled = FarseerPhysics.ConvertUnits.ToSimUnits(diff.Length()) < NetConfig.CharacterIgnoreDistance;
}
if (!monster.IsDead) return; if (!monster.IsDead) return;
ShowMessage(state); ShowMessage(state);
+11 -61
View File
@@ -466,29 +466,6 @@ namespace Barotrauma.Networking
// if 30ms has passed // if 30ms has passed
if (updateTimer < DateTime.Now) if (updateTimer < DateTime.Now)
{ {
/*if (gameStarted)
{
float ignoreDistance = FarseerPhysics.ConvertUnits.ToDisplayUnits(NetConfig.CharacterIgnoreDistance);
foreach (Character c in Character.CharacterList)
{
if (!(c is AICharacter) || c.IsDead) continue;
if (Character.CharacterList.Any(
c2 => c2.IsRemotePlayer &&
Vector2.Distance(c2.WorldPosition, c.WorldPosition) < ignoreDistance))
{
}
//todo: take multiple subs into account
//Vector2 diff = c.WorldPosition - Submarine.MainSub.WorldPosition;
//if (FarseerPhysics.ConvertUnits.ToSimUnits(diff.Length()) > NetConfig.CharacterIgnoreDistance) continue;
}
}*/
if (server.ConnectionsCount > 0) if (server.ConnectionsCount > 0)
{ {
if (sparseUpdateTimer < DateTime.Now) SparseUpdate(); if (sparseUpdateTimer < DateTime.Now) SparseUpdate();
@@ -568,31 +545,6 @@ namespace Barotrauma.Networking
private void SparseUpdate() private void SparseUpdate()
{ {
//if (gameStarted)
//{
// foreach (Submarine sub in Submarine.Loaded)
// {
// //no need to send position updates for submarines that are docked to mainsub
// if (sub != Submarine.MainSub && sub.DockedTo.Contains(Submarine.MainSub)) continue;
// new NetworkEvent(sub.ID, false);
// }
//}
/*foreach (Character c in Character.CharacterList)
{
if (c.IsDead) continue;
if (c is AICharacter)
{
//todo: take multiple subs into account
//Vector2 diff = c.WorldPosition - Submarine.MainSub.WorldPosition;
//if (FarseerPhysics.ConvertUnits.ToSimUnits(diff.Length()) > NetConfig.CharacterIgnoreDistance) continue;
}
}*/
sparseUpdateTimer = DateTime.Now + sparseUpdateInterval; sparseUpdateTimer = DateTime.Now + sparseUpdateInterval;
} }
@@ -672,7 +624,7 @@ namespace Barotrauma.Networking
#if DEBUG #if DEBUG
//client thinks they've received a msg we haven't sent yet (corrupted packet, msg read/written incorrectly?) //client thinks they've received a msg we haven't sent yet (corrupted packet, msg read/written incorrectly?)
if (lastRecvChatMsgID > c.lastChatMsgQueueID) if (NetIdUtils.IdMoreRecent(lastRecvChatMsgID, c.lastChatMsgQueueID))
DebugConsole.ThrowError("client.lastRecvChatMsgID > lastChatMsgQueueID"); DebugConsole.ThrowError("client.lastRecvChatMsgID > lastChatMsgQueueID");
if (lastRecvEntitySpawnID > lastEntitySpawnID) if (lastRecvEntitySpawnID > lastEntitySpawnID)
@@ -814,20 +766,18 @@ namespace Barotrauma.Networking
foreach (Character character in Character.CharacterList) foreach (Character character in Character.CharacterList)
{ {
if (character is AICharacter) if (!character.Enabled) continue;
if (c.Character != null &&
Vector2.DistanceSquared(character.WorldPosition, c.Character.WorldPosition) >=
NetConfig.CharacterIgnoreDistance * NetConfig.CharacterIgnoreDistance)
{ {
//TODO: don't send if the ai character is far from the client continue;
//(some sort of distance-based culling might be a good idea for player-controlled characters as well)
outmsg.Write((byte)ServerNetObject.ENTITY_POSITION);
character.ServerWrite(outmsg, c);
outmsg.WritePadBits();
}
else
{
outmsg.Write((byte)ServerNetObject.ENTITY_POSITION);
character.ServerWrite(outmsg, c);
outmsg.WritePadBits();
} }
outmsg.Write((byte)ServerNetObject.ENTITY_POSITION);
character.ServerWrite(outmsg, c);
outmsg.WritePadBits();
} }
foreach (Submarine sub in Submarine.Loaded) foreach (Submarine sub in Submarine.Loaded)
+2 -9
View File
@@ -12,15 +12,8 @@
public static string MasterServerUrl = GameMain.Config.MasterServerUrl; public static string MasterServerUrl = GameMain.Config.MasterServerUrl;
//if a Character is further than this from the sub, the server will ignore it //if a Character is further than this from the sub, the server will ignore it
//(in sim units) //(in display units)
public const float CharacterIgnoreDistance = 300.0f; public const float CharacterIgnoreDistance = 20000.0f;
//if a ragdoll is further than this from the correct position, teleport it there
//(in sim units)
public const float ResetRagdollDistance = 1.0f;
//if the ragdoll is closer than this, don't try to correct its position
public const float AllowedRagdollDistance = 0.1f;
//how much the physics body of an item has to move until the server //how much the physics body of an item has to move until the server
//send a position update to clients (in sim units) //send a position update to clients (in sim units)