Пример #1
0
        /// <summary>
        /// Fixes switchable file mixups usually caused by a system or DFOCP crash. Does nothing if no problems
        /// are detected. Note if the game is running with switched files, this method will try to "fix" them
        /// and fail.
        /// </summary>
        /// <param name="wereBroken">Set to true if the files were broken and were fixed. Set to false if
        /// the files were not broken.</param>
        /// <exception cref="System.IO.IOException">Something went wrong while trying to fix the mixup.</exception>
        /// <exception cref="System.ArgumentNullException">One of the properties is null.</exception>
        public void FixBrokenFiles(out bool wereBroken)
        {
            wereBroken = false;

            NormalFile.ThrowIfNull("FileToSwitch");
            CustomFile.ThrowIfNull("FileToSwitchWith");
            TempFile.ThrowIfNull("TempFile");

            Logging.Log.DebugFormat("Repairing switchable ('{0}', '{1}', '{2}').",
                                    NormalFile, CustomFile, TempFile);

            Action <string, string> move   = FileType.GetMoveFunction();
            Func <string, bool>     exists = FileType.GetExistsFunction();

            if (exists(TempFile) && exists(NormalFile))
            {
                wereBroken = true;
                Logging.Log.DebugFormat("Normal and temp exist.");

                // Rename FileToSwitch to FileToSwitchWith
                try
                {
                    move(NormalFile, CustomFile);
                    Logging.Log.DebugFormat("Moved file at normal location {0} to custom location {1}",
                                            NormalFile, CustomFile);
                }
                catch (Exception ex)                   // XXX: Catch specific exceptions
                {
                    throw new IOException(string.Format("Could not move {0} to {1}. {2}",
                                                        NormalFile, CustomFile, ex.Message));
                }

                // Rename TempFile to FileToSwitch
                try
                {
                    move(TempFile, NormalFile);
                    Logging.Log.DebugFormat("Moved file at temp location {0} to normal location {1}",
                                            TempFile, NormalFile);
                    Logging.Log.DebugFormat("Repair complete.");
                }
                catch (Exception ex)                   // XXX: Catch specific exceptions
                {
                    throw new IOException(string.Format("Could not move {0} to {1}. {2}",
                                                        TempFile, NormalFile, ex.Message));
                }
            }
            else if (exists(TempFile) && exists(CustomFile))
            {
                wereBroken = true;
                Logging.Log.DebugFormat("Custom and temp exist.");

                // Rename TempFile to FileToSwitch
                try
                {
                    move(TempFile, NormalFile);
                    Logging.Log.DebugFormat("Moved file at temp location {0} to normal location {1}",
                                            TempFile, NormalFile);
                }
                catch (Exception ex)
                {
                    throw new IOException(string.Format("Could not move {0} to {1}. {2}",
                                                        TempFile, NormalFile, ex.Message));
                }
            }
            else
            {
                Logging.Log.DebugFormat("Not broken, nothing to repair.");
                return;
            }
        }
Пример #2
0
        /// <summary>
        /// Moves FileToSwitch to TempFile and FileToSwitchWith to FileToSwitch. If the second move fails,
        /// the first move is attempted to be undone.
        /// </summary>
        /// <returns>A SwitchedFile object you can use to switch back by calling SwitchBack() on it.</returns>
        /// <exception cref="System.ArgumentNullExcepton">One of the properties is null.</exception>
        /// <exception cref="System.IO.IOException">The file could not be switched.</exception>
        public SwitchedFile Switch()
        {
            NormalFile.ThrowIfNull("FileToSwitch");
            CustomFile.ThrowIfNull("FileToSwitchWith");
            TempFile.ThrowIfNull("TempFile");

            Logging.Log.DebugFormat("Switching {0} with {1} using {2} as a temporary.",
                                    NormalFile, CustomFile, TempFile);

            Action <string, string> move = FileType.GetMoveFunction();

            bool firstMoveSuccessful = false;

            try
            {
                move(NormalFile, TempFile);
                firstMoveSuccessful = true;
                Logging.Log.DebugFormat("Moved {0} to {1}.", NormalFile, TempFile);

                move(CustomFile, NormalFile);
                Logging.Log.DebugFormat("Moved {0} to {1}.", CustomFile, NormalFile);
                Logging.Log.DebugFormat("Switch successful.");

                return(new SwitchedFile(NormalFile, CustomFile, TempFile, FileType));
            }
            catch (Exception ex)
            {
                // If the first move was successful, we can probably move it back
                bool      undoSuccess = false;
                Exception undoError   = null;
                if (firstMoveSuccessful)
                {
                    try
                    {
                        move(TempFile, NormalFile);
                        undoSuccess = true;
                    }
                    catch (Exception ex2)
                    {
                        undoError = ex2;
                    }
                }

                if (!firstMoveSuccessful)
                {
                    throw new IOException(string.Format(
                                              "Could not move {0} to {1}. {2}",
                                              NormalFile, TempFile, ex.Message), ex);
                }
                else
                {
                    string undoMessage;
                    if (undoSuccess)
                    {
                        undoMessage = string.Format(
                            "{0} moved back to {1}.",
                            TempFile, NormalFile);
                    }
                    else
                    {
                        undoMessage = string.Format(
                            "{0} could not be moved back to {1}. {2} Files are in an inconsistent state!",
                            TempFile, NormalFile, undoError.Message);
                    }

                    throw new IOException(string.Format(
                                              "Could not move {0} to {1}. {2} {3}",
                                              CustomFile, NormalFile, ex.Message, undoMessage), ex);
                }
            }
        }