Beispiel #1
0
        public MainMenuScreen(GameMain game)
        {
            menuTabs = new GUIFrame[Enum.GetValues(typeof(Tab)).Length + 1];

            buttonsTab         = new GUIFrame(new Rectangle(0, 0, 0, 0), Color.Transparent, Alignment.Left | Alignment.CenterY);
            buttonsTab.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);

            int y = (int)(GameMain.GraphicsHeight * 0.3f);

            Rectangle panelRect = new Rectangle(
                290, y,
                500, 360);

            GUIButton button = new GUIButton(new Rectangle(50, y, 200, 30), TextManager.Get("TutorialButton"), null, Alignment.TopLeft, Alignment.Left, "", buttonsTab);

            button.Color     = button.Color * 0.8f;
            button.OnClicked = TutorialButtonClicked;

            button           = new GUIButton(new Rectangle(50, y + 60, 200, 30), TextManager.Get("NewGameButton"), null, Alignment.TopLeft, Alignment.Left, "", buttonsTab);
            button.Color     = button.Color * 0.8f;
            button.UserData  = Tab.NewGame;
            button.OnClicked = SelectTab;

            button           = new GUIButton(new Rectangle(50, y + 100, 200, 30), TextManager.Get("LoadGameButton"), null, Alignment.TopLeft, Alignment.Left, "", buttonsTab);
            button.Color     = button.Color * 0.8f;
            button.UserData  = Tab.LoadGame;
            button.OnClicked = SelectTab;

            button       = new GUIButton(new Rectangle(50, y + 160, 200, 30), TextManager.Get("JoinServerButton"), null, Alignment.TopLeft, Alignment.Left, "", buttonsTab);
            button.Color = button.Color * 0.8f;
            //button.UserData = (int)Tabs.JoinServer;
            button.OnClicked = JoinServerClicked;

            button           = new GUIButton(new Rectangle(50, y + 200, 200, 30), TextManager.Get("HostServerButton"), null, Alignment.TopLeft, Alignment.Left, "", buttonsTab);
            button.Color     = button.Color * 0.8f;
            button.UserData  = Tab.HostServer;
            button.OnClicked = SelectTab;

            button           = new GUIButton(new Rectangle(50, y + 260, 200, 30), TextManager.Get("SubEditorButton"), null, Alignment.TopLeft, Alignment.Left, "", buttonsTab);
            button.Color     = button.Color * 0.8f;
            button.OnClicked = (GUIButton btn, object userdata) => { GameMain.SubEditorScreen.Select(); return(true); };

            button           = new GUIButton(new Rectangle(50, y + 320, 200, 30), TextManager.Get("SettingsButton"), null, Alignment.TopLeft, Alignment.Left, "", buttonsTab);
            button.Color     = button.Color * 0.8f;
            button.UserData  = Tab.Settings;
            button.OnClicked = SelectTab;

            button           = new GUIButton(new Rectangle(0, 0, 150, 30), TextManager.Get("QuitButton"), Alignment.BottomRight, "", buttonsTab);
            button.Color     = button.Color * 0.8f;
            button.OnClicked = QuitClicked;

            panelRect.Y += 10;

            //----------------------------------------------------------------------

            menuTabs[(int)Tab.NewGame]         = new GUIFrame(panelRect, "");
            menuTabs[(int)Tab.NewGame].Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);

            menuTabs[(int)Tab.LoadGame] = new GUIFrame(panelRect, "");

            campaignSetupUI              = new CampaignSetupUI(false, menuTabs[(int)Tab.NewGame], menuTabs[(int)Tab.LoadGame]);
            campaignSetupUI.LoadGame     = LoadGame;
            campaignSetupUI.StartNewGame = StartGame;

            //----------------------------------------------------------------------

            menuTabs[(int)Tab.HostServer] = new GUIFrame(panelRect, "");

            new GUITextBlock(new Rectangle(0, 0, 100, 30), TextManager.Get("ServerName"), "", Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tab.HostServer]);
            serverNameBox = new GUITextBox(new Rectangle(160, 0, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, "", menuTabs[(int)Tab.HostServer]);

            new GUITextBlock(new Rectangle(0, 50, 100, 30), TextManager.Get("ServerPort"), "", Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tab.HostServer]);
            portBox         = new GUITextBox(new Rectangle(160, 50, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, "", menuTabs[(int)Tab.HostServer]);
            portBox.Text    = NetConfig.DefaultPort.ToString();
            portBox.ToolTip = "Server port";

            new GUITextBlock(new Rectangle(0, 100, 100, 30), TextManager.Get("MaxPlayers"), "", Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tab.HostServer]);
            maxPlayersBox         = new GUITextBox(new Rectangle(195, 100, 30, 30), null, null, Alignment.TopLeft, Alignment.Center, "", menuTabs[(int)Tab.HostServer]);
            maxPlayersBox.Text    = "8";
            maxPlayersBox.Enabled = false;

            var minusPlayersBox = new GUIButton(new Rectangle(160, 100, 30, 30), "-", "", menuTabs[(int)Tab.HostServer]);

            minusPlayersBox.UserData  = -1;
            minusPlayersBox.OnClicked = ChangeMaxPlayers;

            var plusPlayersBox = new GUIButton(new Rectangle(230, 100, 30, 30), "+", "", menuTabs[(int)Tab.HostServer]);

            plusPlayersBox.UserData  = 1;
            plusPlayersBox.OnClicked = ChangeMaxPlayers;

            new GUITextBlock(new Rectangle(0, 150, 100, 30), TextManager.Get("Password"), "", Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tab.HostServer]);
            passwordBox = new GUITextBox(new Rectangle(160, 150, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, "", menuTabs[(int)Tab.HostServer]);

            isPublicBox         = new GUITickBox(new Rectangle(10, 200, 20, 20), TextManager.Get("PublicServer"), Alignment.TopLeft, menuTabs[(int)Tab.HostServer]);
            isPublicBox.ToolTip = TextManager.Get("PublicServerToolTip");

            useUpnpBox         = new GUITickBox(new Rectangle(10, 250, 20, 20), TextManager.Get("AttemptUPnP"), Alignment.TopLeft, menuTabs[(int)Tab.HostServer]);
            useUpnpBox.ToolTip = TextManager.Get("AttemptUPnPToolTip");

            GUIButton hostButton = new GUIButton(new Rectangle(0, 0, 100, 30), TextManager.Get("StartServerButton"), Alignment.BottomRight, "", menuTabs[(int)Tab.HostServer]);

            hostButton.OnClicked = HostServerClicked;

            this.game = game;
        }
Beispiel #2
0
        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();

            StreamWriter sw = new StreamWriter(filePath);

            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");
#if DEBUG
            sb.AppendLine("Game version " + GameMain.Version + " (debug build)");
#else
            sb.AppendLine("Game version " + GameMain.Version);
#endif
            if (GameMain.Config != null)
            {
                sb.AppendLine("Graphics mode: " + GameMain.Config.GraphicsWidth + "x" + GameMain.Config.GraphicsHeight + " (" + GameMain.Config.WindowMode.ToString() + ")");
            }
            if (GameMain.SelectedPackages != null)
            {
                sb.AppendLine("Selected content packages: " + (!GameMain.SelectedPackages.Any() ? "None" : string.Join(", ", GameMain.SelectedPackages.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.Name + " (" + Submarine.MainSub.MD5Hash + ")"));
            sb.AppendLine("Selected screen: " + (Screen.Selected == null ? "None" : Screen.Selected.ToString()));

            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);
            if (exception.TargetSite != null)
            {
                sb.AppendLine("Target site: " + exception.TargetSite.ToString());
            }
            sb.AppendLine("Stack trace: ");
            sb.AppendLine(exception.StackTrace);
            sb.AppendLine("\n");

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

            sw.WriteLine(crashReport);
            sw.Close();

            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.");
                GameAnalytics.AddErrorEvent(EGAErrorSeverity.Critical, crashReport);
                GameAnalytics.OnStop();
            }
            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/");
            }
        }
