示例#1
0
        /// <summary>
        /// Attempts to parse an entry from a raw input.
        /// The input is expected to be in [path]:[hash]:[size] format.
        /// </summary>
        /// <returns><c>true</c>, if the input was successfully parse, <c>false</c> otherwise.</returns>
        /// <param name="rawInput">Raw input.</param>
        /// <param name="entry">The resulting entry.</param>
        public static bool TryParse(string rawInput, out ManifestEntry inEntry)
        {
            //clear out the entry for the new data
            inEntry = new ManifestEntry();

            if (!String.IsNullOrEmpty(rawInput))
            {
                //remove any and all bad characters from the input string,
                //such as \0, \n and \r.
                string cleanInput = Utilities.Clean(rawInput);

                //split the string into its three components - file, hash and size
                string[] entryElements = cleanInput.Split(':');

                //if we have three elements (which we should always have), set them in the provided entry
                if (entryElements.Length == 3)
                {
                    //clean the manifest path, converting \ to / on unix and / to \ on Windows.
                    if (ChecksHandler.IsRunningOnUnix())
                    {
                        inEntry.RelativePath = entryElements [0].Replace("\\", "/");
                    }
                    else
                    {
                        inEntry.RelativePath = entryElements [0].Replace("/", "\\");
                    }

                    //set the hash to the second element
                    inEntry.Hash = entryElements [1];

                    //attempt to parse the final element as a long-type byte count.
                    long parsedSize = 0;
                    if (long.TryParse(entryElements[2], out parsedSize))
                    {
                        inEntry.Size = parsedSize;
                        return(true);
                    }
                    else
                    {
                        //could not parse the size, parsing has failed.
                        return(false);
                    }
                }
                else
                {
                    //wrong number of raw entry elements, parsing has failed.
                    return(false);
                }
            }
            else
            {
                //no input, parsing has failed
                return(false);
            }
        }
示例#2
0
        /// <summary>
        /// Gets the path to the game executable.
        /// </summary>
        /// <returns>The game executable.</returns>
        public string GetGameExecutable()
        {
            string executablePathRootLevel   = String.Empty;
            string executablePathTargetLevel = String.Empty;

            //unix doesn't need (or have!) the .exe extension.
            if (ChecksHandler.IsRunningOnUnix())
            {
                //should return something along the lines of "./Game/<ExecutableName>"
                executablePathRootLevel = String.Format(@"{0}{1}",
                                                        GetGamePath(true),
                                                        GetGameName());

                //should return something along the lines of "./Game/<GameName>/Binaries/<SystemTarget>/<ExecutableName>"
                executablePathTargetLevel = String.Format(@"{0}{1}{3}Binaries{3}{2}{3}{1}",
                                                          GetGamePath(true),
                                                          GetGameName(),
                                                          GetSystemTarget(),
                                                          Path.DirectorySeparatorChar);
            }
            else
            {
                //should return something along the lines of "./Game/<ExecutableName>.exe"
                executablePathRootLevel = String.Format(@"{0}{1}.exe",
                                                        GetGamePath(true),
                                                        GetGameName());

                //should return something along the lines of "./Game/<GameName>/Binaries/<SystemTarget>/<ExecutableName>.exe"
                executablePathTargetLevel = String.Format(@"{0}{1}{3}Binaries{3}{2}{3}{1}.exe",
                                                          GetGamePath(true),
                                                          GetGameName(),
                                                          GetSystemTarget(),
                                                          Path.DirectorySeparatorChar);
            }


            if (File.Exists(executablePathRootLevel))
            {
                return(executablePathRootLevel);
            }
            else if (File.Exists(executablePathTargetLevel))
            {
                return(executablePathTargetLevel);
            }
            else
            {
                Console.WriteLine("Searched at: " + executablePathRootLevel);
                Console.WriteLine("Searched at: " + executablePathTargetLevel);
                throw new FileNotFoundException("The game executable could not be found.");
            }
        }
