Esempio n. 1
0
    private void CompareLocalAndRemotePatchFiles()
    {
        needLoadPatchFiles = new Queue <PatchFileInfo>();
        refreshPatchFiles  = new PatchFiles();

        needLoadSize = 0;
        foreach (PatchFileInfo remotePatchFileInfo in remotePatchFiles.dic.Values)
        {
            if (!localPatchFiles.dic.ContainsKey(remotePatchFileInfo.ResPath))
            {//新增文件
                needLoadSize += remotePatchFileInfo.Size;
                needLoadPatchFiles.Enqueue(remotePatchFileInfo);
            }
            else if (localPatchFiles.dic[remotePatchFileInfo.ResPath].Md5 != remotePatchFileInfo.Md5)
            {//修改文件
                needLoadSize += remotePatchFileInfo.Size;
                needLoadPatchFiles.Enqueue(remotePatchFileInfo);
            }
            else
            {//同样文件
                //refreshPatchFiles.Add(remotePatchFileInfo);
                needLoadSize += remotePatchFileInfo.Size;
                needLoadPatchFiles.Enqueue(remotePatchFileInfo);
            }
        }

        refreshPatchFiles.FileReplace(PathUtil.LocalPatchFilesPath());

        float needLoadSizeM = needLoadSize / (1024 * 1024);

        GLog.Log("needLoadSizeM " + needLoadSizeM + " Count " + needLoadPatchFiles.Count, Color.red);
        if (needLoadPatchFiles.Count > 0)
        {//如果下载列表不为空
            if (NetworkUtil.GetNetworkType() == NetworkType.Wifi)
            {
            }
            else
            {
                if (needLoadSizeM > 5f)
                {
                    //大于5m用户提醒
                }
            }

            HttpPatch();
        }
        else
        {
            PatchComplete();
        }
    }
Esempio n. 2
0
        /// <summary>
        /// Check cache from update and synchronize files from patches
        /// </summary>
        private void LoadCache()
        {
            var patchCachePath = Path.GetFileNameWithoutExtension(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName) + ".patch.cache";

            if (File.Exists(patchCachePath))
            {
                Version cacheVersion = null;
                Dictionary <string, PatchFile> cachePatch = null;
                // Read patch file structure
                using (var reader = new BinaryReader(new FileStream(patchCachePath, FileMode.Open)))
                {
                    cacheVersion = new Version(reader.ReadString());
                    // for each patch file
                    var filesCount = reader.ReadInt32();
                    cachePatch = new Dictionary <string, PatchFile>(filesCount);
                    for (int j = 0; j < filesCount; j++)
                    {
                        var file = new PatchFile(reader.ReadString(), reader.ReadString(), reader.ReadString());
                        cachePatch.Add(file.FullPath, file);
                    }
                }
                // Merge current patches with cache patch to avoid download all the patch again
                foreach (var version in Patches.Keys)
                {
                    if (version == cacheVersion)
                    {
                        var patch = Patches[version];
                        // Create a keys copy to remove from dictionary without issues
                        var paths = new List <string>(patch.Keys);
                        // If file doesn't exist on cache patch, then is already updated
                        foreach (var path in paths)
                        {
                            // Avoid update it again
                            if (!cachePatch.ContainsKey(path))
                            {
                                patch.Remove(path);
                                PatchFiles.Remove(path);
                            }
                        }
                        // Indicate update has been paused
                        IsUpdatePaused = true;
                    }
                }
            }
        }
Esempio n. 3
0
    private void LoadRemotePatchFiles()
    {
        GameEvent.SendEvent(GameEventType.GameFlow, GameFlow.PatchFileRemoteLoad);
        remotePatchFiles = new PatchFiles();
        string remotePatchFilesPath = PathUtil.RemotePatchFilesPath();

        GLog.Log("remotePatchFilesPath " + remotePatchFilesPath);
        if (File.Exists(remotePatchFilesPath))
        {
            HttpManager.Instance.LoadText(remotePatchFilesPath, (res) =>
            {
                remotePatchFiles.Load(res);
                CompareLocalAndRemotePatchFiles();
            });
        }
        else
        {
            GLog.Error(string.Format("{0} is null", remotePatchFilesPath), true);
        }
    }