Beispiel #3
0
        public static void Update(GameMain game, float deltaTime)
        {
            lock (queuedMessages)
            {
                while (queuedMessages.Count > 0)
                {
                    var newMsg = queuedMessages.Dequeue();
                    AddMessage(newMsg);

                    if (GameSettings.SaveDebugConsoleLogs)
                    {
                        unsavedMessages.Add(newMsg);
                        if (unsavedMessages.Count >= messagesPerFile)
                        {
                            SaveLogs();
                            unsavedMessages.Clear();
                        }
                    }
                }
            }

            if (activeQuestionText != null &&
                (listBox.children.Count == 0 || listBox.children[listBox.children.Count - 1] != activeQuestionText))
            {
                listBox.children.Remove(activeQuestionText);
                listBox.children.Add(activeQuestionText);
            }

            if (PlayerInput.KeyHit(Keys.F3))
            {
                isOpen = !isOpen;
                if (isOpen)
                {
                    textBox.Select();
                    AddToGUIUpdateList();
                }
                else
                {
                    GUIComponent.ForceMouseOn(null);
                    textBox.Deselect();
                }
            }

            if (isOpen)
            {
                frame.Update(deltaTime);

                Character.DisableControls = true;

                if (PlayerInput.KeyHit(Keys.Up))
                {
                    textBox.Text = SelectMessage(-1);
                }
                else if (PlayerInput.KeyHit(Keys.Down))
                {
                    textBox.Text = SelectMessage(1);
                }
                else if (PlayerInput.KeyHit(Keys.Tab))
                {
                    textBox.Text = AutoComplete(textBox.Text);
                }

                if (PlayerInput.KeyHit(Keys.Enter))
                {
                    ExecuteCommand(textBox.Text);
                    textBox.Text = "";
                }
            }
        }
        public MainMenuScreen(GameMain game)
        {
            backgroundVignette = new Sprite("Content/UI/MainMenuVignette.png", Vector2.Zero);

            new GUIImage(new RectTransform(new Vector2(0.4f, 0.25f), Frame.RectTransform, Anchor.BottomRight)
            {
                RelativeOffset = new Vector2(0.08f, 0.05f), AbsoluteOffset = new Point(-8, -8)
            },
                         style: "TitleText")
            {
                Color        = Color.Black * 0.5f,
                CanBeFocused = false
            };
            titleText = new GUIImage(new RectTransform(new Vector2(0.4f, 0.25f), Frame.RectTransform, Anchor.BottomRight)
            {
                RelativeOffset = new Vector2(0.08f, 0.05f)
            },
                                     style: "TitleText");

            buttonsParent = new GUILayoutGroup(new RectTransform(new Vector2(0.3f, 0.85f), parent: Frame.RectTransform, anchor: Anchor.CenterLeft)
            {
                AbsoluteOffset = new Point(50, 0)
            })
            {
                Stretch         = true,
                RelativeSpacing = 0.02f
            };

            // === CAMPAIGN
            var campaignHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 1.0f), parent: buttonsParent.RectTransform)
            {
                RelativeOffset = new Vector2(0.1f, 0.0f)
            }, isHorizontal: true);

            new GUIImage(new RectTransform(new Vector2(0.2f, 0.7f), campaignHolder.RectTransform), "MainMenuCampaignIcon")
            {
                CanBeFocused = false
            };

            //spacing
            new GUIFrame(new RectTransform(new Vector2(0.02f, 0.0f), campaignHolder.RectTransform), style: null);

            var campaignNavigation = new GUILayoutGroup(new RectTransform(new Vector2(0.75f, 0.75f), parent: campaignHolder.RectTransform)
            {
                RelativeOffset = new Vector2(0.0f, 0.25f)
            });

            new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), campaignNavigation.RectTransform),
                             TextManager.Get("CampaignLabel"), textAlignment: Alignment.Left, font: GUI.LargeFont, textColor: Color.Black, style: "MainMenuGUITextBlock")
            {
                ForceUpperCase = true
            };

            var campaignButtons = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), parent: campaignNavigation.RectTransform), style: "MainMenuGUIFrame");

            var campaignList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.2f), parent: campaignButtons.RectTransform))
            {
                Stretch         = false,
                RelativeSpacing = 0.035f
            };

            new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), campaignList.RectTransform), TextManager.Get("TutorialButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
            {
                ForceUpperCase = true,
                UserData       = Tab.Tutorials,
                OnClicked      = (tb, userdata) =>
                {
                    SelectTab(tb, userdata);
                    return(true);
                }
            };

            new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), campaignList.RectTransform), TextManager.Get("LoadGameButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
            {
                ForceUpperCase = true,
                UserData       = Tab.LoadGame,
                OnClicked      = (tb, userdata) =>
                {
                    SelectTab(tb, userdata);
                    return(true);
                }
            };

            new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), campaignList.RectTransform), TextManager.Get("NewGameButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
            {
                ForceUpperCase = true,
                UserData       = Tab.NewGame,
                OnClicked      = (tb, userdata) =>
                {
                    SelectTab(tb, userdata);
                    return(true);
                }
            };

            // === MULTIPLAYER
            var multiplayerHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 1.0f), parent: buttonsParent.RectTransform)
            {
                RelativeOffset = new Vector2(0.05f, 0.0f)
            }, isHorizontal: true);

            new GUIImage(new RectTransform(new Vector2(0.2f, 0.7f), multiplayerHolder.RectTransform), "MainMenuMultiplayerIcon")
            {
                CanBeFocused = false
            };

            //spacing
            new GUIFrame(new RectTransform(new Vector2(0.02f, 0.0f), multiplayerHolder.RectTransform), style: null);

            var multiplayerNavigation = new GUILayoutGroup(new RectTransform(new Vector2(0.75f, 0.75f), parent: multiplayerHolder.RectTransform)
            {
                RelativeOffset = new Vector2(0.0f, 0.25f)
            });

            new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), multiplayerNavigation.RectTransform),
                             TextManager.Get("MultiplayerLabel"), textAlignment: Alignment.Left, font: GUI.LargeFont, textColor: Color.Black, style: "MainMenuGUITextBlock")
            {
                ForceUpperCase = true
            };

            var multiplayerButtons = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), parent: multiplayerNavigation.RectTransform), style: "MainMenuGUIFrame");

            var multiplayerList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.2f), parent: multiplayerButtons.RectTransform))
            {
                Stretch         = false,
                RelativeSpacing = 0.035f
            };

            joinServerButton = new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), multiplayerList.RectTransform), TextManager.Get("JoinServerButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
            {
                ForceUpperCase = true,
                UserData       = Tab.JoinServer,
                OnClicked      = (tb, userdata) =>
                {
                    SelectTab(tb, userdata);
                    return(true);
                }
            };
            hostServerButton = new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), multiplayerList.RectTransform), TextManager.Get("HostServerButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
            {
                ForceUpperCase = true,
                UserData       = Tab.HostServer,
                OnClicked      = (tb, userdata) =>
                {
                    SelectTab(tb, userdata);
                    return(true);
                }
            };

            // === CUSTOMIZE
            var customizeHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 1.0f), parent: buttonsParent.RectTransform)
            {
                RelativeOffset = new Vector2(0.15f, 0.0f)
            }, isHorizontal: true);

            new GUIImage(new RectTransform(new Vector2(0.2f, 0.7f), customizeHolder.RectTransform), "MainMenuCustomizeIcon")
            {
                CanBeFocused = false
            };

            //spacing
            new GUIFrame(new RectTransform(new Vector2(0.02f, 0.0f), customizeHolder.RectTransform), style: null);

            var customizeNavigation = new GUILayoutGroup(new RectTransform(new Vector2(0.75f, 0.75f), parent: customizeHolder.RectTransform)
            {
                RelativeOffset = new Vector2(0.0f, 0.25f)
            });

            new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), customizeNavigation.RectTransform),
                             TextManager.Get("CustomizeLabel"), textAlignment: Alignment.Left, font: GUI.LargeFont, textColor: Color.Black, style: "MainMenuGUITextBlock")
            {
                ForceUpperCase = true
            };

            var customizeButtons = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), parent: customizeNavigation.RectTransform), style: "MainMenuGUIFrame");

            var customizeList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.2f), parent: customizeButtons.RectTransform))
            {
                Stretch         = false,
                RelativeSpacing = 0.035f
            };

            if (Steam.SteamManager.USE_STEAM)
            {
                steamWorkshopButton = new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), customizeList.RectTransform), TextManager.Get("SteamWorkshopButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
                {
                    ForceUpperCase = true,
                    Enabled        = false,
                    UserData       = Tab.SteamWorkshop,
                    OnClicked      = SelectTab
                };

/*#if OSX && !DEBUG
 *              steamWorkshopButton.Text += " (Not yet available on MacOS)";
 #endif*/
            }

            new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), customizeList.RectTransform), TextManager.Get("SubEditorButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
            {
                ForceUpperCase = true,
                UserData       = Tab.SubmarineEditor,
                OnClicked      = (tb, userdata) =>
                {
                    SelectTab(tb, userdata);
                    return(true);
                }
            };

            new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), customizeList.RectTransform), TextManager.Get("CharacterEditorButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
            {
                ForceUpperCase = true,
                UserData       = Tab.CharacterEditor,
                OnClicked      = (tb, userdata) =>
                {
                    SelectTab(tb, userdata);
                    return(true);
                }
            };

            // === OPTION
            var optionHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.8f), parent: buttonsParent.RectTransform), isHorizontal: true);

            new GUIImage(new RectTransform(new Vector2(0.15f, 0.6f), optionHolder.RectTransform), "MainMenuOptionIcon")
            {
                CanBeFocused = false
            };

            //spacing
            new GUIFrame(new RectTransform(new Vector2(0.01f, 0.0f), optionHolder.RectTransform), style: null);

            var optionButtons = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 1.0f), parent: optionHolder.RectTransform)
            {
                RelativeOffset = new Vector2(0.0f, 0.0f)
            });

            var optionList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.25f), parent: optionButtons.RectTransform))
            {
                Stretch         = false,
                RelativeSpacing = 0.035f
            };

            new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), optionList.RectTransform), TextManager.Get("SettingsButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
            {
                ForceUpperCase = true,
                UserData       = Tab.Settings,
                OnClicked      = SelectTab
            };
            //TODO: translate
            new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), optionList.RectTransform), TextManager.Get("CreditsButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
            {
                ForceUpperCase = true,
                UserData       = Tab.Credits,
                OnClicked      = SelectTab
            };
            new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), optionList.RectTransform), TextManager.Get("QuitButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
            {
                ForceUpperCase = true,
                OnClicked      = QuitClicked
            };

            //debug button for quickly starting a new round
#if DEBUG
            new GUIButton(new RectTransform(new Point(300, 30), Frame.RectTransform, Anchor.TopRight)
            {
                AbsoluteOffset = new Point(40, 40)
            },
                          "Quickstart (dev)", style: "GUIButtonLarge", color: Color.Red)
            {
                IgnoreLayoutGroups = true,
                UserData           = Tab.QuickStartDev,
                OnClicked          = (tb, userdata) =>
                {
                    SelectTab(tb, userdata);
                    return(true);
                }
            };
#endif

            var minButtonSize = new Point(120, 20);
            var maxButtonSize = new Point(480, 80);

            /*new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("TutorialButton"), style: "GUIButtonLarge")
             * {
             *  UserData = Tab.Tutorials,
             *  OnClicked = SelectTab,
             *  Enabled = false
             * };*/

            /* var buttons = GUI.CreateButtons(9, new Vector2(1, 0.04f), buttonsParent.RectTransform, anchor: Anchor.BottomLeft,
             *   minSize: minButtonSize, maxSize: maxButtonSize, relativeSpacing: 0.005f, extraSpacing: i => i % 2 == 0 ? 20 : 0);
             * buttons.ForEach(b => b.Color *= 0.8f);
             * SetupButtons(buttons);
             * buttons.ForEach(b => b.TextBlock.SetTextPos());*/

            var     relativeSize    = new Vector2(0.6f, 0.65f);
            var     minSize         = new Point(600, 400);
            var     maxSize         = new Point(2000, 1500);
            var     anchor          = Anchor.CenterRight;
            var     pivot           = Pivot.CenterRight;
            Vector2 relativeSpacing = new Vector2(0.05f, 0.0f);

            menuTabs = new GUIFrame[Enum.GetValues(typeof(Tab)).Length + 1];

            menuTabs[(int)Tab.Settings] = new GUIFrame(new RectTransform(new Vector2(relativeSize.X, 0.8f), GUI.Canvas, anchor, pivot, minSize, maxSize)
            {
                RelativeOffset = relativeSpacing
            },
                                                       style: null);

            menuTabs[(int)Tab.NewGame] = new GUIFrame(new RectTransform(relativeSize, GUI.Canvas, anchor, pivot, minSize, maxSize)
            {
                RelativeOffset = relativeSpacing
            });
            var paddedNewGame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), menuTabs[(int)Tab.NewGame].RectTransform, Anchor.Center), style: null);
            menuTabs[(int)Tab.LoadGame] = new GUIFrame(new RectTransform(relativeSize, GUI.Canvas, anchor, pivot, minSize, maxSize)
            {
                RelativeOffset = relativeSpacing
            });
            var paddedLoadGame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), menuTabs[(int)Tab.LoadGame].RectTransform, Anchor.Center), style: null);

            campaignSetupUI = new CampaignSetupUI(false, paddedNewGame, paddedLoadGame, Submarine.SavedSubmarines)
            {
                LoadGame     = LoadGame,
                StartNewGame = StartGame
            };

            var hostServerScale = new Vector2(0.7f, 1.0f);
            menuTabs[(int)Tab.HostServer] = new GUIFrame(new RectTransform(
                                                             Vector2.Multiply(relativeSize, hostServerScale), GUI.Canvas, anchor, pivot, minSize.Multiply(hostServerScale), maxSize.Multiply(hostServerScale))
            {
                RelativeOffset = relativeSpacing
            });

            CreateHostServerFields();

            //----------------------------------------------------------------------

            menuTabs[(int)Tab.Tutorials] = new GUIFrame(new RectTransform(relativeSize, GUI.Canvas, anchor, pivot, minSize, maxSize)
            {
                RelativeOffset = relativeSpacing
            });

            //PLACEHOLDER
            var tutorialList = new GUIListBox(
                new RectTransform(new Vector2(0.95f, 0.85f), menuTabs[(int)Tab.Tutorials].RectTransform, Anchor.TopCenter)
            {
                RelativeOffset = new Vector2(0.0f, 0.1f)
            },
                false, null, "");
            foreach (Tutorial tutorial in Tutorial.Tutorials)
            {
                var tutorialText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), tutorialList.Content.RectTransform), tutorial.DisplayName, textAlignment: Alignment.Center, font: GUI.LargeFont)
                {
                    UserData = tutorial
                };
            }
            tutorialList.OnSelected += (component, obj) =>
            {
                TutorialMode.StartTutorial(obj as Tutorial);
                return(true);
            };

            this.game = game;

            menuTabs[(int)Tab.Credits] = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), style: null, color: Color.Black * 0.5f)
            {
                CanBeFocused = false
            };
            var creditsContainer = new GUIFrame(new RectTransform(new Vector2(0.75f, 1.5f), menuTabs[(int)Tab.Credits].RectTransform, Anchor.CenterRight), style: "OuterGlow", color: Color.Black * 0.8f);
            creditsPlayer = new CreditsPlayer(new RectTransform(Vector2.One, creditsContainer.RectTransform), "Content/Texts/Credits.xml");

            new GUIButton(new RectTransform(new Vector2(0.1f, 0.05f), menuTabs[(int)Tab.Credits].RectTransform, Anchor.BottomLeft)
            {
                RelativeOffset = new Vector2(0.25f, 0.02f)
            },
                          TextManager.Get("Back"), style: "GUIButtonLarge")
            {
                OnClicked = SelectTab
            };
        }
Beispiel #5
0
        static void CrashDump(GameMain game, string filePath, Exception exception)
        {
            DebugConsole.DequeueMessages();

            StreamWriter sw = new StreamWriter(filePath);

            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("If you'd like to help fix the bug that caused the crash, please send this file to the developers on the Undertow Games forums.");
            sb.AppendLine("\n");
            sb.AppendLine("Game version " + GameMain.Version);
            sb.AppendLine("Graphics mode: " + GameMain.Config.GraphicsWidth + "x" + GameMain.Config.GraphicsHeight + " (" + GameMain.Config.WindowMode.ToString() + ")");
            sb.AppendLine("Selected content package: " + GameMain.SelectedPackage.Name);
            sb.AppendLine("Level seed: " + ((Level.Loaded == null) ? "no level loaded" : Level.Loaded.Seed));
            sb.AppendLine("Loaded submarine: " + ((Submarine.MainSub == null) ? "None" : Submarine.MainSub.Name + " (" + Submarine.MainSub.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)"));
            }
            else 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.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);
            sb.AppendLine("Target site: " + exception.TargetSite.ToString());
            sb.AppendLine("Stack trace: ");
            sb.AppendLine(exception.StackTrace);
            sb.AppendLine("\n");

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


            sw.WriteLine(sb.ToString());
            sw.Close();

            CrashMessageBox("A crash report (\"crashreport.txt\") was saved in the root folder of the game." +
                            " If you'd like to help fix this bug, please post the report on the Undertow Games forums.");
        }
Beispiel #6
0
        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.BuildString + ", branch " + AssemblyInfo.GitBranch + ", revision " + AssemblyInfo.GitRevision + ")");
            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());
            }

            if (exception.StackTrace != null)
            {
                sb.AppendLine("Stack trace: ");
                sb.AppendLine(exception.StackTrace.CleanupStackTrace());
                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());
                }
                if (exception.InnerException.StackTrace != null)
                {
                    sb.AppendLine("Stack trace: ");
                    sb.AppendLine(exception.InnerException.StackTrace.CleanupStackTrace());
                }
            }

            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);
            }
        }
