private void Client_OnQueryCallback(object sender, QueryCallbackEventArgs e) { string query = e.CallbackQuery.Data.Split(':').FirstOrDefault(); switch (query) { case CbqGym: Client.AnswerCallbackQuery(e.CallbackQuery.ID); ConversationManager.SetState(e.CallbackQuery.From, StateReadGym); Client.SendMessageToChat(e.CallbackQuery.From.ID, _HTML_(I18N.GetString("Enter the name of the gym."))); break; case CbqRaid: Client.AnswerCallbackQuery(e.CallbackQuery.ID); ConversationManager.SetState(e.CallbackQuery.From, StateReadPokemon); Client.SendMessageToChat(e.CallbackQuery.From.ID, _HTML_(I18N.GetString("Enter the name of the Pokémon."))); break; case CbqAlignment: Client.AnswerCallbackQuery(e.CallbackQuery.ID); Client.SendMessageToChat(e.CallbackQuery.From.ID, _HTML_(I18N.GetString("Specify the current gym's alignment.")), "HTML", true, true, null, CreateAlignmentMenu()); break; case CbqAlignmentSelected: Client.AnswerCallbackQuery(e.CallbackQuery.ID, _HTML_(I18N.GetString("Updated the gym alignment."))); var newValue = int.Parse(e.CallbackQuery.Data.Split(':')[1]); UpdateAlignment(e.CallbackQuery.From, (Team)newValue); ShowMenu(e.CallbackQuery.From); break; case CbqTime: Client.AnswerCallbackQuery(e.CallbackQuery.ID); Client.SendMessageToChat(e.CallbackQuery.From.ID, _HTML_(I18N.GetString("Please specify when the raid will take place. If the egg is yet to hatch, use one of the 🥚 buttons to indicate the amount of time left before the egg hatches. If the egg already hatched use one of the ⛔️ to indicate how many minutes are left for the raid.")), "HTML", true, true, null, CreateTimeMenu()); break; case CbqTimeSelected: Client.AnswerCallbackQuery(e.CallbackQuery.ID, _HTML_(I18N.GetString("Raid time updated."))); var minutesUntilRaidEnd = int.Parse(e.CallbackQuery.Data.Split(':')[1]); UpdateTime(e.CallbackQuery.From, minutesUntilRaidEnd); ShowMenu(e.CallbackQuery.From); break; case CbqManuallyEnterStartTime: Client.AnswerCallbackQuery(e.CallbackQuery.ID); Client.SendMessageToChat(e.CallbackQuery.From.ID, _HTML_(I18N.GetString("Select a date for this raid from the list below.")), "HTML", true, true, null, CreateDateMenu()); break; case CbqOtherDateSelected: Client.AnswerCallbackQuery(e.CallbackQuery.ID); Client.SendMessageToChat(e.CallbackQuery.From.ID, _HTML_(I18N.GetString("Select a start time.")), "HTML", true, true, null, CreateTimeMenu(int.Parse(e.CallbackQuery.Data.Split(':')[1]))); break; case CbqOtherDateTimeSelected: Client.AnswerCallbackQuery(e.CallbackQuery.ID, _HTML_(I18N.GetString("Raid time updated."))); var args = e.CallbackQuery.Data.Split(':'); UpdateTime(e.CallbackQuery.From, int.Parse(args[1]), int.Parse(args[2]), int.Parse(args[3])); ShowMenu(e.CallbackQuery.From); break; case CbqClear: Client.AnswerCallbackQuery(e.CallbackQuery.ID, _HTML_(I18N.GetString("Cleared."))); ResetConversation(e.CallbackQuery.From); ShowMenu(e.CallbackQuery.From); break; case CbqDone: Client.AnswerCallbackQuery(e.CallbackQuery.ID, _HTML_(I18N.GetString("The raid was created but not published yet. You can publish or share the raid with the corresponding buttons in the block."))); ProcessRaidDone(e); break; case CbqPlayerTeamSelected: Client.AnswerCallbackQuery(e.CallbackQuery.ID, _HTML_(I18N.GetString("If you say so."))); DbSet <UserSettings> userSettingsCollection = DB.GetCollection <UserSettings>(); var userSettings = UserSettings.GetOrCreateUserSettings(e.CallbackQuery.From, userSettingsCollection); var team = (Team)(int.Parse(e.CallbackQuery.Data.Split(':')[1])); userSettings.Team = team; userSettingsCollection.Update(userSettings); string msg = I18N.GetString("Your new team is {0}.", _HTML_(team.AsReadableString())); Client.SendMessageToChat(e.CallbackQuery.From.ID, msg, "HTML", true, true); break; } }
private void UpdateTrayIconAndNotifyText() { Configuration config = controller.GetConfigurationCopy(); bool enabled = config.enabled; bool global = config.global; Color colorMask = SelectColorMask(enabled, global); Size iconSize = SelectIconSize(); UpdateIconSet(colorMask, iconSize, out icon, out icon_in, out icon_out, out icon_both); previousIcon = icon; _notifyIcon.Icon = previousIcon; string serverInfo = null; if (controller.GetCurrentStrategy() != null) { serverInfo = controller.GetCurrentStrategy().Name; } else { serverInfo = config.GetCurrentServer().ToString(); } // show more info by hacking the P/Invoke declaration for NOTIFYICONDATA inside Windows Forms string text = I18N.GetString("Shadowsocks") + " " + UpdateChecker.Version + "\n" + (enabled ? I18N.GetString("System Proxy On: ") + (global ? I18N.GetString("Global") : I18N.GetString("PAC")) : I18N.GetString("Running: Port {0}", config.localPort)) // this feedback is very important because they need to know Shadowsocks is running + "\n" + serverInfo; if (text.Length > 127) { text = text.Substring(0, 126 - 3) + "..."; } ViewUtils.SetNotifyIconText(_notifyIcon, text); }
private MenuItem CreateMenuGroup(string text, MenuItem[] items) { return(new MenuItem(I18N.GetString(text), items)); }
private const int WM_NCLBUTTONDBLCLK = 0xA3; //鼠标双击标题栏消息 private void UpdateTexts() { this.Text = I18N.GetString("Rallets"); }
private void ScanQRCodeItem_Click(object sender, EventArgs e) { foreach (Screen screen in Screen.AllScreens) { using (Bitmap fullImage = new Bitmap(screen.Bounds.Width, screen.Bounds.Height)) { using (Graphics g = Graphics.FromImage(fullImage)) { g.CopyFromScreen(screen.Bounds.X, screen.Bounds.Y, 0, 0, fullImage.Size, CopyPixelOperation.SourceCopy); } int maxTry = 10; for (int i = 0; i < maxTry; i++) { int marginLeft = (int)((double)fullImage.Width * i / 2.5 / maxTry); int marginTop = (int)((double)fullImage.Height * i / 2.5 / maxTry); Rectangle cropRect = new Rectangle(marginLeft, marginTop, fullImage.Width - marginLeft * 2, fullImage.Height - marginTop * 2); Bitmap target = new Bitmap(screen.Bounds.Width, screen.Bounds.Height); double imageScale = (double)screen.Bounds.Width / (double)cropRect.Width; using (Graphics g = Graphics.FromImage(target)) { g.DrawImage(fullImage, new Rectangle(0, 0, target.Width, target.Height), cropRect, GraphicsUnit.Pixel); } var source = new BitmapLuminanceSource(target); var bitmap = new BinaryBitmap(new HybridBinarizer(source)); QRCodeReader reader = new QRCodeReader(); var result = reader.decode(bitmap); if (result != null) { var success = controller.AddServerBySSURL(result.Text); QRCodeSplashForm splash = new QRCodeSplashForm(); if (success) { splash.FormClosed += splash_FormClosed; } else if (result.Text.ToLower().StartsWith("http://") || result.Text.ToLower().StartsWith("https://")) { _urlToOpen = result.Text; splash.FormClosed += openURLFromQRCode; } else { MessageBox.Show(I18N.GetString("Failed to decode QRCode")); return; } double minX = Int32.MaxValue, minY = Int32.MaxValue, maxX = 0, maxY = 0; foreach (ResultPoint point in result.ResultPoints) { minX = Math.Min(minX, point.X); minY = Math.Min(minY, point.Y); maxX = Math.Max(maxX, point.X); maxY = Math.Max(maxY, point.Y); } minX /= imageScale; minY /= imageScale; maxX /= imageScale; maxY /= imageScale; // make it 20% larger double margin = (maxX - minX) * 0.20f; minX += -margin + marginLeft; maxX += margin + marginLeft; minY += -margin + marginTop; maxY += margin + marginTop; splash.Location = new Point(screen.Bounds.X, screen.Bounds.Y); // we need a panel because a window has a minimal size // TODO: test on high DPI splash.TargetRect = new Rectangle((int)minX, (int)minY, (int)maxX - (int)minX, (int)maxY - (int)minY); splash.Size = new Size(fullImage.Width, fullImage.Height); splash.Show(); return; } } } } MessageBox.Show(I18N.GetString("No QRCode found. Try to zoom in or move it to the center of the screen.")); }
private void UpdateTrayIcon() { int dpi; using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero)) { dpi = (int)graphics.DpiX; } Configuration config = controller.GetConfiguration(); bool enabled = config.sysProxyMode != (int)ProxyMode.NoModify && config.sysProxyMode != (int)ProxyMode.Direct; bool global = config.sysProxyMode == (int)ProxyMode.Global; bool random = config.random; Bitmap icon = null; try { icon = new Bitmap("icon.png"); } catch { if (dpi < 97) { // dpi = 96; icon = Resources.ss16; } else if (dpi < 121) { // dpi = 120; icon = Resources.ss20; } else { icon = Resources.ss24; } double mul_a = 1.0, mul_r = 1.0, mul_g = 1.0, mul_b = 1.0; if (!enabled) { mul_g = 0.4; } else if (!global) { mul_b = 0.4; mul_g = 0.8; } if (!random) { mul_r = 0.4; } { Bitmap iconCopy = new Bitmap(icon); for (int x = 0; x < iconCopy.Width; x++) { for (int y = 0; y < iconCopy.Height; y++) { Color color = icon.GetPixel(x, y); iconCopy.SetPixel(x, y, Color.FromArgb((byte)(color.A * mul_a), ((byte)(color.R * mul_r)), ((byte)(color.G * mul_g)), ((byte)(color.B * mul_b)))); } } icon = iconCopy; } } _notifyIcon.Icon = Icon.FromHandle(icon.GetHicon()); // we want to show more details but notify icon title is limited to 63 characters string text = (enabled ? I18N.GetString("System Proxy On: ") + (global ? I18N.GetString("Global") : I18N.GetString("PAC")) : String.Format(I18N.GetString("Running: Port {0}"), config.localPort)) // this feedback is very important because they need to know Shadowsocks is running + "\n" + config.GetCurrentServer(null).FriendlyName(); _notifyIcon.Text = text.Substring(0, Math.Min(63, text.Length)); }
private void DonateItem_Click(object sender, EventArgs e) { ShowBalloonTip(I18N.GetString("Donate"), I18N.GetString("Please contract to breakwa11 to get more infomation"), ToolTipIcon.Info, 10000); }
private async void OKButton_Click(object sender, EventArgs e) { if (!SaveOld()) { return; } OKButton.Enabled = false; OKButton.Text = I18N.GetString("Busy..."); try { var currentSvc = _controller.GetCurrentServer(); _controller.SaveSubscribes(_modifiedConfiguration.subscribes); if (_lastSelectedIndex > -1) { var item = _modifiedConfiguration.subscribes[_lastSelectedIndex]; var wc = new WebClient(); if (item.useProxy) { wc.Proxy = new WebProxy(IPAddress.Loopback.ToString(), _modifiedConfiguration.localPort); } var cts = new System.Threading.CancellationTokenSource(); // ReSharper disable once AccessToDisposedClosure cts.Token.Register(() => wc?.CancelAsync()); cts.CancelAfter(10000); var downloadString = await wc.DownloadStringTaskAsync(item.url); wc.Dispose(); var lst = new List <ServerObject>(); if (downloadString.Contains("vmess://")) { var mcg = Regex.Matches(downloadString, @"vmess://(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace); foreach (Match s in mcg) { if (ServerObject.TryParse(s.Value, out ServerObject svc)) { svc.@group = item.name; lst.Add(svc); } } } else { try { var debase64 = downloadString.DeBase64(); var split = debase64.Split('\r', '\n'); foreach (var s in split) { if (ServerObject.TryParse(s, out ServerObject svc)) { svc.@group = item.name; lst.Add(svc); } } } catch { MessageBox.Show(I18N.GetString("Invalid Base64 string."), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } if (lst.Any()) { _modifiedConfiguration.configs.RemoveAll(c => c.@group == oldNames[_lastSelectedIndex]); _modifiedConfiguration.configs.AddRange(lst); } } _controller.SaveServers(_modifiedConfiguration.configs, _modifiedConfiguration.localPort, _modifiedConfiguration.corePort); var newIdx = _modifiedConfiguration.configs.IndexOf(currentSvc); if (newIdx == -1) { await _controller.SelectServerIndex(0); } else if (newIdx != _modifiedConfiguration.index) { await _controller.SelectServerIndex(newIdx); } } catch (Exception exception) { Logging.LogUsefulException(exception); } Close(); }
private void UpdateTrayIcon() { int dpi; Graphics graphics = Graphics.FromHwnd(IntPtr.Zero); dpi = (int)graphics.DpiX; graphics.Dispose(); icon_baseBitmap = null; if (dpi < 97) { // dpi = 96; icon_baseBitmap = Resources.ss16; } else if (dpi < 121) { // dpi = 120; icon_baseBitmap = Resources.ss20; } else { icon_baseBitmap = Resources.ss24; } Configuration config = controller.GetConfigurationCopy(); bool enabled = config.enabled; bool global = config.global; icon_baseBitmap = getTrayIconByState(icon_baseBitmap, enabled, global); icon_base = Icon.FromHandle(icon_baseBitmap.GetHicon()); targetIcon = icon_base; icon_in = Icon.FromHandle(AddBitmapOverlay(icon_baseBitmap, Resources.ssIn24).GetHicon()); icon_out = Icon.FromHandle(AddBitmapOverlay(icon_baseBitmap, Resources.ssOut24).GetHicon()); icon_both = Icon.FromHandle(AddBitmapOverlay(icon_baseBitmap, Resources.ssIn24, Resources.ssOut24).GetHicon()); _notifyIcon.Icon = targetIcon; string serverInfo = null; if (controller.GetCurrentStrategy() != null) { serverInfo = controller.GetCurrentStrategy().Name; } else { serverInfo = config.GetCurrentServer().FriendlyName(); } // show more info by hacking the P/Invoke declaration for NOTIFYICONDATA inside Windows Forms string text = I18N.GetString("Shadowsocks") + " " + UpdateChecker.Version + "\n" + (enabled ? I18N.GetString("System Proxy On: ") + (global ? I18N.GetString("Global") : I18N.GetString("PAC")) : String.Format(I18N.GetString("Running: Port {0}"), config.localPort)) // this feedback is very important because they need to know Shadowsocks is running + "\n" + serverInfo; ViewUtils.SetNotifyIconText(_notifyIcon, text); }
public void BeginConnectDest(EndPoint destEndPoint, AsyncCallback callback, object state) { DestEndPoint = destEndPoint; byte[] request = null; byte atyp = 0; int port; var dep = destEndPoint as DnsEndPoint; if (dep != null) { // is a domain name, we will leave it to server atyp = 3; // DOMAINNAME var enc = Encoding.UTF8; var hostByteCount = enc.GetByteCount(dep.Host); request = new byte[4 + 1 /*length byte*/ + hostByteCount + 2]; request[4] = (byte)hostByteCount; enc.GetBytes(dep.Host, 0, dep.Host.Length, request, 5); port = dep.Port; } else { switch (DestEndPoint.AddressFamily) { case AddressFamily.InterNetwork: request = new byte[4 + 4 + 2]; atyp = 1; // IP V4 address break; case AddressFamily.InterNetworkV6: request = new byte[4 + 16 + 2]; atyp = 4; // IP V6 address break; default: throw new Exception(I18N.GetString("Proxy request failed")); } port = ((IPEndPoint)DestEndPoint).Port; var addr = ((IPEndPoint)DestEndPoint).Address.GetAddressBytes(); Array.Copy(addr, 0, request, 4, request.Length - 4 - 2); } // 构造request包剩余部分 request[0] = 5; request[1] = 1; request[2] = 0; request[3] = atyp; request[request.Length - 2] = (byte)((port >> 8) & 0xff); request[request.Length - 1] = (byte)(port & 0xff); var st = new Socks5State(); st.Callback = callback; st.AsyncState = state; _remote.BeginSend(request, 0, request.Length, 0, Socks5RequestSendCallback, st); }
private async Task DoUpdate() { ServicePointManager.Expect100Continue = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;//3072 ChangeProgress(999); ChangeText(I18N.GetString("Get latest version...")); var newVersion = await GetVersion(); string proxy = null; if (string.IsNullOrEmpty(newVersion)) { proxy = Microsoft.VisualBasic.Interaction.InputBox(I18N.GetString("We need a proxy to download v2ray core"), "Yo", "http://127.0.0.1:1080"); if (Uri.IsWellFormedUriString(proxy, UriKind.Absolute)) { newVersion = await GetVersion(proxy); } } if (string.IsNullOrEmpty(newVersion)) { System.Diagnostics.Process.Start(V2RAY_URL); GoodBye(DialogResult.Abort); return; } ChangeText(I18N.GetString("Upgrade {0} to {1} ...", V2Ray.Version?.ToString() ?? "0.0.0", newVersion)); WebClient webClient = new WebClient(); if (!string.IsNullOrEmpty(proxy) && Uri.IsWellFormedUriString(proxy, UriKind.Absolute)) { webClient.Proxy = new WebProxy(new Uri(proxy)); } webClient.DownloadProgressChanged += (s, e) => { ChangeProgress(e.ProgressPercentage); //ChangeText(newVersion + I18N.GetString("Downloading...") + $" {e.ProgressPercentage}%"); }; var fileName = Utils.GetTempPath(Guid.NewGuid().ToString("N")); var downloadURL = $"https://github.com/v2ray/v2ray-core/releases/download/v{newVersion}/v2ray-windows-{(Environment.Is64BitOperatingSystem ? "64" : "32")}.zip"; ChangeText(I18N.GetString("Downloading file from {0}, You can download it manually and extract to same folder.", downloadURL)); await webClient.DownloadFileTaskAsync(downloadURL, fileName); ChangeProgress(100); ChangeText(newVersion + I18N.GetString("Extracting...")); try { using (ZipArchive archive = ZipFile.OpenRead(fileName)) { var additional = Path.Combine(Global.AppPath, "Additional"); if (!Directory.Exists(additional)) { Directory.CreateDirectory(additional); } V2RayRunner.KillAll(); foreach (ZipArchiveEntry entry in archive.Entries) { if (entry.Length == 0) { continue; } if (entry.FullName.Contains('/')) { continue;//directory, useless } if (entry.FullName == "v2ray.exe" || entry.FullName == "v2ctl.exe") { entry.ExtractToFile(Path.Combine(Global.AppPath, entry.FullName), true); } else { entry.ExtractToFile(Path.Combine(additional, entry.FullName), true); } } } } catch (Exception e) { Logging.LogUsefulException(e); GoodBye(DialogResult.Abort); return; } finally { File.Delete(fileName); } GoodBye(DialogResult.OK); }
private void UpdateTitle() { Title = $@"{I18N.GetString(@"Edit Servers")}({(_controller.GetCurrentConfiguration().shareOverLan ? I18N.GetString(@"Any") : I18N.GetString(@"Local"))}:{_controller.GetCurrentConfiguration().localPort} {I18N.GetString(@"Version")}:{UpdateChecker.FullVersion})"; }
private static void Main(string[] args) { #region Single Instance and IPC bool hasAnotherInstance = !mutex.WaitOne(TimeSpan.Zero, true); // store args for further use Args = args; Parser.Default.ParseArguments <CommandLineOption>(args) .WithParsed(opt => Options = opt) .WithNotParsed(e => e.Output()); if (hasAnotherInstance) { if (!string.IsNullOrWhiteSpace(Options.OpenUrl)) { IPCService.RequestOpenUrl(Options.OpenUrl); } else { MessageBox.Show(I18N.GetString("Find Shadowsocks icon in your notify tray.") + Environment.NewLine + I18N.GetString("If you want to start multiple Shadowsocks, make a copy in another directory."), I18N.GetString("Shadowsocks is already running.")); } return; } #endregion #region Enviroment Setup Directory.SetCurrentDirectory(WorkingDirectory); // todo: initialize the NLog configuartion Model.NLogConfig.TouchAndApplyNLogConfig(); // .NET Framework 4.7.2 on Win7 compatibility ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; #endregion #region Compactibility Check // Check OS since we are using dual-mode socket if (!Utils.IsWinVistaOrHigher()) { MessageBox.Show(I18N.GetString("Unsupported operating system, use Windows Vista at least."), "Shadowsocks Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // Check .NET Framework version if (!Utils.IsSupportedRuntimeVersion()) { if (DialogResult.OK == MessageBox.Show(I18N.GetString("Unsupported .NET Framework, please update to {0} or later.", "4.7.2"), "Shadowsocks Error", MessageBoxButtons.OKCancel, MessageBoxIcon.Error)) { Process.Start("https://dotnet.microsoft.com/download/dotnet-framework/net472"); } return; } #endregion #region Event Handlers Setup Utils.ReleaseMemory(true); Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); // handle UI exceptions Application.ThreadException += Application_ThreadException; // handle non-UI exceptions AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; Application.ApplicationExit += Application_ApplicationExit; SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); AutoStartup.RegisterForRestart(true); #endregion #if DEBUG // truncate privoxy log file while debugging string privoxyLogFilename = Utils.GetTempPath("privoxy.log"); if (File.Exists(privoxyLogFilename)) { using (new FileStream(privoxyLogFilename, FileMode.Truncate)) { } } #endif MainController = new ShadowsocksController(); MenuController = new MenuViewController(MainController); HotKeys.Init(MainController); MainController.Start(); #region IPC Handler and Arguement Process IPCService ipcService = new IPCService(); Task.Run(() => ipcService.RunServer()); ipcService.OpenUrlRequested += (_1, e) => MainController.AskAddServerBySSURL(e.Url); if (!string.IsNullOrWhiteSpace(Options.OpenUrl)) { MainController.AskAddServerBySSURL(Options.OpenUrl); } #endregion Application.Run(); }
private InlineKeyboardMarkup CreateWizardMarkup(User user, RaidDescription record) { InlineKeyboardMarkup result = new InlineKeyboardMarkup(); result.inline_keyboard = new List <List <InlineKeyboardButton> >(); List <InlineKeyboardButton> row; row = new List <InlineKeyboardButton>(); row.Add(new InlineKeyboardButton { text = (string.IsNullOrEmpty(record.Raid) ? "" : "✅ ") + _HTML_(I18N.GetString("Raid")), callback_data = CbqRaid }); row.Add(new InlineKeyboardButton { text = (string.IsNullOrEmpty(record.Gym) ? "" : "✅ ") + _HTML_(I18N.GetString("Gym")), callback_data = CbqGym }); row.Add(new InlineKeyboardButton { text = _HTML_(I18N.GetString("Alignment")), callback_data = CbqAlignment }); result.inline_keyboard.Add(row); row = new List <InlineKeyboardButton>(); row.Add(new InlineKeyboardButton { text = (record.RaidEndTime != default(DateTime) && record.RaidEndTime >= DateTime.UtcNow ? "✅ " : "") + _HTML_(I18N.GetString("Time")), callback_data = CbqTime }); row.Add(new InlineKeyboardButton { text = _HTML_(I18N.GetString("🗑 Reset")), callback_data = CbqClear }); result.inline_keyboard.Add(row); row = new List <InlineKeyboardButton>(); row.Add(new InlineKeyboardButton { text = _HTML_(I18N.GetString("💾 Done")), callback_data = CbqDone }); result.inline_keyboard.Add(row); return(result); }
private static void Main(string[] args) { #region Single Instance and IPC bool hasAnotherInstance = !mutex.WaitOne(TimeSpan.Zero, true); // store args for further use Args = args; Parser.Default.ParseArguments <CommandLineOption>(args) .WithParsed(opt => Options = opt) .WithNotParsed(e => e.Output()); if (hasAnotherInstance) { if (!string.IsNullOrWhiteSpace(Options.OpenUrl)) { IPCService.RequestOpenUrl(Options.OpenUrl); } else { MessageBox.Show(I18N.GetString("Find Shadowsocks icon in your notify tray.") + Environment.NewLine + I18N.GetString("If you want to start multiple Shadowsocks, make a copy in another directory."), I18N.GetString("Shadowsocks is already running.")); } return; } #endregion #region Enviroment Setup Directory.SetCurrentDirectory(WorkingDirectory); // todo: initialize the NLog configuartion Model.NLogConfig.TouchAndApplyNLogConfig(); // .NET Framework 4.7.2 on Win7 compatibility ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; #endregion #region Compactibility Check // Check OS since we are using dual-mode socket if (!Utils.IsWinVistaOrHigher()) { MessageBox.Show(I18N.GetString("Unsupported operating system, use Windows Vista at least."), "Shadowsocks Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // Check .NET Framework version if (!Utils.IsSupportedRuntimeVersion()) { if (DialogResult.OK == MessageBox.Show(I18N.GetString("Unsupported .NET Framework, please update to {0} or later.", "4.8"), "Shadowsocks Error", MessageBoxButtons.OKCancel, MessageBoxIcon.Error)) { Process.Start("https://dotnet.microsoft.com/download/dotnet-framework/net48"); } return; } #endregion #region Event Handlers Setup Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); // handle UI exceptions Application.ThreadException += Application_ThreadException; // handle non-UI exceptions AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; Application.ApplicationExit += Application_ApplicationExit; SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); AutoStartup.RegisterForRestart(true); #endregion // We would use this in v5. // Parameters would have to be dropped from views' constructors (VersionUpdatePromptView) //Locator.CurrentMutable.RegisterViewsForViewModels(Assembly.GetCallingAssembly()); // Workaround for hosting WPF controls in a WinForms app. // We have to manually set the culture for the LocalizeDictionary instance. // https://stackoverflow.com/questions/374518/localizing-a-winforms-application-with-embedded-wpf-user-controls // https://stackoverflow.com/questions/14668640/wpf-localize-extension-translate-window-at-run-time LocalizeDictionary.Instance.Culture = Thread.CurrentThread.CurrentCulture; #if DEBUG // truncate privoxy log file while debugging string privoxyLogFilename = Utils.GetTempPath("privoxy.log"); if (File.Exists(privoxyLogFilename)) { using (new FileStream(privoxyLogFilename, FileMode.Truncate)) { } } #endif MainController = new ShadowsocksController(); MenuController = new MenuViewController(MainController); HotKeys.Init(MainController); MainController.Start(); // Update online config Task.Run(async() => { await Task.Delay(10 * 1000); await MainController.UpdateAllOnlineConfig(); }); #region IPC Handler and Arguement Process IPCService ipcService = new IPCService(); Task.Run(() => ipcService.RunServer()); ipcService.OpenUrlRequested += (_1, e) => MainController.AskAddServerBySSURL(e.Url); if (!string.IsNullOrWhiteSpace(Options.OpenUrl)) { MainController.AskAddServerBySSURL(Options.OpenUrl); } #endregion Application.Run(); }
private void UpdateTrayIcon() { int dpi; Graphics graphics = Graphics.FromHwnd(IntPtr.Zero); dpi = (int)graphics.DpiX; graphics.Dispose(); icon_baseBitmap = null; if (dpi < 97) { // dpi = 96; icon_baseBitmap = Resources.ss16; } else if (dpi < 121) { // dpi = 120; icon_baseBitmap = Resources.ss20; } else { icon_baseBitmap = Resources.ss24; } Configuration config = controller.GetConfigurationCopy(); bool enabled = config.enabled; bool global = config.global; icon_baseBitmap = getTrayIconByState(icon_baseBitmap, enabled, global); icon_base = Icon.FromHandle(icon_baseBitmap.GetHicon()); targetIcon = icon_base; icon_in = Icon.FromHandle(AddBitmapOverlay(icon_baseBitmap, Resources.ssIn24).GetHicon()); icon_out = Icon.FromHandle(AddBitmapOverlay(icon_baseBitmap, Resources.ssOut24).GetHicon()); icon_both = Icon.FromHandle(AddBitmapOverlay(icon_baseBitmap, Resources.ssIn24, Resources.ssOut24).GetHicon()); _notifyIcon.Icon = targetIcon; string serverInfo = null; if (controller.GetCurrentStrategy() != null) { serverInfo = controller.GetCurrentStrategy().Name; } else { serverInfo = config.GetCurrentServer().FriendlyName(); } // we want to show more details but notify icon title is limited to 63 characters string text = I18N.GetString("Shadowsocks") + " " + UpdateChecker.Version + "\n" + (enabled ? I18N.GetString("System Proxy On: ") + (global ? I18N.GetString("Global") : I18N.GetString("PAC")) : String.Format(I18N.GetString("Running: Port {0}"), config.localPort)) // this feedback is very important because they need to know Shadowsocks is running + "\n" + serverInfo; _notifyIcon.Text = text.Substring(0, Math.Min(63, text.Length)); }
private void ScanScreenQRCode(bool ss_only) { Thread.Sleep(100); foreach (Screen screen in Screen.AllScreens) { Point screen_size = Util.Utils.GetScreenPhysicalSize(); using (Bitmap fullImage = new Bitmap(screen_size.X, screen_size.Y)) { using (Graphics g = Graphics.FromImage(fullImage)) { g.CopyFromScreen(screen.Bounds.X, screen.Bounds.Y, 0, 0, fullImage.Size, CopyPixelOperation.SourceCopy); } bool decode_fail = false; for (int i = 0; i < 100; i++) { double stretch; Rectangle cropRect = GetScanRect(fullImage.Width, fullImage.Height, i, out stretch); if (cropRect.Width == 0) { break; } string url; Rectangle rect; if (stretch == 1 ? ScanQRCode(screen, fullImage, cropRect, out url, out rect) : ScanQRCodeStretch(screen, fullImage, cropRect, stretch, out url, out rect)) { var success = controller.AddServerBySSURL(url); QRCodeSplashForm splash = new QRCodeSplashForm(); if (success) { splash.FormClosed += splash_FormClosed; } else if (!ss_only) { _urlToOpen = url; //if (url.StartsWith("http://") || url.StartsWith("https://")) // splash.FormClosed += openURLFromQRCode; //else splash.FormClosed += showURLFromQRCode; } else { decode_fail = true; continue; } splash.Location = new Point(screen.Bounds.X, screen.Bounds.Y); double dpi = Screen.PrimaryScreen.Bounds.Width / (double)screen_size.X; splash.TargetRect = new Rectangle( (int)(rect.Left * dpi + screen.Bounds.X), (int)(rect.Top * dpi + screen.Bounds.Y), (int)(rect.Width * dpi), (int)(rect.Height * dpi)); splash.Size = new Size(fullImage.Width, fullImage.Height); splash.Show(); return; } } if (decode_fail) { MessageBox.Show(I18N.GetString("Failed to decode QRCode")); return; } } } MessageBox.Show(I18N.GetString("No QRCode found. Try to zoom in or move it to the center of the screen.")); }
void controller_UpdatePACFromGFWListCompleted(object sender, GFWListUpdater.ResultEventArgs e) { string result = e.Success ? I18N.GetString("PAC updated") : I18N.GetString("No updates found. Please report to GFWList if you have problems with it."); ShowBalloonTip(I18N.GetString("Shadowsocks"), result, ToolTipIcon.Info, 1000); }
void controller_UpdatePACFromGFWListCompleted(object sender, GFWListUpdater.ResultEventArgs e) { GFWListUpdater updater = (GFWListUpdater)sender; string result = e.Success ? (updater.update_type <= 1 ? I18N.GetString("PAC updated") : I18N.GetString("Domain white list list updated")) : I18N.GetString("No updates found. Please report to GFWList if you have problems with it."); ShowBalloonTip(I18N.GetString("Shadowsocks"), result, ToolTipIcon.Info, 1000); if (updater.update_type == 8) { controller.ToggleBypass(httpWhiteListItem.Checked); } }
void updateChecker_NewVersionFound(object sender, EventArgs e) { ShowBalloonTip(String.Format(I18N.GetString("Shadowsocks {0} Update Found"), updateChecker.LatestVersionNumber), I18N.GetString("Click here to download"), ToolTipIcon.Info, 5000); _notifyIcon.BalloonTipClicked += notifyIcon1_BalloonTipClicked; _isFirstRun = false; }
private void LoadCurrentConfiguration() { config = controller.GetCurrentConfiguration(); LoadConfiguration(config); _lastSelectedIndex = config.index; if (0 <= _lastSelectedIndex && _lastSelectedIndex < ServersListBox.Items.Count) { ServersListBox.SelectedIndex = _lastSelectedIndex; } ModeSelectButton.Text = I18N.GetString(config.global ? "Smart Mode" : "Global Mode"); EnableButton.Text = I18N.GetString((config.enabled ? "Disable" : "Enable") + " System Proxy"); StateLabel.Text = I18N.GetString(config.enabled ? "Enable" : "Disable") + " / " + I18N.GetString(config.global ? "Global Mode" : "Smart Mode"); TrafficLabel.Text = MenuViewController.one().LeftTraffic; LoadSelectedServer(); }
private void UpdateTrayIcon() { int dpi; Graphics graphics = Graphics.FromHwnd(IntPtr.Zero); dpi = (int)graphics.DpiX; graphics.Dispose(); Bitmap icon = null; if (dpi < 97) { // dpi = 96; icon = Resources.ss16; } else if (dpi < 121) { // dpi = 120; icon = Resources.ss20; } else { icon = Resources.ss24; } Configuration config = controller.GetConfiguration(); bool enabled = config.enabled; bool global = config.global; if (!enabled) { Bitmap iconCopy = new Bitmap(icon); for (int x = 0; x < iconCopy.Width; x++) { for (int y = 0; y < iconCopy.Height; y++) { Color color = icon.GetPixel(x, y); iconCopy.SetPixel(x, y, Color.FromArgb((byte)(color.A / 1.25), color.R, color.G, color.B)); } } icon = iconCopy; } _notifyIcon.Icon = Icon.FromHandle(icon.GetHicon()); // we want to show more details but notify icon title is limited to 63 characters string text = I18N.GetString("Shadowsocks") + " " + UpdateChecker.Version + "\n" + (enabled ? I18N.GetString("System Proxy On: ") + (global ? I18N.GetString("Global") : I18N.GetString("PAC")) : String.Format(I18N.GetString("Running: Port {0}"), config.localPort)) // this feedback is very important because they need to know Shadowsocks is running + "\n" + config.GetCurrentServer().FriendlyName(); _notifyIcon.Text = text.Substring(0, Math.Min(63, text.Length)); }
void controller_UpdatePACFromGFWListError(object sender, System.IO.ErrorEventArgs e) { ShowBalloonTip(I18N.GetString("Failed to update PAC file"), e.GetException().Message, ToolTipIcon.Error, 5000); Logging.LogUsefulException(e.GetException()); }
static void Main(string[] args) { #if !_CONSOLE foreach (string arg in args) { if (arg == "--setautorun") { if (!Controller.AutoStartup.Switch()) { Environment.ExitCode = 1; } return; } } using (Mutex mutex = new Mutex(false, "Global\\ShadowsocksR_" + Application.StartupPath.GetHashCode())) { AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; Application.EnableVisualStyles(); Application.ApplicationExit += Application_ApplicationExit; SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; Application.SetCompatibleTextRenderingDefault(false); if (!mutex.WaitOne(0, false)) { MessageBox.Show(I18N.GetString("Find Shadowsocks icon in your notify tray.") + "\n" + I18N.GetString("If you want to start multiple Shadowsocks, make a copy in another directory."), I18N.GetString("ShadowsocksR is already running.")); return; } #endif Directory.SetCurrentDirectory(Application.StartupPath); #if !_CONSOLE int try_times = 0; while (Configuration.Load() == null) { if (try_times >= 5) return; using (InputPassword dlg = new InputPassword()) { if (dlg.ShowDialog() == DialogResult.OK) Configuration.SetPassword(dlg.password); else return; } try_times += 1; } if (try_times > 0) Logging.save_to_file = false; #endif //#if !DEBUG Logging.OpenLogFile(); //#endif _controller = new ShadowsocksController(); HostMap.Instance().LoadHostFile(); #if _DOTNET_4_0 // Enable Modern TLS when .NET 4.5+ installed. if (Util.EnvCheck.CheckDotNet45()) ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; #endif #if !_CONSOLE _viewController = new MenuViewController(_controller); #endif _controller.Start(); #if !_CONSOLE //Util.Utils.ReleaseMemory(); Application.Run(); } #else Console.ReadLine(); _controller.Stop(); #endif }
void updateChecker_CheckUpdateCompleted(object sender, EventArgs e) { if (updateChecker.NewVersionFound) { ShowBalloonTip(I18N.GetString("Shadowsocks {0} Update Found", updateChecker.LatestVersionNumber + updateChecker.LatestVersionSuffix), I18N.GetString("Click here to update"), ToolTipIcon.Info, 5000); } else if (!_isStartupChecking) { ShowBalloonTip(I18N.GetString("Shadowsocks"), I18N.GetString("No update is available"), ToolTipIcon.Info, 5000); } _isStartupChecking = false; }
private static void Main(string[] args) { Directory.SetCurrentDirectory(Path.GetDirectoryName(Utils.GetExecutablePath()) ?? throw new InvalidOperationException()); if (args.Any(arg => arg == @"--setautorun")) { if (!AutoStartup.Switch()) { Environment.ExitCode = 1; } return; } using var mutex = new Mutex(false, $@"Global\ShadowsocksR_{Directory.GetCurrentDirectory().GetDeterministicHashCode()}"); if (!mutex.WaitOne(0, false)) { MessageBox.Show(I18N.GetString("Find Shadowsocks icon in your notify tray.") + Environment.NewLine + I18N.GetString("If you want to start multiple Shadowsocks, make a copy in another directory."), I18N.GetString("ShadowsocksR is already running.")); return; } var app = new Application { ShutdownMode = ShutdownMode.OnExplicitShutdown }; AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; app.Exit += App_Exit; var tryTimes = 0; while (Configuration.Load() == null) { if (tryTimes >= 5) { return; } var dlg = new InputPasswordWindow(); if (dlg.ShowDialog() == true) { Configuration.SetPassword(dlg.Password); } else { return; } tryTimes += 1; } _controller = new ShadowsocksController(); HostMap.Instance().LoadHostFile(); // Logging Logging.DefaultOut = Console.Out; Logging.DefaultError = Console.Error; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; _viewController = new MenuViewController(_controller); SystemEvents.SessionEnding += _viewController.Quit_Click; _controller.Start(); app.Run(); }
private MenuItem CreateMenuItem(string text, EventHandler click) { return(new MenuItem(I18N.GetString(text), click)); }
private void Application_Startup(object sender, StartupEventArgs e) { try { var isSingle = SingleInstance.IsSingle(); if (!isSingle) { SingleInstance.SetForeground(); return; } var isTrueDirectory = DirectoryCheck.IsTrueDirectory(); if (!isTrueDirectory) { throw new Exception(I18N.GetString("FileNotFound")); } var isAdmin = Administrator.IsAdmin(); if (e.Args.Length == 0 && isAdmin) { switch (MessageBox.Show($"{I18N.GetString("Setup")}", name, MessageBoxButton.YesNoCancel, MessageBoxImage.Information)) { case MessageBoxResult.Yes: Autorun.Add(); DesktopMenu.Add(); break; case MessageBoxResult.No: Autorun.Remove(); DesktopMenu.Remove(); V2Ray.Stop(); break; default: break; } } else if (e.Args.Length == 0 && !isAdmin) { throw new Exception(I18N.GetString("PermissionDenied")); } else if (e.Args[0] == "-start") { V2Ray.Start(); } else if (e.Args[0] == "-stop") { V2Ray.Stop(); } else if (e.Args[0] == "-config") { var window = new MainWindow(); window.ShowDialog(); } else { throw new ArgumentException(); } } catch (Exception ex) { MessageBox.Show(ex.Message, name, MessageBoxButton.OK, MessageBoxImage.Error); } finally { Environment.Exit(Environment.ExitCode); } }
void controller_Errored(object sender, System.IO.ErrorEventArgs e) { MessageBox.Show(e.GetException().ToString(), I18N.GetString("Shadowsocks Error: {0}", e.GetException().Message)); }
private void timer1_Tick(object sender, EventArgs e) { this.LabTime.Text = (I18N.GetString("Time:")) + DateTime.Now.ToString(); }