Esempio n. 4
0
    private void HandlePatch()
    {
        GameEvent.SendEvent(GameEventType.GameFlow, GameFlow.PatchFileLocalLoad);

        localPatchFiles = new PatchFiles();
        string localPatchFilesPath = PathUtil.LocalPatchFilesPath();

        if (File.Exists(localPatchFilesPath))
        {
            GLog.Log("localPatchFilesPath " + localPatchFilesPath);
            HttpManager.Instance.LoadText(localPatchFilesPath, (res) =>
            {
                localPatchFiles.Load(res);
                LoadRemotePatchFiles();
            });
        }
        else
        {
            string streamingPatchFilesPath = PathUtil.StreamingPatchFilesPath();

            if (File.Exists(streamingPatchFilesPath))
            {
                GLog.Log("localPatchFilesPath " + streamingPatchFilesPath);
                HttpManager.Instance.LoadText(streamingPatchFilesPath, (res) =>
                {
                    File.WriteAllText(localPatchFilesPath, res);
                    localPatchFiles.Load(res);
                    LoadRemotePatchFiles();
                });
            }
            else
            {
                GLog.Error(string.Format("{0} is not find", streamingPatchFilesPath), true);
            }
        }
    }
Esempio n. 5
0
        public static bool DoCommandLine(string[] args)
        {
            if (args.Length <= 1)
                return true;

            patchList.Clear();
            System.Text.StringBuilder errorOutput = new System.Text.StringBuilder();
            errorOutput.AppendLine("-- ERROR LOG --");

            for (int i = 0; i < args.Length; i++)
            {
                if (args[i].Equals(CMD_HELP, StringComparison.OrdinalIgnoreCase))
                {
                    bHelp = true;
                    break;
                }
                else if ((!bEnablelog) && args[i].Equals(CMD_LOG, StringComparison.OrdinalIgnoreCase))
                {
                    bEnablelog = true;
                }
                else if ((!bInputfile) && args[i].Equals(CMD_INPUT, StringComparison.OrdinalIgnoreCase))
                {
                    if ((i + 1) < args.Length)
                    {
                        sInputpath = args[i + 1];
                        sInputpath = sInputpath.Trim();

                        if (sInputpath.Length > 0)
                            bInputfile = true;
                    }
                    else
                    {
                        errorOutput.AppendLine(CMD_INPUT + " switch without argument");
                    }
                }
                else if ((!bOutputfile) && args[i].Equals(CMD_OUTPUT, StringComparison.OrdinalIgnoreCase))
                {
                    if ((i + 1) < args.Length)
                    {
                        sOutputpath = args[i + 1];
                        sOutputpath = sOutputpath.Trim();

                        if (sOutputpath.Length > 0)
                            bOutputfile = true;
                    }
                    else
                    {
                        errorOutput.AppendLine(CMD_OUTPUT + " switch without argument");
                    }
                }
                else if ((!bUnpack) && args[i].Equals(CMD_UNPACK, StringComparison.OrdinalIgnoreCase))
                {
                    bUnpack = true;
                }
                else if ((!bDontfix) && args[i].Equals(CMD_DONTFIX, StringComparison.OrdinalIgnoreCase))
                {
                    bDontfix = true;
                }
                else if (args[i].Equals(CMD_PATCH, StringComparison.OrdinalIgnoreCase))
                {
                    if ((i + 1) < args.Length)
                    {
                        try
                        {
                            string[] patchParams = args[i + 1].Split(new char[] { ',' }, 4);
                            PatchFiles pfTemp = new PatchFiles();
                            pfTemp.file = patchParams[0];
                            pfTemp.index = Int32.Parse(patchParams[1]);
                            pfTemp.subindex = Int32.Parse(patchParams[2]);
                            pfTemp.compress = Int32.Parse(patchParams[3]);
                            patchList.Push(pfTemp);
                            bPatch = true;
                        }
                        catch
                        {
                            errorOutput.AppendLine(CMD_PATCH + " switch with incorrect argument (\"" + args[i + 1] + "\")");
                        }
                    }
                    else
                    {
                        errorOutput.AppendLine(CMD_PATCH + " switch without argument");
                    }
                }
                else if ((!bFullpatch) && args[i].Equals(CMD_FULLPATCH, StringComparison.OrdinalIgnoreCase))
                {
                    if ((i + 1) < args.Length)
                    {
                        sFullpatchPath = args[i + 1];
                        sFullpatchPath = sFullpatchPath.Trim();

                        if (sFullpatchPath.Length > 0)
                            bFullpatch = true;
                    }
                    else
                    {
                        errorOutput.AppendLine(CMD_FULLPATCH + " switch without argument");
                    }
                }
            }

            if (bHelp)
            {
                MessageBox.Show(MESSAGEBOX_HELP, "UO:KR Uop Dumper - Patch Help", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else if (bInputfile)
            {
                if (UopManager.getIstance().Load(sInputpath))
                {
                    if (bUnpack)
                    {
                        string thePath = Application.StartupPath + StaticData.UNPACK_DIR; ;
                        if (!Directory.Exists(thePath))
                            Directory.CreateDirectory(thePath);

                        if (!UopManager.getIstance().UnPack(thePath))
                        {
                            errorOutput.AppendLine("Error while unpacking the uop file to (\"" + thePath + "\")");
                        }
                    }
                    else if (bFullpatch)
                    {
                        UopManager.UopPatchError upeError = UopManager.UopPatchError.Okay;

                        if (Directory.Exists(sFullpatchPath))
                        {
                            try
                            {
                                string uopName = Path.GetFileNameWithoutExtension(UopManager.getIstance().UopPath);
                                string[] filesFound = Directory.GetFiles(sFullpatchPath, uopName + "*.*", SearchOption.TopDirectoryOnly);
                                foreach (string currentFile in filesFound)
                                {
                                    string strippedName = Path.GetFileName(currentFile);
                                    if (!strippedName.StartsWith(uopName + "-", StringComparison.OrdinalIgnoreCase))
                                    {
                                        errorOutput.AppendLine("Error while patching \"" + strippedName  + "\".");
                                        continue;
                                    }

                                    string parseName = strippedName.Substring(uopName.Length + 1);
                                    if (parseName.IndexOf('_') == -1)
                                    {
                                        errorOutput.AppendLine("Error while patching \"" + strippedName + "\".");
                                        continue;
                                    }

                                    int indexA = -1, indexB = -1;
                                    if (!Int32.TryParse(parseName.Substring(0, parseName.IndexOf('_')), out indexA))
                                    {
                                        errorOutput.AppendLine("Error while patching \"" + strippedName + "\".");
                                        continue;
                                    }

                                    parseName = parseName.Substring(parseName.IndexOf('_') + 1);
                                    if (!Int32.TryParse(parseName.Substring(0, parseName.IndexOf('.')), out indexB))
                                    {
                                        errorOutput.AppendLine("Error while patching \"" + strippedName + "\".");
                                        continue;
                                    }

                                    if ((indexA == -1) || (indexB == -1))
                                    {
                                        errorOutput.AppendLine("Error while patching \"" + strippedName + "\".");
                                        continue;
                                    }

                                    if (parseName.EndsWith("." + StaticData.UNPACK_EXT_COMP))
                                    {
                                        upeError = UopManager.getIstance().Replace(currentFile, indexA, indexB, false);
                                    }
                                    else if (parseName.EndsWith("." + StaticData.UNPACK_EXT_UCOMP))
                                    {
                                        upeError = UopManager.getIstance().Replace(currentFile, indexA, indexB, true);
                                    }
                                    else
                                    {
                                        errorOutput.AppendLine("Error while patching \"" + strippedName + "\".");
                                        continue;
                                    }

                                    if (upeError != UopManager.UopPatchError.Okay)
                                    {
                                        errorOutput.AppendLine("Error while patching \"" + strippedName + "\" (" + upeError.ToString() + ").");
                                        continue;
                                    }
                                }

                                if (!bOutputfile)
                                {
                                    sOutputpath = Utility.GetPathForSave(UopManager.getIstance().UopPath);
                                }

                                if (!bDontfix)
                                {
                                    UopManager.getIstance().FixOffsets(0, 0);
                                }

                                if (!UopManager.getIstance().Write(sOutputpath))
                                {
                                    errorOutput.AppendLine("Error while writing the new uop file (\"" + sOutputpath + "\")");
                                }
                            }
                            catch
                            {
                                errorOutput.AppendLine("Error while full-patching \"" + UopManager.getIstance().UopPath + "\" from \"" + sFullpatchPath + "\".");
                            }
                        }
                        else
                        {
                            errorOutput.AppendLine("Error while opening non-accessible directory \"" + sFullpatchPath + "\"");
                        }
                    }
                    else if (bPatch)
                    {
                        UopManager.UopPatchError upeError = UopManager.UopPatchError.Okay;
                        int iMinIndex = Int32.MaxValue, iMinSubindex = Int32.MaxValue;

                        foreach (PatchFiles pfCurrent in patchList)
                        {
                            iMinIndex = Math.Min(iMinIndex, pfCurrent.index);
                            iMinSubindex = Math.Min(iMinSubindex, pfCurrent.subindex);
                            upeError = UopManager.getIstance().Replace(pfCurrent.file, pfCurrent.index, pfCurrent.subindex, pfCurrent.compress > 0);

                            if (upeError != UopManager.UopPatchError.Okay)
                            {
                                errorOutput.AppendLine("Error (" + upeError.ToString() + ") while patching file \"" + pfCurrent.file + "\" to " + pfCurrent.index.ToString() + "," + pfCurrent.subindex.ToString() + " (" + ((pfCurrent.compress > 0) ? "UN" : "") + "compressed)");
                                break;
                            }
                        }

                        if (upeError == UopManager.UopPatchError.Okay)
                        {
                            if (!bOutputfile)
                            {
                                sOutputpath = Utility.GetPathForSave(UopManager.getIstance().UopPath);
                            }

                            if (bDontfix)
                            {
                                UopManager.getIstance().FixOffsets(iMinIndex, iMinSubindex);
                            }

                            if (!UopManager.getIstance().Write(sOutputpath))
                            {
                                errorOutput.AppendLine("Error while writing the new uop file (\"" + sOutputpath + "\")");
                            }
                        }
                    }
                }
                else
                {
                    errorOutput.AppendLine("Error while opening the uop file (\"" + UopManager.getIstance().UopPath + "\")");
                }
            }
            else
            {
                errorOutput.AppendLine("ERROR: No action defined.");
            }

            if (bEnablelog)
            {
                try
                {
                    File.WriteAllText(Application.StartupPath + @"\error.log", errorOutput.ToString());
                }
                catch { }
            }

            return false;
        }
Esempio n. 6
0
        public static bool DoCommandLine(string[] args)
        {
            if (args.Length <= 1)
            {
                return(true);
            }

            patchList.Clear();
            System.Text.StringBuilder errorOutput = new System.Text.StringBuilder();
            errorOutput.AppendLine("-- ERROR LOG --");

            for (int i = 0; i < args.Length; i++)
            {
                if (args[i].Equals(CMD_HELP, StringComparison.OrdinalIgnoreCase))
                {
                    bHelp = true;
                    break;
                }
                else if ((!bEnablelog) && args[i].Equals(CMD_LOG, StringComparison.OrdinalIgnoreCase))
                {
                    bEnablelog = true;
                }
                else if ((!bInputfile) && args[i].Equals(CMD_INPUT, StringComparison.OrdinalIgnoreCase))
                {
                    if ((i + 1) < args.Length)
                    {
                        sInputpath = args[i + 1];
                        sInputpath = sInputpath.Trim();

                        if (sInputpath.Length > 0)
                        {
                            bInputfile = true;
                        }
                    }
                    else
                    {
                        errorOutput.AppendLine(CMD_INPUT + " switch without argument");
                    }
                }
                else if ((!bOutputfile) && args[i].Equals(CMD_OUTPUT, StringComparison.OrdinalIgnoreCase))
                {
                    if ((i + 1) < args.Length)
                    {
                        sOutputpath = args[i + 1];
                        sOutputpath = sOutputpath.Trim();

                        if (sOutputpath.Length > 0)
                        {
                            bOutputfile = true;
                        }
                    }
                    else
                    {
                        errorOutput.AppendLine(CMD_OUTPUT + " switch without argument");
                    }
                }
                else if ((!bUnpack) && args[i].Equals(CMD_UNPACK, StringComparison.OrdinalIgnoreCase))
                {
                    bUnpack = true;
                }
                else if ((!bDontfix) && args[i].Equals(CMD_DONTFIX, StringComparison.OrdinalIgnoreCase))
                {
                    bDontfix = true;
                }
                else if (args[i].Equals(CMD_PATCH, StringComparison.OrdinalIgnoreCase))
                {
                    if ((i + 1) < args.Length)
                    {
                        try
                        {
                            string[]   patchParams = args[i + 1].Split(new char[] { ',' }, 4);
                            PatchFiles pfTemp      = new PatchFiles();
                            pfTemp.file     = patchParams[0];
                            pfTemp.index    = Int32.Parse(patchParams[1]);
                            pfTemp.subindex = Int32.Parse(patchParams[2]);
                            pfTemp.compress = Int32.Parse(patchParams[3]);
                            patchList.Push(pfTemp);
                            bPatch = true;
                        }
                        catch
                        {
                            errorOutput.AppendLine(CMD_PATCH + " switch with incorrect argument (\"" + args[i + 1] + "\")");
                        }
                    }
                    else
                    {
                        errorOutput.AppendLine(CMD_PATCH + " switch without argument");
                    }
                }
                else if ((!bFullpatch) && args[i].Equals(CMD_FULLPATCH, StringComparison.OrdinalIgnoreCase))
                {
                    if ((i + 1) < args.Length)
                    {
                        sFullpatchPath = args[i + 1];
                        sFullpatchPath = sFullpatchPath.Trim();

                        if (sFullpatchPath.Length > 0)
                        {
                            bFullpatch = true;
                        }
                    }
                    else
                    {
                        errorOutput.AppendLine(CMD_FULLPATCH + " switch without argument");
                    }
                }
            }

            if (bHelp)
            {
                MessageBox.Show(MESSAGEBOX_HELP, "UO:KR Uop Dumper - Patch Help", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else if (bInputfile)
            {
                if (UopManager.getIstance().Load(sInputpath))
                {
                    if (bUnpack)
                    {
                        string thePath = Application.StartupPath + StaticData.UNPACK_DIR;;
                        if (!Directory.Exists(thePath))
                        {
                            Directory.CreateDirectory(thePath);
                        }

                        if (!UopManager.getIstance().UnPack(thePath))
                        {
                            errorOutput.AppendLine("Error while unpacking the uop file to (\"" + thePath + "\")");
                        }
                    }
                    else if (bFullpatch)
                    {
                        UopManager.UopPatchError upeError = UopManager.UopPatchError.Okay;

                        if (Directory.Exists(sFullpatchPath))
                        {
                            try
                            {
                                string   uopName    = Path.GetFileNameWithoutExtension(UopManager.getIstance().UopPath);
                                string[] filesFound = Directory.GetFiles(sFullpatchPath, uopName + "*.*", SearchOption.TopDirectoryOnly);
                                foreach (string currentFile in filesFound)
                                {
                                    string strippedName = Path.GetFileName(currentFile);
                                    if (!strippedName.StartsWith(uopName + "-", StringComparison.OrdinalIgnoreCase))
                                    {
                                        errorOutput.AppendLine("Error while patching \"" + strippedName + "\".");
                                        continue;
                                    }

                                    string parseName = strippedName.Substring(uopName.Length + 1);
                                    if (parseName.IndexOf('_') == -1)
                                    {
                                        errorOutput.AppendLine("Error while patching \"" + strippedName + "\".");
                                        continue;
                                    }

                                    int indexA = -1, indexB = -1;
                                    if (!Int32.TryParse(parseName.Substring(0, parseName.IndexOf('_')), out indexA))
                                    {
                                        errorOutput.AppendLine("Error while patching \"" + strippedName + "\".");
                                        continue;
                                    }

                                    parseName = parseName.Substring(parseName.IndexOf('_') + 1);
                                    if (!Int32.TryParse(parseName.Substring(0, parseName.IndexOf('.')), out indexB))
                                    {
                                        errorOutput.AppendLine("Error while patching \"" + strippedName + "\".");
                                        continue;
                                    }

                                    if ((indexA == -1) || (indexB == -1))
                                    {
                                        errorOutput.AppendLine("Error while patching \"" + strippedName + "\".");
                                        continue;
                                    }

                                    if (parseName.EndsWith("." + StaticData.UNPACK_EXT_COMP))
                                    {
                                        upeError = UopManager.getIstance().Replace(currentFile, indexA, indexB, false);
                                    }
                                    else if (parseName.EndsWith("." + StaticData.UNPACK_EXT_UCOMP))
                                    {
                                        upeError = UopManager.getIstance().Replace(currentFile, indexA, indexB, true);
                                    }
                                    else
                                    {
                                        errorOutput.AppendLine("Error while patching \"" + strippedName + "\".");
                                        continue;
                                    }

                                    if (upeError != UopManager.UopPatchError.Okay)
                                    {
                                        errorOutput.AppendLine("Error while patching \"" + strippedName + "\" (" + upeError.ToString() + ").");
                                        continue;
                                    }
                                }

                                if (!bOutputfile)
                                {
                                    sOutputpath = Utility.GetPathForSave(UopManager.getIstance().UopPath);
                                }

                                if (!bDontfix)
                                {
                                    UopManager.getIstance().FixOffsets(0, 0);
                                }

                                if (!UopManager.getIstance().Write(sOutputpath))
                                {
                                    errorOutput.AppendLine("Error while writing the new uop file (\"" + sOutputpath + "\")");
                                }
                            }
                            catch
                            {
                                errorOutput.AppendLine("Error while full-patching \"" + UopManager.getIstance().UopPath + "\" from \"" + sFullpatchPath + "\".");
                            }
                        }
                        else
                        {
                            errorOutput.AppendLine("Error while opening non-accessible directory \"" + sFullpatchPath + "\"");
                        }
                    }
                    else if (bPatch)
                    {
                        UopManager.UopPatchError upeError = UopManager.UopPatchError.Okay;
                        int iMinIndex = Int32.MaxValue, iMinSubindex = Int32.MaxValue;

                        foreach (PatchFiles pfCurrent in patchList)
                        {
                            iMinIndex    = Math.Min(iMinIndex, pfCurrent.index);
                            iMinSubindex = Math.Min(iMinSubindex, pfCurrent.subindex);
                            upeError     = UopManager.getIstance().Replace(pfCurrent.file, pfCurrent.index, pfCurrent.subindex, pfCurrent.compress > 0);

                            if (upeError != UopManager.UopPatchError.Okay)
                            {
                                errorOutput.AppendLine("Error (" + upeError.ToString() + ") while patching file \"" + pfCurrent.file + "\" to " + pfCurrent.index.ToString() + "," + pfCurrent.subindex.ToString() + " (" + ((pfCurrent.compress > 0) ? "UN" : "") + "compressed)");
                                break;
                            }
                        }

                        if (upeError == UopManager.UopPatchError.Okay)
                        {
                            if (!bOutputfile)
                            {
                                sOutputpath = Utility.GetPathForSave(UopManager.getIstance().UopPath);
                            }

                            if (bDontfix)
                            {
                                UopManager.getIstance().FixOffsets(iMinIndex, iMinSubindex);
                            }

                            if (!UopManager.getIstance().Write(sOutputpath))
                            {
                                errorOutput.AppendLine("Error while writing the new uop file (\"" + sOutputpath + "\")");
                            }
                        }
                    }
                }
                else
                {
                    errorOutput.AppendLine("Error while opening the uop file (\"" + UopManager.getIstance().UopPath + "\")");
                }
            }
            else
            {
                errorOutput.AppendLine("ERROR: No action defined.");
            }

            if (bEnablelog)
            {
                try
                {
                    File.WriteAllText(Application.StartupPath + @"\error.log", errorOutput.ToString());
                }
                catch { }
            }

            return(false);
        }
Esempio n. 7
0
        /// <summary>
        /// Start/continue updating the application
        /// </summary>
        private async Task StartUpdating()
        {
            IsUpdatePaused = false;

            // Check there is files to update
            if (PatchFiles == null || PatchFiles.Count == 0)
            {
                return;
            }

            // Path to check if the executable needs to be updated
            var exePath = Path.GetFileName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);

            // Start Downloading files from old patches to new ones
            var versions = new List <Version>(Patches.Keys);

            versions.Sort((a, b) => { return(a.CompareTo(b)); });
            foreach (var version in versions)
            {
                var patch = Patches[version];
                // Create a different instance of keys to remove it without issues
                var paths = new List <string>(patch.Keys);
                // Download and update each file from this version
                for (int i = 0; i < paths.Count; i++)
                {
                    // track updating file
                    var f = m_CurrentFileUpdating = patch[paths[i]];
                    // Check if the file is going to replace this executable
                    bool isExecutable = f.FullPath == exePath;
                    if (isExecutable)
                    {
                        // Check if is not last file to update
                        if (i < (paths.Count - 1))
                        {
                            // Add it again as last one
                            paths.Add(f.FullPath);
                            continue;
                        }
                    }

                    // call event
                    OnFileDownloadReady(f);

                    // track event
                    f.DownloadProgressChanged += OnFileDownloadProgressChanged;

                    // download it
                    await f.StartDownload();

                    // untrack event
                    f.DownloadProgressChanged -= OnFileDownloadProgressChanged;

                    // Check if download has been paused
                    if (f.IsPaused)
                    {
                        break;
                    }

                    // call event
                    var completedEventArgs = OnFileDownloadCompleted(f);

                    // Check if the updating process is going to be handled by manager
                    if (completedEventArgs.CancelUpdate)
                    {
                        await completedEventArgs.ExecuteAction();
                    }
                    else
                    {
                        // Check if is executable
                        if (isExecutable)
                        {
                            // update it slightly different (delete super old, move old and forget then move new)
                            var thrashPath = Path.Combine(DownloadingPath, exePath + ".old");
                            await Task.Run(() =>
                            {
                                if (File.Exists(thrashPath))
                                {
                                    File.Delete(thrashPath);
                                }
                                File.Move(exePath, thrashPath);
                                File.Move(f.DownloadPath, exePath);
                            });
                        }
                        else
                        {
                            // update it
                            await f.Update();
                        }
                    }

                    // Check if is the executable being updated
                    if (isExecutable)
                    {
                        // delete cache
                        DeleteCache();
                    }
                    else
                    {
                        // Create backup to continue the update on restart
                        SaveCache(version, patch);
                    }

                    // remove it from tracking
                    patch.Remove(f.FullPath);
                    PatchFiles.Remove(f.FullPath);

                    // call event
                    OnFileUpdateCompleted(f);

                    // Start calling a events to restart the application
                    if (isExecutable)
                    {
                        // call event
                        OnPatchCompleted(version);

                        // Check if this is the last file from everything for update
                        if (PatchFiles.Count == 0)
                        {
                            // call event
                            OnUpdateCompleted();
                        }

                        // Restart application
                        OnApplicationRestart();

                        // Execute new executable and exit from this one
                        System.Diagnostics.Process.Start(exePath);
                        Environment.Exit(0);
                    }
                }

                // Stop tracking as updating
                m_CurrentFileUpdating = null;

                // Check if update has been paused
                if (IsUpdatePaused)
                {
                    break;
                }

                // call event
                OnPatchCompleted(version);
            }

            // Patch finished
            if (PatchFiles.Count == 0)
            {
                // delete cache
                DeleteCache();
                // call event
                OnUpdateCompleted();
            }
        }