Beispiel #7
0
        public GameMain(string[] args)
        {
            Content.RootDirectory = "Content";

#if DEBUG && WINDOWS
            GraphicsAdapter.UseDebugLayers = true;
#endif
            GraphicsDeviceManager = new GraphicsDeviceManager(this)
            {
                IsFullScreen    = false,
                GraphicsProfile = GfxProfile
            };
            GraphicsDeviceManager.ApplyChanges();

            Window.Title = "Barotrauma";

            Instance = this;

            if (!Directory.Exists(Content.RootDirectory))
            {
                throw new Exception("Content folder not found. If you are trying to compile the game from the source code and own a legal copy of the game, you can copy the Content folder from the game's files to BarotraumaShared/Content.");
            }

            Config = new GameSettings();

            Md5Hash.LoadCache();

            ConsoleArguments = args;

            ConnectName     = null;
            ConnectEndpoint = null;
            ConnectLobby    = 0;

            try
            {
                ToolBox.ParseConnectCommand(ConsoleArguments, out ConnectName, out ConnectEndpoint, out ConnectLobby);
            }
            catch (IndexOutOfRangeException e)
            {
                DebugConsole.ThrowError($"Failed to parse console arguments ({string.Join(' ', ConsoleArguments)})", e);
                ConnectName     = null;
                ConnectEndpoint = null;
                ConnectLobby    = 0;
            }

            GUI.KeyboardDispatcher = new EventInput.KeyboardDispatcher(Window);

            PerformanceCounter = new PerformanceCounter();

            IsFixedTimeStep = false;

            GameMain.ResetFrameTime();
            fixedTime = new GameTime();

            World = new World(new Vector2(0, -9.82f));
            FarseerPhysics.Settings.AllowSleep         = true;
            FarseerPhysics.Settings.ContinuousPhysics  = false;
            FarseerPhysics.Settings.VelocityIterations = 1;
            FarseerPhysics.Settings.PositionIterations = 1;

            MainThread = Thread.CurrentThread;
        }
Beispiel #8
0
        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);
            }

            StreamWriter sw = new StreamWriter(filePath);

            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");
#if DEBUG
            sb.AppendLine("Game version " + GameMain.Version + " (debug build)");
#else
            sb.AppendLine("Game version " + GameMain.Version);
