/// <summary>
        /// Uses the given <see cref="VersionFileList"/> to set up the next version.
        /// </summary>
        /// <param name="vfl">The <see cref="VersionFileList"/> for the next version..</param>
        /// <exception cref="ArgumentException">The <paramref name="vfl"/> was invalid or the version failed
        /// to be created.</exception>
        public void SetNextVersion(VersionFileList vfl)
        {
            var nextVersion = LiveVersion + 1;

            // Save the file listing
            var outFilePath = VersionHelper.GetVersionFileListPath(nextVersion);

            vfl.Write(outFilePath);

            // Save the hash for the file listing
            var hash        = Hasher.GetFileHash(outFilePath);
            var outHashPath = VersionHelper.GetVersionFileListHashPath(nextVersion);

            if (File.Exists(outHashPath))
            {
                File.Delete(outHashPath);
            }

            File.WriteAllText(outHashPath, hash);

            // Notify listeners
            if (NextVersionCreated != null)
            {
                NextVersionCreated(this);
            }
        }
        /// <summary>
        /// Raises the <see cref="E:System.Windows.Forms.Form.Load"/> event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs"/> that contains the event data.</param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if (DesignMode)
            {
                return;
            }

            // Use the version immediately after the live version
            _version = ManagerSettings.Instance.LiveVersion + 1;

            lblVersion.Text = _version.ToString();

            try
            {
                // Load the filters from the previous version and use that for the default filter
                var prevVersionPath = VersionHelper.GetVersionFileListPath(_version - 1);
                if (File.Exists(prevVersionPath))
                {
                    var pv = VersionFileList.CreateFromFile(prevVersionPath);

                    var sb = new StringBuilder();
                    foreach (var f in pv.Filters)
                    {
                        sb.AppendLine(f);
                    }

                    txtIgnoreFilter.Text = sb.ToString();
                }
            }
            catch (Exception ex)
            {
                Debug.Fail(ex.ToString());
                txtIgnoreFilter.Text = string.Empty;
            }
        }
Exemple #3
0
        /// <summary>
        /// Uses the given <see cref="VersionFileList"/> to set up the next version.
        /// </summary>
        /// <param name="vfl">The <see cref="VersionFileList"/> for the next version..</param>
        /// <exception cref="ArgumentException">The <paramref name="vfl"/> was invalid or the version failed
        /// to be created.</exception>
        public void SetNextVersion(VersionFileList vfl)
        {
            var nextVersion = LiveVersion + 1;

            // Save the file listing
            var outFilePath = VersionHelper.GetVersionFileListPath(nextVersion);
            vfl.Write(outFilePath);

            // Save the hash for the file listing
            var hash = Hasher.GetFileHash(outFilePath);
            var outHashPath = VersionHelper.GetVersionFileListHashPath(nextVersion);
            if (File.Exists(outHashPath))
                File.Delete(outHashPath);

            File.WriteAllText(outHashPath, hash);

            // Notify listeners
            if (NextVersionCreated != null)
                NextVersionCreated(this);
        }
