/// <summary>
        /// Loads valid profile entries and reloads the necessary UI components.
        /// </summary>
        private void LoadProfilesAndAdjustLists()
        {
            // Reset loaded profiles
            profileDropDown.Items.Clear();
            profileList.Clear();
            profileIndex = null;

            // Load the profileList
            profileList = Profile.LoadProfiles();

            // Add profile names to the profileDropDown
            foreach (ProfileXML profile in profileList)
            {
                // Archive version notes
                if (!profile.Installable)
                {
                    if (profile.Name.Contains("Community Updates"))
                    {
                        profile.ProfileNotes = Text.ArchiveNotesCommunityUpdates;
                    }
                    else
                    {
                        profile.ProfileNotes = Text.ArchiveNotesMods + "\n\n" + profile.ProfileNotes;
                    }
                }

                profileDropDown.Items.Add(profile.Name);
            }

            // Read the value from the config
            string profIndexString = CrossPlatformOperations.ReadFromConfig("ProfileIndex");

            // Check if either no profile was found or the setting says that the last current profile didn't exist
            if (profileDropDown.Items.Count == 0)
            {
                profileIndex = null;
            }
            else
            {
                // We know that profiles exist at this point, so we're going to point it to 0 instead so the following code doesn't fail
                if (profIndexString == "null")
                {
                    profIndexString = "0";
                }

                // We parse from the settings, and check if profiles got deleted from the last time the launcher has been selected. if yes, we revert the last selection to 0;
                int intParseResult = Int32.Parse(profIndexString);
                profileIndex = intParseResult;
                if (profileIndex >= profileDropDown.Items.Count)
                {
                    profileIndex = 0;
                }
                profileDropDown.SelectedIndex = profileIndex.Value;
            }

            // Update stored profiles in the Profile Settings tab
            modSettingsProfileDropDown.Items.Clear();
            modSettingsProfileDropDown.Items.AddRange(profileDropDown.Items);
            modSettingsProfileDropDown.SelectedIndex = profileDropDown.Items.Count != 0 ? 0 : -1;

            // Refresh the author and version label on the main tab
            if (profileList.Count > 0)
            {
                profileAuthorLabel.Text  = Text.Author + " " + profileList[profileDropDown.SelectedIndex].Author;
                profileVersionLabel.Text = Text.VersionLabel + " " + profileList[profileDropDown.SelectedIndex].Version;
            }

            log.Info("Reloading UI components after loading successful.");

            UpdateStateMachine();
        }