#endif
            sb.AppendLine("Selected content packages: " + (!GameMain.SelectedPackages.Any() ? "None" : string.Join(", ", GameMain.SelectedPackages.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.Name + " (" + Submarine.MainSub.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);
            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 > 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);

            sw.WriteLine(sb.ToString());
            sw.Close();

            if (GameSettings.SendUserStatistics)
            {
                GameAnalytics.AddErrorEvent(EGAErrorSeverity.Critical, crashReport);
                GameAnalytics.OnQuit();
                Console.Write("A crash report (\"crashreport.log\") was saved in the root folder of the game and sent to the developers.");
            }
            else
            {
                Console.Write("A crash report(\"crashreport.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();
        }
Beispiel #9
0
        public void StartRound(Level level, bool mirrorLevel = false)
        {
            //make sure no status effects have been carried on from the next round
            //(they should be stopped in EndRound, this is a safeguard against cases where the round is ended ungracefully)
            StatusEffect.StopAll();

#if CLIENT
            GameMain.LightManager.LosEnabled = GameMain.Client == null || GameMain.Client.CharacterInfo != null;
            if (GameMain.Client == null)
            {
                GameMain.LightManager.LosMode = GameMain.Config.LosMode;
            }
#endif
            this.Level = level;

            if (SubmarineInfo == null)
            {
                DebugConsole.ThrowError("Couldn't start game session, submarine not selected.");
                return;
            }

            if (SubmarineInfo.IsFileCorrupted)
            {
                DebugConsole.ThrowError("Couldn't start game session, submarine file corrupted.");
                return;
            }

            Submarine.Unload();
            Submarine         = Submarine.MainSub = new Submarine(SubmarineInfo);
            Submarine.MainSub = Submarine;
            if (GameMode.Mission != null && GameMode.Mission.TeamCount > 1 && Submarine.MainSubs[1] == null)
            {
                Submarine.MainSubs[1] = new Submarine(SubmarineInfo, true);
            }

            if (level != null)
            {
                level.Generate(mirrorLevel);
                if (level.StartOutpost != null)
                {
                    //start by placing the sub below the outpost
                    Rectangle outpostBorders = Level.Loaded.StartOutpost.GetDockedBorders();
                    Rectangle subBorders     = Submarine.GetDockedBorders();

                    Vector2 startOutpostSize = Vector2.Zero;
                    if (Level.Loaded.StartOutpost != null)
                    {
                        startOutpostSize = Level.Loaded.StartOutpost.Borders.Size.ToVector2();
                    }
                    Submarine.SetPosition(
                        Level.Loaded.StartOutpost.WorldPosition -
                        new Vector2(0.0f, outpostBorders.Height / 2 + subBorders.Height / 2));

                    //find the port that's the nearest to the outpost and dock if one is found
                    float       closestDistance = 0.0f;
                    DockingPort myPort = null, outPostPort = null;
                    foreach (DockingPort port in DockingPort.List)
                    {
                        if (port.IsHorizontal || port.Docked)
                        {
                            continue;
                        }
                        if (port.Item.Submarine == level.StartOutpost)
                        {
                            outPostPort = port;
                            continue;
                        }
                        if (port.Item.Submarine != Submarine)
                        {
                            continue;
                        }

                        //the submarine port has to be at the top of the sub
                        if (port.Item.WorldPosition.Y < Submarine.WorldPosition.Y)
                        {
                            continue;
                        }

                        float dist = Vector2.DistanceSquared(port.Item.WorldPosition, level.StartOutpost.WorldPosition);
                        if (myPort == null || dist < closestDistance || (port.MainDockingPort && !myPort.MainDockingPort))
                        {
                            myPort          = port;
                            closestDistance = dist;
                        }
                    }

                    if (myPort != null && outPostPort != null)
                    {
                        Vector2 portDiff = myPort.Item.WorldPosition - Submarine.WorldPosition;
                        Submarine.SetPosition((outPostPort.Item.WorldPosition - portDiff) - Vector2.UnitY * outPostPort.DockedDistance);
                        myPort.Dock(outPostPort);
                        myPort.Lock(true);
                    }
                }
                else
                {
                    Submarine.SetPosition(Submarine.FindSpawnPos(level.StartPosition));
                }
            }

            foreach (var sub in Submarine.Loaded)
            {
                if (sub.Info.IsOutpost)
                {
                    sub.DisableObstructedWayPoints();
                }
            }

            Entity.Spawner = new EntitySpawner();

            if (GameMode.Mission != null)
            {
                Mission = GameMode.Mission;
            }
            if (GameMode != null)
            {
                GameMode.Start();
            }
            if (GameMode.Mission != null)
            {
                int prevEntityCount = Entity.GetEntityList().Count;
                Mission.Start(Level.Loaded);
                if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient && Entity.GetEntityList().Count != prevEntityCount)
                {
                    DebugConsole.ThrowError(
                        "Entity count has changed after starting a mission as a client. " +
                        "The clients should not instantiate entities themselves when starting the mission," +
                        " but instead the server should inform the client of the spawned entities using Mission.ServerWriteInitial.");
                }
            }

            EventManager?.StartRound(level);
            SteamAchievementManager.OnStartRound();

            if (GameMode != null)
            {
                GameMode.ShowStartMessage();

                if (GameMain.NetworkMember == null)
                {
                    //only place items and corpses here in single player
                    //the server does this after loading the respawn shuttle
                    Level?.SpawnCorpses();
                    AutoItemPlacer.PlaceIfNeeded(GameMode);
                }
                if (GameMode is MultiPlayerCampaign mpCampaign && GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
                {
                    mpCampaign.CargoManager.CreateItems();
                }
            }

            GameAnalyticsManager.AddDesignEvent("Submarine:" + Submarine.Info.Name);
            GameAnalyticsManager.AddDesignEvent("Level", ToolBox.StringToInt(level?.Seed ?? "[NO_LEVEL]"));
            GameAnalyticsManager.AddProgressionEvent(GameAnalyticsSDK.Net.EGAProgressionStatus.Start,
                                                     GameMode.Preset.Identifier, (Mission == null ? "None" : Mission.GetType().ToString()));

#if CLIENT
            if (GameMode is SinglePlayerCampaign)
            {
                SteamAchievementManager.OnBiomeDiscovered(level.Biome);
            }
            if (!(GameMode is SubTestMode))
            {
                RoundSummary = new RoundSummary(this);
            }

            GameMain.GameScreen.ColorFade(Color.Black, Color.TransparentBlack, 5.0f);

            if (!(GameMode is TutorialMode) && !(GameMode is SubTestMode))
            {
                GUI.AddMessage("", Color.Transparent, 3.0f, playSound: false);
                GUI.AddMessage(level.Biome.DisplayName, Color.Lerp(Color.CadetBlue, Color.DarkRed, level.Difficulty / 100.0f), 5.0f, playSound: false);
                GUI.AddMessage(TextManager.AddPunctuation(':', TextManager.Get("Destination"), EndLocation.Name), Color.CadetBlue, playSound: false);
                GUI.AddMessage(TextManager.AddPunctuation(':', TextManager.Get("Mission"), (Mission == null ? TextManager.Get("None") : Mission.Name)), Color.CadetBlue, playSound: false);
            }
#endif

            RoundStartTime = Timing.TotalTime;
            GameMain.ResetFrameTime();
        }
Beispiel #10
0
        public static void ExecuteCommand(string command, GameMain game)
        {
            if (string.IsNullOrWhiteSpace(command))
            {
                return;
            }
            string[] commands = command.Split(' ');

            if (!commands[0].ToLowerInvariant().Equals("admin"))
            {
                NewMessage(textBox.Text, Color.White);
            }

#if !DEBUG
            if (GameMain.Client != null && !IsCommandPermitted(commands[0].ToLowerInvariant(), GameMain.Client))
            {
                ThrowError("You're not permitted to use the command \"" + commands[0].ToLowerInvariant() + "\"!");
                return;
            }
#endif

            switch (commands[0].ToLowerInvariant())
            {
            case "help":
                NewMessage("menu: go to main menu", Color.Cyan);
                NewMessage("game: enter the \"game screen\"", Color.Cyan);
                NewMessage("edit: switch to submarine editor", Color.Cyan);
                NewMessage("edit [submarine name]: load a submarine and switch to submarine editor", Color.Cyan);
                NewMessage("load [submarine name]: load a submarine", Color.Cyan);
                NewMessage("save [submarine name]: save the current submarine using the specified name", Color.Cyan);

                NewMessage(" ", Color.Cyan);

                NewMessage("spawn [creaturename] [near/inside/outside]: spawn a creature at a random spawnpoint (use the second parameter to only select spawnpoints near/inside/outside the submarine)", Color.Cyan);
                NewMessage("spawnitem [itemname] [cursor/inventory]: spawn an item at the position of the cursor, in the inventory of the controlled character or at a random spawnpoint if the last parameter is omitted", Color.Cyan);

                NewMessage(" ", Color.Cyan);

                NewMessage("lights: disable lighting", Color.Cyan);
                NewMessage("los: disable the line of sight effect", Color.Cyan);
                NewMessage("freecam: detach the camera from the controlled character", Color.Cyan);
                NewMessage("control [character name]: start controlling the specified character", Color.Cyan);

                NewMessage(" ", Color.Cyan);

                NewMessage("water: allows adding water into rooms or removing it by holding the left/right mouse buttons", Color.Cyan);
                NewMessage("fire: allows putting up fires by left clicking", Color.Cyan);

                NewMessage(" ", Color.Cyan);

                NewMessage("teleport: teleport the controlled character to the position of the cursor", Color.Cyan);
                NewMessage("teleport [character name]: teleport the specified character to the position of the cursor", Color.Cyan);
                NewMessage("heal: restore the controlled character to full health", Color.Cyan);
                NewMessage("heal [character name]: restore the specified character to full health", Color.Cyan);
                NewMessage("revive: bring the controlled character back from the dead", Color.Cyan);
                NewMessage("revive [character name]: bring the specified character back from the dead", Color.Cyan);
                NewMessage("killmonsters: immediately kills all AI-controlled enemies in the level", Color.Cyan);

                NewMessage(" ", Color.Cyan);

                NewMessage("fixwalls: fixes all the walls", Color.Cyan);
                NewMessage("fixitems: fixes every item/device in the sub", Color.Cyan);
                NewMessage("oxygen: replenishes the oxygen in every room to 100%", Color.Cyan);
                NewMessage("power [amount]: immediately sets the temperature of the reactor to the specified value", Color.Cyan);

                NewMessage(" ", Color.Cyan);

                NewMessage("kick [name]: kick a player out from the server", Color.Cyan);
                NewMessage("ban [name]: kick and ban the player from the server", Color.Cyan);
                NewMessage("banip [IP address]: ban the IP address from the server", Color.Cyan);
                NewMessage("debugdraw: toggles the \"debug draw mode\"", Color.Cyan);
                NewMessage("netstats: toggles the visibility of the network statistics panel", Color.Cyan);

                break;

            case "createfilelist":
                UpdaterUtil.SaveFileList("filelist.xml");
                break;

            case "spawn":
            case "spawncharacter":
                if (commands.Length == 1)
                {
                    return;
                }

                Character spawnedCharacter = null;

                Vector2  spawnPosition = Vector2.Zero;
                WayPoint spawnPoint    = null;

                if (commands.Length > 2)
                {
                    switch (commands[2].ToLowerInvariant())
                    {
                    case "inside":
                        spawnPoint = WayPoint.GetRandom(SpawnType.Human, null, Submarine.MainSub);
                        break;

                    case "outside":
                        spawnPoint = WayPoint.GetRandom(SpawnType.Enemy);
                        break;

                    case "near":
                    case "close":
                        float closestDist = -1.0f;
                        foreach (WayPoint wp in WayPoint.WayPointList)
                        {
                            if (wp.Submarine != null)
                            {
                                continue;
                            }

                            //don't spawn inside hulls
                            if (Hull.FindHull(wp.WorldPosition, null) != null)
                            {
                                continue;
                            }

                            float dist = Vector2.Distance(wp.WorldPosition, GameMain.GameScreen.Cam.WorldViewCenter);

                            if (closestDist < 0.0f || dist < closestDist)
                            {
                                spawnPoint  = wp;
                                closestDist = dist;
                            }
                        }
                        break;

                    case "cursor":
                        spawnPosition = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
                        break;

                    default:
                        spawnPoint = WayPoint.GetRandom(commands[1].ToLowerInvariant() == "human" ? SpawnType.Human : SpawnType.Enemy);
                        break;
                    }
                }
                else
                {
                    spawnPoint = WayPoint.GetRandom(commands[1].ToLowerInvariant() == "human" ? SpawnType.Human : SpawnType.Enemy);
                }

                if (string.IsNullOrWhiteSpace(commands[1]))
                {
                    return;
                }

                if (spawnPoint != null)
                {
                    spawnPosition = spawnPoint.WorldPosition;
                }

                if (commands[1].ToLowerInvariant() == "human")
                {
                    spawnedCharacter = Character.Create(Character.HumanConfigFile, spawnPosition);

                    if (GameMain.GameSession != null)
                    {
                        SinglePlayerMode mode = GameMain.GameSession.gameMode as SinglePlayerMode;
                        if (mode != null)
                        {
                            Character.Controlled = spawnedCharacter;
                            GameMain.GameSession.CrewManager.AddCharacter(Character.Controlled);
                            GameMain.GameSession.CrewManager.SelectCharacter(null, Character.Controlled);
                        }
                    }
                }
                else
                {
                    spawnedCharacter = Character.Create(
                        "Content/Characters/"
                        + commands[1].First().ToString().ToUpper() + commands[1].Substring(1)
                        + "/" + commands[1].ToLower() + ".xml", spawnPosition);
                }

                break;

            case "spawnitem":
                if (commands.Length < 2)
                {
                    return;
                }

                Vector2?  spawnPos       = null;
                Inventory spawnInventory = null;

                int extraParams = 0;
                switch (commands.Last())
                {
                case "cursor":
                    extraParams = 1;
                    spawnPos    = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
                    break;

                case "inventory":
                    extraParams    = 1;
                    spawnInventory = Character.Controlled == null ? null : Character.Controlled.Inventory;
                    break;

                default:
                    extraParams = 0;
                    break;
                }

                string itemName = string.Join(" ", commands.Skip(1).Take(commands.Length - extraParams - 1)).ToLowerInvariant();

                var itemPrefab = MapEntityPrefab.list.Find(ip => ip.Name.ToLowerInvariant() == itemName) as ItemPrefab;
                if (itemPrefab == null)
                {
                    ThrowError("Item \"" + itemName + "\" not found!");
                    return;
                }

                if (spawnPos == null && spawnInventory == null)
                {
                    var wp = WayPoint.GetRandom(SpawnType.Human, null, Submarine.MainSub);
                    spawnPos = wp == null ? Vector2.Zero : wp.WorldPosition;
                }

                if (spawnPos != null)
                {
                    Item.Spawner.AddToSpawnQueue(itemPrefab, (Vector2)spawnPos);
                }
                else if (spawnInventory != null)
                {
                    Item.Spawner.AddToSpawnQueue(itemPrefab, spawnInventory);
                }

                break;

            case "disablecrewai":
                HumanAIController.DisableCrewAI = !HumanAIController.DisableCrewAI;
                break;

            case "enablecrewai":
                HumanAIController.DisableCrewAI = false;
                break;

            /*case "admin":
             *  if (commands.Length < 2) break;
             *
             *  if (GameMain.Server != null)
             *  {
             *      GameMain.Server.AdminAuthPass = commands[1];
             *
             *  }
             *  else if (GameMain.Client != null)
             *  {
             *      GameMain.Client.RequestAdminAuth(commands[1]);
             *  }
             *  break;*/
            case "kick":
                if (GameMain.NetworkMember == null || commands.Length < 2)
                {
                    break;
                }
                GameMain.NetworkMember.KickPlayer(string.Join(" ", commands.Skip(1)), false);

                break;

            case "ban":
                if (GameMain.NetworkMember == null || commands.Length < 2)
                {
                    break;
                }
                GameMain.NetworkMember.KickPlayer(string.Join(" ", commands.Skip(1)), true);

                break;

            case "banip":
            {
                if (GameMain.Server == null || commands.Length < 2)
                {
                    break;
                }

                var client = GameMain.Server.ConnectedClients.Find(c => c.Connection.RemoteEndPoint.Address.ToString() == commands[1]);
                if (client == null)
                {
                    GameMain.Server.BanList.BanPlayer("Unnamed", commands[1]);
                }
                else
                {
                    GameMain.Server.KickClient(client, true);
                }
            }
            break;

            case "startclient":
                if (commands.Length == 1)
                {
                    return;
                }
                if (GameMain.Client == null)
                {
                    GameMain.NetworkMember = new GameClient("Name");
                    GameMain.Client.ConnectToServer(commands[1]);
                }
                break;

            case "mainmenuscreen":
            case "mainmenu":
            case "menu":
                GameMain.GameSession = null;

                List <Character> characters = new List <Character>(Character.CharacterList);
                foreach (Character c in characters)
                {
                    c.Remove();
                }

                GameMain.MainMenuScreen.Select();
                break;

            case "gamescreen":
            case "game":
                GameMain.GameScreen.Select();
                break;

            case "editmapscreen":
            case "editmap":
            case "edit":
                if (commands.Length > 1)
                {
                    Submarine.Load(string.Join(" ", commands.Skip(1)), true);
                }
                GameMain.EditMapScreen.Select();
                break;

            case "test":
                Submarine.Load("aegir mark ii", true);
                GameMain.DebugDraw = true;
                GameMain.LightManager.LosEnabled = false;
                GameMain.EditMapScreen.Select();
                break;

            case "editcharacter":
            case "editchar":
                GameMain.EditCharacterScreen.Select();
                break;

            case "controlcharacter":
            case "control":
            {
                if (commands.Length < 2)
                {
                    break;
                }

                var character = FindMatchingCharacter(commands, true);

                if (character != null)
                {
                    Character.Controlled = character;
                }
            }
            break;

            case "setclientcharacter":
            {
                if (GameMain.Server == null)
                {
                    break;
                }

                int separatorIndex = Array.IndexOf(commands, ";");

                if (separatorIndex == -1 || commands.Length < 4)
                {
                    ThrowError("Invalid parameters. The command should be formatted as \"setclientcharacter [client] ; [character]\"");
                    break;
                }

                string[] commandsLeft  = commands.Take(separatorIndex).ToArray();
                string[] commandsRight = commands.Skip(separatorIndex).ToArray();

                string clientName = String.Join(" ", commandsLeft.Skip(1));

                var client = GameMain.Server.ConnectedClients.Find(c => c.name == clientName);
                if (client == null)
                {
                    ThrowError("Client \"" + clientName + "\" not found.");
                }

                var character = FindMatchingCharacter(commandsRight, false);
                GameMain.Server.SetClientCharacter(client, character);
            }
            break;

            case "teleportcharacter":
            case "teleport":
                var tpCharacter = FindMatchingCharacter(commands, false);

                if (commands.Length < 2)
                {
                    tpCharacter = Character.Controlled;
                }

                if (tpCharacter != null)
                {
                    var cam = GameMain.GameScreen.Cam;
                    tpCharacter.AnimController.CurrentHull = null;
                    tpCharacter.Submarine = null;
                    tpCharacter.AnimController.SetPosition(ConvertUnits.ToSimUnits(cam.ScreenToWorld(PlayerInput.MousePosition)));
                    tpCharacter.AnimController.FindHull(cam.ScreenToWorld(PlayerInput.MousePosition), true);
                }
                break;

            case "godmode":
                if (Submarine.MainSub == null)
                {
                    return;
                }

                Submarine.MainSub.GodMode = !Submarine.MainSub.GodMode;
                break;

            case "lockx":
                Submarine.LockX = !Submarine.LockX;
                break;

            case "locky":
                Submarine.LockY = !Submarine.LockY;
                break;

            case "dumpids":
                try
                {
                    int count = commands.Length < 2 ? 10 : int.Parse(commands[1]);
                    Entity.DumpIds(count);
                }
                catch
                {
                    return;
                }
                break;

            case "heal":
                Character healedCharacter = null;
                if (commands.Length == 1)
                {
                    healedCharacter = Character.Controlled;
                }
                else
                {
                    healedCharacter = FindMatchingCharacter(commands);
                }

                if (healedCharacter != null)
                {
                    healedCharacter.AddDamage(CauseOfDeath.Damage, -healedCharacter.MaxHealth, null);
                    healedCharacter.Oxygen   = 100.0f;
                    healedCharacter.Bleeding = 0.0f;
                    healedCharacter.Stun     = 0.0f;
                }

                break;

            case "revive":
                Character revivedCharacter = null;
                if (commands.Length == 1)
                {
                    revivedCharacter = Character.Controlled;
                }
                else
                {
                    revivedCharacter = FindMatchingCharacter(commands);
                }

                if (revivedCharacter != null)
                {
                    revivedCharacter.Revive(false);
                    if (GameMain.Server != null)
                    {
                        foreach (Client c in GameMain.Server.ConnectedClients)
                        {
                            if (c.Character != revivedCharacter)
                            {
                                continue;
                            }
                            //clients stop controlling the character when it dies, force control back
                            GameMain.Server.SetClientCharacter(c, revivedCharacter);
                            break;
                        }
                    }
                }
                break;

            case "freeze":
                if (Character.Controlled != null)
                {
                    Character.Controlled.AnimController.Frozen = !Character.Controlled.AnimController.Frozen;
                }
                break;

            case "freecamera":
            case "freecam":
                Character.Controlled = null;
                GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
                break;

            case "editwater":
            case "water":
                if (GameMain.Client == null)
                {
                    Hull.EditWater = !Hull.EditWater;
                }

                break;

            case "fire":
                if (GameMain.Client == null)
                {
                    Hull.EditFire = !Hull.EditFire;
                }

                break;

            case "fixitems":
                foreach (Item it in Item.ItemList)
                {
                    it.Condition = 100.0f;
                }
                break;

            case "fixhull":
            case "fixwalls":
                foreach (Structure w in Structure.WallList)
                {
                    for (int i = 0; i < w.SectionCount; i++)
                    {
                        w.AddDamage(i, -100000.0f);
                    }
                }
                break;

            case "power":
                Item reactorItem = Item.ItemList.Find(i => i.GetComponent <Reactor>() != null);
                if (reactorItem == null)
                {
                    return;
                }

                float power = 5000.0f;
                if (commands.Length > 1)
                {
                    float.TryParse(commands[1], out power);
                }

                var reactor = reactorItem.GetComponent <Reactor>();
                reactor.ShutDownTemp = power == 0 ? 0 : 7000.0f;
                reactor.AutoTemp     = true;
                reactor.Temperature  = power;

                if (GameMain.Server != null)
                {
                    reactorItem.CreateServerEvent(reactor);
                }
                break;

            case "shake":
                GameMain.GameScreen.Cam.Shake = 10.0f;
                break;

            case "losenabled":
            case "los":
            case "drawlos":
                GameMain.LightManager.LosEnabled = !GameMain.LightManager.LosEnabled;
                break;

            case "lighting":
            case "lightingenabled":
            case "light":
            case "lights":
                GameMain.LightManager.LightingEnabled = !GameMain.LightManager.LightingEnabled;
                break;

            case "oxygen":
            case "air":
                foreach (Hull hull in Hull.hullList)
                {
                    hull.OxygenPercentage = 100.0f;
                }
                break;

            case "tutorial":
                TutorialMode.StartTutorial(Tutorials.TutorialType.TutorialTypes[0]);


                break;

            case "editortutorial":
                GameMain.EditMapScreen.Select();
                GameMain.EditMapScreen.StartTutorial();
                break;

            case "lobbyscreen":
            case "lobby":
                GameMain.LobbyScreen.Select();
                break;

            case "savemap":
            case "savesub":
            case "save":
                if (commands.Length < 2)
                {
                    break;
                }

                if (GameMain.EditMapScreen.CharacterMode)
                {
                    GameMain.EditMapScreen.ToggleCharacterMode();
                }

                string fileName = string.Join(" ", commands.Skip(1));
                if (fileName.Contains("../"))
                {
                    DebugConsole.ThrowError("Illegal symbols in filename (../)");
                    return;
                }

                if (Submarine.SaveCurrent(System.IO.Path.Combine(Submarine.SavePath, fileName + ".sub")))
                {
                    NewMessage("Sub saved", Color.Green);
                    //Submarine.Loaded.First().CheckForErrors();
                }

                break;

            case "loadmap":
            case "loadsub":
            case "load":
                if (commands.Length < 2)
                {
                    break;
                }

                Submarine.Load(string.Join(" ", commands.Skip(1)), true);
                break;

            case "cleansub":
                for (int i = MapEntity.mapEntityList.Count - 1; i >= 0; i--)
                {
                    MapEntity me = MapEntity.mapEntityList[i];

                    if (me.SimPosition.Length() > 2000.0f)
                    {
                        DebugConsole.NewMessage("Removed " + me.Name + " (simposition " + me.SimPosition + ")", Color.Orange);
                        MapEntity.mapEntityList.RemoveAt(i);
                    }
                    else if (me.MoveWithLevel)
                    {
                        DebugConsole.NewMessage("Removed " + me.Name + " (MoveWithLevel==true)", Color.Orange);
                        MapEntity.mapEntityList.RemoveAt(i);
                    }
                    else if (me is Item)
                    {
                        Item item = me as Item;
                        var  wire = item.GetComponent <Wire>();
                        if (wire == null)
                        {
                            continue;
                        }

                        if (wire.GetNodes().Count > 0 && !wire.Connections.Any(c => c != null))
                        {
                            wire.Item.Drop(null);
                            DebugConsole.NewMessage("Dropped wire (ID: " + wire.Item.ID + ") - attached on wall but no connections found", Color.Orange);
                        }
                    }
                }
                break;

            case "messagebox":
                if (commands.Length < 3)
                {
                    break;
                }
                new GUIMessageBox(commands[1], commands[2]);
                break;

            case "debugdraw":
                GameMain.DebugDraw = !GameMain.DebugDraw;
                break;

            case "disablehud":
            case "hud":
                GUI.DisableHUD = !GUI.DisableHUD;
                GameMain.Instance.IsMouseVisible = !GameMain.Instance.IsMouseVisible;
                break;

            case "followsub":
                Camera.FollowSub = !Camera.FollowSub;
                break;

            case "drawaitargets":
            case "showaitargets":
                AITarget.ShowAITargets = !AITarget.ShowAITargets;
                break;

            case "killmonsters":
                foreach (Character c in Character.CharacterList)
                {
                    if (!(c.AIController is EnemyAIController))
                    {
                        continue;
                    }
                    c.AddDamage(CauseOfDeath.Damage, 10000.0f, null);
                }
                break;

            case "netstats":
                if (GameMain.Server == null)
                {
                    return;
                }

                GameMain.Server.ShowNetStats = !GameMain.Server.ShowNetStats;
                break;

#if DEBUG
            case "spamevents":
                foreach (Item item in Item.ItemList)
                {
                    for (int i = 0; i < item.components.Count; i++)
                    {
                        if (item.components[i] is IServerSerializable)
                        {
                            GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ComponentState, i });
                        }
                        var itemContainer = item.GetComponent <ItemContainer>();
                        if (itemContainer != null)
                        {
                            GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.InventoryState });
                        }

                        GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.Status });

                        item.NeedsPositionUpdate = true;
                    }
                }

                foreach (Character c in Character.CharacterList)
                {
                    GameMain.Server.CreateEntityEvent(c, new object[] { NetEntityEvent.Type.Status });
                }

                foreach (Structure wall in Structure.WallList)
                {
                    GameMain.Server.CreateEntityEvent(wall);
                }
                break;

            case "spamchatmessages":
                int msgCount = 1000;
                if (commands.Length > 1)
                {
                    int.TryParse(commands[1], out msgCount);
                }
                int msgLength = 50;
                if (commands.Length > 2)
                {
                    int.TryParse(commands[2], out msgLength);
                }

                for (int i = 0; i < msgCount; i++)
                {
                    if (GameMain.Server != null)
                    {
                        GameMain.Server.SendChatMessage(ToolBox.RandomSeed(msgLength), ChatMessageType.Default);
                    }
                    else
                    {
                        GameMain.Client.SendChatMessage(ToolBox.RandomSeed(msgLength));
                    }
                }
                break;
