private PluginToUpdate CheckAddPluginsByConfig() { PluginToUpdate result = null; var PluginsDir = new DirectoryInfo("plugins"); foreach (var pluginDirectoryInfo in PluginsDir.GetDirectories()) { var gitConfigFilePath = Path.Combine(pluginDirectoryInfo.FullName, "GitUpdateConfig.txt"); if (File.Exists(gitConfigFilePath)) { if ( !AllPlugins.Any( x => string.Equals(x.PluginDirectory, pluginDirectoryInfo.FullName, StringComparison.OrdinalIgnoreCase))) { var pluginFolderName = Path.GetFileName(pluginDirectoryInfo.FullName); result = AddPlugin(pluginFolderName, pluginDirectoryInfo.FullName); } } } return(result); }
private void AddPoeHudPlugin() { var poehudExePath = Assembly.GetEntryAssembly().Location; var poehudExeLocation = Path.GetDirectoryName(poehudExePath); var poehudExeName = Path.GetFileName(poehudExePath); var plugVariant = new PluginToUpdate { RepoOwner = "TehCheat", RepoName = "PoEHUD", PluginName = "PoeHUD", PluginDirectory = poehudExeLocation,//\src\bin\x64\Debug\plugins\PoeHUD bAllowCheckUpdate = true, bHasGitConfig = true, BranchName = Settings.PoeHUDBranch, UpdateVariant = ePluginSourceOfUpdate.RepoBranch, UpdateState = ePluginUpdateState.ReadyToInstal, IgnoredEntities = new List <string>() { "src", ".gitattributes", ".gitignore", "README.md", "shortcut.bat" }, IsPoeHUD = true, PoehudExeRealName = poehudExeName }; plugVariant.DoAfterUpdate += ProcessPoehudUpdate; AllPlugins.Insert(0, plugVariant); }
private void ProcessPoehudUpdate(PluginToUpdate plugin) { var poehudExePath = Assembly.GetEntryAssembly().Location; var poehudExeName = Path.GetFileName(poehudExePath); var poehudExeLocation = Path.GetDirectoryName(poehudExePath); string exeToDelete = "-"; string exeToStart = poehudExeName; var newExe = plugin.FilesToDownload.Find(x => x.Path.EndsWith("PoeHUD.exe")); if (newExe != null) { exeToStart = Path.GetFileName(newExe.Path); exeToDelete = poehudExePath; } var poeHudUpdateFilesDir = Path.Combine(poehudExeLocation, UpdateTempDir); var poeProcess = Process.GetCurrentProcess(); string updaterFilePath = Path.Combine(PluginDirectory, "PoeHUDUpdater.exe"); if (!File.Exists(updaterFilePath)) { LogError("Can't find PoeHUDUpdater.exe in PoeHUD_PluginsUpdater folder to update PoeHUD!", 10); return; } string exeHash = ""; if (newExe != null) { exeHash = newExe.Sha; } var psi = new ProcessStartInfo(); psi.CreateNoWindow = true; //This hides the dos-style black window that the command prompt usually shows psi.FileName = @"cmd.exe"; psi.Verb = "runas"; //this is what actually runs the command as administrator psi.Arguments = $"/C {updaterFilePath} {poeHudUpdateFilesDir} {poehudExeLocation} {poeProcess.Id} {Path.Combine(poehudExeLocation, exeToStart)} {exeToDelete} {exeHash}"; try { var process = new Process(); process.StartInfo = psi; process.Start(); process.WaitForExit(); } catch (Exception) { LogError("PoeHUD Updater: Can't start PoeUpdater.exe with admin rights", 10); //If you are here the user clicked declined to grant admin privileges (or he's not administrator) } }
private PluginToUpdate AddPlugin(string pluginName, string pluginDirectory) { var plugVariant = new PluginToUpdate { PluginName = pluginName, PluginDirectory = pluginDirectory }; AllPlugins.Add(plugVariant); GitConfigParser.Parse(plugVariant); return(plugVariant); }
public static void Parse(PluginToUpdate plugVariant) { try { var gitConfigFilePath = Path.Combine(plugVariant.PluginDirectory, ConfigFileName); if (File.Exists(gitConfigFilePath)) { plugVariant.bHasGitConfig = true; var configLines = File.ReadAllLines(gitConfigFilePath); var handleIgnore = false; for (var i = 0; i < configLines.Length; i++) { var line = configLines[i]; if (line.StartsWith("#")) { continue; } var spacelessLine = line.Replace(" ", ""); if (spacelessLine.Replace("\r", "").Replace("\n", "").Length == 0) { continue; } if (handleIgnore) { plugVariant.IgnoredEntities.Add(line); continue; } if (spacelessLine == OPTION_FILESIGNORE) { handleIgnore = true; continue; } //Repository owner var ownerIndex = line.IndexOf(OPTION_OWNER); if (ownerIndex != -1) { plugVariant.RepoOwner = line.Substring(ownerIndex + OPTION_OWNER.Length); TrimName(ref plugVariant.RepoOwner); continue; } //Repository name var reposNameIndex = line.IndexOf(OPTION_REPONAME); if (reposNameIndex != -1) { plugVariant.RepoName = line.Substring(reposNameIndex + OPTION_REPONAME.Length); TrimName(ref plugVariant.RepoName); continue; } //Only from release if (spacelessLine == OPTION_RELEASE) { if (plugVariant.UpdateVariant != ePluginSourceOfUpdate.Undefined) { BasePlugin.LogMessage( "PluginUpdater: " + plugVariant.PluginName + ", both update variants (Release and Commit) is not allowed. Check GitUpdateConfig. Current update variant is: " + plugVariant.UpdateVariant, 10); } else { plugVariant.UpdateVariant = ePluginSourceOfUpdate.Release; } continue; } //Only from repository if (spacelessLine == OPTION_REPOONLY) { if (plugVariant.UpdateVariant != ePluginSourceOfUpdate.Undefined) { BasePlugin.LogMessage( "PluginUpdater: " + plugVariant.PluginName + ", both update variants (Release and Commit) is not allowed. Check GitUpdateConfig. Current update variant is: " + plugVariant.UpdateVariant, 10); } else { plugVariant.UpdateVariant = ePluginSourceOfUpdate.RepoBranch; } continue; } //Release tag regex filter var tagIndex = line.IndexOf(OPTION_RELEASETAGREGEXFILTER); if (tagIndex != -1) { plugVariant.ReleaseRegexTag = line.Substring(tagIndex + OPTION_RELEASETAGREGEXFILTER.Length); TrimName(ref plugVariant.ReleaseRegexTag); plugVariant.bCustomTag = true; } var branchNameIndex = line.IndexOf(OPTION_REPOBRANCH); if (branchNameIndex != -1) { plugVariant.BranchName = line.Substring(branchNameIndex + OPTION_REPOBRANCH.Length); TrimName(ref plugVariant.BranchName); } } plugVariant.bAllowCheckUpdate = true; if (string.IsNullOrEmpty(plugVariant.RepoOwner)) { BasePlugin.LogError("PluginUpdater: Repository Owner is not defined in plugin: " + plugVariant.PluginName, 10); plugVariant.UpdateState = ePluginUpdateState.WrongConfig; plugVariant.bAllowCheckUpdate = false; } if (string.IsNullOrEmpty(plugVariant.RepoName)) { BasePlugin.LogError("PluginUpdater: Repository Name is not defined in plugin: " + plugVariant.PluginName, 10); plugVariant.UpdateState = ePluginUpdateState.WrongConfig; plugVariant.bAllowCheckUpdate = false; } if (plugVariant.UpdateVariant == ePluginSourceOfUpdate.Undefined) { BasePlugin.LogError("PluginUpdater: Update type (Release or Repository) is not defined in plugin: " + plugVariant.PluginName, 10); plugVariant.UpdateState = ePluginUpdateState.WrongConfig; plugVariant.bAllowCheckUpdate = false; } } } catch { BasePlugin.LogError("PluginUpdater: Error while parsing git update config for plugin: " + plugVariant.PluginName, 10); } }
private float DrawPlugin(float drawPosX, float drawPosY, float width, PluginToUpdate plug) { var pluginFrame = new RectangleF(drawPosX + 5, drawPosY, width - 10, 26); int frameBorderWidth = 2; if (plug.IsPoeHUD) { pluginFrame.Height += 50; frameBorderWidth = 4; } Graphics.DrawBox(pluginFrame, Color.Black); Graphics.DrawFrame(pluginFrame, frameBorderWidth, Color.Gray); pluginFrame.X += 10; Graphics.DrawText(plug.PluginName, 20, new Vector2(pluginFrame.X, pluginFrame.Y)); Graphics.DrawText(plug.LocalVersion + (plug.LocalTag.Length > 0 ? $" ({plug.LocalTag})" : ""), 15, new Vector2(pluginFrame.X + 200, pluginFrame.Y + 5), Color.Gray); var color = Color.Gray; if (plug.UpdateState == ePluginUpdateState.HasUpdate) { color = Color.Green; } else if (plug.UpdateState == ePluginUpdateState.HasLowerUpdate) { color = Color.Red; } Graphics.DrawText(plug.RemoteVersion + (plug.RemoteTag.Length > 0 ? $" ({plug.RemoteTag})" : ""), 15, new Vector2(pluginFrame.X + 400, pluginFrame.Y + 5), color); var buttonRect = new RectangleF(pluginFrame.X + pluginFrame.Width - 75, drawPosY + 4, 60, 20); var buttonTextPos = buttonRect.TopRight; buttonTextPos.X -= 5; buttonTextPos.Y += 2; if (!string.IsNullOrEmpty(plug.InstallProgress)) { Graphics.DrawText(plug.InstallProgress, 15, buttonTextPos, Color.White, FontDrawFlags.Right); } else if (!plug.bHasGitConfig) { Graphics.DrawText("No git config", 15, buttonTextPos, Color.Gray, FontDrawFlags.Right); } else if (plug.UpdateState == ePluginUpdateState.HasUpdate || plug.UpdateState == ePluginUpdateState.HasLowerUpdate || plug.UpdateState == ePluginUpdateState.UnknownUpdate) { if (UpdaterUtils.DrawButton(buttonRect, 1, new Color(50, 50, 50, 220), Color.White)) { plug.UpdatePlugin(); } if (plug.UpdateState == ePluginUpdateState.UnknownUpdate) { Graphics.DrawText("Unknown update", 15, buttonTextPos, Color.Gray, FontDrawFlags.Right); } else if (plug.UpdateState == ePluginUpdateState.HasLowerUpdate) { Graphics.DrawText("Update", 15, buttonTextPos, Color.Red, FontDrawFlags.Right); } else { Graphics.DrawText("Update", 15, buttonTextPos, Color.Yellow, FontDrawFlags.Right); } } else if (plug.UpdateState == ePluginUpdateState.NoUpdate) { Graphics.DrawText("Updated", 15, buttonTextPos, Color.Green, FontDrawFlags.Right); } else if (plug.UpdateState == ePluginUpdateState.ReadyToInstal) { Graphics.DrawText("(Restart PoeHUD)", 15, buttonTextPos, Color.Green, FontDrawFlags.Right); } else { Graphics.DrawText("Wrong git config", 15, buttonTextPos, Color.Gray, FontDrawFlags.Right); } if (plug.IsPoeHUD) { if (string.IsNullOrEmpty(plug.InstallProgress)) { var selectBranchRect = new RectangleF(pluginFrame.X + 10, drawPosY + 30, 150, 20); selectBranchRect.Y += 2; Graphics.DrawText("Select PoeHUD branch: ", 15, selectBranchRect.TopLeft); selectBranchRect.Y -= 2; selectBranchRect.X += 150; for (int i = 0; i < PoeHUDBranches.Length; i++) { bool selected = Settings.PoeHUDBranch == PoeHUDBranches[i]; var selColor = selected ? Color.White : Color.Gray; if (UpdaterUtils.DrawTextButton(selectBranchRect, PoeHUDBranches[i], 15, selected ? 3 : 1, new Color(50, 50, 50, 220), selColor, selColor)) { if (Settings.PoeHUDBranch != PoeHUDBranches[i]) { Settings.PoeHUDBranch = PoeHUDBranches[i]; plug.InstallProgress = "Restart PoeHUD. It will check updates from " + Settings.PoeHUDBranch + " branch."; plug.RemoteVersion = ""; plug.LocalVersion = ""; } } selectBranchRect.X += 170; } selectBranchRect = new RectangleF(pluginFrame.X + 10, drawPosY + 55, 150, 20); Graphics.DrawText("Note: PoeHUD will be automatically restarted.", 15, selectBranchRect.TopLeft, Color.Gray); } drawPosY += 55; WindowHeight += 55; } drawPosY += 30; return(drawPosY); }
private async Task CheckFiles(PluginToUpdate plugin, string branch, string path) { IReadOnlyList <RepositoryContent> allContent = null; try { if (!string.IsNullOrEmpty(branch)) { if (!string.IsNullOrEmpty(path)) { allContent = await gitClient.Repository.Content.GetAllContentsByRef(plugin.RepoOwner, plugin.RepoName, path, branch); } else { allContent = await gitClient.Repository.Content.GetAllContentsByRef(plugin.RepoOwner, plugin.RepoName, branch); } } else { if (!string.IsNullOrEmpty(path)) { allContent = await gitClient.Repository.Content.GetAllContents(plugin.RepoOwner, plugin.RepoName, path); } else { allContent = await gitClient.Repository.Content.GetAllContents(plugin.RepoOwner, plugin.RepoName); } } } catch (Exception ex) { LogError($"Plugin '" + plugin.PluginName + "' check update unhandled error: " + ex.Message, 10); return; } foreach (var contentEntity in allContent) { if (plugin.IgnoredEntities.Contains(contentEntity.Path)) { continue; } if (contentEntity.Type == ContentType.File) { RepoFilesCheckedCount++; var download = false; if (plugin.IsPoeHUD && contentEntity.Name.Contains("PoeHUD.exe")) { var localPath = Path.Combine(plugin.PluginDirectory + @"\", plugin.PoehudExeRealName); var poeHudFInfo = new FileInfo(localPath); if (poeHudFInfo.Exists) { if (poeHudFInfo.Length != contentEntity.Size) { download = true; } } } else { var localPath = Path.Combine(plugin.PluginDirectory + @"\" + path, contentEntity.Name); if (plugin.IsPoeHUD && path.Contains("Release")) { localPath = Path.Combine(plugin.PluginDirectory + @"\" + path.Remove(path.IndexOf("Release"), 7), contentEntity.Name); } if (File.Exists(localPath)) { var fileSha = UpdaterUtils.GetGitObjectChecksum(localPath); if (fileSha != contentEntity.Sha) { download = true; } } else { download = true; } } if (download) { var updateFilePath = Path.Combine(plugin.PluginDirectory + @"\" + UpdateTempDir + @"\" + path, contentEntity.Name); if (plugin.IsPoeHUD && path.Contains("Release")) { updateFilePath = Path.Combine(plugin.PluginDirectory + @"\" + UpdateTempDir + @"\" + path.Remove(path.IndexOf("Release"), 7), contentEntity.Name); } plugin.FilesToDownload.Add(new FileToDownload { Name = contentEntity.Name, Url = contentEntity.DownloadUrl.AbsoluteUri, Path = updateFilePath }); } } else if (contentEntity.Type == ContentType.Dir) { var newPath = Path.Combine(path, contentEntity.Name); await CheckFiles(plugin, branch, newPath); } else { LogMessage("Ignore update content type: " + contentEntity.Type, 10); } } }
private async Task CheckPluginUpdate(PluginToUpdate plugin) { plugin.LocalVersion = "Undefined"; plugin.RemoteVersion = "Undefined"; if (!plugin.bAllowCheckUpdate) { return; } var versionFilePath = Path.Combine(plugin.PluginDirectory, VersionFileName); if (File.Exists(versionFilePath)) { var lovalVersionLines = File.ReadAllLines(versionFilePath); plugin.LocalVersion = lovalVersionLines[0]; if (lovalVersionLines.Length > 1) { plugin.LocalTag = lovalVersionLines[1]; } } if (plugin.UpdateVariant == ePluginSourceOfUpdate.Release) //Release { #region ReleaseCheck IReadOnlyList <Release> releases = null; try { releases = await gitClient.Repository.Release.GetAll(plugin.RepoOwner, plugin.RepoName); } catch (NotFoundException notFoundEx) { plugin.UpdateState = ePluginUpdateState.WrongConfig; LogError($"Plugin '" + plugin.PluginName + "' check update error: " + notFoundEx.Message, 10); return; } catch (Exception ex) { plugin.UpdateState = ePluginUpdateState.WrongConfig; LogError($"Plugin '" + plugin.PluginName + "' check update unhandled error: " + ex.Message, 10); return; } foreach (var release in releases) { if (plugin.bCustomTag && !Regex.Match(release.TagName, plugin.ReleaseRegexTag).Success) { //LogMessage("Fail match: " + plugin.ReleaseRegexTag + " " + release.TagName, 10); continue; } //LogMessage("Pass match: " + plugin.ReleaseRegexTag + " " + release.TagName, 10); foreach (var asset in release.Assets) { if (asset.Name.EndsWith(".zip")) { plugin.RemoteVersion = release.PublishedAt?.ToString("dd.MM.yy, hh:mm"); plugin.RemoteTag = release.TagName; if (plugin.LocalVersion == plugin.RemoteVersion) { plugin.UpdateState = ePluginUpdateState.NoUpdate; } else if (plugin.LocalVersion == "Undefined") { plugin.UpdateState = ePluginUpdateState.UnknownUpdate; } else { plugin.UpdateState = ePluginUpdateState.Undefined; DateTimeOffset localParseResult; if (DateTimeOffset.TryParse(plugin.LocalVersion, out localParseResult)) { DateTimeOffset remoteParseResult; if (DateTimeOffset.TryParse(plugin.RemoteVersion, out remoteParseResult)) { if (remoteParseResult > localParseResult) { plugin.UpdateState = ePluginUpdateState.HasUpdate; } else if (remoteParseResult < localParseResult) { plugin.UpdateState = ePluginUpdateState.HasLowerUpdate; } } } } var updateDirectory = Path.Combine(plugin.PluginDirectory, UpdateTempDir, asset.Name); plugin.FilesToDownload.Add(new FileToDownload { Name = asset.Name, Url = asset.BrowserDownloadUrl, Path = updateDirectory }); break; } } if (plugin.FilesToDownload.Count > 0) { break; } } #endregion } else if (plugin.UpdateVariant == ePluginSourceOfUpdate.RepoBranch) //Branch { plugin.UpdateState = ePluginUpdateState.NoUpdate; RepoFilesCheckedCount = 0; await CheckFiles(plugin, plugin.BranchName, ""); if (plugin.FilesToDownload.Count > 0) { plugin.UpdateState = ePluginUpdateState.HasUpdate; plugin.RemoteVersion = plugin.FilesToDownload.Count + " files changed"; } else { plugin.RemoteVersion = "No changes"; } plugin.LocalVersion = RepoFilesCheckedCount + " files checked"; } }