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); }