#endif
            case "cleanbuild":
                GameMain.Config.MusicVolume = 0.5f;
                GameMain.Config.SoundVolume = 0.5f;
                DebugConsole.NewMessage("Music and sound volume set to 0.5", Color.Green);

                GameMain.Config.GraphicsWidth  = 0;
                GameMain.Config.GraphicsHeight = 0;
                GameMain.Config.WindowMode     = WindowMode.Fullscreen;
                DebugConsole.NewMessage("Resolution set to 0 x 0 (screen resolution will be used)", Color.Green);
                DebugConsole.NewMessage("Fullscreen enabled", Color.Green);

                GameSettings.VerboseLogging = false;

                if (GameMain.Config.MasterServerUrl != "http://www.undertowgames.com/baromaster")
                {
                    DebugConsole.ThrowError("MasterServerUrl \"" + GameMain.Config.MasterServerUrl + "\"!");
                }

                GameMain.Config.Save("config.xml");

                var saveFiles = System.IO.Directory.GetFiles(SaveUtil.SaveFolder);

                foreach (string saveFile in saveFiles)
                {
                    System.IO.File.Delete(saveFile);
                    DebugConsole.NewMessage("Deleted " + saveFile, Color.Green);
                }

                if (System.IO.Directory.Exists(System.IO.Path.Combine(SaveUtil.SaveFolder, "temp")))
                {
                    System.IO.Directory.Delete(System.IO.Path.Combine(SaveUtil.SaveFolder, "temp"), true);
                    DebugConsole.NewMessage("Deleted temp save folder", Color.Green);
                }

                if (System.IO.Directory.Exists(ServerLog.SavePath))
                {
                    var logFiles = System.IO.Directory.GetFiles(ServerLog.SavePath);

                    foreach (string logFile in logFiles)
                    {
                        System.IO.File.Delete(logFile);
                        DebugConsole.NewMessage("Deleted " + logFile, Color.Green);
                    }
                }

                if (System.IO.File.Exists("filelist.xml"))
                {
                    System.IO.File.Delete("filelist.xml");
                    DebugConsole.NewMessage("Deleted filelist", Color.Green);
                }


                if (System.IO.File.Exists("Submarines/TutorialSub.sub"))
                {
                    System.IO.File.Delete("Submarines/TutorialSub.sub");

                    DebugConsole.NewMessage("Deleted TutorialSub from the submarine folder", Color.Green);
                }

                if (System.IO.File.Exists(GameServer.SettingsFile))
                {
                    System.IO.File.Delete(GameServer.SettingsFile);
                    DebugConsole.NewMessage("Deleted server settings", Color.Green);
                }

                if (System.IO.File.Exists(GameServer.ClientPermissionsFile))
                {
                    System.IO.File.Delete(GameServer.ClientPermissionsFile);
                    DebugConsole.NewMessage("Deleted client permission file", Color.Green);
                }

                if (System.IO.File.Exists("crashreport.txt"))
                {
                    System.IO.File.Delete("crashreport.txt");
                    DebugConsole.NewMessage("Deleted crashreport.txt", Color.Green);
                }

                if (!System.IO.File.Exists("Content/Map/TutorialSub.sub"))
                {
                    DebugConsole.ThrowError("TutorialSub.sub not found!");
                }

                break;

            default:
                NewMessage("Command not found", Color.Red);
                break;
            }
        }
Beispiel #11
0
        public MainMenuScreen(GameMain game)
        {
            buttonsParent = new GUILayoutGroup(new RectTransform(new Vector2(0.15f, 0.5f), parent: Frame.RectTransform, anchor: Anchor.BottomLeft)
            {
                RelativeOffset = new Vector2(0, 0.1f),
                AbsoluteOffset = new Point(50, 0)
            })
            {
                Stretch         = true,
                RelativeSpacing = 0.02f
            };

            //debug button for quickly starting a new round
            new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform, Anchor.TopCenter, Pivot.BottomCenter)
            {
                AbsoluteOffset = new Point(0, -40)
            },
                          "Quickstart (dev)", style: "GUIButtonLarge", color: Color.Red)
            {
                IgnoreLayoutGroups = true,
                OnClicked          = (tb, userdata) =>
                {
                    Submarine selectedSub = null;
                    string    subName     = GameMain.Config.QuickStartSubmarineName;
                    if (!string.IsNullOrEmpty(subName))
                    {
                        DebugConsole.NewMessage($"Loading the predefined quick start sub \"{subName}\"", Color.White);
                        selectedSub = Submarine.SavedSubmarines.FirstOrDefault(s =>
                                                                               s.Name.ToLower() == subName.ToLower());

                        if (selectedSub == null)
                        {
                            DebugConsole.NewMessage($"Cannot find a sub that matches the name \"{subName}\".", Color.Red);
                        }
                    }
                    if (selectedSub == null)
                    {
                        DebugConsole.NewMessage("Loading a random sub.", Color.White);
                        var subs = Submarine.SavedSubmarines.Where(s => !s.HasTag(SubmarineTag.Shuttle) && !s.HasTag(SubmarineTag.HideInMenus));
                        selectedSub = subs.ElementAt(Rand.Int(subs.Count()));
                    }
                    var gamesession = new GameSession(
                        selectedSub,
                        "Data/Saves/test.xml",
                        GameModePreset.list.Find(gm => gm.Name == "SPSandbox"),
                        missionPrefab: null);
                    //(gamesession.GameMode as SinglePlayerCampaign).GenerateMap(ToolBox.RandomSeed(8));
                    gamesession.StartRound(ToolBox.RandomSeed(8));
                    GameMain.GameScreen.Select();

                    string[] jobIdentifiers = new string[] { "captain", "engineer", "mechanic" };
                    for (int i = 0; i < 3; i++)
                    {
                        var spawnPoint = WayPoint.GetRandom(SpawnType.Human, null, Submarine.MainSub);
                        if (spawnPoint == null)
                        {
                            DebugConsole.ThrowError("No spawnpoints found in the selected submarine. Quickstart failed.");
                            GameMain.MainMenuScreen.Select();
                            return(true);
                        }
                        var characterInfo = new CharacterInfo(
                            Character.HumanConfigFile,
                            jobPrefab: JobPrefab.List.Find(j => j.Identifier == jobIdentifiers[i]));
                        if (characterInfo.Job == null)
                        {
                            DebugConsole.ThrowError("Failed to find the job \"" + jobIdentifiers[i] + "\"!");
                        }

                        var newCharacter = Character.Create(Character.HumanConfigFile, spawnPoint.WorldPosition, ToolBox.RandomSeed(8), characterInfo);
                        newCharacter.GiveJobItems(spawnPoint);
                        gamesession.CrewManager.AddCharacter(newCharacter);
                        Character.Controlled = newCharacter;
                    }
                    return(true);
                }
            };

            var minButtonSize = new Point(120, 20);
            var maxButtonSize = new Point(240, 40);

            new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("TutorialButton"), style: "GUIButtonLarge")
            {
                UserData  = Tab.Tutorials,
                OnClicked = SelectTab,
                Enabled   = false
            };

            new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), buttonsParent.RectTransform), style: null); //spacing

            new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("NewGameButton"), style: "GUIButtonLarge")
            {
                UserData  = Tab.NewGame,
                OnClicked = SelectTab
            };
            new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("LoadGameButton"), style: "GUIButtonLarge")
            {
                UserData  = Tab.LoadGame,
                OnClicked = SelectTab
            };

            new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), buttonsParent.RectTransform), style: null); //spacing

            new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("JoinServerButton"), style: "GUIButtonLarge")
            {
                OnClicked = JoinServerClicked
            };
            new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("HostServerButton"), style: "GUIButtonLarge")
            {
                UserData  = Tab.HostServer,
                OnClicked = SelectTab
            };


            new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), buttonsParent.RectTransform), style: null); //spacing

            new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("SubEditorButton"), style: "GUIButtonLarge")
            {
                OnClicked = (btn, userdata) => { GameMain.SubEditorScreen.Select(); return(true); }
            };

            new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("CharacterEditorButton"), style: "GUIButtonLarge")
            {
                OnClicked = (btn, userdata) =>
                {
                    Submarine.MainSub = null;
                    GameMain.CharacterEditorScreen.Select();
                    return(true);
                }
            };

            if (Steam.SteamManager.USE_STEAM)
            {
                steamWorkshopButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("SteamWorkshopButton"), style: "GUIButtonLarge")
                {
                    Enabled   = false,
                    OnClicked = SteamWorkshopClicked
                };
            }

            new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), buttonsParent.RectTransform), style: null); //spacing

            new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("SettingsButton"), style: "GUIButtonLarge")
            {
                UserData  = Tab.Settings,
                OnClicked = SelectTab
            };
            new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("QuitButton"), style: "GUIButtonLarge")
            {
                OnClicked = QuitClicked
            };


            /* var buttons = GUI.CreateButtons(9, new Vector2(1, 0.04f), buttonsParent.RectTransform, anchor: Anchor.BottomLeft,
             *   minSize: minButtonSize, maxSize: maxButtonSize, relativeSpacing: 0.005f, extraSpacing: i => i % 2 == 0 ? 20 : 0);
             * buttons.ForEach(b => b.Color *= 0.8f);
             * SetupButtons(buttons);
             * buttons.ForEach(b => b.TextBlock.SetTextPos());*/

            var relativeSize = new Vector2(0.5f, 0.5f);
            var minSize      = new Point(600, 400);
            var maxSize      = new Point(900, 600);
            var anchor       = Anchor.Center;
            var pivot        = Pivot.Center;

            menuTabs = new GUIFrame[Enum.GetValues(typeof(Tab)).Length + 1];

            menuTabs[(int)Tab.NewGame] = new GUIFrame(new RectTransform(relativeSize, Frame.RectTransform, anchor, pivot, minSize, maxSize));
            var paddedNewGame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), menuTabs[(int)Tab.NewGame].RectTransform, Anchor.Center), style: null);

            menuTabs[(int)Tab.LoadGame] = new GUIFrame(new RectTransform(relativeSize, Frame.RectTransform, anchor, pivot, minSize, maxSize));
            var paddedLoadGame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), menuTabs[(int)Tab.LoadGame].RectTransform, Anchor.Center), style: null);

            campaignSetupUI = new CampaignSetupUI(false, paddedNewGame, paddedLoadGame)
            {
                LoadGame     = LoadGame,
                StartNewGame = StartGame
            };

            var hostServerScale = new Vector2(0.7f, 1.0f);

            menuTabs[(int)Tab.HostServer] = new GUIFrame(new RectTransform(
                                                             Vector2.Multiply(relativeSize, hostServerScale), Frame.RectTransform, anchor, pivot, minSize.Multiply(hostServerScale), maxSize.Multiply(hostServerScale)));

            CreateHostServerFields();

            //----------------------------------------------------------------------

            menuTabs[(int)Tab.Tutorials] = new GUIFrame(new RectTransform(relativeSize, Frame.RectTransform, anchor, pivot, minSize, maxSize));

            //PLACEHOLDER
            var tutorialList = new GUIListBox(
                new RectTransform(new Vector2(0.95f, 0.85f), menuTabs[(int)Tab.Tutorials].RectTransform, Anchor.TopCenter)
            {
                RelativeOffset = new Vector2(0.0f, 0.1f)
            },
                false, null, "");

            foreach (Tutorial tutorial in Tutorial.Tutorials)
            {
                var tutorialText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), tutorialList.Content.RectTransform), tutorial.Name, textAlignment: Alignment.Center, font: GUI.LargeFont)
                {
                    UserData = tutorial
                };
            }
            tutorialList.OnSelected += (component, obj) =>
            {
                TutorialMode.StartTutorial(obj as Tutorial);
                return(true);
            };

            UpdateTutorialList();

            this.game = game;
        }