Beispiel #2
0
        public MainForm()
        {
            // Exit if we're already running the AM2RLauncher
            // Thanks, StackOverflow! https://stackoverflow.com/questions/184084/how-to-force-c-sharp-net-app-to-run-only-one-instance-in-windows
            if (!singleInstance)
            {
                // If on Windows, set the original app to the foreground window to prevent confusion
                if (OS.IsWindows)
                {
                    Process current = Process.GetCurrentProcess();
                    Process process = Process.GetProcessesByName(current.ProcessName).First(p => p.Id == current.Id);
                    if (process != null)
                    {
                        Core.Core.SetForegroundWindow(process.MainWindowHandle);
                    }
                }
                Environment.Exit(0);
            }

            log.Info("Mutex check passed. Entering main thread.");
            log.Info("Current Launcher Version: " + VERSION);
            log.Info("Current Platform-ID is: " + Platform.ID);
            log.Info("Current OS is: " + OS.Name);

            // Set the Current Directory to the path the Launcher is located. Fixes some relative path issues.
            Environment.CurrentDirectory = CrossPlatformOperations.CURRENTPATH;
            log.Info("Set Launcher CWD to " + Environment.CurrentDirectory);

            // But log actual folder location nonetheless
            log.Info("Actual Launcher location: " + Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory));

            // Set the language to what User wanted or choose local language
            string userLanguage = CrossPlatformOperations.ReadFromConfig("Language").ToLower();

            if (!userLanguage.Equals("default"))
            {
                Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultures(CultureTypes.AllCultures).First(c => c.NativeName.ToLower().Contains(userLanguage));
            }

            log.Info("Language has been set to: " + Thread.CurrentThread.CurrentUICulture.EnglishName);

            #region VARIABLE INITIALIZATION
            log.Info("Beginning UI initialization...");

            Bitmap am2rIcon = new Bitmap(AM2RLauncher.Properties.Resources.AM2RIcon);

            // System tray indicator
            ButtonMenuItem showButton = new ButtonMenuItem {
                Text = Text.TrayButtonShow
            };
            trayIndicator = new TrayIndicator
            {
                Menu    = new ContextMenu(showButton),
                Title   = "AM2RLauncher",
                Visible = false,
                Image   = am2rIcon
            };

            // Create menubar with defaults for mac
            if (OS.IsMac)
            {
                Menu = new MenuBar();
            }

            // Create array from validCount
            profileList = new List <ProfileXML>();

            //TODO: whenever profileDropDown gets rewritten to use a datastore, scrap this
            profileNames = new List <ListItem>();
            foreach (var profile in profileList)
            {
                profileNames.Add(profile.Name);
            }

            // Custom splash texts
            string splash = Splash.GetSplash();
            log.Info("Randomly chosen splash: " + splash);

            Font smallButtonFont = new Font(SystemFont.Default, 10);

            // Create mirror list - eventually this should be platform specific!
            // We do this as a List<Uri> so we can add more dynamically on user input... if necessary.
            mirrorList = CrossPlatformOperations.GenerateMirrorList();

            // Create mirror list
            // We do this as a list<listItem> for 1) make this dynamic and 2) make ETO happy
            mirrorDescriptionList = new List <ListItem>();
            // Add each entry dynamically instead of harcoding it to two. If we have neither a github or gitlab mirror, we use the mirror itself as text
            foreach (var mirror in mirrorList)
            {
                string text = mirror;
                if (text.Contains("github.com"))
                {
                    text = Text.MirrorGithubText;
                }
                else if (text.Contains("gitlab.com"))
                {
                    text = Text.MirrorGitlabText;
                }
                mirrorDescriptionList.Add(new ListItem()
                {
                    Key = mirror, Text = text
                });
            }
            #endregion

            Icon        = new Icon(1f, am2rIcon);
            Title       = "AM2RLauncher " + VERSION + ": " + splash;
            MinimumSize = new Size(500, 400);
            // TODO: for some reason, this sometimes doesn't work on Linux. Was reported at eto, stays here until its fixed
            ClientSize = new Size(Int32.Parse(CrossPlatformOperations.ReadFromConfig("Width")), Int32.Parse(CrossPlatformOperations.ReadFromConfig("Height")));
            if (ClientSize.Width < 500)
            {
                ClientSize = new Size(500, ClientSize.Height);
            }
            if (ClientSize.Height < 400)
            {
                ClientSize = new Size(ClientSize.Width, 400);
            }
            log.Info("Start the launcher with Size: " + ClientSize.Width + ", " + ClientSize.Height);
            if (Boolean.Parse(CrossPlatformOperations.ReadFromConfig("IsMaximized")))
            {
                Maximize();
            }

            drawable = new Drawable {
                BackgroundColor = colBGNoAlpha
            };

            // Drawable paint event
            drawable.Paint += DrawablePaintEvent;
            // Some systems don't call the paintEvent by default and only do so after actual resizing
            if (OS.IsMac)
            {
                LoadComplete += (sender, e) => { Size = new Size(Size.Width + 1, Size.Height); Size = new Size(Size.Width - 1, Size.Height); }
            }
            ;

            #region MAIN WINDOW

            // Center buttons/interface panel
            var centerInterface = new DynamicLayout();

            // PLAY button
            playButton = new ColorButton
            {
                ToolTip = "",
                BackgroundColorHover = colBGHover,
                Height             = 40,
                Width              = 250,
                TextColor          = colGreen,
                TextColorDisabled  = colInactive,
                BackgroundColor    = colBG,
                FrameColor         = colGreen,
                FrameColorDisabled = colInactive
            };

            UpdateStateMachine();

            SetPlayButtonState(updateState);

            centerInterface.AddRow(playButton);

            // 2px spacer between playButton and apkButton (Windows only)
            if (OS.IsWindows)
            {
                centerInterface.AddRow(new Label {
                    BackgroundColor = colBG, Height = 2
                });
            }

            // APK button
            apkButton = new ColorButton
            {
                Text                 = Text.CreateAPK,
                Height               = 40,
                Width                = 250,
                TextColor            = colGreen,
                BackgroundColor      = colBG,
                FrameColor           = colGreen,
                BackgroundColorHover = colBGHover
            };

            centerInterface.AddRow(apkButton);

            progressBar = new ProgressBar
            {
                Visible = false,
                Height  = 15
            };

            // 4px spacer between APK button and progressBar (Windows only)
            if (OS.IsWindows)
            {
                centerInterface.AddRow(new Label {
                    BackgroundColor = colBG, Height = 4
                });
            }

            centerInterface.AddRow(progressBar);

            progressLabel = new Label
            {
                BackgroundColor = colBG,
                Height          = 15,
                Text            = "",
                TextColor       = colGreen,
                Visible         = false
            };

            centerInterface.AddRow(progressLabel);

            // 3px spacer between progressBar and profile label (Windows only)
            if (OS.IsWindows)
            {
                centerInterface.AddRow(new Label {
                    BackgroundColor = colBG, Height = 3
                });
            }

            profileLabel = new Label
            {
                BackgroundColor = colBG,
                Height          = 15,
                Text            = Text.CurrentProfile,
                TextColor       = colGreen
            };

            centerInterface.AddRow(profileLabel);

            // Profiles dropdown

            // Yes, we know this looks horrific on GTK. Sorry.
            // We're not exactly in a position to rewrite the entire DropDown object as a Drawable child, but if you want to, you're more than welcome!
            // Mac gets a default BackgroundColor because it looks waaaaaaay better.
            profileDropDown = new DropDown
            {
                TextColor       = colGreen,
                BackgroundColor = OS.IsWindows ? colBGNoAlpha : new Color()
            };
            // In order to not have conflicting theming, we just always respect the users theme for dropdown on GTK.
            if (OS.IsLinux)
            {
                profileDropDown = new DropDown();
            }

            profileDropDown.Items.AddRange(profileNames);   // It's actually more comfortable if it's outside, because of GTK shenanigans

            centerInterface.AddRow(profileDropDown);

            // Profiles label
            profileAuthorLabel = new Label
            {
                BackgroundColor = colBG,
                Height          = 16,
                Text            = Text.Author + " ",
                TextColor       = colGreen
            };

            centerInterface.AddRow(profileAuthorLabel);

            profileVersionLabel = new Label
            {
                BackgroundColor = colBG,
                Height          = 16,
                Text            = Text.VersionLabel + " ",
                TextColor       = colGreen
            };

            centerInterface.AddRow(profileVersionLabel);

            saveWarningLabel = new Label
            {
                Visible         = false,
                BackgroundColor = colBG,
                Width           = 20,
                Height          = 55,
                Text            = Text.SaveLocationWarning,
                TextColor       = colRed
            };

            centerInterface.AddRow(saveWarningLabel);


            // Social buttons
            Bitmap redditIcon   = new Bitmap(Resources.redditIcon48);
            var    redditButton = new ImageButton {
                ToolTip = Text.RedditToolTip, Image = redditIcon
            };
            redditButton.Click += (sender, e) => CrossPlatformOperations.OpenURL("https://www.reddit.com/r/AM2R");

            Bitmap githubIcon   = new Bitmap(Resources.githubIcon48);
            var    githubButton = new ImageButton {
                ToolTip = Text.GithubToolTip, Image = githubIcon
            };
            githubButton.Click += (sender, e) => CrossPlatformOperations.OpenURL("https://www.github.com/AM2R-Community-Developers");

            Bitmap youtubeIcon   = new Bitmap(Resources.youtubeIcon48);
            var    youtubeButton = new ImageButton {
                ToolTip = Text.YoutubeToolTip, Image = youtubeIcon
            };
            youtubeButton.Click += (sender, e) => CrossPlatformOperations.OpenURL("https://www.youtube.com/c/AM2RCommunityUpdates");

            Bitmap discordIcon   = new Bitmap(Resources.discordIcon48);
            var    discordButton = new ImageButton {
                ToolTip = Text.DiscordToolTip, Image = discordIcon
            };
            discordButton.Click += (sender, e) => CrossPlatformOperations.OpenURL("https://discord.gg/nk7UYPbd5u");


            // Social button panel
            var socialPanel = new DynamicLayout();
            socialPanel.BeginVertical();
            socialPanel.AddRow(redditButton);
            socialPanel.AddRow(githubButton);
            socialPanel.AddRow(youtubeButton);
            socialPanel.AddRow(discordButton);
            socialPanel.EndVertical();


            // Version number label
            Label versionLabel = new Label
            {
                Text  = "v" + VERSION + (isThisRunningFromWine ? "-WINE" : ""),
                Width = 48, TextAlignment = TextAlignment.Right, TextColor = colGreen,
                Font  = new Font(SystemFont.Default, 12)
            };

            // Tie everything together
            var mainLayout = new DynamicLayout();

            mainLayout.BeginHorizontal();
            mainLayout.AddColumn(null, socialPanel);

            mainLayout.AddSpace();
            mainLayout.AddColumn(null, centerInterface, null);
            mainLayout.AddSpace();

            // Yes, I'm hardcoding this string. Linux users can english.
            mainLayout.AddColumn(versionLabel, isThisRunningFromWine ? new Label {
                Text = "Unsupported", TextColor = colRed, TextAlignment = TextAlignment.Right
            } : null);

            drawable.Content = mainLayout;

            #endregion

            #region TABS

            #region MAIN PAGE
            // [MAIN PAGE]
            TabPage mainPage = new TabPage
            {
                BackgroundColor = colBGNoAlpha,
                Text            = Text.PlayTab,
                Content         = drawable
            };
            #endregion

            #region CHANGELOG PAGE
            // [CHANGELOG]
            Uri     changelogUri     = new Uri("https://am2r-community-developers.github.io/DistributionCenter/changelog.html");
            WebView changelogWebView = new WebView {
                Url = changelogUri
            };

            if (OS.IsUnix && !isInternetThere)
            {
                changelogWebView = new WebView();
            }

            Label changelogNoConnectionLabel = new Label
            {
                Text      = Text.NoInternetConnection,
                TextColor = colGreen
            };

            TabPage changelogPage = new TabPage
            {
                BackgroundColor = colBGNoAlpha,
                Text            = Text.ChangelogTab,

                Content = new TableLayout
                {
                    Rows =
                    {
                        changelogWebView
                    }
                }
            };

            #endregion

            #region NEWS PAGE

            // [NEWS]
            Uri     newsUri     = new Uri("https://am2r-community-developers.github.io/DistributionCenter/news.html");
            WebView newsWebView = new WebView {
                Url = newsUri
            };

            //TODO: why exactly is this check necessary?
            if (OS.IsUnix && !isInternetThere)
            {
                newsWebView = new WebView();
            }

            Label newsNoConnectionLabel = new Label
            {
                Text      = Text.NoInternetConnection,
                TextColor = colGreen
            };

            TabPage newsPage = new TabPage
            {
                Text            = Text.NewsTab,
                BackgroundColor = colBGNoAlpha,

                Content = new TableLayout
                {
                    Rows =
                    {
                        newsWebView
                    }
                }
            };

            //TODO: this is hack because on linux / mac the other way doesn't work. eto issue?
            if (OS.IsUnix && !isInternetThere)
            {
                changelogPage.Content = new TableLayout
                {
                    Rows =
                    {
                        null,
                        changelogNoConnectionLabel,
                        null
                    }
                };
                newsPage.Content = new TableLayout
                {
                    Rows =
                    {
                        null,
                        newsNoConnectionLabel,
                        null
                    }
                };
            }

            #endregion

            #region SETTINGS PAGE

            // [LAUNCHER SETTINGS]
            DynamicLayout settingsLayout = new DynamicLayout();

            // LanguageLabel
            Label languageLabel = new Label
            {
                Text      = Text.LanguageNotice,
                TextColor = colGreen
            };

            // Language DropDown menu

            List <ListItem> languageList = new List <ListItem>
            {
                Text.SystemLanguage,
                "Deutsch",
                "English",
                "Español",
                "Français",
                "Italiano",
                "Português",
                "Русский",
                "日本語",
                "中文(简体)"
            };

            languageDropDown = new DropDown
            {
                TextColor       = colGreen,
                BackgroundColor = OS.IsWindows ? colBGNoAlpha : new Color()
            };
            if (OS.IsLinux)
            {
                languageDropDown = new DropDown();
            }

            languageDropDown.Items.AddRange(languageList);

            var tmpLanguage = CrossPlatformOperations.ReadFromConfig("Language");
            languageDropDown.SelectedIndex = tmpLanguage == "Default" ? 0 : languageDropDown.Items.IndexOf(languageDropDown.Items.FirstOrDefault(x => x.Text.Equals(tmpLanguage)));

            if (languageDropDown.SelectedIndex == -1)
            {
                log.Info("User has tried to use " + tmpLanguage + " as a Language, but it was not found. Reverting to System Language");
                languageDropDown.SelectedIndex = 0;
            }

            // autoUpdateAM2R checkbox
            autoUpdateAM2RCheck = new CheckBox
            {
                Checked   = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("AutoUpdateAM2R")),
                Text      = Text.AutoUpdateAM2R,
                TextColor = colGreen
            };


            // autoUpdateLauncher checkbox
            autoUpdateLauncherCheck = new CheckBox
            {
                Checked   = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("AutoUpdateLauncher")),
                Text      = Text.AutoUpdateLauncher,
                TextColor = colGreen
            };

            // HQ music, PC
            hqMusicPCCheck = new CheckBox
            {
                Checked   = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("MusicHQPC")),
                Text      = Text.HighQualityPC,
                TextColor = colGreen
            };

            // HQ music, Android
            hqMusicAndroidCheck = new CheckBox
            {
                Checked   = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("MusicHQAndroid")),
                Text      = Text.HighQualityAndroid,
                TextColor = colGreen
            };

            // Create game debug logs
            profileDebugLogCheck = new CheckBox
            {
                Checked   = bool.Parse(CrossPlatformOperations.ReadFromConfig("ProfileDebugLog")),
                Text      = Text.ProfileDebugCheckBox,
                TextColor = colGreen
            };

            // Custom environment variables label
            Label customEnvVarLabel = new Label();
            if (OS.IsLinux)
            {
                customEnvVarLabel = new Label
                {
                    Text      = Text.CustomEnvVarLabel,
                    TextColor = colGreen
                };
            }

            // Custom environment variables textbox
            customEnvVarTextBox = null;
            if (OS.IsLinux)
            {
                customEnvVarTextBox = new TextBox
                {
                    Text            = CrossPlatformOperations.ReadFromConfig("CustomEnvVar"),
                    BackgroundColor = colBGNoAlpha,
                    TextColor       = colGreen
                };
            }

            // Mirror list
            mirrorLabel = new Label
            {
                Text      = Text.DownloadSource,
                TextColor = colGreen
            };

            mirrorDropDown = new DropDown
            {
                TextColor       = colGreen,
                BackgroundColor = OS.IsWindows ? colBGNoAlpha : new Color()
            };
            if (OS.IsLinux)
            {
                mirrorDropDown = new DropDown();
            }

            mirrorDropDown.Items.AddRange(mirrorDescriptionList);   // As above, find a way to get this inside the dropDown definition
            mirrorIndex = (Int32.Parse(CrossPlatformOperations.ReadFromConfig("MirrorIndex")) < mirrorDropDown.Items.Count) ? Int32.Parse(CrossPlatformOperations.ReadFromConfig("MirrorIndex"))
                                                                                                                            : 0;
            mirrorDropDown.SelectedIndex = mirrorIndex;

            currentMirror = mirrorList[mirrorDropDown.SelectedIndex];

            // Custom mirror
            customMirrorCheck = new CheckBox
            {
                Checked   = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("CustomMirrorEnabled")),
                Text      = Text.CustomMirrorCheck,
                TextColor = colGreen
            };

            customMirrorTextBox = new TextBox
            {
                Text            = CrossPlatformOperations.ReadFromConfig("CustomMirrorText"),
                BackgroundColor = colBGNoAlpha,
                TextColor       = colGreen
            };

            EnableMirrorControlsAccordingly();

            settingsLayout.BeginHorizontal();
            settingsLayout.AddSpace();
            settingsLayout.AddColumn(null, languageLabel, languageDropDown, autoUpdateAM2RCheck, autoUpdateLauncherCheck, hqMusicPCCheck, hqMusicAndroidCheck, profileDebugLogCheck, customEnvVarLabel, (Control)customEnvVarTextBox ?? new Label(), mirrorLabel, mirrorDropDown, customMirrorCheck, customMirrorTextBox, null);
            settingsLayout.AddSpace();

            TabPage settingsPage = new TabPage
            {
                BackgroundColor = colBGNoAlpha,
                Content         = settingsLayout,
                Text            = Text.LauncherSettingsTab
            };

            #endregion

            #region MODSETTINGS PAGE

            // [MOD SETTINGS]
            DynamicLayout modSettingsLayout = new DynamicLayout();


            addModButton = new ColorButton
            {
                ToolTip              = null,
                Text                 = Text.AddNewMod,
                Font                 = smallButtonFont,
                Height               = 30,
                Width                = 275,
                TextColor            = colGreen,
                BackgroundColor      = colBG,
                FrameColor           = colGreen,
                BackgroundColorHover = colBGHover
            };

            Label modSpacer = new Label
            {
                Height = 14
            };

            settingsProfileLabel = new Label
            {
                Text      = Text.CurrentProfile,
                TextColor = colGreen,
                Width     = 275
            };

            modSettingsProfileDropDown = new DropDown
            {
                TextColor       = colGreen,
                BackgroundColor = OS.IsWindows ? colBGNoAlpha : new Color()
            };

            // In order to not have conflicting theming, we just always respect the users theme for dropdown on GTK.
            if (OS.IsLinux)
            {
                modSettingsProfileDropDown = new DropDown();
            }

            modSettingsProfileDropDown.Items.AddRange(profileNames);   // It's actually more comfortable if it's outside, because of GTK shenanigans

            profileButton = new ColorButton
            {
                ToolTip              = null,
                Text                 = Text.OpenProfileFolder,
                Font                 = smallButtonFont,
                Height               = 30,
                Width                = 275,
                TextColor            = colGreen,
                BackgroundColor      = colBG,
                FrameColor           = colGreen,
                BackgroundColorHover = colBGHover
            };

            saveButton = new ColorButton
            {
                ToolTip              = null,
                Text                 = Text.OpenSaveFolder,
                Font                 = smallButtonFont,
                Height               = 30,
                Width                = 275,
                TextColor            = colGreen,
                BackgroundColor      = colBG,
                FrameColor           = colGreen,
                BackgroundColorHover = colBGHover
            };

            updateModButton = new ColorButton
            {
                ToolTip              = null,
                Text                 = Text.UpdateModButtonText,
                Font                 = smallButtonFont,
                Height               = 30,
                Width                = 275,
                TextColor            = colGreen,
                BackgroundColor      = colBG,
                FrameColor           = colGreen,
                BackgroundColorHover = colBGHover
            };

            deleteModButton = new ColorButton
            {
                ToolTip              = null,
                Text                 = Text.DeleteModButtonText,
                Font                 = smallButtonFont,
                Height               = 30,
                Width                = 275,
                TextColor            = colGreen,
                BackgroundColor      = colBG,
                FrameColor           = colGreen,
                BackgroundColorHover = colBGHover
            };

            profileNotesTextArea = new TextArea
            {
                ReadOnly        = true,
                BackgroundColor = colBGNoAlpha,
                TextColor       = colInactive,
                SpellCheck      = false,
                Width           = 275,
                Height          = 150,
                Text            = Text.ProfileNotes
            };

            modSettingsLayout.BeginHorizontal();
            modSettingsLayout.AddSpace();
            modSettingsLayout.AddColumn(null, addModButton, modSpacer, settingsProfileLabel, modSettingsProfileDropDown, profileButton, saveButton, updateModButton, deleteModButton, profileNotesTextArea, null);
            modSettingsLayout.AddSpace();

            TabPage modSettingsPage = new TabPage
            {
                BackgroundColor = colBGNoAlpha,
                Content         = modSettingsLayout,
                Text            = Text.ModSettingsTab
            };

            #endregion

            #endregion

            Content = new TabControl
            {
                Pages =
                {
                    mainPage,

                    changelogPage,

                    newsPage,

                    settingsPage,

                    modSettingsPage
                }
            };

            #region EVENTS
            log.Info("All UI objects have been initialized, UI has been set up.");
            log.Info("Beginning event linkage...");

            Closing          += MainformClosing;
            showButton.Click += ShowButtonClick;
            profileDropDown.SelectedIndexChanged   += ProfileDropDownSelectedIndexChanged;
            languageDropDown.SelectedIndexChanged  += LanguageDropDownSelectedIndexChanged;
            autoUpdateAM2RCheck.CheckedChanged     += AutoUpdateAM2RCheckChanged;
            autoUpdateLauncherCheck.CheckedChanged += AutoUpdateLauncherCheckChanged;
            hqMusicAndroidCheck.CheckedChanged     += HqMusicAndroidCheckChanged;
            hqMusicPCCheck.CheckedChanged          += HqMusicPCCheckChanged;
            customMirrorCheck.CheckedChanged       += CustomMirrorCheckChanged;
            apkButton.Click                                 += ApkButtonClickEvent;
            apkButton.LoadComplete                          += (sender, e) => UpdateApkState();
            profileDropDown.LoadComplete                    += (sender, e) => UpdateProfileState();
            playButton.Click                                += PlayButtonClickEvent;
            playButton.LoadComplete                         += PlayButtonLoadComplete;
            customMirrorTextBox.LostFocus                   += CustomMirrorTextBoxLostFocus;
            mirrorDropDown.SelectedIndexChanged             += MirrorDropDownSelectedIndexChanged;
            modSettingsLayout.LoadComplete                  += ProfileLayoutLoadComplete;
            addModButton.Click                              += AddModButtonClicked;
            profileButton.Click                             += ProfileDataButtonClickEvent;
            saveButton.Click                                += SaveButtonClickEvent;
            modSettingsProfileDropDown.SelectedIndexChanged += ModSettingsProfileDropDownSelectedIndexChanged;
            deleteModButton.Click                           += DeleteModButtonClicked;
            updateModButton.Click                           += UpdateModButtonClicked;
            profileDebugLogCheck.CheckedChanged             += ProfileDebugLogCheckedChanged;
            if (OS.IsLinux)
            {
                customEnvVarTextBox.LostFocus += CustomEnvVarTextBoxLostFocus;
            }

            //TODO: Retest if these now work on mac
            newsWebView.DocumentLoaded      += (sender, e) => ChangeToEmptyPageOnNoInternet(newsPage, newsNoConnectionLabel);
            changelogWebView.DocumentLoaded += (sender, e) => ChangeToEmptyPageOnNoInternet(changelogPage, changelogNoConnectionLabel);

            log.Info("Events linked successfully.");

            #endregion
        }
