public DefaultPatcher(IClientProfile clientProfile, IServerProfile serverProfile, PatcherContext patcherContext) { ClientProfile = clientProfile; ServerProfile = serverProfile; PatcherContext = patcherContext; PatcherType = DefaultPatcherTypes.Default; }
/// <summary> /// Creates a task which represent an individual patch operation /// </summary> /// <param name="clientProfile"></param> /// <param name="patchInfo"></param> /// <param name="officialPatchInfo"></param> /// <param name="patcherContext"></param> public PatchTask(PatcherContext patcherContext, IClientProfile clientProfile, PatchInfo patchInfo, OfficialPatchInfo officialPatchInfo) { _patcherContext = patcherContext; _clientProfile = clientProfile; PatchInfo = patchInfo; OfficialPatchInfo = officialPatchInfo; }
public PatchDownloader(List <Patch> patches, IClientProfile clientProfile, PatcherContext patcherContext) { _patches = patches; _clientProfile = clientProfile; _patcherContext = patcherContext; _queueManager = new QueueManager(_patcherContext); }
/// <summary> /// Creates a download queue but does not initialize it /// </summary> /// <param name="patcherContext"></param> /// <param name="patchInfos"></param> /// <param name="officialPatchInfo"></param> public DownloadQueue(PatcherContext patcherContext, IClientProfile clientProfile, List <PatchInfo> patchInfos, OfficialPatchInfo officialPatchInfo) { _patcherContext = patcherContext; _clientProfile = clientProfile; _patchInfos = patchInfos; _patchTasks = new List <PatchTask>(); _officialPatchInfo = officialPatchInfo; }
/// <summary> /// Creates a new instance of PatcherDownloader that accepts a PatchSequence /// </summary> /// <param name="patchSequence">PatchSequence representing a collection of patches</param> /// <param name="officialPatchInfo"></param> /// <param name="clientProfile"></param> public PatchDownloader(PatcherContext patcherContext, PatchSequence patchSequence, OfficialPatchInfo officialPatchInfo, IClientProfile clientProfile) { Patches = new List <PatchInfo>(); _patcherContext = patcherContext; _officialPatchInfo = officialPatchInfo; _clientProfile = clientProfile; Patches.AddRange(patchSequence.Patches); }
public override async Task <bool> CheckForUpdates() { if (ClientProfile == null) { return(false); } if (ServerProfile == null) { return(false); } // Should never hit, earlier logic shouldn't even call the function if (!ServerProfile.IsOfficial) { return(false); } if (ClientProfile.Localization != ClientLocalization.Japan && ClientProfile.Localization != ClientLocalization.JapanHangame) { return(false); } PatcherContext.SetPatcherState(true); PatcherContext.UpdateMainProgress("Checking for updates...", "", 0, true, true); _officialPatchInfo = OfficialPatchInfo.Parse(MabiVersion.Versions .Find(version => version.Name == ClientProfile.Localization).PatchUrl); if (int.TryParse(_officialPatchInfo["main_version"], out var versionConverted)) { _remoteVersion = versionConverted; } if (_currentVersion == _remoteVersion) { PatcherContext.SetPatcherState(false); PatcherContext.UpdateMainProgress("", "", 0, false, false); return(false); } try { await Task.Run(() => _patchSequence = FindPatchSequence()); } catch (PatchSequenceNotFoundException ex) { Log.Exception(ex); PatcherContext.SetPatcherState(false); PatcherContext.UpdateMainProgress("", "", 0, false, false); return(false); } PatcherContext.SetPatcherState(false); PatcherContext.UpdateMainProgress("", "", 0, false, false); return(true); }
private async Task <List <FileDownloadInfo> > GetFileDownloadInfo() { double entries = ((ICollection)PatchData.files).Count; PatcherContext.UpdateMainProgress(Properties.Resources.ParsingManifest, $"0/{entries}", 0, false, true); var fileDownloadInfos = new List <FileDownloadInfo>(); await Task.Delay(1); int entry = 0; // Decode filepaths into new collection foreach (var file in PatchData["files"]) { entry++; PatcherContext.UpdateMainProgress(Properties.Resources.ParsingManifest, $"{entry}/{entries}", entry / entries * 100, false, true); var isDirectory = false; var filename = file.Name; var decodedFilename = DecodeFilename(filename); // Nexon does not intend for this file to be downloaded or this may be some other specification if (file.Value["objects"].Count == 0) { Log.Info(Properties.Resources.FileWithNoObjectsIgnored, decodedFilename); continue; } if (file.Value["objects"][0] == "__DIR__") { isDirectory = true; } var fileDownloadInfo = new FileDownloadInfo(decodedFilename, file.Value["fsize"].Value, isDirectory ? FileInfoType.Directory : FileInfoType.File); fileDownloadInfo.SetModifiedTimeDateTime(file.Value["mtime"].Value); if (isDirectory) { continue; } for (var i = 0; i < file.Value["objects"].Count; i++) { var filePartInfo = new FilePartInfo(file.Value["objects"][i].Value, decodedFilename, file.Value["objects_fsize"][i].Value, i); fileDownloadInfo.FileParts.Add(filePartInfo); } fileDownloadInfos.Add(fileDownloadInfo); } return(fileDownloadInfos); }
public override async Task <bool> RepairInstall() { var shouldUpdate = await CheckForUpdatesInternal(-1, true); if (shouldUpdate) { return(await ApplyUpdates()); } PatcherContext.SetPatcherState(false); PatcherContext.UpdateMainProgress("", "", 0, false, false); return(true); }
private bool ValidateAction(bool silent = false) { if (ClientProfile == null) { if (!silent) { PatcherContext.ShowDialog(Properties.Resources.NoProfileSelected, Properties.Resources.NoProfileSelectedMessage2); } return(true); } if (string.IsNullOrWhiteSpace(ClientProfile.Location)) { if (!silent) { PatcherContext.ShowDialog(Properties.Resources.ProfileError, string.Format( Properties.Resources.ProfileErrorMessage, ClientProfile.Name)); } return(true); } if (!ServerProfile.IsOfficial) { if (!silent) { PatcherContext.ShowDialog(Properties.Resources.ActionCancelled, Properties.Resources.ActionCancelledMessage); } return(true); } if (File.Exists("steam_connector_config.json")) { Log.Info("Patching for steam is not supported at this time."); return(true); } if (ClientLocalization.GetLocalization(ClientProfile.Localization) != "NorthAmerica") { if (!silent) { PatcherContext.ShowDialog(Properties.Resources.UnsupportedLocalization, Properties.Resources.UnsupportedLocalizationMessage); } return(true); } return(false); }
public override async Task <bool> ApplyUpdates() { PatcherContext.SetPatcherState(true); PatcherContext.ShowSession(); var downloader = new PatchDownloader(PatcherContext, _patchSequence, _officialPatchInfo, ClientProfile); await Task.Run(() => downloader.Prepare()); await Task.Run(() => downloader.Patch()); WriteVersion(_remoteVersion); PatcherContext.SetPatcherState(false); PatcherContext.HideSession(); return(true); }
public override async Task <bool> CheckForUpdates() { if (ValidateAction(true)) { return(false); } PatcherContext.UpdateMainProgress(Properties.Resources.Initialize, "", 0, true, true); var completed = "true"; PatcherContext.SetPatcherState(true); PatcherContext.UpdateMainProgress(Properties.Resources.CheckingForUpdates, "", 0, true, true); if (!NexonApi.Instance.IsAccessTokenValid(ClientProfile.Guid)) { completed = ""; PatcherContext.RequestUserLogin(() => completed = "true", () => completed = "false"); } while (completed == "") { await Task.Delay(100); } if (completed == "false") { PatcherContext.SetPatcherState(false); PatcherContext.UpdateMainProgress("", "", 0, false, false); return(false); } var result = await CheckForUpdatesInternal(ReadVersion()); PatcherContext.SetPatcherState(false); PatcherContext.UpdateMainProgress("", "", 0, false, false); return(result); }
private async Task GetManifestJson(int version) { if (version == -1) { PatcherContext.UpdateMainProgress(Properties.Resources.GettingLatestVersion, "", 0, true, true); _version = version = await NexonApi.Instance.GetLatestVersion(); } PatcherContext.UpdateMainProgress(Properties.Resources.DownloadingManifest, "", 0, true, true); // Get Manifest String var manifestHashString = await NexonApi.Instance.GetManifestHashString(); // Download Manifest var buffer = DownloadManifestBuffer(manifestHashString); PatcherContext.UpdateMainProgress(Properties.Resources.DecompressingManifest, "", 0, true, true); // Decompress Manifest and Convert to Object var manifestContent = ZlibStream.UncompressString(buffer); var data = JsonConvert.DeserializeObject <dynamic>(manifestContent); PatchData = data; }
public override async Task <bool> ApplyUpdates() { if (ValidateAction()) { return(false); } PatcherContext.SetPatcherState(true); PatcherContext.ShowSession(); PatcherContext.UpdateMainProgress(Properties.Resources.ApplyingUpdates, "", 0, true, true); var patchDownloader = new PatchDownloader(Patches, ClientProfile, PatcherContext); bool result = false; try { await Task.Run(() => patchDownloader.Prepare()); result = await Task.Run(() => patchDownloader.Patch()); await Task.Run(() => patchDownloader.Cleanup()); } catch (Exception ex) { Log.Exception(ex, "Failed to patch!"); } finally { PatcherContext.UpdateMainProgress(result ? Properties.Resources.PatchComplete : Properties.Resources.PatchFailed); PatcherContext.SetPatcherState(false); PatcherContext.HideSession(); } return(result); }
public DownloadWrapper(Patch patch, PatcherContext patcherContext) { Patch = patch; _patcherContext = patcherContext; }
public NxlPatcher(IClientProfile clientProfile, IServerProfile serverProfile, PatcherContext patcherContext) : base(clientProfile, serverProfile, patcherContext) { PatcherType = DefaultPatcherTypes.NxLauncher; PatchSettingsManager.Initialize(); PatchIgnore = new PatchIgnore(PatcherContext); }
private void GetPatchList(bool overrideSettings = false) { double entries = FileDownloadInfos.Count; PatcherContext.UpdateMainProgress(Properties.Resources.CheckingFiles, $"0/{entries}", 0, false, true); var entry = 0; foreach (var fileDownloadInfo in FileDownloadInfos) { entry++; PatcherContext.UpdateMainProgress(Properties.Resources.CheckingFiles, $"{entry}/{entries}", entry / entries * 100, false, true); var filePath = fileDownloadInfo.FileName; if (!overrideSettings) { if (filePath.StartsWith("package\\") && PatchSettingsManager.Instance.PatcherSettings.IgnorePackageFolder && !GetIsNewPackFile(filePath)) { continue; } } if (PatchIgnore.IgnoredFiles.Contains(filePath)) { Log.Info($"File: '{filePath}' in ignore list, file will not be patched!"); continue; } if (fileDownloadInfo.FileInfoType == FileInfoType.Directory) { if (Directory.Exists(fileDownloadInfo.FileName)) { continue; } Patches.Add(new Patch(fileDownloadInfo, PatchReason.DoesNotExist)); continue; } var modified = false; var fileExists = true; var actualModified = new DateTime(); var correctSize = true; long length = 0; if (File.Exists(filePath)) { length = new FileInfo(filePath).Length; actualModified = File.GetLastWriteTime(filePath); if (actualModified != fileDownloadInfo.LastModifiedDateTime) { modified = true; } else if (length != fileDownloadInfo.FileSize) { correctSize = false; } } else { fileExists = false; } if (!correctSize) { var patch = new Patch(fileDownloadInfo, PatchReason.SizeNotMatch); Patches.Add(patch); Log.Info(Properties.Resources.PatchRequiredForSize, filePath, patch.PatchReason.LocalizedPatchReason(), fileDownloadInfo.FileSize, length); continue; } if (!fileExists) { var patch = new Patch(fileDownloadInfo, PatchReason.DoesNotExist); Patches.Add(patch); Log.Info(Properties.Resources.PatchRequiredFor, filePath, patch.PatchReason.LocalizedPatchReason()); continue; } if (!modified) { continue; } if (actualModified > fileDownloadInfo.LastModifiedDateTime) { var patch = new Patch(fileDownloadInfo, PatchReason.Modified); Patches.Add(patch); Log.Info(Properties.Resources.PatchRequiredFor, filePath, patch.PatchReason.LocalizedPatchReason()); } else { var patch = new Patch(fileDownloadInfo); Patches.Add(patch); Log.Info(Properties.Resources.PatchRequiredFor, filePath, patch.PatchReason.LocalizedPatchReason()); } } }
public QueueManager(PatcherContext patcherContext) { _patcherContext = patcherContext; _downloadWrappers = new Dictionary <string, DownloadWrapper>(); _fileParts = new Queue <FilePartInfo>(); }
public PatchIgnore(PatcherContext patcherContext) { _pluginContext = patcherContext; }
private PatchSequence FindPatchSequence(int currentVersion = -1, int remoteVersion = -1) { if (currentVersion == -1) { currentVersion = _currentVersion; } if (remoteVersion == -1) { remoteVersion = _remoteVersion; } Log.Info("Attempting to find sequence from {0} to {1}", currentVersion, remoteVersion); var patchInfos = new List <PatchInfo>(); var format = "Attempting to patch from {0} to {1}. Currently checking {2}."; try { using (var webClient = new WebClient()) { if (currentVersion == 0) { PatcherContext.UpdateMainProgress(string.Format(format, 0, remoteVersion, remoteVersion), "", 0, true, true); var patchInfo = GetPatchInfo(webClient, remoteVersion, $"{remoteVersion}_full.txt"); if (patchInfo == null) { throw new PatchSequenceNotFoundException(currentVersion, remoteVersion); } patchInfos.Add(patchInfo); } else { var fromNumber = currentVersion; var toNumber = remoteVersion; while (fromNumber != toNumber) { PatcherContext.UpdateMainProgress(string.Format(format, currentVersion, remoteVersion, fromNumber), "", (fromNumber - (double)currentVersion / (remoteVersion - currentVersion)), true, true); var patchInfo = GetPatchInfo(webClient, remoteVersion, $"{fromNumber}_to_{toNumber}.txt"); if (patchInfo != null) { patchInfos.Add(patchInfo); fromNumber = toNumber; toNumber += 5; } else if (--toNumber == fromNumber) { return(FindPatchSequence(0, remoteVersion)); } } } } } finally { PatcherContext.UpdateMainProgress(); } return(new PatchSequence(patchInfos)); }
public LegacyPatcher(ClientProfile clientProfile, ServerProfile serverProfile, PatcherContext patcherContext) : base(clientProfile, serverProfile, patcherContext) { PatcherType = DefaultPatcherTypes.Legacy; _currentVersion = ReadVersion(); }