Beispiel #12
0
        static void CrashDump(GameMain game, string filePath, Exception exception)
        {
            DebugConsole.DequeueMessages();

            StreamWriter sw = new StreamWriter(filePath);

            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");
#if DEBUG
            sb.AppendLine("Game version " + GameMain.Version + " NILMOD SERVER MODIFICATION" + " (debug build)");
#else
            sb.AppendLine("Game version " + GameMain.Version + " NILMOD SERVER MODIFICATION");
#endif
            sb.AppendLine("Nilmod version stamp: " + NilMod.NilModVersionDate);
            sb.AppendLine("Graphics mode: " + GameMain.Config.GraphicsWidth + "x" + GameMain.Config.GraphicsHeight + " (" + GameMain.Config.WindowMode.ToString() + ")");
            sb.AppendLine("Selected content package: " + GameMain.SelectedPackage.Name);
            sb.AppendLine("Level seed: " + ((Level.Loaded == null) ? "no level loaded" : Level.Loaded.Seed));
            sb.AppendLine("Loaded submarine: " + ((Submarine.MainSub == null) ? "None" : Submarine.MainSub.Name + " (" + Submarine.MainSub.MD5Hash + ")"));
            sb.AppendLine("Selected screen: " + (Screen.Selected == null ? "None" : Screen.Selected.ToString()));

            if (GameMain.GameSession != null)
            {
                if (GameMain.GameSession.GameMode != null)
                {
                    sb.AppendLine("Gamemode: " + GameMain.GameSession.GameMode.Name);
                }
                if (GameMain.GameSession.Mission != null)
                {
                    sb.AppendLine("Mission: " + GameMain.GameSession.Mission.Name);
                }
            }

            if (Character.CharacterList != null && Character.CharacterList.Count > 0)
            {
                sb.AppendLine("\n");
                if (Character.CharacterList.FindAll(c => c.Removed).Count > 0)
                {
                    sb.AppendLine("Removed character references detected, " + Character.CharacterList.Count + " Characters in list, " + Character.CharacterList.FindAll(c => c.Removed).Count + " Removed.");
                }

                int foundnullanimcontroller = 0;
                int foundnulllimbs          = 0;
                int foundzerolengthlimbs    = 0;
                for (int i = Character.CharacterList.Count - 1; i >= 0; i--)
                {
                    if (Character.CharacterList[i].AnimController == null)
                    {
                        foundnullanimcontroller += 1;
                    }
                    else
                    {
                        if (Character.CharacterList[i].AnimController.Limbs == null)
                        {
                            foundnulllimbs += 1;
                        }
                        else if (Character.CharacterList[i].AnimController.Limbs.Length < 1)
                        {
                            foundzerolengthlimbs += 1;
                        }
                    }
                }
                if (foundnullanimcontroller > 0)
                {
                    sb.AppendLine(foundnullanimcontroller + " Characters with null AnimControllers found.");
                }
                if (foundnulllimbs > 0)
                {
                    sb.AppendLine(foundnulllimbs + " Characters with null limbs[] reference found.");
                }
                if (foundzerolengthlimbs > 0)
                {
                    sb.AppendLine(foundzerolengthlimbs + " characters with 0 limbs found.");
                }
            }

            if (GameMain.Server != null)
            {
                sb.AppendLine("Server (" + (GameMain.Server.GameStarted ? "Round had started)" : "Round hadn't been started)"));
            }
            else 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.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);
            }

#if LINUX
            if (GameMain.NilMod != null && GameMain.NilMod.CrashRestart)
            {
                sb.AppendLine("\n");
                sb.AppendLine("Attempted restart of process using: " + System.Diagnostics.Process.Start(System.Reflection.Assembly.GetEntryAssembly().CodeBase + "\\Barotrauma NilEdit.exe"));
                sb.AppendLine("\n");
            }
#else
            if (GameMain.NilMod != null && GameMain.NilMod.CrashRestart)
            {
                sb.AppendLine("\n");
                sb.AppendLine("Attempted restart of process using: " + Application.StartupPath + "\\Barotrauma NilEdit.exe");
                sb.AppendLine("\n");
            }
#endif

            sb.AppendLine("\n");
            sb.AppendLine("This was running NilMod Code!");
            sb.AppendLine("\n");
            sb.AppendLine("Exception: " + exception.Message);
            sb.AppendLine("Target site: " + exception.TargetSite.ToString());
            sb.AppendLine("Stack trace: ");
            sb.AppendLine(exception.StackTrace);
            sb.AppendLine("\n");

            sb.AppendLine("Last debug messages:");
            if (game != null)
            {
                if (GameMain.NilMod != null)
                {
                    if (GameMain.NilMod.DebugConsoleTimeStamp)
                    {
                        for (int i = DebugConsole.Messages.Count - 1; i > 0; i--)
                        {
                            sb.AppendLine(DebugConsole.Messages[i].Text);
                        }
                    }
                    else
                    {
                        for (int i = DebugConsole.Messages.Count - 1; i > 0; i--)
                        {
                            sb.AppendLine("[" + DebugConsole.Messages[i].Time + "] " + DebugConsole.Messages[i].Text);
                        }
                    }
                }
                else
                {
                    for (int i = DebugConsole.Messages.Count - 1; i > 0; i--)
                    {
                        sb.AppendLine("[" + DebugConsole.Messages[i].Time + "] " + DebugConsole.Messages[i].Text);
                    }
                }
            }
            else
            {
                for (int i = DebugConsole.Messages.Count - 1; i > 0; i--)
                {
                    sb.AppendLine("[" + DebugConsole.Messages[i].Time + "] " + DebugConsole.Messages[i].Text);
                }
            }

            string crashReport = sb.ToString();

            sw.WriteLine(crashReport);
            sw.Close();

            if (GameMain.NilMod != null)
            {
                if (GameMain.NilMod.CrashRestart && GameMain.NilMod.SuccesfulStart)
                {
                    if (GameSettings.SaveDebugConsoleLogs)
                    {
                        DebugConsole.SaveLogs();
                    }

                    if (GameSettings.SendUserStatistics)
                    {
                        GameAnalytics.AddErrorEvent(EGAErrorSeverity.Critical, crashReport);
                        GameAnalytics.OnStop();
                    }

                    CrashRestart(null, exception);
                }
                else
                {
                    if (GameSettings.SaveDebugConsoleLogs)
                    {
                        DebugConsole.SaveLogs();
                    }

                    if (GameSettings.SendUserStatistics)
                    {
                        CrashMessageBox("A crash report (\"crashreport.log\") was saved in the root folder of the game and sent to the developers.");
                        GameAnalytics.AddErrorEvent(EGAErrorSeverity.Critical, crashReport);
                        GameAnalytics.OnStop();
                    }
                    else
                    {
                        CrashMessageBox("A crash report (\"crashreport.log\") was saved in the root folder of the game." + Environment.NewLine +
                                        "If you'd like to help fix this bug, please post the report on Barotrauma's GitHub issue tracker: https://github.com/Regalis11/Barotrauma/issues/" + Environment.NewLine +
                                        "Alternatively, If you believe this to be a mod bug, please post the report on the forum topic or the mods GitHub issue tracker: https://github.com/NilanthAnimosus/Barotrauma---Nilanths-Edits/issues");
                    }
                }
            }
            else
            {
                if (GameSettings.SaveDebugConsoleLogs)
                {
                    DebugConsole.SaveLogs();
                }

                CrashMessageBox("A crash report (\"crashreport.log\") was saved in the root folder of the game." + Environment.NewLine +
                                "If you'd like to help fix this bug, please post the report on Barotrauma's GitHub issue tracker: https://github.com/Regalis11/Barotrauma/issues/" + Environment.NewLine +
                                "Alternatively, If you believe this to be a mod bug, please post the report on the forum topic or the mods GitHub issue tracker: https://github.com/NilanthAnimosus/Barotrauma---Nilanths-Edits/issues");
            }
        }