示例#3
0
        static void Main()
        {
            if (ChecksHandler.IsRunningOnUnix())
            {
                // run a GTK UI instead of WinForms
                Gtk.Application.Init();

                MainWindow win = new MainWindow();
                win.Show();
                Gtk.Application.Run();
            }
            else
            {
                // run a WinForms UI instead of GTK
                System.Windows.Forms.Application.EnableVisualStyles();
                System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);
                System.Windows.Forms.Application.Run(new MainForm());
            }
        }
示例#4
0
        static void Main()
        {
            // Set correct working directory for compatibility with double-clicking
            Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));

            if (ChecksHandler.IsRunningOnUnix())
            {
                // run a GTK UI instead of WinForms
                Gtk.Application.Init();

                MainWindow win = new MainWindow();
                win.Show();
                Gtk.Application.Run();
            }
            else
            {
                // run a WinForms UI instead of GTK
                System.Windows.Forms.Application.EnableVisualStyles();
                System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);
                System.Windows.Forms.Application.Run(new MainForm());
            }
        }
示例#5
0
        private static void Main()
        {
            // Bind any unhandled exceptions in the main thread so that they are logged.
            AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;

            Log.Info("----------------");
            Log.Info($"Launchpad v{Config.GetLocalLauncherVersion()} starting...");
            Log.Info($"Current platform: {ConfigHandler.GetCurrentPlatform()} ({(Environment.Is64BitOperatingSystem ? "x64" : "x86")})");

            // Set correct working directory for compatibility with double-clicking
            Directory.SetCurrentDirectory(ConfigHandler.GetLocalDir());

            if (ChecksHandler.IsRunningOnUnix())
            {
                Log.Info("Initializing GTK UI.");
                RunUnixInterface();
            }
            else
            {
                Log.Info("Initializing WinForms UI.");
                RunWindowsInterface();
            }
        }
示例#6
0
        /// <summary>
        /// Creates the update script on disk.
        /// </summary>
        /// <returns>ProcessStartInfo for the update script.</returns>
        private static ProcessStartInfo CreateUpdateScript()
        {
            try
            {
                //maintain the executable name if it was renamed to something other than 'Launchpad'
                string fullName       = Assembly.GetEntryAssembly().Location;
                string executableName = Path.GetFileName(fullName);                 // should be "Launchpad", unless the user has renamed it

                if (ChecksHandler.IsRunningOnUnix())
                {
                    //creating a .sh script
                    string scriptPath = String.Format(@"{0}launchpadupdate.sh",
                                                      ConfigHandler.GetTempDir());


                    FileStream updateScript = File.Create(scriptPath);
                    TextWriter tw           = new StreamWriter(updateScript);

                    //write commands to the script
                    //wait five seconds, then copy the new executable
                    string copyCom = String.Format("cp -rf {0} {1}",
                                                   ConfigHandler.GetTempDir() + "launchpad/*",
                                                   ConfigHandler.GetLocalDir());

                    string delCom = String.Format("rm -rf {0}",
                                                  ConfigHandler.GetTempDir() + "launchpad");

                    string dirCom    = String.Format("cd {0}", ConfigHandler.GetLocalDir());
                    string launchCom = String.Format(@"nohup ./{0} &", executableName);
                    tw.WriteLine(@"#!/bin/sh");
                    tw.WriteLine("sleep 5");
                    tw.WriteLine(copyCom);
                    tw.WriteLine(delCom);
                    tw.WriteLine(dirCom);
                    tw.WriteLine("chmod +x " + executableName);
                    tw.WriteLine(launchCom);
                    tw.Close();

                    UnixHandler.MakeExecutable(scriptPath);


                    //Now create some ProcessStartInfo for this script
                    ProcessStartInfo updateShellProcess = new ProcessStartInfo();

                    updateShellProcess.FileName               = scriptPath;
                    updateShellProcess.UseShellExecute        = false;
                    updateShellProcess.RedirectStandardOutput = false;
                    updateShellProcess.WindowStyle            = ProcessWindowStyle.Hidden;

                    return(updateShellProcess);
                }
                else
                {
                    //creating a .bat script
                    string scriptPath = String.Format(@"{0}launchpadupdate.bat",
                                                      ConfigHandler.GetTempDir());

                    FileStream updateScript = File.Create(scriptPath);

                    TextWriter tw = new StreamWriter(updateScript);

                    //write commands to the script
                    //wait three seconds, then copy the new executable
                    tw.WriteLine(String.Format(@"timeout 3 & xcopy /e /s /y ""{0}\launchpad"" ""{1}"" && rmdir /s /q {0}\launchpad",
                                               ConfigHandler.GetTempDir(),
                                               ConfigHandler.GetLocalDir()));

                    //then start the new executable
                    tw.WriteLine(String.Format(@"start {0}", executableName));
                    tw.Close();

                    ProcessStartInfo updateBatchProcess = new ProcessStartInfo();

                    updateBatchProcess.FileName               = scriptPath;
                    updateBatchProcess.UseShellExecute        = true;
                    updateBatchProcess.RedirectStandardOutput = false;
                    updateBatchProcess.WindowStyle            = ProcessWindowStyle.Hidden;

                    return(updateBatchProcess);
                }
            }
            catch (IOException ioex)
            {
                Console.WriteLine("IOException in CreateUpdateScript(): " + ioex.Message);

                return(null);
            }
        }