Exemple #4
0
        /// <summary>
        /// When overridden in the derived class, handles synchronizing the given version.
        /// </summary>
        /// <param name="fu">The <see cref="IFileUploader"/> to use.</param>
        /// <param name="v">The version to synchronize.</param>
        /// <param name="reEnqueue">True if the <paramref name="v"/> should be re-enqueued so it can be re-attempted.
        /// If the method throws an <see cref="Exception"/>, the <paramref name="v"/> will be re-enqueued no matter what.</param>
        /// <returns>The error string, or null if the synchronization was successful.</returns>
        protected override string DoSync(IFileUploader fu, int v, out bool reEnqueue)
        {
            fu.SkipIfExists = false;

            reEnqueue = false;

            var remoteFileListFilePath     = PathHelper.GetVersionString(v) + ".txt";
            var remoteFileListHashFilePath = PathHelper.GetVersionString(v) + ".hash";

            // Ensure the live version is written. This is a very small but very important file, so just write it during
            // every synchronization.
            fu.UploadAsync(_settings.LiveVersionFilePath, MasterServerReader.CurrentVersionFilePath);

            // Also ensure the master server and file server lists are up-to-date. Again, we will just do this every time we
            // check to sync since they are relatively small lists but very important to keep up-to-date.
            fu.UploadAsync(_settings.FileServerListFilePath, MasterServerReader.CurrentDownloadSourcesFilePath);
            fu.UploadAsync(_settings.MasterServerListFilePath, MasterServerReader.CurrentMasterServersFilePath);

            // Load the VersionFileList for the version to check
            var vflPath = VersionHelper.GetVersionFileListPath(v);

            if (!File.Exists(vflPath))
            {
                // Version doesn't exist at all
                while (fu.IsBusy)
                {
                    Thread.Sleep(500);
                }
                return(null);
            }

            // Test the creation of the VersionFileList to ensure its valid
            VersionFileList.CreateFromFile(vflPath);

            // Try to download the version's file list hash
            var vflHash = fu.DownloadAsString(remoteFileListHashFilePath);

            // Check if the hash file exists on the server
            if (vflHash != null)
            {
                // Check if the hash matches the current version's hash
                var expectedVflHash = File.ReadAllText(VersionHelper.GetVersionFileListHashPath(v));
                if (vflHash != expectedVflHash)
                {
                    // We don't need to delete anything since we make the MasterServer overwrite instead
                }
                else
                {
                    // Hash existed and was correct - good enough for us! But first, wait for uploads to finish...
                    while (fu.IsBusy)
                    {
                        Thread.Sleep(500);
                    }

                    return(null);
                }
            }
            else
            {
                // Hash didn't exist at all, so we will have to update. As long as SkipIfExists is set to true, files
                // that already exist will be skipped, so we will only end up uploading the new files. In any case, its
                // the same process either way.
            }

            // Upload the files
            fu.UploadAsync(VersionHelper.GetVersionFileListPath(v), remoteFileListFilePath);
            fu.UploadAsync(VersionHelper.GetVersionFileListHashPath(v), remoteFileListHashFilePath);

            // Wait for uploads to finish
            while (fu.IsBusy)
            {
                Thread.Sleep(1000);
            }

            // All done!
            return(null);
        }
