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(); } }
/// <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; } } } }
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); } }
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); } } }
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; }
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); }
/// <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(); } }