Beispiel #13
0
        public void StartRound(Level level, bool reloadSub = true, bool loadSecondSub = false, bool mirrorLevel = false)
        {
#if CLIENT
            GameMain.LightManager.LosEnabled = GameMain.Client == null || GameMain.Client.CharacterInfo != null;
            if (GameMain.Client == null)
            {
                GameMain.LightManager.LosMode = GameMain.Config.LosMode;
            }
#endif
            this.Level = level;

            if (Submarine == null)
            {
                DebugConsole.ThrowError("Couldn't start game session, submarine not selected");
                return;
            }

            if (reloadSub || Submarine.MainSub != Submarine)
            {
                Submarine.Load(true);
            }
            Submarine.MainSub = Submarine;
            if (loadSecondSub)
            {
                if (Submarine.MainSubs[1] == null)
                {
                    Submarine.MainSubs[1] = new Submarine(Submarine.MainSub.FilePath, Submarine.MainSub.MD5Hash.Hash, true);
                    Submarine.MainSubs[1].Load(false);
                }
                else if (reloadSub)
                {
                    Submarine.MainSubs[1].Load(false);
                }
            }

            if (level != null)
            {
                level.Generate(mirrorLevel);
                if (level.StartOutpost != null)
                {
                    //start by placing the sub below the outpost
                    Rectangle outpostBorders = Level.Loaded.StartOutpost.GetDockedBorders();
                    Rectangle subBorders     = Submarine.GetDockedBorders();

                    Vector2 startOutpostSize = Vector2.Zero;
                    if (Level.Loaded.StartOutpost != null)
                    {
                        startOutpostSize = Level.Loaded.StartOutpost.Borders.Size.ToVector2();
                    }
                    Submarine.SetPosition(
                        Level.Loaded.StartOutpost.WorldPosition -
                        new Vector2(0.0f, outpostBorders.Height / 2 + subBorders.Height / 2));

                    //find the port that's the nearest to the outpost and dock if one is found
                    float       closestDistance = 0.0f;
                    DockingPort myPort = null, outPostPort = null;
                    foreach (DockingPort port in DockingPort.List)
                    {
                        if (port.IsHorizontal || port.Docked)
                        {
                            continue;
                        }
                        if (port.Item.Submarine == level.StartOutpost)
                        {
                            outPostPort = port;
                            continue;
                        }
                        if (port.Item.Submarine != Submarine)
                        {
                            continue;
                        }

                        //the submarine port has to be at the top of the sub
                        if (port.Item.WorldPosition.Y < Submarine.WorldPosition.Y)
                        {
                            continue;
                        }

                        float dist = Vector2.DistanceSquared(port.Item.WorldPosition, level.StartOutpost.WorldPosition);
                        if (myPort == null || dist < closestDistance)
                        {
                            myPort          = port;
                            closestDistance = dist;
                        }
                    }

                    if (myPort != null && outPostPort != null)
                    {
                        Vector2 portDiff = myPort.Item.WorldPosition - Submarine.WorldPosition;
                        Submarine.SetPosition((outPostPort.Item.WorldPosition - portDiff) - Vector2.UnitY * outPostPort.DockedDistance);
                        myPort.Dock(outPostPort);
                        myPort.Lock(true);
                    }
                }
                else
                {
                    Submarine.SetPosition(Submarine.FindSpawnPos(level.StartPosition));
                }
            }

            foreach (var sub in Submarine.Loaded)
            {
                if (sub.IsOutpost)
                {
                    sub.DisableObstructedWayPoints();
                }
            }

            Entity.Spawner = new EntitySpawner();

            if (GameMode.Mission != null)
            {
                Mission = GameMode.Mission;
            }
            if (GameMode != null)
            {
                GameMode.Start();
            }
            if (GameMode.Mission != null)
            {
                Mission.Start(Level.Loaded);
            }

            EventManager.StartRound(level);
            SteamAchievementManager.OnStartRound();

            if (GameMode != null)
            {
                GameMode.MsgBox();

                if (GameMode is MultiPlayerCampaign mpCampaign && GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
                {
                    mpCampaign.CargoManager.CreateItems();
                }
            }

            GameAnalyticsManager.AddDesignEvent("Submarine:" + Submarine.Name);
            GameAnalyticsManager.AddDesignEvent("Level", ToolBox.StringToInt(level.Seed));
            GameAnalyticsManager.AddProgressionEvent(GameAnalyticsSDK.Net.EGAProgressionStatus.Start,
                                                     GameMode.Preset.Identifier, (Mission == null ? "None" : Mission.GetType().ToString()));


#if CLIENT
            if (GameMode is SinglePlayerCampaign)
            {
                SteamAchievementManager.OnBiomeDiscovered(level.Biome);
            }
            roundSummary = new RoundSummary(this);

            GameMain.GameScreen.ColorFade(Color.Black, Color.TransparentBlack, 5.0f);

            if (!(GameMode is TutorialMode))
            {
                GUI.AddMessage("", Color.Transparent, 3.0f, playSound: false);
                //TODO: re-enable when biome names have been translated
                //GUI.AddMessage(level.Biome.Name, Color.Lerp(Color.CadetBlue, Color.DarkRed, level.Difficulty / 100.0f), 5.0f, playSound: false);
                GUI.AddMessage(TextManager.AddPunctuation(':', TextManager.Get("Destination"), EndLocation.Name), Color.CadetBlue, playSound: false);
                GUI.AddMessage(TextManager.AddPunctuation(':', TextManager.Get("Mission"), (Mission == null ? TextManager.Get("None") : Mission.Name)), Color.CadetBlue, playSound: false);
            }
#endif

            RoundStartTime = Timing.TotalTime;
            GameMain.ResetFrameTime();
        }
Beispiel #14
0
        static void Main()
        {
            GameMain game = null;

#if !DEBUG
            try
            {
#endif
            game = new GameMain();
            //game.GraphicsDevice.PresentationParameters.IsFullScreen = false;
#if !DEBUG
        }
        catch (Exception e)
        {
            if (game != null)
            {
                game.Dispose();
            }
            CrashDump(null, "crashreport.log", e);
            return;
        }
#endif

#if DEBUG
            game.Run();
#else
            bool attemptRestart = false;

            do
            {
                try
                {
                    game.Run();
                    attemptRestart = false;
                }
                catch (Exception e)
                {
                    if (restartAttempts < 5 && CheckException(game, e))
                    {
                        attemptRestart = true;
                        restartAttempts++;
                    }
                    else
                    {
                        CrashDump(game, "crashreport.log", e);
                        attemptRestart = false;
                    }
                }
            } while (attemptRestart);
#endif

#if !DEBUG
            try
            {
#endif
            game.Dispose();
#if !DEBUG
        }
        catch (Exception e)
        {
            CrashDump(null, "crashreport.log", e);
        }
#endif
        }
Beispiel #15
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds;
            int updateIterations = (int)Math.Floor(Timing.Accumulator / Timing.Step);

            if (Timing.Accumulator > Timing.Step * 6.0)
            {
                //if the game's running too slowly then we have no choice
                //but to skip a bunch of steps
                //otherwise it snowballs and becomes unplayable
                Timing.Accumulator = Timing.Step;
            }

            CrossThread.ProcessTasks();

            PlayerInput.UpdateVariable();

            if (SoundManager != null)
            {
                if (WindowActive || !Config.MuteOnFocusLost)
                {
                    SoundManager.ListenerGain = SoundManager.CompressionDynamicRangeGain;
                }
                else
                {
                    SoundManager.ListenerGain = 0.0f;
                }
            }

            while (Timing.Accumulator >= Timing.Step)
            {
                Timing.TotalTime += Timing.Step;

                Stopwatch sw = new Stopwatch();
                sw.Start();

                fixedTime.IsRunningSlowly = gameTime.IsRunningSlowly;
                TimeSpan addTime = new TimeSpan(0, 0, 0, 0, 16);
                fixedTime.ElapsedGameTime = addTime;
                fixedTime.TotalGameTime.Add(addTime);
                base.Update(fixedTime);

                PlayerInput.Update(Timing.Step);


                if (loadingScreenOpen)
                {
                    //reset accumulator if loading
                    // -> less choppy loading screens because the screen is rendered after each update
                    // -> no pause caused by leftover time in the accumulator when starting a new shift
                    GameMain.ResetFrameTime();

                    if (!TitleScreen.PlayingSplashScreen)
                    {
                        SoundPlayer.Update((float)Timing.Step);
                    }

                    if (TitleScreen.LoadState >= 100.0f && !TitleScreen.PlayingSplashScreen &&
                        (!waitForKeyHit || ((PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.PrimaryMouseButtonClicked()) && WindowActive)))
                    {
                        loadingScreenOpen = false;
                    }

#if DEBUG
                    if (TitleScreen.LoadState >= 100.0f && !TitleScreen.PlayingSplashScreen && Config.AutomaticQuickStartEnabled && FirstLoad)
                    {
                        loadingScreenOpen = false;
                        FirstLoad         = false;
                        MainMenuScreen.QuickStart();
                    }
#endif

                    if (!hasLoaded && !CoroutineManager.IsCoroutineRunning(loadingCoroutine))
                    {
                        throw new LoadingException(loadingCoroutine.Exception);
                    }
                }
                else if (hasLoaded)
                {
                    if (ConnectLobby != 0)
                    {
                        if (Client != null)
                        {
                            Client.Disconnect();
                            Client = null;

                            GameMain.MainMenuScreen.Select();
                        }
                        Steam.SteamManager.JoinLobby(ConnectLobby, true);

                        ConnectLobby    = 0;
                        ConnectEndpoint = null;
                        ConnectName     = null;
                    }
                    else if (!string.IsNullOrWhiteSpace(ConnectEndpoint))
                    {
                        if (Client != null)
                        {
                            Client.Disconnect();
                            Client = null;

                            GameMain.MainMenuScreen.Select();
                        }
                        UInt64 serverSteamId = SteamManager.SteamIDStringToUInt64(ConnectEndpoint);
                        Client = new GameClient(Config.PlayerName,
                                                serverSteamId != 0 ? null : ConnectEndpoint,
                                                serverSteamId,
                                                string.IsNullOrWhiteSpace(ConnectName) ? ConnectEndpoint : ConnectName);
                        ConnectLobby    = 0;
                        ConnectEndpoint = null;
                        ConnectName     = null;
                    }

                    SoundPlayer.Update((float)Timing.Step);

                    if (PlayerInput.KeyHit(Keys.Escape) && WindowActive)
                    {
                        // Check if a text input is selected.
                        if (GUI.KeyboardDispatcher.Subscriber != null)
                        {
                            if (GUI.KeyboardDispatcher.Subscriber is GUITextBox textBox)
                            {
                                textBox.Deselect();
                            }
                            GUI.KeyboardDispatcher.Subscriber = null;
                        }
                        //if a verification prompt (are you sure you want to x) is open, close it
                        else if (GUIMessageBox.VisibleBox as GUIMessageBox != null &&
                                 GUIMessageBox.VisibleBox.UserData as string == "verificationprompt")
                        {
                            ((GUIMessageBox)GUIMessageBox.VisibleBox).Close();
                        }
                        else if (Tutorial.Initialized && Tutorial.ContentRunning)
                        {
                            (GameSession.GameMode as TutorialMode).Tutorial.CloseActiveContentGUI();
                        }
                        else if (GameSession.IsTabMenuOpen)
                        {
                            gameSession.ToggleTabMenu();
                        }
                        else if (GUI.PauseMenuOpen)
                        {
                            GUI.TogglePauseMenu();
                        }
                        //open the pause menu if not controlling a character OR if the character has no UIs active that can be closed with ESC
                        else if ((Character.Controlled == null || !itemHudActive())
                                 //TODO: do we need to check Inventory.SelectedSlot?
                                 && Inventory.SelectedSlot == null && CharacterHealth.OpenHealthWindow == null &&
                                 !CrewManager.IsCommandInterfaceOpen &&
                                 !(Screen.Selected is SubEditorScreen editor && !editor.WiringMode && Character.Controlled.SelectedConstruction != null))
                        {
                            // Otherwise toggle pausing, unless another window/interface is open.
                            GUI.TogglePauseMenu();
                        }

                        bool itemHudActive()
                        {
                            if (Character.Controlled?.SelectedConstruction == null)
                            {
                                return(false);
                            }
                            return
                                (Character.Controlled.SelectedConstruction.ActiveHUDs.Any(ic => ic.GuiFrame != null) ||
                                 ((Character.Controlled.ViewTarget as Item)?.Prefab?.FocusOnSelected ?? false));
                        }
                    }

#if DEBUG
                    if (GameMain.NetworkMember == null)
                    {
                        if (PlayerInput.KeyHit(Keys.P) && !(GUI.KeyboardDispatcher.Subscriber is GUITextBox))
                        {
                            DebugConsole.Paused = !DebugConsole.Paused;
                        }
                    }
#endif

                    GUI.ClearUpdateList();
                    Paused = (DebugConsole.IsOpen || GUI.PauseMenuOpen || GUI.SettingsMenuOpen || Tutorial.ContentRunning || DebugConsole.Paused) &&
                             (NetworkMember == null || !NetworkMember.GameStarted);

#if !DEBUG
                    if (NetworkMember == null && !WindowActive && !Paused && true && Screen.Selected != MainMenuScreen && Config.PauseOnFocusLost)
                    {
                        GUI.TogglePauseMenu();
                        Paused = true;
                    }
#endif

                    Screen.Selected.AddToGUIUpdateList();

                    if (Client != null)
                    {
                        Client.AddToGUIUpdateList();
                    }

                    FileSelection.AddToGUIUpdateList();

                    DebugConsole.AddToGUIUpdateList();

                    DebugConsole.Update((float)Timing.Step);
                    Paused = Paused || (DebugConsole.IsOpen && (NetworkMember == null || !NetworkMember.GameStarted));

                    if (!Paused)
                    {
                        Screen.Selected.Update(Timing.Step);
                    }
                    else if (Tutorial.Initialized && Tutorial.ContentRunning)
                    {
                        (GameSession.GameMode as TutorialMode).Update((float)Timing.Step);
                    }
                    else if (DebugConsole.Paused)
                    {
                        if (Screen.Selected.Cam == null)
                        {
                            DebugConsole.Paused = false;
                        }
                        else
                        {
                            Screen.Selected.Cam.MoveCamera((float)Timing.Step);
                        }
                    }

                    if (NetworkMember != null)
                    {
                        NetworkMember.Update((float)Timing.Step);
                    }

                    GUI.Update((float)Timing.Step);
                }

                CoroutineManager.Update((float)Timing.Step, Paused ? 0.0f : (float)Timing.Step);

                SteamManager.Update((float)Timing.Step);

                TaskPool.Update();

                SoundManager?.Update();

                Timing.Accumulator -= Timing.Step;

                sw.Stop();
                PerformanceCounter.AddElapsedTicks("Update total", sw.ElapsedTicks);
                PerformanceCounter.UpdateTimeGraph.Update(sw.ElapsedTicks * 1000.0f / (float)Stopwatch.Frequency);
                PerformanceCounter.UpdateIterationsGraph.Update(updateIterations);
            }

            if (!Paused)
            {
                Timing.Alpha = Timing.Accumulator / Timing.Step;
            }
        }