Exemple #5
0
        /// <summary>
        /// Handles the Click event of the btnChangeLiveVersion control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        static void btnChangeLiveVersion_Click(object sender, EventArgs e)
        {
            // Check that the next version even exists
            var nextVersion = _settings.LiveVersion + 1;

            if (!Directory.Exists(VersionHelper.GetVersionPath(nextVersion)) ||
                !File.Exists(VersionHelper.GetVersionFileListPath(nextVersion)))
            {
                MessageBox.Show(
                    "Cannot change the live version since you are already at the latest version." + Environment.NewLine +
                    "If you want to change the live version, create a new version first.", "Error", MessageBoxButtons.OK);
                return;
            }

            // Ensure the next version's contents are valid
            try
            {
                VersionFileList.CreateFromFile(VersionHelper.GetVersionFileListPath(nextVersion));
            }
            catch (Exception ex)
            {
                const string errmsg =
                    "The file listing file for the next version exists, but it is corrupt." +
                    " Please use Create New Version to recreate the next version then try again.{0}Inner Exception:{0}{1}";
                MessageBox.Show(string.Format(errmsg, Environment.NewLine, ex), "Corrupt file listing file", MessageBoxButtons.OK);
                return;
            }

            // Confirm change
            if (
                MessageBox.Show("Are you sure you wish to update the live version?", "Update live version?",
                                MessageBoxButtons.YesNo) == DialogResult.No)
            {
                return;
            }

            // If the new version is still being uploaded to the servers, warn the user
            var areServersBusy = _settings.FileServers.Any(x => x.IsBusySyncing);

            if (areServersBusy)
            {
                const string msg =
                    "Are you sure you wish to update the live version? One or more servers (either file or master servers)" +
                    " are still synchronizing. Updating the live version now may leave you in a state where not all of the files" +
                    " are available on all of the servers. It is highly recommended you wait until all synchronization finishes." +
                    "{0}{0}Do you wish to continue? (Canceling is highly recommended!)";
                if (MessageBox.Show(msg, "Continue updating live version?", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
                {
                    return;
                }
            }

            // Update the version number on the master servers
            _settings.TrySetLiveVersion(_settings.LiveVersion + 1);

            // Done!
            const string doneMsg =
                "The live version has been successfully updated!" +
                " The master servers will automatically start to update with the new live version number.";

            MessageBox.Show(doneMsg, "Done!", MessageBoxButtons.OK);
        }
Exemple #6
0
        /// <summary>
        /// When overridden in the derived class, handles synchronizing the given version.
        /// </summary>
        /// <param name="fu">The <see cref="IFileUploader"/> to use.</param>
        /// <param name="v">The version to synchronize.</param>
        /// <param name="reEnqueue">True if the <paramref name="v"/> should be re-enqueued so it can be re-attempted.
        /// If the method throws an <see cref="Exception"/>, the <paramref name="v"/> will be re-enqueued no matter what.</param>
        /// <returns>
        /// The error string, or null if the synchronization was successful.
        /// </returns>
        protected override string DoSync(IFileUploader fu, int v, out bool reEnqueue)
        {
            reEnqueue = false;

            // Load the VersionFileList for the version to check
            var vflPath = VersionHelper.GetVersionFileListPath(v);

            if (!File.Exists(vflPath))
            {
                // Version doesn't exist at all
                return(null);
            }

            var vfl = VersionFileList.CreateFromFile(vflPath);

            // Try to download the version's file list hash
            var fileListHashPath = GetVersionRemoteFilePath(v, PathHelper.RemoteFileListHashFileName);
            var vflHash          = fu.DownloadAsString(fileListHashPath);

            // Check if the hash file exists on the server
            if (vflHash != null)
            {
                // Check if the hash matches the current version's hash
                var expectedVflHash = File.ReadAllText(VersionHelper.GetVersionFileListHashPath(v));
                if (vflHash != expectedVflHash)
                {
                    // Delete the whole version folder first
                    fu.DeleteDirectory(GetVersionRemoteFilePath(v, null));
                }
                else
                {
                    // Hash existed and was correct - good enough for us!
                    return(null);
                }
            }
            else
            {
                // Hash didn't exist at all, so we will have to update. As long as SkipIfExists is set to true, files
                // that already exist will be skipped, so we will only end up uploading the new files. In any case, its
                // the same process either way.
            }

            // Check the hashes of the local files
            foreach (var f in vfl.Files)
            {
                // Get the local file path
                var localPath = VersionHelper.GetVersionFile(v, f.FilePath);

                // Confirm the hash of the file
                var fileHash = Hasher.GetFileHash(localPath);
                if (fileHash != f.Hash)
                {
                    const string errmsg =
                        "The cached hash ({0}) of file `{1}` does not match the real hash ({2}) for version {3}." +
                        " Possible version corruption.";
                    return(string.Format(errmsg, f.Hash, f.FilePath, fileHash, v));
                }
            }

            // Hashes check out, start uploading
            foreach (var f in vfl.Files)
            {
                // Get the local file path
                var localPath = VersionHelper.GetVersionFile(v, f.FilePath);

                var remotePath = GetVersionRemoteFilePath(v, f.FilePath);
                fu.UploadAsync(localPath, remotePath);
            }

            // Wait for uploads to finish
            while (fu.IsBusy)
            {
                Thread.Sleep(1000);
            }

            // All uploads have finished, so upload the VersionFileList hash
            fu.UploadAsync(VersionHelper.GetVersionFileListHashPath(v), fileListHashPath);

            // All done! That was easy enough, eh? *sigh*
            return(null);
        }
        /// <summary>
        /// Handles the Click event of the btnCreate control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        void btnCreate_Click(object sender, EventArgs e)
        {
            // Create the directory if it does not already exist
            try
            {
                if (!Directory.Exists(txtRootPath.Text))
                {
                    Directory.CreateDirectory(txtRootPath.Text);
                }
            }
            catch (Exception)
            {
            }

            // Ensure there are files in the list
            if (!Directory.Exists(txtRootPath.Text) ||
                Directory.GetFiles(txtRootPath.Text, "*", SearchOption.AllDirectories).Length <= 0)
            {
                const string errmsg = "You must first add the files for this new version to the path:{0}{1}";
                MessageBox.Show(string.Format(errmsg, Environment.NewLine, txtRootPath.Text));
                return;
            }

            const string confirmationMsg = "Are you sure you wish to create this new version?";

            if (MessageBox.Show(confirmationMsg, "Create new version?", MessageBoxButtons.YesNo) == DialogResult.No)
            {
                return;
            }

            // Create the version file list
            VersionFileList vfl;

            try
            {
                vfl = VersionFileList.Create(txtRootPath.Text, txtIgnoreFilter.Lines);
            }
            catch (Exception ex)
            {
                const string errmsg =
                    "Failed to create VersionFileList due to an unexpected error." +
                    " Please resolve the error below then try again.{0}{0}{1}";
                MessageBox.Show(string.Format(errmsg, Environment.NewLine, ex));
                return;
            }

            // Save the file list
            try
            {
                ManagerSettings.Instance.SetNextVersion(vfl);
            }
            catch (Exception ex)
            {
                const string errmsg =
                    "Failed to set the next version due to an unexpected error." +
                    " Please resolve the error below then try again.{0}{1}";
                MessageBox.Show(string.Format(errmsg, Environment.NewLine, ex));
                return;
            }

            MessageBox.Show("Version `" + _version + "` successfully created!", "Success!", MessageBoxButtons.OK);
            Close();
        }