From 05cc34afd887dbdb52f656a095de11677e269155 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Fri, 22 Mar 2019 13:57:35 +0200 Subject: [PATCH] 4d2bcb1...1473f77 commit 1473f77ba0c85b80d48dce3e0fca809a9d5da98c Author: Joonas Rikkonen Date: Fri Mar 22 12:39:03 2019 +0200 Server automatically ends rounds if there have been no players alive in 60 seconds and respawning is not allowed during the round. Otherwise campaign rounds can get "bricked" if all the clients die/disconnect and there's no-one who's allowed to manually end the round. Closes #1319 commit 7096983fb10e48c2866393d30420bfaa79a0719b Author: Joonas Rikkonen Date: Fri Mar 22 12:03:10 2019 +0200 Some extra error logging in an attempt to diagnose #1327 (seems that the server is trying to start a campaign round after the campaign has been disposed and another game mode selected). commit 2d7a3be83cd8865869837879b965fa9aeb046042 Author: Joonas Rikkonen Date: Fri Mar 22 10:53:08 2019 +0200 Use null as the rotation and angular velocity of a character's collider in network state buffers if the collider is set to a fixed rotation (i.e. when standing). Previously the _current_ rotation and angular velocity was used if the server didn't send the values, which caused the collider to "wobble" when getting up from the ground, because the clients used the current rotation and angular velocity to determine if their predicted state is correct, even though they should've been using past states (or rather, not attempting to correct at all because both the rotation and ang velocity should be 0 when the rotation is fixed). commit 2e2fd7078798703bc5d6ae398f75fa580ecca566 Author: Joonas Rikkonen Date: Thu Mar 21 22:44:11 2019 +0200 Disabled kicking clients out of the server if their Steam auth becomes invalid after they've already been authenticated. Got some reports from players about this occasionally happening for no apparent reason, and I don't see the need to kick the clients if they've already been successfully authenticated during that session. --- .../Source/Characters/Animation/Ragdoll.cs | 4 +- .../Source/Characters/CharacterNetworking.cs | 4 +- .../Source/Physics/PhysicsBody.cs | 10 ++--- .../Source/Networking/GameServer.cs | 43 +++++++++++++++++-- .../Source/Networking/GameServerLogin.cs | 4 +- .../Source/Characters/CharacterNetworking.cs | 6 +-- .../Source/Physics/PhysicsBody.cs | 14 +++--- 7 files changed, 61 insertions(+), 24 deletions(-) diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs b/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs index 5c3dd9749..c6f95eda7 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs @@ -210,7 +210,9 @@ namespace Barotrauma else { Vector2 positionError = serverPos.Position - localPos.Position; - float rotationError = serverPos.Rotation - localPos.Rotation; + float rotationError = serverPos.Rotation.HasValue && localPos.Rotation.HasValue ? + serverPos.Rotation.Value - localPos.Rotation.Value : + 0.0f; for (int i = localPosIndex; i < character.MemLocalState.Count; i++) { diff --git a/Barotrauma/BarotraumaClient/Source/Characters/CharacterNetworking.cs b/Barotrauma/BarotraumaClient/Source/Characters/CharacterNetworking.cs index 54acd801e..c53b261fa 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/CharacterNetworking.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/CharacterNetworking.cs @@ -214,8 +214,8 @@ namespace Barotrauma msg.ReadRangedSingle(-MaxVel, MaxVel, 12)); bool fixedRotation = msg.ReadBoolean(); - float rotation = AnimController.Collider.Rotation; - float angularVelocity = AnimController.Collider.AngularVelocity; + float? rotation = null; + float? angularVelocity = null; if (!fixedRotation) { rotation = msg.ReadFloat(); diff --git a/Barotrauma/BarotraumaClient/Source/Physics/PhysicsBody.cs b/Barotrauma/BarotraumaClient/Source/Physics/PhysicsBody.cs index 1fc27d949..f231c83a0 100644 --- a/Barotrauma/BarotraumaClient/Source/Physics/PhysicsBody.cs +++ b/Barotrauma/BarotraumaClient/Source/Physics/PhysicsBody.cs @@ -150,10 +150,10 @@ namespace Barotrauma float MaxAngularVel = NetConfig.MaxPhysicsBodyAngularVelocity; Vector2 newPosition = SimPosition; - float newRotation = Rotation; + float? newRotation = null; bool awake = body.Awake; Vector2 newVelocity = LinearVelocity; - float newAngularVelocity = AngularVelocity; + float? newAngularVelocity = null; newPosition = new Vector2( msg.ReadFloat(), @@ -179,12 +179,12 @@ namespace Barotrauma msg.ReadPadBits(); if (!MathUtils.IsValid(newPosition) || - !MathUtils.IsValid(newRotation) || !MathUtils.IsValid(newVelocity) || - !MathUtils.IsValid(newAngularVelocity)) + (newRotation.HasValue && !MathUtils.IsValid(newRotation.Value)) || + (newAngularVelocity.HasValue && !MathUtils.IsValid(newAngularVelocity.Value))) { string errorMsg = "Received invalid position data for \"" + parentDebugName - + "\" (position: " + newPosition + ", rotation: " + newRotation + ", velocity: " + newVelocity + ", angular velocity: " + newAngularVelocity + ")"; + + "\" (position: " + newPosition + ", rotation: " + (newRotation ?? 0) + ", velocity: " + newVelocity + ", angular velocity: " + (newAngularVelocity ?? 0) + ")"; #if DEBUG DebugConsole.ThrowError(errorMsg); #endif diff --git a/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs b/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs index 8e1165135..4ea71904f 100644 --- a/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs +++ b/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs @@ -43,6 +43,7 @@ namespace Barotrauma.Networking private IRestResponse masterServerResponse; private bool autoRestartTimerRunning; + private float endRoundTimer; public VoipServer VoipServer { @@ -405,20 +406,38 @@ namespace Barotrauma.Networking } } + if (isCrewDead && respawnManager == null) + { + if (endRoundTimer <= 0.0f) + { + SendChatMessage(TextManager.Get("CrewDeadNoRespawns").Replace("[time]", "60"), ChatMessageType.Server); + } + endRoundTimer += deltaTime; + } + else + { + endRoundTimer = 0.0f; + } + //restart if all characters are dead or submarine is at the end of the level if ((serverSettings.AutoRestart && isCrewDead) || - (serverSettings.EndRoundAtLevelEnd && subAtLevelEnd)) + (serverSettings.EndRoundAtLevelEnd && subAtLevelEnd) + || + (isCrewDead && respawnManager == null && endRoundTimer >= 60.0f)) { if (serverSettings.AutoRestart && isCrewDead) { Log("Ending round (entire crew dead)", ServerLog.MessageType.ServerMessage); } - else + else if (serverSettings.EndRoundAtLevelEnd && subAtLevelEnd) { Log("Ending round (submarine reached the end of the level)", ServerLog.MessageType.ServerMessage); } - + else + { + Log("Ending round (no living players left and respawning is not enabled during this round)", ServerLog.MessageType.ServerMessage); + } EndGame(); return; } @@ -1630,9 +1649,23 @@ namespace Barotrauma.Networking Rand.SetSyncedSeed(roundStartSeed); int teamCount = 1; - MultiPlayerCampaign campaign = GameMain.NetLobbyScreen.SelectedMode == GameMain.GameSession?.GameMode.Preset ? + MultiPlayerCampaign campaign = selectedMode == GameMain.GameSession?.GameMode.Preset ? GameMain.GameSession?.GameMode as MultiPlayerCampaign : null; + if (campaign != null && campaign.Map == null) + { + initiatedStartGame = false; + startGameCoroutine = null; + string errorMsg = "Starting the round failed. Campaign was still active, but the map has been disposed. Try selecting another game mode."; + DebugConsole.ThrowError(errorMsg); + GameAnalyticsManager.AddErrorEventOnce("GameServer.StartGame:InvalidCampaignState", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); + if (OwnerConnection != null) + { + SendDirectChatMessage(errorMsg, connectedClients.Find(c => c.Connection == OwnerConnection), ChatMessageType.Error); + } + yield return CoroutineStatus.Failure; + } + //don't instantiate a new gamesession if we're playing a campaign if (campaign == null || GameMain.GameSession == null) { @@ -1891,6 +1924,8 @@ namespace Barotrauma.Networking Mission mission = GameMain.GameSession.Mission; GameMain.GameSession.GameMode.End(endMessage); + + endRoundTimer = 0.0f; if (serverSettings.AutoRestart) { diff --git a/Barotrauma/BarotraumaServer/Source/Networking/GameServerLogin.cs b/Barotrauma/BarotraumaServer/Source/Networking/GameServerLogin.cs index fe0b66db2..630c09a08 100644 --- a/Barotrauma/BarotraumaServer/Source/Networking/GameServerLogin.cs +++ b/Barotrauma/BarotraumaServer/Source/Networking/GameServerLogin.cs @@ -158,7 +158,7 @@ namespace Barotrauma.Networking } //kick connected client if status becomes invalid (e.g. VAC banned, not connected to steam) - if (status != Facepunch.Steamworks.ServerAuth.Status.OK && GameMain.Config.RequireSteamAuthentication) + /*if (status != Facepunch.Steamworks.ServerAuth.Status.OK && GameMain.Config.RequireSteamAuthentication) { var connectedClient = connectedClients.Find(c => c.SteamID == ownerID); if (connectedClient != null) @@ -166,7 +166,7 @@ namespace Barotrauma.Networking Log("Disconnecting client " + connectedClient.Name + " (Steam ID: " + steamID + "). Steam authentication no longer valid (" + status + ").", ServerLog.MessageType.ServerMessage); KickClient(connectedClient, $"DisconnectMessage.SteamAuthNoLongerValid_[status]={status.ToString()}"); } - } + }*/ } private bool IsServerOwner(NetIncomingMessage inc, NetConnection senderConnection) diff --git a/Barotrauma/BarotraumaShared/Source/Characters/CharacterNetworking.cs b/Barotrauma/BarotraumaShared/Source/Characters/CharacterNetworking.cs index f0b5af9d2..500b69c5e 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/CharacterNetworking.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/CharacterNetworking.cs @@ -13,17 +13,17 @@ namespace Barotrauma public readonly AnimController.Animation Animation; - public CharacterStateInfo(Vector2 pos, float rotation, Vector2 velocity, float angularVelocity, float time, Direction dir, Entity interact, AnimController.Animation animation = AnimController.Animation.None) + public CharacterStateInfo(Vector2 pos, float? rotation, Vector2 velocity, float? angularVelocity, float time, Direction dir, Entity interact, AnimController.Animation animation = AnimController.Animation.None) : this(pos, rotation, velocity, angularVelocity, 0, time, dir, interact, animation) { } - public CharacterStateInfo(Vector2 pos, float rotation, UInt16 ID, Direction dir, Entity interact, AnimController.Animation animation = AnimController.Animation.None) + public CharacterStateInfo(Vector2 pos, float? rotation, UInt16 ID, Direction dir, Entity interact, AnimController.Animation animation = AnimController.Animation.None) : this(pos, rotation, Vector2.Zero, 0.0f, ID, 0.0f, dir, interact, animation) { } - protected CharacterStateInfo(Vector2 pos, float rotation, Vector2 velocity, float angularVelocity, UInt16 ID, float time, Direction dir, Entity interact, AnimController.Animation animation = AnimController.Animation.None) + protected CharacterStateInfo(Vector2 pos, float? rotation, Vector2 velocity, float? angularVelocity, UInt16 ID, float time, Direction dir, Entity interact, AnimController.Animation animation = AnimController.Animation.None) : base(pos, rotation, velocity, angularVelocity, ID, time) { Direction = dir; diff --git a/Barotrauma/BarotraumaShared/Source/Physics/PhysicsBody.cs b/Barotrauma/BarotraumaShared/Source/Physics/PhysicsBody.cs index 9e7228401..d87c6ab3b 100644 --- a/Barotrauma/BarotraumaShared/Source/Physics/PhysicsBody.cs +++ b/Barotrauma/BarotraumaShared/Source/Physics/PhysicsBody.cs @@ -18,7 +18,7 @@ namespace Barotrauma private set; } - public float Rotation + public float? Rotation { get; private set; @@ -30,7 +30,7 @@ namespace Barotrauma private set; } - public float AngularVelocity + public float? AngularVelocity { get; private set; @@ -39,17 +39,17 @@ namespace Barotrauma public readonly float Timestamp; public readonly UInt16 ID; - public PosInfo(Vector2 pos, float rotation, Vector2 linearVelocity, float angularVelocity, float time) + public PosInfo(Vector2 pos, float? rotation, Vector2 linearVelocity, float? angularVelocity, float time) : this(pos, rotation, linearVelocity, angularVelocity, 0, time) { } - public PosInfo(Vector2 pos, float rotation, Vector2 linearVelocity, float angularVelocity, UInt16 ID) + public PosInfo(Vector2 pos, float? rotation, Vector2 linearVelocity, float? angularVelocity, UInt16 ID) : this(pos, rotation, linearVelocity, angularVelocity, ID, 0.0f) { } - protected PosInfo(Vector2 pos, float rotation, Vector2 linearVelocity, float angularVelocity, UInt16 ID, float time) + protected PosInfo(Vector2 pos, float? rotation, Vector2 linearVelocity, float? angularVelocity, UInt16 ID, float time) { Position = pos; Rotation = rotation; @@ -775,8 +775,8 @@ namespace Barotrauma newVelocity = positionBuffer[0].LinearVelocity; newPosition = positionBuffer[0].Position; - newRotation = positionBuffer[0].Rotation; - newAngularVelocity = positionBuffer[0].AngularVelocity; + newRotation = positionBuffer[0].Rotation ?? Rotation; + newAngularVelocity = positionBuffer[0].AngularVelocity ?? AngularVelocity; positionBuffer.RemoveAt(0); }