Beispiel #3
0
        /// <summary>
        /// Performs the entire AM2RLauncher update procedure.
        /// </summary>
        public static void Main()
        {
            log.Info("Running update check...");

            // Update section

            // Clean old files that have been left
            if (File.Exists(CrossPlatformOperations.CURRENTPATH + "/AM2RLauncher.bak"))
            {
                log.Info("AM2RLauncher.bak detected. Removing file.");
                File.Delete(CrossPlatformOperations.CURRENTPATH + "/AM2RLauncher.bak");
            }
            if (OS.IsWindows && File.Exists(oldConfigPath))
            {
                log.Info(CrossPlatformOperations.LAUNCHERNAME + ".oldCfg detected. Removing file.");
                File.Delete(oldConfigPath);
            }
            if (OS.IsWindows && Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/oldLib"))
            {
                log.Info("Old lib folder detected, removing folder.");
                Directory.Delete(CrossPlatformOperations.CURRENTPATH + "/oldLib", true);
            }

            // Clean up old update libs
            if (OS.IsWindows && Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/lib"))
            {
                foreach (FileInfo file in new DirectoryInfo(CrossPlatformOperations.CURRENTPATH + "/lib").GetFiles())
                {
                    if (file.Name.EndsWith(".bak"))
                    {
                        file.Delete();
                    }
                }

                // Do the same for each subdir
                foreach (DirectoryInfo dir in new DirectoryInfo(CrossPlatformOperations.CURRENTPATH + "/lib").GetDirectories())
                {
                    foreach (FileInfo file in dir.GetFiles())
                    {
                        if (file.Name.EndsWith(".bak"))
                        {
                            file.Delete();
                        }
                    }
                }
            }

            // Check settings if autoUpdateLauncher is set to true
            bool autoUpdate = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("AutoUpdateLauncher"));

            if (autoUpdate)
            {
                log.Info("AutoUpdate Launcher set to true!");

                // This is supposed to fix the updater throwing an exception on windows 7 and earlier(?)
                // See this for information: https://stackoverflow.com/q/2859790 and https://stackoverflow.com/a/50977774
                if (OS.IsWindows)
                {
                    ServicePointManager.Expect100Continue = true;
                    ServicePointManager.SecurityProtocol  = SecurityProtocolType.Tls12;
                }

                HttpWebRequest  request = (HttpWebRequest)WebRequest.Create("https://github.com/AM2R-Community-Developers/AM2RLauncher/releases/latest");
                HttpWebResponse response;
                try
                {
                    response = (HttpWebResponse)request.GetResponse();
                }
                catch (WebException)
                {
                    log.Error("WebException caught! Displaying MessageBox.");
                    MessageBox.Show(Language.Text.NoInternetConnection);
                    return;
                }

                Uri    realUri                  = response.ResponseUri;
                string onlineVersion            = realUri.AbsoluteUri.Substring(realUri.AbsoluteUri.LastIndexOf('/') + 1);
                bool   isCurrentVersionOutdated = false;

                string[] localVersionArray  = VERSION.Split('.');
                string[] onlineVersionArray = onlineVersion.Split('.');

                for (int i = 0; i < localVersionArray.Length; i++)
                {
                    int onlineNum = Int32.Parse(onlineVersionArray[i]);
                    int localNum  = Int32.Parse(localVersionArray[i]);
                    if (onlineNum > localNum)
                    {
                        isCurrentVersionOutdated = true;
                        break;
                    }
                    if (localNum > onlineNum)
                    {
                        break;
                    }
                }

                log.Info((isCurrentVersionOutdated ? "Updating" : "Not Updating") + " from " + VERSION + " to " + onlineVersion);

                // No new update, exiting
                if (!isCurrentVersionOutdated)
                {
                    return;
                }

                // For mac, we just show a message box that a new version is available, because I don't want to support it yet.
                // hardcoded string, since also temporarily until it gets supported one day.
                if (OS.IsMac)
                {
                    MessageBox.Show("Your current version is outdated! The newest version is " + onlineVersion + "." +
                                    "Please recompile AM2RLauncher again or disable auto-updating");
                    return;
                }

                log.Info("Current version (" + VERSION + ") is outdated! Initiating update for version " + onlineVersion + ".");

                string tmpUpdatePath = CrossPlatformOperations.CURRENTPATH + "/tmpupdate/";
                string zipPath       = CrossPlatformOperations.CURRENTPATH + "/launcher.zip";

                // Clean tmpupdate
                if (Directory.Exists(tmpUpdatePath))
                {
                    Directory.Delete(tmpUpdatePath, true);
                }
                if (!Directory.Exists(tmpUpdatePath))
                {
                    Directory.CreateDirectory(tmpUpdatePath);
                }

                try
                {
                    using (var client = new WebClient())
                    {
                        string platformSuffix = "";
                        if (OS.IsWindows)
                        {
                            platformSuffix = "_win";
                        }
                        else if (OS.IsLinux)
                        {
                            platformSuffix = "_lin";
                        }

                        log.Info("Downloading https://github.com/AM2R-Community-Developers/AM2RLauncher/releases/latest/download/AM2RLauncher_" + onlineVersion + platformSuffix + ".zip to " + zipPath + ".");

                        client.DownloadFile("https://github.com/AM2R-Community-Developers/AM2RLauncher/releases/latest/download/AM2RLauncher_" + onlineVersion + platformSuffix + ".zip", zipPath);

                        log.Info("File successfully downloaded.");
                    }
                }
                catch (UnauthorizedAccessException)
                {
                    log.Error("UnauthorizedAccessException caught! Displaying MessageBox.");
                    MessageBox.Show(Language.Text.UnauthorizedAccessMessage);
                    return;
                }

                ZipFile.ExtractToDirectory(zipPath, tmpUpdatePath);
                log.Info("Updates successfully extracted to " + tmpUpdatePath);

                File.Delete(zipPath);
                File.Move(updatePath + "/" + CrossPlatformOperations.LAUNCHERNAME, CrossPlatformOperations.CURRENTPATH + "/AM2RLauncher.bak");
                if (OS.IsWindows)
                {
                    File.Move(CrossPlatformOperations.LAUNCHERNAME + ".config", CrossPlatformOperations.LAUNCHERNAME + ".oldCfg");
                }

                foreach (var file in new DirectoryInfo(tmpUpdatePath).GetFiles())
                {
                    log.Info("Moving " + file.FullName + " to " + CrossPlatformOperations.CURRENTPATH + "/" + file.Name);
                    File.Copy(file.FullName, updatePath + "/" + file.Name, true);
                }
                // For windows, the actual application is in "AM2RLauncher.dll". Which means, we need to update the lib folder as well.
                if (OS.IsWindows && Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/lib"))
                {
                    // So, because Windows behavior is dumb...

                    // Rename all files in lib to *.bak
                    foreach (FileInfo file in new DirectoryInfo(CrossPlatformOperations.CURRENTPATH + "/lib").GetFiles())
                    {
                        file.CopyTo(file.Directory + "/" + file.Name + ".bak");
                    }

                    // Do the same for each subdir
                    foreach (DirectoryInfo dir in new DirectoryInfo(CrossPlatformOperations.CURRENTPATH + "/lib").GetDirectories())
                    {
                        foreach (FileInfo file in dir.GetFiles())
                        {
                            file.CopyTo(file.Directory + "/" + file.Name + ".bak");
                        }
                    }

                    // Yes, the above calls could be recursive. No, I can't be bothered to make them as such.
                    if (Directory.Exists(tmpUpdatePath + "lib"))
                    {
                        HelperMethods.DirectoryCopy(tmpUpdatePath + "lib", CrossPlatformOperations.CURRENTPATH + "/lib");
                    }
                }

                Directory.Delete(tmpUpdatePath, true);

                CrossPlatformOperations.CopyOldConfigToNewConfig();

                log.Info("Files extracted. Preparing to restart executable...");
                if (OS.IsLinux)
                {
                    System.Diagnostics.Process.Start("chmod", "+x " + updatePath + "./AM2RLauncher.Gtk");
                }

                System.Diagnostics.Process.Start(updatePath + "/" + CrossPlatformOperations.LAUNCHERNAME);
                Environment.Exit(0);
            }
            else
            {
                log.Info("AutoUpdate Launcher set to false. Exiting update check.");
            }
        }