Merge remote-tracking branch 'upstream/master' into develop

This commit is contained in:
EvilFactory
2024-12-11 10:44:53 -03:00
257 changed files with 4793 additions and 1653 deletions
@@ -519,10 +519,12 @@ namespace Barotrauma.Networking
{
string errorMsg = "Error while reading a message from server. ";
if (GameMain.Client == null) { errorMsg += "Client disposed."; }
AppendExceptionInfo(ref errorMsg, e);
GameAnalyticsManager.AddErrorEventOnce("GameClient.Update:CheckServerMessagesException" + e.TargetSite.ToString(), GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
DebugConsole.ThrowError(errorMsg);
new GUIMessageBox(TextManager.Get("Error"), TextManager.GetWithVariables("MessageReadError", ("[message]", e.Message), ("[targetsite]", e.TargetSite.ToString())))
AppendExceptionInfo(ref errorMsg, out Entity causingEntity, e);
string targetSite = e.TargetSite?.ToString() ?? "unknown";
GameAnalyticsManager.AddErrorEventOnce("GameClient.Update:CheckServerMessagesException" + targetSite, GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
DebugConsole.ThrowError(errorMsg, contentPackage: causingEntity?.ContentPackage);
new GUIMessageBox(TextManager.Get("Error"), TextManager.GetWithVariables("MessageReadError", ("[message]", e.Message), ("[targetsite]", targetSite)))
{
DisplayInLoadingScreens = true
};
@@ -664,7 +666,7 @@ namespace Barotrauma.Networking
catch (Exception e)
{
string errorMsg = "Error while reading an ingame update message from server.";
AppendExceptionInfo(ref errorMsg, e);
AppendExceptionInfo(ref errorMsg, out Entity causingEntity, e);
GameAnalyticsManager.AddErrorEventOnce("GameClient.ReadDataMessage:ReadIngameUpdate", GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
throw;
}
@@ -988,13 +990,15 @@ namespace Barotrauma.Networking
{
if (Level.Loaded.EqualityCheckValues[stage] != levelEqualityCheckValues[stage])
{
string errorMsg = "Level equality check failed. The level generated at your end doesn't match the level generated by the server" +
" (client value " + stage + ": " + Level.Loaded.EqualityCheckValues[stage].ToString("X") +
", server value " + stage + ": " + levelEqualityCheckValues[stage].ToString("X") +
", level value count: " + levelEqualityCheckValues.Count +
", seed: " + Level.Loaded.Seed +
", sub: " + (Submarine.MainSub == null ? "null" : (Submarine.MainSub.Info.Name + " (" + Submarine.MainSub.Info.MD5Hash.ShortRepresentation + ")")) +
", mirrored: " + Level.Loaded.Mirrored + "). Round init status: " + roundInitStatus + "." + campaignErrorInfo;
string errorMsg = "Level equality check failed. The level generated at your end doesn't match the level generated by the server, " +
$"(client value {stage}:{Level.Loaded.EqualityCheckValues[stage].ToString("X")}, " +
$"server value {stage}: {levelEqualityCheckValues[stage].ToString("X")}, " +
$"level value count: {levelEqualityCheckValues.Count}, " +
$"seed: {Level.Loaded.Seed}, " +
$"missions: {string.Join(", ", GameMain.GameSession.GameMode.Missions.Select(m => m.Prefab.Identifier))}, " +
$"sub: {(Submarine.MainSub == null ? "null" : (Submarine.MainSub.Info.Name + " (" + Submarine.MainSub.Info.MD5Hash.ShortRepresentation))}, " +
$"mirrored: {Level.Loaded.Mirrored}). Round init status: {roundInitStatus}." +
campaignErrorInfo;
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:LevelsDontMatch" + Level.Loaded.Seed, GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
throw new Exception(errorMsg);
}
@@ -1472,6 +1476,7 @@ namespace Barotrauma.Networking
{
string levelSeed = inc.ReadString();
float levelDifficulty = inc.ReadSingle();
Identifier biomeId = inc.ReadIdentifier();
string subName = inc.ReadString();
string subHash = inc.ReadString();
string shuttleName = inc.ReadString();
@@ -1559,7 +1564,7 @@ namespace Barotrauma.Networking
var selectedEnemySub = hasEnemySub && GameMain.NetLobbyScreen.SelectedEnemySub is { } enemySub ? Option.Some(enemySub) : Option.None;
GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedSub, selectedEnemySub, gameMode, missionPrefabs: selectedMissions);
GameMain.GameSession.StartRound(levelSeed, levelDifficulty, levelGenerationParams: null, forceBiome: ServerSettings.Biome);
GameMain.GameSession.StartRound(levelSeed, levelDifficulty, levelGenerationParams: null, forceBiome: biomeId);
}
else
{
@@ -2077,16 +2082,15 @@ namespace Barotrauma.Networking
UInt16 updateID = inc.ReadUInt16();
UInt16 settingsLen = inc.ReadUInt16();
byte[] settingsData = inc.ReadBytes(settingsLen);
bool isInitialUpdate = inc.ReadBoolean();
DebugConsole.Log($"Received {(isInitialUpdate ? "initial" : string.Empty)} lobby update ID: {updateID}, last ID: {GameMain.NetLobbyScreen.LastUpdateID}.");
if (isInitialUpdate)
{
if (GameSettings.CurrentConfig.VerboseLogging)
{
DebugConsole.NewMessage("Received initial lobby update, ID: " + updateID + ", last ID: " + GameMain.NetLobbyScreen.LastUpdateID, Color.Gray);
}
{
ReadInitialUpdate(inc);
initialUpdateReceived = true;
}
@@ -2365,7 +2369,7 @@ namespace Barotrauma.Networking
GameAnalyticsManager.AddErrorEventOnce("GameClient.ReadInGameUpdate", GameAnalyticsManager.ErrorSeverity.Critical, string.Join("\n", errorLines));
throw new Exception(
$"Exception thrown while reading segment {segment.Identifier} at position {segment.Pointer}." +
$"Exception thrown while reading a message of the type \"{segment.Identifier}\" at position {segment.Pointer}." +
(prevSegments.Any() ? $" Previous segments: {string.Join(", ", prevSegments)}" : ""),
ex);
});
@@ -3767,16 +3771,24 @@ namespace Barotrauma.Networking
eventErrorWritten = true;
}
private static void AppendExceptionInfo(ref string errorMsg, Exception e)
private static void AppendExceptionInfo(ref string errorMsg, out Entity causingEntity, Exception e)
{
if (!errorMsg.EndsWith("\n")) { errorMsg += "\n"; }
Exception innerMostException = e.GetInnermost();
causingEntity = GetCausingEntity(e);
if (causingEntity != null)
{
errorMsg += "Entity: " + causingEntity + "\n";
}
errorMsg += e.Message + "\n";
var innermostException = e.GetInnermost();
if (innermostException != e)
if (innerMostException != e)
{
// If available, only append the stacktrace of the innermost exception,
// because that's the most important one to fix
errorMsg += "Inner exception: " + innermostException.Message + "\n" + innermostException.StackTrace.CleanupStackTrace();
errorMsg += "Inner exception: " + innerMostException.Message + "\n" + innerMostException.StackTrace.CleanupStackTrace();
}
else
{
@@ -3784,6 +3796,24 @@ namespace Barotrauma.Networking
}
}
/// <summary>
/// Checks if the exception or any of its inner exceptions are EntityEventExceptions, and returns the entity that caused the innermost EntityEventException.
/// </summary>
private static Entity GetCausingEntity(Exception e)
{
Entity causingEntity = null;
Exception currentException = e;
while (currentException != null)
{
if (currentException is EntityEventException entityEventException)
{
causingEntity = entityEventException.Entity;
}
currentException = currentException.InnerException;
}
return causingEntity;
}
#if DEBUG
public void ForceTimeOut()
{