private async void Initialize() { pluginStatusText.Text = Resources.InitRuntime; var container = new TinyIoCContainer(); logger = new Logger(); container.Register(logger); container.Register <ILogger>(logger); asmResolver.ExceptionOccured += (o, e) => logger.Log(LogLevel.Error, Resources.AssemblyResolverError, e.Exception); asmResolver.AssemblyLoaded += (o, e) => logger.Log(LogLevel.Debug, Resources.AssemblyResolverLoaded, e.LoadedAssembly.FullName); this.Container = container; pluginMain = new PluginMain(pluginDirectory, logger, container); container.Register(pluginMain); pluginStatusText.Text = Resources.InitCef; SanityChecker.CheckDependencyVersions(logger); try { CurlWrapper.Init(pluginDirectory); } catch (Exception ex) { logger.Log(LogLevel.Error, ex.ToString()); ActGlobals.oFormActMain.WriteDebugLog(ex.ToString()); } await FinishInit(container); }
public static Task <(bool, Version, string)> CheckForUpdate(Control parent) { return(Task.Run(() => { var currentVersion = Assembly.GetExecutingAssembly().GetName().Version; Version remoteVersion; string response; try { response = CurlWrapper.Get(REL_URL); } catch (CurlException ex) { MessageBox.Show(string.Format(Resources.UpdateCheckException, ex.ToString()), Resources.UpdateCheckTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); return (false, null, ""); } var releaseNotes = ""; try { // JObject doesn't accept arrays so we have to package the response in a JSON object. var tmp = JObject.Parse("{\"content\":" + response + "}"); remoteVersion = Version.Parse(tmp["content"][0]["tag_name"].ToString().Substring(1)); foreach (var rel in tmp["content"]) { var version = Version.Parse(rel["tag_name"].ToString().Substring(1)); if (version.CompareTo(currentVersion) < 1) { break; } releaseNotes += "---\n\n# " + rel["name"].ToString() + "\n\n" + rel["body"].ToString() + "\n\n"; } if (releaseNotes.Length > 5) { releaseNotes = releaseNotes.Substring(5); } } catch (Exception ex) { parent.Invoke((Action)(() => { MessageBox.Show(string.Format(Resources.UpdateParseVersionError, ex.ToString()), Resources.UpdateTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); })); return (false, null, null); } return (remoteVersion.CompareTo(currentVersion) > 0, remoteVersion, releaseNotes); })); }
private void GenSsl() { try { var mkcertPath = Path.Combine(_plugin.PluginDirectory, "mkcert.exe"); if (!File.Exists(mkcertPath)) { logDisplay.AppendText("Downloading mkcert...\r\n"); try { CurlWrapper.Get(MKCERT_DOWNLOAD, new Dictionary <string, string>(), mkcertPath, null, false); } catch (Exception e) { logDisplay.AppendText(string.Format("\nFailed: {0}", e)); genSslBtn.Enabled = true; return; } } logDisplay.AppendText("Installing CA...\r\n"); if (!RunLogCmd(mkcertPath, "-install")) { logDisplay.AppendText("\r\nFailed!\r\n"); genSslBtn.Enabled = true; return; } logDisplay.AppendText("Generating certificate...\r\n"); if (!RunLogCmd(mkcertPath, string.Format("-pkcs12 -p12-file \"{0}\" localhost 127.0.0.1 ::1", _server.GetCertPath()))) { logDisplay.AppendText("\r\nFailed!\r\n"); genSslBtn.Enabled = true; return; } logDisplay.AppendText("\r\nDone.\r\n"); sslBox.Enabled = _server.IsSSLPossible(); sslBox.Checked = sslBox.Enabled; _config.WSServerSSL = sslBox.Enabled; genSslBtn.Enabled = true; } catch (Exception e) { logDisplay.AppendText(string.Format("\r\nException: {0}", e)); genSslBtn.Enabled = true; } }
private async void Initialize() { pluginStatusText.Text = Resources.InitRuntime; Registry.Init(); logger = new Logger(); asmResolver.ExceptionOccured += (o, e) => logger.Log(LogLevel.Error, Resources.AssemblyResolverError, e.Exception); asmResolver.AssemblyLoaded += (o, e) => logger.Log(LogLevel.Debug, Resources.AssemblyResolverLoaded, e.LoadedAssembly.FullName); pluginMain = new PluginMain(pluginDirectory, logger); pluginStatusText.Text = Resources.InitCef; try { CurlWrapper.Init(pluginDirectory); } catch (Exception ex) { logger.Log(LogLevel.Error, ex.ToString()); } await FinishInit(); }
private async void Initialize(TabPage pluginScreenSpace, Label pluginStatusText) { pluginStatusText.Text = Resources.InitRuntime; Registry.Init(); logger = new Logger(); asmResolver.ExceptionOccured += (o, e) => logger.Log(LogLevel.Error, Resources.AssemblyResolverError, e.Exception); asmResolver.AssemblyLoaded += (o, e) => logger.Log(LogLevel.Debug, Resources.AssemblyResolverLoaded, e.LoadedAssembly.FullName); pluginMain = new PluginMain(pluginDirectory, logger); pluginStatusText.Text = Resources.InitCef; try { CurlWrapper.Init(pluginDirectory); } catch (Exception ex) { logger.Log(LogLevel.Error, ex.ToString()); } if (await CefInstaller.EnsureCef(GetCefPath())) { // Finally, load the html renderer. We load it here since HtmlRenderer depends on CEF which we can't load these before // the CefInstaller is done. if (SanityChecker.LoadSaneAssembly("HtmlRenderer")) { // Since this is an async method, we could have switched threds. Make sure InitPlugin() runs on the ACT main thread. ActGlobals.oFormActMain.Invoke((Action)(() => { pluginMain.InitPlugin(pluginScreenSpace, pluginStatusText); })); } else { pluginStatusText.Text = Resources.CoreOrHtmlRendererInsane; } } }
public bool Download(string url, string dest, bool useHttpClient = false) { try { if (Directory.Exists(TempDir)) { Directory.Delete(TempDir, true); } Directory.CreateDirectory(TempDir); } catch (Exception ex) { _display.Log(string.Format(Resources.CreatingTempDirFailed, TempDir, ex)); return(false); } _display.UpdateStatus(0, string.Format(Resources.StatusDownloadStarted, 1, 2)); // Avoid confusing users with the DO_NOT_DOWNLOAD extension. Users aren't supposed to manually download // these files from the GH releases page so I added that extension and didn't expect people to pay // attention to the download URL in the updater log. _display.Log(string.Format(Resources.LogDownloading, url.Replace(".DO_NOT_DOWNLOAD", ""), dest)); var success = false; var cancel = _display.GetCancelToken(); _token = cancel; try { var retries = 10; while (retries > 0 && !cancel.IsCancellationRequested) { try { if (useHttpClient) { HttpClientWrapper.Get(url, new Dictionary <string, string>(), dest, DlProgressCallback, true); } else { CurlWrapper.Get(url, new Dictionary <string, string>(), dest, DlProgressCallback, true); } success = true; break; } catch (Exception ex) { _display.Log(string.Format(Resources.LogDownloadInterrupted, ex)); if (retries > 0 && !cancel.IsCancellationRequested) { // If this is a curl exception, it's most likely network related. Wait a second // before trying again. We don't want to spam the other side with download requests. if (ex.GetType() == typeof(CurlException)) { if (!((CurlException)ex).Retry) { // Retrying won't fix this kind of error. Abort. success = false; break; } Thread.Sleep(1000); } _display.Log(Resources.LogResumingDownload); success = false; continue; } } } if (cancel.IsCancellationRequested || !success) { _display.UpdateStatus(0, Resources.StatusCancelling); File.Delete(dest); if (!cancel.IsCancellationRequested) { _display.UpdateStatus(0, Resources.OutOfRetries); _display.Log(Resources.OutOfRetries); } else { _display.UpdateStatus(0, Resources.StatusCancelled); _display.Log(Resources.LogAbortedByUser); } return(false); } } catch (Exception ex) { if (cancel.IsCancellationRequested) { _display.UpdateStatus(1, Resources.StatusCancelled); _display.Log(Resources.LogAbortedByUser); return(false); } _display.Log(string.Format(Resources.Exception, ex)); return(false); } finally { _display.DisposeCancelSource(); if (!success) { Cleanup(); } } return(true); }
public static Task <(bool, Version, string, string)> CheckForGitHubUpdate(UpdaterOptions options, TinyIoCContainer container) { var logger = container.Resolve <ILogger>(); return(Task.Run(() => { Version remoteVersion = null; string response; if (options.actPluginId > 0) { try { response = ActGlobals.oFormActMain.PluginGetRemoteVersion(options.actPluginId); if (!response.StartsWith("v") || !Version.TryParse(response.Substring(1), out remoteVersion)) { logger.Log(LogLevel.Warning, string.Format(Resources.ActUpdateCheckFailed, options.project)); } } catch (Exception ex) { logger.Log(LogLevel.Error, string.Format(Resources.ActUpdateException, options.project, ex)); } } if (remoteVersion == null) { try { response = CurlWrapper.Get(CHECK_URL.Replace("{REPO}", options.repo)); var tmp = JObject.Parse(response); remoteVersion = Version.Parse(tmp["tag_name"].ToString().Substring(1)); } catch (Exception ex) { MessageBox.Show( string.Format(Resources.UpdateCheckException, ex.ToString()), string.Format(Resources.UpdateCheckTitle, options.project), MessageBoxButtons.OK, MessageBoxIcon.Error ); return (false, null, "", ""); } } var releaseNotes = ""; var downloadUrl = ""; try { if (remoteVersion <= options.currentVersion) { // Exit early if no new version is available. return (false, remoteVersion, "", ""); } response = CurlWrapper.Get(ALL_RELEASES_URL.Replace("{REPO}", options.repo)); // JObject doesn't accept arrays so we have to package the response in a JSON object. var tmp = JObject.Parse("{\"content\":" + response + "}"); downloadUrl = options.downloadUrl.Replace("{REPO}", options.repo).Replace("{VERSION}", remoteVersion.ToString()); foreach (var rel in tmp["content"]) { var version = Version.Parse(rel["tag_name"].ToString().Substring(1)); if (version < options.currentVersion) { break; } releaseNotes += "---\n\n# " + rel["name"].ToString() + "\n\n" + rel["body"].ToString() + "\n\n"; } if (releaseNotes.Length > 5) { releaseNotes = releaseNotes.Substring(5); } } catch (Exception ex) { ActGlobals.oFormActMain.Invoke((Action)(() => { MessageBox.Show( string.Format(Resources.UpdateParseVersionError, ex.ToString()), string.Format(Resources.UpdateTitle, options.project), MessageBoxButtons.OK, MessageBoxIcon.Error ); })); return (false, null, "", ""); } try { releaseNotes = Regex.Replace(releaseNotes, @"<!-- TRAILER BEGIN -->(?:[^<]|<(?!!-- TRAILER END -->))+<!-- TRAILER END -->", ""); } catch (Exception ex) { logger.Log(LogLevel.Error, $"Failed to remove trailers from release notes: {ex}"); } releaseNotes = RenderMarkdown(releaseNotes); return (remoteVersion.CompareTo(options.currentVersion) > 0, remoteVersion, releaseNotes, downloadUrl); })); }
public static Task <(bool, Version, string, string)> CheckForManifestUpdate(UpdaterOptions options) { return(Task.Run(() => { Version remoteVersion; string response; try { response = CurlWrapper.Get(options.manifestUrl); } catch (CurlException ex) { MessageBox.Show( string.Format(Resources.UpdateCheckException, ex.ToString()), string.Format(Resources.UpdateCheckTitle, options.project), MessageBoxButtons.OK, MessageBoxIcon.Error ); return (false, null, "", ""); } var releaseNotes = ""; var downloadUrl = ""; try { var tmp = JObject.Parse(response); remoteVersion = Version.Parse(tmp["version"].ToString()); if (remoteVersion.CompareTo(options.currentVersion) <= 0) { // Exit early if no new version is available. return (false, remoteVersion, "", ""); } response = CurlWrapper.Get(options.notesUrl); // JObject doesn't accept arrays so we have to package the response in a JSON object. tmp = JObject.Parse("{\"content\":" + response + "}"); downloadUrl = tmp[0]["download"].ToString(); foreach (var rel in tmp["content"]) { var version = Version.Parse(rel["version"].ToString()); if (version.CompareTo(options.currentVersion) <= 0) { break; } releaseNotes += rel["notes"]; } } catch (Exception ex) { ActGlobals.oFormActMain.Invoke((Action)(() => { MessageBox.Show( string.Format(Resources.UpdateParseVersionError, ex.ToString()), string.Format(Resources.UpdateTitle, options.project), MessageBoxButtons.OK, MessageBoxIcon.Error ); })); return (false, null, "", ""); } return (remoteVersion.CompareTo(options.currentVersion) > 0, remoteVersion, releaseNotes, downloadUrl); })); }
public bool Download(string url, string dest) { try { if (Directory.Exists(_tempDir)) { Directory.Delete(_tempDir, true); } Directory.CreateDirectory(_tempDir); } catch (Exception ex) { _display.Log(string.Format(Resources.CreatingTempDirFailed, _tempDir, ex)); return(false); } _display.UpdateStatus(0, string.Format(Resources.StatusDownloadStarted, 1, 2)); _display.Log(string.Format(Resources.LogDownloading, url, dest)); var success = false; var cancel = _display.GetCancelToken(); _token = cancel; try { var retries = 10; while (retries > 0 && !cancel.IsCancellationRequested) { try { CurlWrapper.Get(url, new Dictionary <string, string>(), dest, DlProgressCallback, true); success = true; break; } catch (Exception ex) { _display.Log(string.Format(Resources.LogDownloadInterrupted, ex)); if (retries > 0) { if (ex.GetType().IsSubclassOf(typeof(CurlException))) { Thread.Sleep(1000); } _display.Log(Resources.LogResumingDownload); success = false; continue; } } } if (cancel.IsCancellationRequested || !success) { _display.UpdateStatus(0, Resources.StatusCancelling); File.Delete(dest); if (!cancel.IsCancellationRequested) { _display.UpdateStatus(0, Resources.OutOfRetries); _display.Log(Resources.OutOfRetries); } else { _display.UpdateStatus(0, Resources.StatusCancelled); _display.Log(Resources.LogAbortedByUser); } return(false); } } catch (Exception ex) { if (cancel.IsCancellationRequested) { _display.UpdateStatus(1, Resources.StatusCancelled); _display.Log(Resources.LogAbortedByUser); return(false); } _display.Log(string.Format(Resources.Exception, ex)); return(false); } finally { _display.DisposeCancelSource(); if (!success) { Cleanup(); } } return(true); }
private bool FetchNgrok(string ngrokPath) { try { UpdateTunnelStatus(TunnelStatus.Downloading); simpLogBox.AppendText("Fetching latest ngrok version...\r\n"); string dlPage; try { dlPage = CurlWrapper.Get(NGROK_DOWNLOAD_IDX); } catch (Exception e) { simpLogBox.AppendText(string.Format("\r\nFailed: {0}\r\n\r\n", e)); return(false); } var arch = Environment.Is64BitOperatingSystem ? "amd64" : "386"; // <a id="dl-windows-amd64" href="https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-windows-amd64.zip" class="download-btn" var match = Regex.Match(dlPage, " href=\"(https://bin.equinox.io/c/[^/]+/ngrok-stable-windows-" + arch + "\\.zip)\""); if (match == Match.Empty) { simpLogBox.AppendText("Failed to find version on the download page! Please notify ngld or some other dev working on OverlayPlugin.\r\n"); return(false); } simpLogBox.AppendText("Downloading ngrok client...\r\n"); try { CurlWrapper.Get(match.Groups[1].Captures[0].Value, new Dictionary <string, string>(), ngrokPath + ".zip", NgrokProgressCallback, false); } catch (Exception e) { simpLogBox.AppendText(string.Format("\r\nFailed: {0}\r\n\r\n", e)); return(false); } simpLogBox.AppendText("\r\nExtracting ngrok client...\r\n"); try { using (var archive = ZipArchive.Open(ngrokPath + ".zip")) using (var reader = archive.ExtractAllEntries()) { while (reader.MoveToNextEntry()) { if (reader.Entry.Key == "ngrok.exe") { using (var writer = File.OpenWrite(ngrokPath)) { reader.WriteEntryTo(writer); } break; } } } File.Delete(ngrokPath + ".zip"); } catch (Exception e) { simpLogBox.AppendText(string.Format("\r\n{0}\r\n\r\n", e)); } if (!File.Exists(ngrokPath)) { simpLogBox.AppendText("\r\nExtraction failed!\r\n"); return(false); } return(true); } catch (Exception e) { simpLogBox.AppendText(string.Format("\r\nException: {0}\r\n\r\n", e)); return(false); } }
private void simpStartBtn_Click(object sender, EventArgs e) { simpStartBtn.Enabled = false; Task.Run(() => { try { var ngrokPath = Path.Combine(ActGlobals.oFormActMain.AppDataFolder.FullName, "ngrok-" + (Environment.Is64BitOperatingSystem ? "x64" : "x86") + ".exe"); if (!File.Exists(ngrokPath)) { if (!FetchNgrok(ngrokPath)) { return; } } UpdateTunnelStatus(TunnelStatus.Launching); if (_ngrok != null && !_ngrok.HasExited) { simpLogBox.AppendText("Detected left over ngrok process. Performing cleanup...\r\n"); _ngrok.Kill(); _ngrok = null; } // Enforce sensible settings ipTxt.Text = "127.0.0.1"; sslBox.Checked = false; _config.WSServerIP = "127.0.0.1"; _config.WSServerSSL = false; if (_config.WSServerPort < 1024) { portTxt.Text = "10501"; _config.WSServerPort = 10501; } simpLogBox.AppendText("Launching WSServer...\r\n"); _config.WSServerRunning = true; _server.Start(); simpLogBox.AppendText("Launching ngrok...\r\n"); var region = _config.TunnelRegion; if (region == null) { region = "us"; } else { region = region.Split(' ')[0]; } var config = @" region: " + region + @" console_ui: false web_addr: 127.0.0.1:" + (_config.WSServerPort + 1) + @" tunnels: wsserver: proto: http addr: 127.0.0.1:" + _config.WSServerPort + @" inspect: false bind_tls: true "; var ngrokConfigPath = Path.Combine(ActGlobals.oFormActMain.AppDataFolder.FullName, "ngrok.yml"); File.WriteAllText(ngrokConfigPath, config); var p = new Process(); p.StartInfo.FileName = ngrokPath; p.StartInfo.Arguments = "start -config=\"" + ngrokConfigPath + "\" wsserver"; p.StartInfo.UseShellExecute = false; p.StartInfo.CreateNoWindow = true; p.StartInfo.RedirectStandardError = true; p.StartInfo.RedirectStandardOutput = true; DataReceivedEventHandler showLine = (_, ev) => { if (ev.Data != null) { simpLogBox.AppendText(ev.Data.Replace("\n", "\r\n") + "\r\n"); } }; p.OutputDataReceived += showLine; p.ErrorDataReceived += showLine; p.Start(); p.BeginOutputReadLine(); p.BeginErrorReadLine(); if (p.WaitForExit(3000)) { simpLogBox.AppendText("ngrok crashed!\r\n"); UpdateTunnelStatus(TunnelStatus.Error); return; } _ngrok = p; var apiUrl = "http://127.0.0.1:" + (_config.WSServerPort + 1) + "/api/tunnels"; var headers = new Dictionary <string, string>() { { "Content-Type", "application/json" }, }; string data = null; while (true) { try { data = CurlWrapper.Get(apiUrl, headers, null, null, false); break; } catch (CurlException ex) { if (!ex.Retry) { simpLogBox.AppendText(string.Format("Failed: {0}\r\n", ex)); UpdateTunnelStatus(TunnelStatus.Error); return; } else { Thread.Sleep(500); } } catch (Exception ex) { simpLogBox.AppendText(string.Format("Failed: {0}\r\n", ex)); UpdateTunnelStatus(TunnelStatus.Error); return; } } var tunnels = JObject.Parse(data); var done = false; foreach (var tun in tunnels["tunnels"]) { if (tun["name"] != null && tun["name"].ToString() == "wsserver" && tun["public_url"] != null) { _ngrokPrefix = tun["public_url"].ToString().Replace("https://", "wss://"); // Update the generated URL box cbOverlay_SelectedIndexChanged(null, null); done = true; break; } } if (done) { simpLogBox.AppendText("Done!\r\n"); simpLogBox.AppendText("\r\n#############################################\r\nUse the URL Generator below to generate URLs for you.\r\n\r\n"); simpLogBox.AppendText("\r\nIf you know what you're doing or you're using an overlay that isn't listed, here are some query strings for you:\r\n"); simpLogBox.AppendText("\r\n ?HOST_PORT=" + _ngrokPrefix + "\r\n ?OVERLAY_WS=" + _ngrokPrefix + "/ws\r\n"); simpLogBox.AppendText("#############################################\r\n"); UpdateTunnelStatus(TunnelStatus.Active); p.Exited += (_, ev) => { UpdateTunnelStatus(TunnelStatus.Error); }; } else { simpLogBox.AppendText("Failed!\r\n"); UpdateTunnelStatus(TunnelStatus.Error); } } catch (Exception ex) { simpLogBox.AppendText(string.Format("\r\nUncaught exception: {0}\r\n\r\n", ex)); UpdateTunnelStatus(TunnelStatus.Error); } }); }