Beispiel #16
0
        private static bool CheckException(GameMain game, Exception e)
        {
#if WINDOWS
            if (e is SharpDX.SharpDXException sharpDxException)
            {
                DebugConsole.NewMessage("SharpDX exception caught. ("
                                        + e.Message + ", " + sharpDxException.ResultCode.Code.ToString("X") + "). Attempting to fix...", Microsoft.Xna.Framework.Color.Red);

                switch ((UInt32)sharpDxException.ResultCode.Code)
                {
                case 0x887A0022:     //DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
                    switch (restartAttempts)
                    {
                    case 0:
                        //just wait and try again
                        DebugConsole.NewMessage("Retrying after 100 ms...", Microsoft.Xna.Framework.Color.Red);
                        System.Threading.Thread.Sleep(100);
                        return(true);

                    case 1:
                        //force focus to this window
                        DebugConsole.NewMessage("Forcing focus to the window and retrying...", Microsoft.Xna.Framework.Color.Red);
                        var myForm = (Form)Control.FromHandle(game.Window.Handle);
                        myForm.Focus();
                        return(true);

                    case 2:
                        //try disabling hardware mode switch
                        if (GameMain.Config.WindowMode == WindowMode.Fullscreen)
                        {
                            DebugConsole.NewMessage("Failed to set fullscreen mode, switching configuration to borderless windowed.", Microsoft.Xna.Framework.Color.Red);
                            GameMain.Config.WindowMode = WindowMode.BorderlessWindowed;
                            GameMain.Config.SaveNewPlayerConfig();
                        }
                        return(false);

                    default:
                        DebugConsole.NewMessage("Failed to resolve the DXGI_ERROR_NOT_CURRENTLY_AVAILABLE exception. Give up and let it crash :(", Microsoft.Xna.Framework.Color.Red);
                        return(false);
                    }

                case 0x80070057:     //E_INVALIDARG/Invalid Arguments
                    DebugConsole.NewMessage("Invalid graphics settings, attempting to fix...", Microsoft.Xna.Framework.Color.Red);

                    GameMain.Config.GraphicsWidth  = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
                    GameMain.Config.GraphicsHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;

                    DebugConsole.NewMessage("Display size set to " + GameMain.Config.GraphicsWidth + "x" + GameMain.Config.GraphicsHeight, Microsoft.Xna.Framework.Color.Red);

                    game.ApplyGraphicsSettings();

                    return(true);

                default:
                    DebugConsole.NewMessage("Unknown SharpDX exception code (" + sharpDxException.ResultCode.Code.ToString("X") + ")", Microsoft.Xna.Framework.Color.Red);
                    return(false);
                }
            }
#endif

            return(false);
        }
        private void InitializeLevel(Level level)
        {
            //make sure no status effects have been carried on from the next round
            //(they should be stopped in EndRound, this is a safeguard against cases where the round is ended ungracefully)
            StatusEffect.StopAll();

#if CLIENT
            GameMain.LightManager.LosEnabled = GameMain.Client == null || GameMain.Client.CharacterInfo != null;
            if (GameMain.Client == null)
            {
                GameMain.LightManager.LosMode = GameMain.Config.LosMode;
            }
#endif
            LevelData = level?.LevelData;
            Level     = level;

            PlaceSubAtStart(Level);

            foreach (var sub in Submarine.Loaded)
            {
                if (sub.Info.IsOutpost)
                {
                    sub.DisableObstructedWayPoints();
                }
            }

            Entity.Spawner = new EntitySpawner();

            if (GameMode.Mission != null)
            {
                Mission = GameMode.Mission;
            }
            if (GameMode != null)
            {
                GameMode.Start();
            }
            if (GameMode.Mission != null)
            {
                int prevEntityCount = Entity.GetEntities().Count();
                Mission.Start(Level.Loaded);
                if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient && Entity.GetEntities().Count() != prevEntityCount)
                {
                    DebugConsole.ThrowError(
                        "Entity count has changed after starting a mission as a client. " +
                        "The clients should not instantiate entities themselves when starting the mission," +
                        " but instead the server should inform the client of the spawned entities using Mission.ServerWriteInitial.");
                }
            }

            EventManager?.StartRound(Level.Loaded);
            SteamAchievementManager.OnStartRound();

            if (GameMode != null)
            {
                GameMode.ShowStartMessage();

                if (GameMain.NetworkMember == null)
                {
                    //only place items and corpses here in single player
                    //the server does this after loading the respawn shuttle
                    Level?.SpawnNPCs();
                    Level?.SpawnCorpses();
                    Level?.PrepareBeaconStation();
                    AutoItemPlacer.PlaceIfNeeded();
                }
                if (GameMode is MultiPlayerCampaign mpCampaign)
                {
                    if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
                    {
                        mpCampaign.CargoManager.CreatePurchasedItems();
#if SERVER
                        mpCampaign.SendCrewState(false, null);
#endif
                    }
                    mpCampaign.UpgradeManager.ApplyUpgrades();
                    mpCampaign.UpgradeManager.SanityCheckUpgrades(Submarine);
                }
                if (GameMode is CampaignMode)
                {
                    Submarine.WarmStartPower();
                }
            }

            GameMain.Config.RecentlyEncounteredCreatures.Clear();

            GameMain.GameScreen.Cam.Position = Character.Controlled?.WorldPosition ?? Submarine.MainSub.WorldPosition;
            RoundStartTime = Timing.TotalTime;
            GameMain.ResetFrameTime();
            IsRunning = true;
        }
Beispiel #18
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            Timing.TotalTime    = gameTime.TotalGameTime.TotalSeconds;
            Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds;
            int updateIterations = (int)Math.Floor(Timing.Accumulator / Timing.Step);

            if (Timing.Accumulator > Timing.Step * 6.0)
            {
                //if the game's running too slowly then we have no choice
                //but to skip a bunch of steps
                //otherwise it snowballs and becomes unplayable
                Timing.Accumulator = Timing.Step;
            }

            CrossThread.ProcessTasks();

            PlayerInput.UpdateVariable();

            bool paused = true;

            if (SoundManager != null)
            {
                if (WindowActive || !Config.MuteOnFocusLost)
                {
                    SoundManager.ListenerGain = 1.0f;
                }
                else
                {
                    SoundManager.ListenerGain = 0.0f;
                }
            }

            while (Timing.Accumulator >= Timing.Step)
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();

                fixedTime.IsRunningSlowly = gameTime.IsRunningSlowly;
                TimeSpan addTime = new TimeSpan(0, 0, 0, 0, 16);
                fixedTime.ElapsedGameTime = addTime;
                fixedTime.TotalGameTime.Add(addTime);
                base.Update(fixedTime);

                PlayerInput.Update(Timing.Step);


                if (loadingScreenOpen)
                {
                    //reset accumulator if loading
                    // -> less choppy loading screens because the screen is rendered after each update
                    // -> no pause caused by leftover time in the accumulator when starting a new shift
                    GameMain.ResetFrameTime();

                    if (!TitleScreen.PlayingSplashScreen)
                    {
                        SoundPlayer.Update((float)Timing.Step);
                    }

                    if (TitleScreen.LoadState >= 100.0f && !TitleScreen.PlayingSplashScreen &&
                        (!waitForKeyHit || ((PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.LeftButtonClicked()) && WindowActive)))
                    {
                        loadingScreenOpen = false;
                    }

                    if (!hasLoaded && !CoroutineManager.IsCoroutineRunning(loadingCoroutine))
                    {
                        string errMsg = "Loading was interrupted due to an error";
                        if (loadingCoroutine.Exception != null)
                        {
                            errMsg += ": " + loadingCoroutine.Exception.Message + "\n" + loadingCoroutine.Exception.StackTrace;
                        }
                        throw new Exception(errMsg);
                    }
                }
                else if (hasLoaded)
                {
                    SoundPlayer.Update((float)Timing.Step);

                    if (PlayerInput.KeyHit(Keys.Escape) && WindowActive)
                    {
                        // Check if a text input is selected.
                        if (GUI.KeyboardDispatcher.Subscriber != null)
                        {
                            if (GUI.KeyboardDispatcher.Subscriber is GUITextBox textBox)
                            {
                                textBox.Deselect();
                            }
                            GUI.KeyboardDispatcher.Subscriber = null;
                        }
                        //if a verification prompt (are you sure you want to x) is open, close it
                        else if (GUIMessageBox.VisibleBox as GUIMessageBox != null &&
                                 GUIMessageBox.VisibleBox.UserData as string == "verificationprompt")
                        {
                            ((GUIMessageBox)GUIMessageBox.VisibleBox).Close();
                        }
                        else if (Tutorial.Initialized && Tutorial.ContentRunning)
                        {
                            (GameSession.GameMode as TutorialMode).Tutorial.CloseActiveContentGUI();
                        }
                        else if (GUI.PauseMenuOpen)
                        {
                            GUI.TogglePauseMenu();
                        }
                        else if ((Character.Controlled?.SelectedConstruction == null || !Character.Controlled.SelectedConstruction.ActiveHUDs.Any(ic => ic.GuiFrame != null)) &&
                                 Inventory.SelectedSlot == null && CharacterHealth.OpenHealthWindow == null)
                        {
                            // Otherwise toggle pausing, unless another window/interface is open.
                            GUI.TogglePauseMenu();
                        }
                    }

                    GUI.ClearUpdateList();
                    paused = (DebugConsole.IsOpen || GUI.PauseMenuOpen || GUI.SettingsMenuOpen || Tutorial.ContentRunning) &&
                             (NetworkMember == null || !NetworkMember.GameStarted);

#if !DEBUG
                    if (NetworkMember == null && !WindowActive && !paused && true && Screen.Selected != MainMenuScreen && Config.PauseOnFocusLost)
                    {
                        GUI.TogglePauseMenu();
                        paused = true;
                    }
#endif

                    Screen.Selected.AddToGUIUpdateList();

                    if (Client != null)
                    {
                        Client.AddToGUIUpdateList();
                    }

                    DebugConsole.AddToGUIUpdateList();

                    DebugConsole.Update(this, (float)Timing.Step);
                    paused = paused || (DebugConsole.IsOpen && (NetworkMember == null || !NetworkMember.GameStarted));

                    if (!paused)
                    {
                        Screen.Selected.Update(Timing.Step);
                    }
                    else if (Tutorial.Initialized && Tutorial.ContentRunning)
                    {
                        (GameSession.GameMode as TutorialMode).Update((float)Timing.Step);
                    }

                    if (NetworkMember != null)
                    {
                        NetworkMember.Update((float)Timing.Step);
                    }

                    GUI.Update((float)Timing.Step);
                }

                CoroutineManager.Update((float)Timing.Step, paused ? 0.0f : (float)Timing.Step);

                SteamManager.Update((float)Timing.Step);

                Timing.Accumulator -= Timing.Step;

                sw.Stop();
                PerformanceCounter.AddElapsedTicks("Update total", sw.ElapsedTicks);
                PerformanceCounter.UpdateTimeGraph.Update(sw.ElapsedTicks / (float)TimeSpan.TicksPerMillisecond);
                PerformanceCounter.UpdateIterationsGraph.Update(updateIterations);
            }

            if (!paused)
            {
                Timing.Alpha = Timing.Accumulator / Timing.Step;
            }
        }
Beispiel #19
0
        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();

            string  exePath = System.Reflection.Assembly.GetEntryAssembly().Location;
            var     md5     = System.Security.Cryptography.MD5.Create();
            Md5Hash exeHash = null;

            try
            {
                using (var stream = File.OpenRead(exePath))
                {
                    exeHash = new Md5Hash(stream);
                }
            }
            catch
            {
                //gotta catch them all, we don't want to throw an exception while writing a crash report
            }

            StreamWriter sw = new StreamWriter(filePath);

            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");
            if (exeHash?.Hash != null)
            {
                sb.AppendLine(exeHash.Hash);
            }
            sb.AppendLine("\n");
#if DEBUG
            sb.AppendLine("Game version " + GameMain.Version + " (debug build)");
#else
            sb.AppendLine("Game version " + GameMain.Version);
#endif
            if (GameMain.Config != null)
            {
                sb.AppendLine("Graphics mode: " + GameMain.Config.GraphicsWidth + "x" + GameMain.Config.GraphicsHeight + " (" + GameMain.Config.WindowMode.ToString() + ")");
            }
            if (GameMain.SelectedPackages != null)
            {
                sb.AppendLine("Selected content packages: " + (!GameMain.SelectedPackages.Any() ? "None" : string.Join(", ", GameMain.SelectedPackages.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.Name + " (" + Submarine.MainSub.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);
#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();

            sw.WriteLine(crashReport);
            sw.Close();

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