static void Main(string[] args) { #if !DEBUG AppDomain currentDomain = AppDomain.CurrentDomain; currentDomain.UnhandledException += new UnhandledExceptionEventHandler(CrashHandler); #endif #if LINUX setLinuxEnv(); #endif Console.WriteLine("Barotrauma Dedicated Server " + GameMain.Version + " (" + AssemblyInfo.GetBuildString() + ", branch " + AssemblyInfo.GetGitBranch() + ", revision " + AssemblyInfo.GetGitRevision() + ")"); Game = new GameMain(args); Game.Run(); if (GameSettings.SendUserStatistics) { GameAnalytics.OnQuit(); } SteamManager.ShutDown(); }
static void CrashDump(string filePath, Exception exception) { try { GameMain.Server?.ServerSettings?.SaveSettings(); GameMain.Server?.ServerSettings?.BanList.Save(); if (GameMain.Server?.ServerSettings?.KarmaPreset == "custom") { GameMain.Server?.KarmaManager?.SaveCustomPreset(); GameMain.Server?.KarmaManager?.Save(); } } catch (Exception e) { //couldn't save, whatever } int existingFiles = 0; string originalFilePath = filePath; while (File.Exists(filePath)) { existingFiles++; filePath = Path.GetFileNameWithoutExtension(originalFilePath) + " (" + (existingFiles + 1) + ")" + Path.GetExtension(originalFilePath); } StringBuilder sb = new StringBuilder(); sb.AppendLine("Barotrauma Dedicated Server crash report (generated on " + DateTime.Now + ")"); sb.AppendLine("\n"); sb.AppendLine("Barotrauma seems to have crashed. Sorry for the inconvenience! "); sb.AppendLine("\n"); sb.AppendLine("Game version " + GameMain.Version + " (" + AssemblyInfo.GetBuildString() + ", branch " + AssemblyInfo.GetGitBranch() + ", revision " + AssemblyInfo.GetGitRevision() + ")"); if (GameMain.Config != null) { sb.AppendLine("Language: " + (GameMain.Config.Language ?? "none")); } if (GameMain.Config.AllEnabledPackages != null) { sb.AppendLine("Selected content packages: " + (!GameMain.Config.AllEnabledPackages.Any() ? "None" : string.Join(", ", GameMain.Config.AllEnabledPackages.Select(c => c.Name)))); } sb.AppendLine("Level seed: " + ((Level.Loaded == null) ? "no level loaded" : Level.Loaded.Seed)); sb.AppendLine("Loaded submarine: " + ((Submarine.MainSub == null) ? "None" : Submarine.MainSub.Info.Name + " (" + Submarine.MainSub.Info.MD5Hash + ")")); sb.AppendLine("Selected screen: " + (Screen.Selected == null ? "None" : Screen.Selected.ToString())); if (GameMain.Server != null) { sb.AppendLine("Server (" + (GameMain.Server.GameStarted ? "Round had started)" : "Round hadn't been started)")); } sb.AppendLine("\n"); sb.AppendLine("System info:"); sb.AppendLine(" Operating system: " + System.Environment.OSVersion + (System.Environment.Is64BitOperatingSystem ? " 64 bit" : " x86")); sb.AppendLine("\n"); sb.AppendLine("Exception: " + exception.Message + " (" + exception.GetType().ToString() + ")"); sb.AppendLine("Target site: " + exception.TargetSite.ToString()); sb.AppendLine("Stack trace: "); sb.AppendLine(exception.StackTrace); sb.AppendLine("\n"); if (exception.InnerException != null) { sb.AppendLine("InnerException: " + exception.InnerException.Message); if (exception.InnerException.TargetSite != null) { sb.AppendLine("Target site: " + exception.InnerException.TargetSite.ToString()); } sb.AppendLine("Stack trace: "); sb.AppendLine(exception.InnerException.StackTrace); } sb.AppendLine("Last debug messages:"); DebugConsole.Clear(); for (int i = DebugConsole.Messages.Count - 1; i > 0 && i > DebugConsole.Messages.Count - 15; i--) { sb.AppendLine(" " + DebugConsole.Messages[i].Time + " - " + DebugConsole.Messages[i].Text); } string crashReport = sb.ToString(); Console.ForegroundColor = ConsoleColor.Red; Console.Write(crashReport); File.WriteAllText(filePath, sb.ToString()); if (GameSettings.SendUserStatistics) { GameAnalytics.AddErrorEvent(EGAErrorSeverity.Critical, crashReport); GameAnalytics.OnQuit(); Console.Write("A crash report (\"servercrashreport.log\") was saved in the root folder of the game and sent to the developers."); } else { Console.Write("A crash report(\"servercrashreport.log\") was saved in the root folder of the game. The error was not sent to the developers because user statistics have been disabled, but" + " if you'd like to help fix this bug, you may post it on Barotrauma's GitHub issue tracker: https://github.com/Regalis11/Barotrauma/issues/"); } SteamManager.ShutDown(); }
static void CrashDump(GameMain game, string filePath, Exception exception) { int existingFiles = 0; string originalFilePath = filePath; while (File.Exists(filePath)) { existingFiles++; filePath = Path.GetFileNameWithoutExtension(originalFilePath) + " (" + (existingFiles + 1) + ")" + Path.GetExtension(originalFilePath); } DebugConsole.DequeueMessages(); Md5Hash exeHash = null; try { string exePath = System.Reflection.Assembly.GetEntryAssembly().Location; var md5 = System.Security.Cryptography.MD5.Create(); byte[] exeBytes = File.ReadAllBytes(exePath); exeHash = new Md5Hash(exeBytes); } catch { //do nothing, generate the rest of the crash report } StringBuilder sb = new StringBuilder(); sb.AppendLine("Barotrauma Client crash report (generated on " + DateTime.Now + ")"); sb.AppendLine("\n"); sb.AppendLine("Barotrauma seems to have crashed. Sorry for the inconvenience! "); sb.AppendLine("\n"); try { if (exception is GameMain.LoadingException) { //exception occurred in loading screen: //assume content packages are the culprit and reset them XDocument doc = XMLExtensions.TryLoadXml(GameSettings.PlayerSavePath); XDocument baseDoc = XMLExtensions.TryLoadXml(GameSettings.SavePath); if (doc != null && baseDoc != null) { XElement newElement = new XElement(doc.Root.Name); newElement.Add(doc.Root.Attributes()); newElement.Add(doc.Root.Elements().Where(e => !e.Name.LocalName.Equals("contentpackage", StringComparison.InvariantCultureIgnoreCase))); newElement.Add(baseDoc.Root.Elements().Where(e => e.Name.LocalName.Equals("contentpackage", StringComparison.InvariantCultureIgnoreCase))); XDocument newDoc = new XDocument(newElement); newDoc.Save(GameSettings.PlayerSavePath); sb.AppendLine("To prevent further startup errors, installed mods will be disabled the next time you launch the game."); sb.AppendLine("\n"); } } } catch { //welp i guess we couldn't reset the config! } if (exeHash?.Hash != null) { sb.AppendLine(exeHash.Hash); } sb.AppendLine("\n"); sb.AppendLine("Game version " + GameMain.Version + " (" + AssemblyInfo.GetBuildString() + ", branch " + AssemblyInfo.GetGitBranch() + ", revision " + AssemblyInfo.GetGitRevision() + ")"); if (GameMain.Config != null) { sb.AppendLine("Graphics mode: " + GameMain.Config.GraphicsWidth + "x" + GameMain.Config.GraphicsHeight + " (" + GameMain.Config.WindowMode.ToString() + ")"); sb.AppendLine("VSync " + (GameMain.Config.VSyncEnabled ? "ON" : "OFF")); sb.AppendLine("Language: " + (GameMain.Config.Language ?? "none")); } if (GameMain.Config.AllEnabledPackages != null) { sb.AppendLine("Selected content packages: " + (!GameMain.Config.AllEnabledPackages.Any() ? "None" : string.Join(", ", GameMain.Config.AllEnabledPackages.Select(c => c.Name)))); } sb.AppendLine("Level seed: " + ((Level.Loaded == null) ? "no level loaded" : Level.Loaded.Seed)); sb.AppendLine("Loaded submarine: " + ((Submarine.MainSub == null) ? "None" : Submarine.MainSub.Info.Name + " (" + Submarine.MainSub.Info.MD5Hash + ")")); sb.AppendLine("Selected screen: " + (Screen.Selected == null ? "None" : Screen.Selected.ToString())); if (SteamManager.IsInitialized) { sb.AppendLine("SteamManager initialized"); } if (GameMain.Client != null) { sb.AppendLine("Client (" + (GameMain.Client.GameStarted ? "Round had started)" : "Round hadn't been started)")); } sb.AppendLine("\n"); sb.AppendLine("System info:"); sb.AppendLine(" Operating system: " + System.Environment.OSVersion + (System.Environment.Is64BitOperatingSystem ? " 64 bit" : " x86")); if (game == null) { sb.AppendLine(" Game not initialized"); } else { if (game.GraphicsDevice == null) { sb.AppendLine(" Graphics device not set"); } else { if (game.GraphicsDevice.Adapter == null) { sb.AppendLine(" Graphics adapter not set"); } else { sb.AppendLine(" GPU name: " + game.GraphicsDevice.Adapter.Description); sb.AppendLine(" Display mode: " + game.GraphicsDevice.Adapter.CurrentDisplayMode); } sb.AppendLine(" GPU status: " + game.GraphicsDevice.GraphicsDeviceStatus); } } sb.AppendLine("\n"); sb.AppendLine("Exception: " + exception.Message + " (" + exception.GetType().ToString() + ")"); #if WINDOWS if (exception is SharpDXException sharpDxException && ((uint)sharpDxException.HResult) == 0x887A0005) { var dxDevice = (SharpDX.Direct3D11.Device)game.GraphicsDevice.Handle; sb.AppendLine("Device removed reason: " + dxDevice.DeviceRemovedReason.ToString()); } #endif if (exception.TargetSite != null) { sb.AppendLine("Target site: " + exception.TargetSite.ToString()); } sb.AppendLine("Stack trace: "); sb.AppendLine(exception.StackTrace); sb.AppendLine("\n"); if (exception.InnerException != null) { sb.AppendLine("InnerException: " + exception.InnerException.Message); if (exception.InnerException.TargetSite != null) { sb.AppendLine("Target site: " + exception.InnerException.TargetSite.ToString()); } sb.AppendLine("Stack trace: "); sb.AppendLine(exception.InnerException.StackTrace); } sb.AppendLine("Last debug messages:"); for (int i = DebugConsole.Messages.Count - 1; i >= 0; i--) { sb.AppendLine("[" + DebugConsole.Messages[i].Time + "] " + DebugConsole.Messages[i].Text); } string crashReport = sb.ToString(); File.WriteAllText(filePath, crashReport); if (GameSettings.SaveDebugConsoleLogs) { DebugConsole.SaveLogs(); } if (GameSettings.SendUserStatistics) { CrashMessageBox("A crash report (\"" + filePath + "\") was saved in the root folder of the game and sent to the developers.", filePath); GameAnalytics.AddErrorEvent(EGAErrorSeverity.Critical, crashReport); GameAnalytics.OnQuit(); } else { CrashMessageBox("A crash report (\"" + filePath + "\") was saved in the root folder of the game. The error was not sent to the developers because user statistics have been disabled, but" + " if you'd like to help fix this bug, you may post it on Barotrauma's GitHub issue tracker: https://github.com/Regalis11/Barotrauma/issues/", filePath); } }