4d2bcb1...1473f77
commit 1473f77ba0c85b80d48dce3e0fca809a9d5da98c Author: Joonas Rikkonen <poe.regalis@gmail.com> 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 <poe.regalis@gmail.com> 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 <poe.regalis@gmail.com> 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 <poe.regalis@gmail.com> 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.
This commit is contained in:
@@ -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++)
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user