示例#7
0
        public MainForm()
        {
            InitializeComponent();

            Config.Initialize();

            MessageLabel.Text          = LocalizationCatalog.GetString("idleString");
            downloadProgressLabel.Text = String.Empty;

            //set the window text to match the game name
            this.Text = "Launchpad - " + Config.GetGameName();

            //first of all, check if we can connect to the FTP server.
            if (!Checks.CanConnectToFTP())
            {
                MessageBox.Show(
                    this,
                    LocalizationCatalog.GetString("ftpConnectionFailureMessage"),
                    LocalizationCatalog.GetString("ftpConnectionFailureString"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error,
                    MessageBoxDefaultButton.Button1);

                MessageLabel.Text     = LocalizationCatalog.GetString("ftpConnectionFailureString");
                PrimaryButton.Text    = ":(";
                PrimaryButton.Enabled = false;
            }
            else
            {
                //if we can connect, proceed with the rest of our checks.
                if (ChecksHandler.IsInitialStartup())
                {
                    DialogResult shouldInstallHere = MessageBox.Show(
                        this,
                        String.Format(
                            LocalizationCatalog.GetString("initialStartupMessage"), ConfigHandler.GetLocalDir()),
                        LocalizationCatalog.GetString("infoTitle"),
                        MessageBoxButtons.YesNo,
                        MessageBoxIcon.Question,
                        MessageBoxDefaultButton.Button1);

                    if (shouldInstallHere == DialogResult.Yes)
                    {
                        //yes, install here
                        ConfigHandler.CreateUpdateCookie();
                    }
                    else
                    {
                        //no, don't install here
                        Environment.Exit(2);
                    }
                }


                if (bSendAnonStats)
                {
                    StatsHandler.SendUsageStats();
                }
                else
                {
                    Stream iconStream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("Launchpad.Launcher.Resources.RocketIcon.ico");
                    if (iconStream != null)
                    {
                        NotifyIcon noUsageStatsNotification = new NotifyIcon();
                        noUsageStatsNotification.Icon    = new System.Drawing.Icon(iconStream);
                        noUsageStatsNotification.Visible = true;

                        noUsageStatsNotification.BalloonTipTitle = LocalizationCatalog.GetString("infoTitle");
                        noUsageStatsNotification.BalloonTipText  = LocalizationCatalog.GetString("usageTitle");

                        noUsageStatsNotification.ShowBalloonTip(10000);
                    }
                }

                //load the changelog from the server
                Launcher.ChangelogDownloadFinished += OnChangelogDownloadFinished;
                Launcher.LoadChangelog();

                //Does the launcher need an update?
                if (!Checks.IsLauncherOutdated())
                {
                    if (Checks.IsManifestOutdated())
                    {
                        Launcher.DownloadManifest();
                    }

                    if (!Checks.IsGameInstalled())
                    {
                        SetLauncherMode(ELauncherMode.Install, false);
                    }
                    else
                    {
                        if (Checks.IsGameOutdated())
                        {
                            SetLauncherMode(ELauncherMode.Update, false);
                        }
                        else
                        {
                            SetLauncherMode(ELauncherMode.Launch, false);
                        }
                    }
                }
                else
                {
                    SetLauncherMode(ELauncherMode.Update, false);
                }
            }
        }
示例#8
0
        public MainWindow() :
            base(WindowType.Toplevel)
        {
            //initialize localization
            Mono.Unix.Catalog.Init("Launchpad", "./locale");

            //Initialize the config files and check values.
            Config.Initialize();

            //Initialize the GTK UI
            this.Build();

            //set the window title
            Title = "Launchpad - " + Config.GetGameName();

            // Configure the WebView for our changelog
            Browser.SetSizeRequest(290, 300);

            scrolledwindow2.Add(Browser);
            scrolledwindow2.ShowAll();

            MessageLabel.Text = Mono.Unix.Catalog.GetString("Idle");

            //First of all, check if we can connect to the FTP server.
            if (!Checks.CanConnectToFTP())
            {
                MessageDialog dialog = new MessageDialog(
                    null,
                    DialogFlags.Modal,
                    MessageType.Warning,
                    ButtonsType.Ok,
                    Mono.Unix.Catalog.GetString("Failed to connect to the FTP server. Please check your FTP settings."));

                dialog.Run();
                dialog.Destroy();
                MessageLabel.Text = Mono.Unix.Catalog.GetString("Could not connect to server.");
            }
            else
            {
                //if we can connect, proceed with the rest of our checks.
                if (ChecksHandler.IsInitialStartup())
                {
                    MessageDialog shouldInstallHereDialog = new MessageDialog(
                        null,
                        DialogFlags.Modal,
                        MessageType.Question,
                        ButtonsType.OkCancel,
                        String.Format(Mono.Unix.Catalog.GetString(
                                          "This appears to be the first time you're starting the launcher.\n" +
                                          "Is this the location where you would like to install the game?" +
                                          "\n\n{0}"), ConfigHandler.GetLocalDir()
                                      ));

                    if (shouldInstallHereDialog.Run() == (int)ResponseType.Ok)
                    {
                        shouldInstallHereDialog.Destroy();
                        //yes, install here
                        Console.WriteLine("Installing in current directory.");
                        ConfigHandler.CreateUpdateCookie();
                    }
                    else
                    {
                        shouldInstallHereDialog.Destroy();
                        //no, don't install here
                        Console.WriteLine("Exiting...");
                        Environment.Exit(0);
                    }
                }

                if (bSendAnonStats)
                {
                    StatsHandler.SendUsageStats();
                }
                else
                {
                    Notification noUsageStatsNotification = new Notification();

                    noUsageStatsNotification.IconName = Stock.DialogWarning;
                    noUsageStatsNotification.Urgency  = Urgency.Normal;
                    noUsageStatsNotification.Summary  = Mono.Unix.Catalog.GetString("Launchpad - Warning");
                    noUsageStatsNotification.Body     = Mono.Unix.Catalog.GetString("Anonymous useage stats are not enabled.");

                    noUsageStatsNotification.Show();
                }


                //Start loading the changelog asynchronously
                Launcher.ChangelogDownloadFinished += OnChangelogDownloadFinished;
                Launcher.LoadChangelog();

                //if the launcher does not need an update at this point, we can continue checks for the game
                if (!Checks.IsLauncherOutdated())
                {
                    if (Checks.IsManifestOutdated())
                    {
                        Launcher.DownloadManifest();
                    }

                    if (!Checks.IsGameInstalled())
                    {
                        //if the game is not installed, offer to install it
                        Console.WriteLine("Not installed.");
                        SetLauncherMode(ELauncherMode.Install, false);
                    }
                    else
                    {
                        //if the game is installed (which it should be at this point), check if it needs to be updated
                        if (Checks.IsGameOutdated())
                        {
                            //if it does, offer to update it
                            Console.WriteLine("Game is outdated or not installed");
                            SetLauncherMode(ELauncherMode.Update, false);
                        }
                        else
                        {
                            //if not, enable launching the game
                            SetLauncherMode(ELauncherMode.Launch, false);
                        }
                    }
                }
                else
                {
                    //the launcher was outdated.
                    SetLauncherMode(ELauncherMode.Update, false);
                }
            }
        }
示例#9
0
        private void RepairGameAsync()
        {
            //This value is filled with either a path to the last downloaded file, or with an exception message
            //this message is used in the main UI to determine how it responds to a failed download.
            string repairMetadata = "";

            try
            {
                //check all local file MD5s against latest manifest. Resume partial files, download broken files.
                FTPHandler FTP = new FTPHandler();

                //bind event handlers
                FTP.FileProgressChanged += OnDownloadProgressChanged;

                //first, verify that the manifest is correct.
                string LocalManifestHash  = MD5Handler.GetFileHash(File.OpenRead(ConfigHandler.GetManifestPath()));
                string RemoteManifestHash = FTP.GetRemoteManifestChecksum();

                //if it is not, download a new copy.
                if (!(LocalManifestHash == RemoteManifestHash))
                {
                    LauncherHandler Launcher = new LauncherHandler();
                    Launcher.DownloadManifest();
                }

                //then, begin repairing the game
                ManifestHandler      manifestHandler = new ManifestHandler();
                List <ManifestEntry> Manifest        = manifestHandler.Manifest;

                ProgressArgs.TotalFiles = Manifest.Count;

                int i = 0;
                foreach (ManifestEntry Entry in Manifest)
                {
                    string RemotePath = String.Format("{0}{1}",
                                                      Config.GetGameURL(true),
                                                      Entry.RelativePath);

                    string LocalPath = String.Format("{0}{1}",
                                                     Config.GetGamePath(true),
                                                     Entry.RelativePath);

                    ProgressArgs.FileName = Path.GetFileName(LocalPath);

                    //make sure the directory for the file exists
                    Directory.CreateDirectory(Directory.GetParent(LocalPath).ToString());

                    if (File.Exists(LocalPath))
                    {
                        FileInfo fileInfo = new FileInfo(LocalPath);
                        if (fileInfo.Length != Entry.Size)
                        {
                            //Resume the download of this partial file.
                            OnProgressChanged();
                            repairMetadata = FTP.DownloadFTPFile(RemotePath, LocalPath, fileInfo.Length, false);

                            //Now verify the file
                            string localHash = MD5Handler.GetFileHash(File.OpenRead(LocalPath));

                            if (localHash != Entry.Hash)
                            {
                                Console.WriteLine("RepairGameAsync: Resumed file hash was invalid, downloading fresh copy from server.");

                                //download the file, since it was broken
                                OnProgressChanged();
                                repairMetadata = FTP.DownloadFTPFile(RemotePath, LocalPath, false);
                            }
                        }
                    }
                    else
                    {
                        //download the file, since it was missing
                        OnProgressChanged();
                        repairMetadata = FTP.DownloadFTPFile(RemotePath, LocalPath, false);
                    }

                    if (ChecksHandler.IsRunningOnUnix())
                    {
                        //if we're dealing with a file that should be executable,
                        string gameName = Config.GetGameName();
                        bool   bFileIsGameExecutable = (Path.GetFileName(LocalPath).EndsWith(".exe")) || (Path.GetFileNameWithoutExtension(LocalPath) == gameName);
                        if (bFileIsGameExecutable)
                        {
                            //set the execute bits.
                            UnixHandler.MakeExecutable(LocalPath);
                        }
                    }

                    ++i;
                    ProgressArgs.DownloadedFiles = i;
                    OnProgressChanged();
                }

                OnGameRepairFinished();

                //clear out the event handler
                FTP.FileProgressChanged -= OnDownloadProgressChanged;
            }
            catch (IOException ioex)
            {
                Console.WriteLine("IOException in RepairGameAsync(): " + ioex.Message);

                DownloadFailedArgs.Result     = "1";
                DownloadFailedArgs.ResultType = "Repair";
                DownloadFailedArgs.Metadata   = repairMetadata;

                OnGameRepairFailed();
            }
        }
示例#10
0
        private void InstallGameAsync()
        {
            //This value is filled with either a path to the last downloaded file, or with an exception message
            //this message is used in the main UI to determine how it responds to a failed download.
            string fileReturn = "";

            try
            {
                FTPHandler           FTP             = new FTPHandler();
                ManifestHandler      manifestHandler = new ManifestHandler();
                List <ManifestEntry> Manifest        = manifestHandler.Manifest;

                //create the .install file to mark that an installation has begun
                //if it exists, do nothing.
                ConfigHandler.CreateInstallCookie();


                //raise the progress changed event by binding to the
                //event in the FTP class
                FTP.FileProgressChanged += OnDownloadProgressChanged;

                //in order to be able to resume downloading, we check if there is an entry
                //stored in the install cookie.
                ManifestEntry lastDownloadedFile = null;
                string        installCookiePath  = ConfigHandler.GetInstallCookiePath();

                //attempt to parse whatever is inside the install cookie
                if (ManifestEntry.TryParse(File.ReadAllText(installCookiePath), out lastDownloadedFile))
                {
                    //loop through all the entries in the manifest until we encounter
                    //an entry which matches the one in the install cookie

                    foreach (ManifestEntry Entry in Manifest)
                    {
                        if (lastDownloadedFile == Entry)
                        {
                            //remove all entries before the one we were last at.
                            Manifest.RemoveRange(0, Manifest.IndexOf(Entry));
                        }
                    }
                }

                //then, start downloading the entries that remain in the manifest.
                foreach (ManifestEntry Entry in Manifest)
                {
                    string RemotePath = String.Format("{0}{1}",
                                                      Config.GetGameURL(true),
                                                      Entry.RelativePath);

                    string LocalPath = String.Format("{0}{1}{2}",
                                                     Config.GetGamePath(true),
                                                     System.IO.Path.DirectorySeparatorChar,
                                                     Entry.RelativePath);

                    //make sure we have a game directory to put files in
                    Directory.CreateDirectory(Path.GetDirectoryName(LocalPath));

                    //write the current file progress to the install cookie
                    TextWriter textWriterProgress = new StreamWriter(ConfigHandler.GetInstallCookiePath());
                    textWriterProgress.WriteLine(Entry.ToString());
                    textWriterProgress.Close();

                    if (File.Exists(LocalPath))
                    {
                        FileInfo fileInfo = new FileInfo(LocalPath);
                        if (fileInfo.Length != Entry.Size)
                        {
                            //Resume the download of this partial file.
                            OnProgressChanged();
                            fileReturn = FTP.DownloadFTPFile(RemotePath, LocalPath, fileInfo.Length, false);

                            //Now verify the file
                            string localHash = MD5Handler.GetFileHash(File.OpenRead(LocalPath));

                            if (localHash != Entry.Hash)
                            {
                                Console.WriteLine("InstallGameAsync: Resumed file hash was invalid, downloading fresh copy from server.");
                                OnProgressChanged();
                                fileReturn = FTP.DownloadFTPFile(RemotePath, LocalPath, false);
                            }
                        }
                    }
                    else
                    {
                        //no file, download it
                        OnProgressChanged();
                        fileReturn = FTP.DownloadFTPFile(RemotePath, LocalPath, false);
                    }

                    if (ChecksHandler.IsRunningOnUnix())
                    {
                        //if we're dealing with a file that should be executable,
                        string gameName = Config.GetGameName();
                        bool   bFileIsGameExecutable = (Path.GetFileName(LocalPath).EndsWith(".exe")) || (Path.GetFileNameWithoutExtension(LocalPath) == gameName);
                        if (bFileIsGameExecutable)
                        {
                            //set the execute bits
                            UnixHandler.MakeExecutable(LocalPath);
                        }
                    }
                }

                //we've finished the download, so empty the cookie
                File.WriteAllText(ConfigHandler.GetInstallCookiePath(), String.Empty);

                //raise the finished event
                OnGameDownloadFinished();

                //clear out the event handler
                FTP.FileProgressChanged -= OnDownloadProgressChanged;
            }
            catch (IOException ioex)
            {
                Console.WriteLine("IOException in InstallGameAsync(): " + ioex.Message);

                DownloadFailedArgs.Result     = "1";
                DownloadFailedArgs.ResultType = "Install";
                DownloadFinishedArgs.Metadata = fileReturn;

                OnGameDownloadFailed();
            }
        }
示例#11
0
        /// <summary>
        /// Replaces and updates the old pre-unix config.
        /// </summary>
        /// <returns><c>true</c>, if an old config was copied over to the new format, <c>false</c> otherwise.</returns>
        private bool UpdateOldConfig()
        {
            string oldConfigPath = String.Format(@"{0}config{1}launcherConfig.ini",
                                                 GetLocalDir(),
                                                 Path.DirectorySeparatorChar);

            string oldConfigDir = String.Format(@"{0}config", GetLocalDir());

            if (ChecksHandler.IsRunningOnUnix())
            {
                //Case sensitive
                //Is there an old config file?
                if (File.Exists(oldConfigPath))
                {
                    lock (ReadLock)
                    {
                        //Have we not already created the new config dir?
                        if (!Directory.Exists(GetConfigDir()))
                        {
                            //if not, create it.
                            Directory.CreateDirectory(GetConfigDir());

                            //Copy the old config file to the new location.
                            File.Copy(oldConfigPath, GetConfigPath());

                            //read our new file.
                            FileIniDataParser Parser = new FileIniDataParser();
                            IniData           data   = Parser.ReadFile(GetConfigPath());

                            //replace the old invalid keys with new, updated keys.
                            string launcherVersion = data["Local"]["launcherVersion"];
                            string gameName        = data["Local"]["gameName"];
                            string systemTarget    = data["Local"]["systemTarget"];

                            data["Local"].RemoveKey("launcherVersion");
                            data["Local"].RemoveKey("gameName");
                            data["Local"].RemoveKey("systemTarget");

                            data["Local"].AddKey("LauncherVersion", launcherVersion);
                            data["Local"].AddKey("GameName", gameName);
                            data["Local"].AddKey("SystemTarget", systemTarget);

                            WriteConfig(Parser, data);
                            //We were successful, so return true.

                            File.Delete(oldConfigPath);
                            Directory.Delete(oldConfigDir, true);
                            return(true);
                        }
                        else
                        {
                            //The new config dir already exists, so we'll just toss out the old one.
                            //Delete the old config
                            File.Delete(oldConfigPath);
                            Directory.Delete(oldConfigDir, true);
                            return(false);
                        }
                    }
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                lock (ReadLock)
                {
                    //Windows is not case sensitive, so we'll use direct access without copying.
                    if (File.Exists(oldConfigPath))
                    {
                        FileIniDataParser Parser = new FileIniDataParser();
                        IniData           data   = Parser.ReadFile(GetConfigPath());

                        //replace the old invalid keys with new, updated keys.
                        string launcherVersion = data["Local"]["launcherVersion"];
                        string gameName        = data["Local"]["gameName"];
                        string systemTarget    = data["Local"]["systemTarget"];

                        data["Local"].RemoveKey("launcherVersion");
                        data["Local"].RemoveKey("gameName");
                        data["Local"].RemoveKey("systemTarget");

                        data["Local"].AddKey("LauncherVersion", launcherVersion);
                        data["Local"].AddKey("GameName", gameName);
                        data["Local"].AddKey("SystemTarget", systemTarget);

                        WriteConfig(Parser, data);

                        //We were successful, so return true.
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }
            }
        }