mirror of
				https://github.com/2dust/v2rayN.git
				synced 2025-10-27 10:40:08 +00:00 
			
		
		
		
	Compare commits
	
		
			5 commits
		
	
	
		
			a7de149fd7
			...
			e70658f311
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | e70658f311 | ||
|   | 2dd10cf5a1 | ||
|   | 96781a784b | ||
|   | 9748fbb076 | ||
|   | aa5e4378ab | 
					 24 changed files with 254 additions and 105 deletions
				
			
		|  | @ -1,29 +1,39 @@ | |||
| namespace AmazTool | ||||
| namespace AmazTool | ||||
| { | ||||
|     internal static class Program | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// 应用程序的主入口点。 | ||||
|         /// </summary> | ||||
|         [STAThread] | ||||
|         private static void Main(string[] args) | ||||
|         { | ||||
|             if (args.Length == 0) | ||||
|             { | ||||
|                 Console.WriteLine(Resx.Resource.Guidelines); | ||||
|                 Thread.Sleep(5000); | ||||
|                 Utils.WriteLine(Resx.Resource.Guidelines); | ||||
|                 Utils.Waiting(5); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             var argData = Uri.UnescapeDataString(string.Join(" ", args)); | ||||
|             if (argData.Equals("rebootas")) | ||||
|             { | ||||
|                 Thread.Sleep(1000); | ||||
|                 Utils.Waiting(1); | ||||
|                 Utils.StartV2RayN(); | ||||
|                 return; | ||||
|             } | ||||
|             | ||||
|             UpgradeApp.Upgrade(argData); | ||||
|             var tryTimes = 0; | ||||
|             UpgradeApp.Init(); | ||||
|             while (tryTimes++ < 3) | ||||
|             { | ||||
|                 if (!UpgradeApp.Upgrade(argData)) | ||||
|                 { | ||||
|                     continue; | ||||
|                 } | ||||
| 
 | ||||
|                 Utils.WriteLine(Resx.Resource.Restartv2rayN); | ||||
|                 Utils.Waiting(3); | ||||
|                 Utils.StartV2RayN(); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -6,19 +6,99 @@ namespace AmazTool | |||
| { | ||||
|     internal class UpgradeApp | ||||
|     { | ||||
|         public static void Upgrade(string fileName) | ||||
|         public static bool Upgrade(string fileName) | ||||
|         { | ||||
|             Console.WriteLine($"{Resx.Resource.StartUnzipping}\n{fileName}"); | ||||
| 
 | ||||
|             Utils.Waiting(5); | ||||
|             Utils.WriteLine($"{Resx.Resource.StartUnzipping}\n{fileName}"); | ||||
| 
 | ||||
|             if (!File.Exists(fileName)) | ||||
|             { | ||||
|                 Console.WriteLine(Resx.Resource.UpgradeFileNotFound); | ||||
|                 return; | ||||
|                 Utils.WriteLine(Resx.Resource.UpgradeFileNotFound); | ||||
|                 return false; | ||||
|             } | ||||
| 
 | ||||
|             Console.WriteLine(Resx.Resource.TryTerminateProcess); | ||||
|             Utils.Waiting(5); | ||||
| 
 | ||||
|             KillV2rayN(); | ||||
| 
 | ||||
|             Utils.WriteLine(Resx.Resource.StartUnzipping); | ||||
|             StringBuilder sb = new(); | ||||
|             try | ||||
|             { | ||||
|                 var splitKey = "/"; | ||||
| 
 | ||||
|                 using var archive = ZipFile.OpenRead(fileName); | ||||
|                 foreach (var entry in archive.Entries) | ||||
|                 { | ||||
|                     try | ||||
|                     { | ||||
|                         if (entry.Length == 0) | ||||
|                         { | ||||
|                             continue; | ||||
|                         } | ||||
| 
 | ||||
|                         Utils.WriteLine(entry.FullName); | ||||
| 
 | ||||
|                         var lst = entry.FullName.Split(splitKey); | ||||
|                         if (lst.Length == 1) | ||||
|                         { | ||||
|                             continue; | ||||
|                         } | ||||
| 
 | ||||
|                         var fullName = string.Join(splitKey, lst[1..lst.Length]); | ||||
|                         var entryOutputPath = Utils.GetPath(fullName); | ||||
|                         Directory.CreateDirectory(Path.GetDirectoryName(entryOutputPath)!); | ||||
|                         //In the bin folder, if the file already exists, it will be skipped | ||||
|                         if (fullName.StartsWith("bin") && File.Exists(entryOutputPath)) | ||||
|                         { | ||||
|                             continue; | ||||
|                         } | ||||
|                         entry.ExtractToFile(entryOutputPath, true); | ||||
| 
 | ||||
|                         Utils.WriteLine(entryOutputPath); | ||||
|                     } | ||||
|                     catch (Exception ex) | ||||
|                     { | ||||
|                         sb.Append(ex.Message); | ||||
|                         sb.Append(ex.StackTrace); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 sb.Append(Resx.Resource.FailedUpgrade + ex.StackTrace); | ||||
|             } | ||||
| 
 | ||||
|             if (sb.Length <= 0) | ||||
|             { | ||||
|                 return true; | ||||
|             } | ||||
| 
 | ||||
|             Utils.WriteLine(sb.ToString()); | ||||
|             Utils.WriteLine(Resx.Resource.FailedUpgrade); | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         public static bool Init() | ||||
|         { | ||||
|             //Process temporary files generated by the last update | ||||
|             var files = Directory.GetFiles(Utils.GetPath(""), "*.tmp"); | ||||
|             foreach (var file in files) | ||||
|             { | ||||
|                 if (file.Contains(Utils.AmazTool)) | ||||
|                 { | ||||
|                     File.Delete(file); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             var destFileName = $"{Utils.GetExePath()}{Guid.NewGuid().ToString("N")[..8]}.tmp"; | ||||
|             File.Move(Utils.GetExePath(), destFileName); | ||||
| 
 | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         private static bool KillV2rayN() | ||||
|         { | ||||
|             Utils.WriteLine(Resx.Resource.TryTerminateProcess); | ||||
|             try | ||||
|             { | ||||
|                 var existing = Process.GetProcessesByName(Utils.V2rayN); | ||||
|  | @ -35,71 +115,10 @@ namespace AmazTool | |||
|             catch (Exception ex) | ||||
|             { | ||||
|                 // Access may be denied without admin right. The user may not be an administrator. | ||||
|                 Console.WriteLine(Resx.Resource.FailedTerminateProcess + ex.StackTrace); | ||||
|                 Utils.WriteLine(Resx.Resource.FailedTerminateProcess + ex.StackTrace); | ||||
|             } | ||||
| 
 | ||||
|             Console.WriteLine(Resx.Resource.StartUnzipping); | ||||
|             StringBuilder sb = new(); | ||||
|             try | ||||
|             { | ||||
|                 var thisAppOldFile = $"{Utils.GetExePath()}.tmp"; | ||||
|                 File.Delete(thisAppOldFile); | ||||
|                 var splitKey = "/"; | ||||
| 
 | ||||
|                 using var archive = ZipFile.OpenRead(fileName); | ||||
|                 foreach (var entry in archive.Entries) | ||||
|                 { | ||||
|                     try | ||||
|                     { | ||||
|                         if (entry.Length == 0) | ||||
|                         { | ||||
|                             continue; | ||||
|                         } | ||||
| 
 | ||||
|                         Console.WriteLine(entry.FullName); | ||||
| 
 | ||||
|                         var lst = entry.FullName.Split(splitKey); | ||||
|                         if (lst.Length == 1) | ||||
|                             continue; | ||||
|                         var fullName = string.Join(splitKey, lst[1..lst.Length]); | ||||
| 
 | ||||
|                         if (string.Equals(Utils.GetExePath(), Utils.GetPath(fullName), StringComparison.OrdinalIgnoreCase)) | ||||
|                         { | ||||
|                             File.Move(Utils.GetExePath(), thisAppOldFile); | ||||
|                         } | ||||
| 
 | ||||
|                         var entryOutputPath = Utils.GetPath(fullName); | ||||
|                         Directory.CreateDirectory(Path.GetDirectoryName(entryOutputPath)!); | ||||
|                         //In the bin folder, if the file already exists, it will be skipped | ||||
|                         if (fullName.StartsWith("bin") && File.Exists(entryOutputPath)) | ||||
|                         { | ||||
|                             continue; | ||||
|                         } | ||||
|                         entry.ExtractToFile(entryOutputPath, true); | ||||
| 
 | ||||
|                         Console.WriteLine(entryOutputPath); | ||||
|                     } | ||||
|                     catch (Exception ex) | ||||
|                     { | ||||
|                         sb.Append(ex.StackTrace); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 Console.WriteLine(Resx.Resource.FailedUpgrade + ex.StackTrace); | ||||
|                 //return; | ||||
|             } | ||||
|             if (sb.Length > 0) | ||||
|             { | ||||
|                 Console.WriteLine(Resx.Resource.FailedUpgrade + sb.ToString()); | ||||
|                 //return; | ||||
|             } | ||||
| 
 | ||||
|             Console.WriteLine(Resx.Resource.Restartv2rayN); | ||||
|             Utils.Waiting(2); | ||||
| 
 | ||||
|             Utils.StartV2RayN(); | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| using System.Diagnostics; | ||||
| using System.Diagnostics; | ||||
| 
 | ||||
| namespace AmazTool | ||||
| { | ||||
|  | @ -14,9 +14,9 @@ namespace AmazTool | |||
|             return AppDomain.CurrentDomain.BaseDirectory; | ||||
|         } | ||||
| 
 | ||||
|         public static string GetPath(string fileName) | ||||
|         public static string GetPath(string? fileName) | ||||
|         { | ||||
|             string startupPath = StartupPath(); | ||||
|             var startupPath = StartupPath(); | ||||
|             if (string.IsNullOrEmpty(fileName)) | ||||
|             { | ||||
|                 return startupPath; | ||||
|  | @ -25,6 +25,7 @@ namespace AmazTool | |||
|         } | ||||
| 
 | ||||
|         public static string V2rayN => "v2rayN"; | ||||
|         public static string AmazTool => "AmazTool"; | ||||
| 
 | ||||
|         public static void StartV2RayN() | ||||
|         { | ||||
|  | @ -44,9 +45,14 @@ namespace AmazTool | |||
|         { | ||||
|             for (var i = second; i > 0; i--) | ||||
|             { | ||||
|                 Console.WriteLine(i); | ||||
|                 Utils.WriteLine(i); | ||||
|                 Thread.Sleep(1000); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public static void WriteLine(object obj) | ||||
|         { | ||||
|             Console.WriteLine(obj); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -1 +1 @@ | |||
| Subproject commit 35901e2eaa40bc697e3864cb63812fb355af4087 | ||||
| Subproject commit b3b635ef46b7aed3ee9e27abe7ec1f2688695bfb | ||||
|  | @ -109,7 +109,7 @@ namespace ServiceLib.Handler | |||
|             task.Settings.RunOnlyIfIdle = false; | ||||
|             task.Settings.IdleSettings.StopOnIdleEnd = false; | ||||
|             task.Settings.ExecutionTimeLimit = TimeSpan.Zero; | ||||
|             task.Triggers.Add(new Microsoft.Win32.TaskScheduler.LogonTrigger { UserId = logonUser, Delay = TimeSpan.FromSeconds(10) }); | ||||
|             task.Triggers.Add(new Microsoft.Win32.TaskScheduler.LogonTrigger { UserId = logonUser, Delay = TimeSpan.FromSeconds(20) }); | ||||
|             task.Principal.RunLevel = Microsoft.Win32.TaskScheduler.TaskRunLevel.Highest; | ||||
|             task.Actions.Add(new Microsoft.Win32.TaskScheduler.ExecAction(fileName.AppendQuotes(), null, Path.GetDirectoryName(fileName))); | ||||
| 
 | ||||
|  |  | |||
|  | @ -217,6 +217,7 @@ namespace ServiceLib.Handler | |||
|                 item.Remarks = profileItem.Remarks; | ||||
|                 item.Address = profileItem.Address; | ||||
|                 item.Port = profileItem.Port; | ||||
|                 item.Ports = profileItem.Ports; | ||||
| 
 | ||||
|                 item.Id = profileItem.Id; | ||||
|                 item.AlterId = profileItem.AlterId; | ||||
|  |  | |||
|  | @ -197,6 +197,7 @@ namespace ServiceLib.Models | |||
|     { | ||||
|         public int UpMbps { get; set; } | ||||
|         public int DownMbps { get; set; } | ||||
|         public int HopInterval { get; set; } = 30; | ||||
|     } | ||||
| 
 | ||||
|     [Serializable] | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| using SQLite; | ||||
| using SQLite; | ||||
| 
 | ||||
| namespace ServiceLib.Models | ||||
| { | ||||
|  | @ -64,11 +64,11 @@ namespace ServiceLib.Models | |||
| 
 | ||||
|         [PrimaryKey] | ||||
|         public string IndexId { get; set; } | ||||
| 
 | ||||
|         public EConfigType ConfigType { get; set; } | ||||
|         public int ConfigVersion { get; set; } | ||||
|         public string Address { get; set; } | ||||
|         public int Port { get; set; } | ||||
|         public string Ports { get; set; } | ||||
|         public string Id { get; set; } | ||||
|         public int AlterId { get; set; } | ||||
|         public string Security { get; set; } | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| namespace ServiceLib.Models | ||||
| namespace ServiceLib.Models | ||||
| { | ||||
|     public class SingboxConfig | ||||
|     { | ||||
|  | @ -101,21 +101,23 @@ | |||
|         public string tag { get; set; } | ||||
|         public string? server { get; set; } | ||||
|         public int? server_port { get; set; } | ||||
|         public string uuid { get; set; } | ||||
|         public string security { get; set; } | ||||
|         public List<string>? server_ports { get; set; } | ||||
|         public string? uuid { get; set; } | ||||
|         public string? security { get; set; } | ||||
|         public int? alter_id { get; set; } | ||||
|         public string flow { get; set; } | ||||
|         public string? flow { get; set; } | ||||
|         public string? hop_interval { get; set; } | ||||
|         public int? up_mbps { get; set; } | ||||
|         public int? down_mbps { get; set; } | ||||
|         public string auth_str { get; set; } | ||||
|         public string? auth_str { get; set; } | ||||
|         public int? recv_window_conn { get; set; } | ||||
|         public int? recv_window { get; set; } | ||||
|         public bool? disable_mtu_discovery { get; set; } | ||||
|         public string? detour { get; set; } | ||||
|         public string method { get; set; } | ||||
|         public string username { get; set; } | ||||
|         public string password { get; set; } | ||||
|         public string congestion_control { get; set; } | ||||
|         public string? method { get; set; } | ||||
|         public string? username { get; set; } | ||||
|         public string? password { get; set; } | ||||
|         public string? congestion_control { get; set; } | ||||
|         public string? version { get; set; } | ||||
|         public string? network { get; set; } | ||||
|         public string? packet_encoding { get; set; } | ||||
|  |  | |||
							
								
								
									
										18
									
								
								v2rayN/ServiceLib/Resx/ResUI.Designer.cs
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										18
									
								
								v2rayN/ServiceLib/Resx/ResUI.Designer.cs
									
									
									
										generated
									
									
									
								
							|  | @ -2536,6 +2536,24 @@ namespace ServiceLib.Resx { | |||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Server port range 的本地化字符串。 | ||||
|         /// </summary> | ||||
|         public static string TbPorts7 { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("TbPorts7", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Will cover the port, separate with commas (,) 的本地化字符串。 | ||||
|         /// </summary> | ||||
|         public static string TbPorts7Tips { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("TbPorts7Tips", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Socks port 的本地化字符串。 | ||||
|         /// </summary> | ||||
|  |  | |||
|  | @ -1396,4 +1396,10 @@ | |||
|   <data name="RemoveInvalidServerResultTip" xml:space="preserve"> | ||||
|     <value>Removed {0} invalid test results.</value> | ||||
|   </data> | ||||
|   <data name="TbPorts7" xml:space="preserve"> | ||||
|     <value>Server port range</value> | ||||
|   </data> | ||||
|   <data name="TbPorts7Tips" xml:space="preserve"> | ||||
|     <value>Will cover the port, separate with commas (,)</value> | ||||
|   </data> | ||||
| </root> | ||||
|  | @ -1396,4 +1396,10 @@ | |||
|   <data name="RemoveInvalidServerResultTip" xml:space="preserve"> | ||||
|     <value>Removed {0} invalid test results.</value> | ||||
|   </data> | ||||
|   <data name="TbPorts7" xml:space="preserve"> | ||||
|     <value>Server port range</value> | ||||
|   </data> | ||||
|   <data name="TbPorts7Tips" xml:space="preserve"> | ||||
|     <value>Will cover the port, separate with commas (,)</value> | ||||
|   </data> | ||||
| </root> | ||||
|  | @ -1396,4 +1396,10 @@ | |||
|   <data name="RemoveInvalidServerResultTip" xml:space="preserve"> | ||||
|     <value>Removed {0} invalid test results.</value> | ||||
|   </data> | ||||
|   <data name="TbPorts7" xml:space="preserve"> | ||||
|     <value>Server port range</value> | ||||
|   </data> | ||||
|   <data name="TbPorts7Tips" xml:space="preserve"> | ||||
|     <value>Will cover the port, separate with commas (,)</value> | ||||
|   </data> | ||||
| </root> | ||||
|  | @ -1396,4 +1396,10 @@ | |||
|   <data name="RemoveInvalidServerResultTip" xml:space="preserve"> | ||||
|     <value>Removed {0} invalid test results.</value> | ||||
|   </data> | ||||
|   <data name="TbPorts7" xml:space="preserve"> | ||||
|     <value>Server port range</value> | ||||
|   </data> | ||||
|   <data name="TbPorts7Tips" xml:space="preserve"> | ||||
|     <value>Will cover the port, separate with commas (,)</value> | ||||
|   </data> | ||||
| </root> | ||||
|  | @ -1393,4 +1393,10 @@ | |||
|   <data name="RemoveInvalidServerResultTip" xml:space="preserve"> | ||||
|     <value>移除无效测试结果 {0} 个。</value> | ||||
|   </data> | ||||
|   <data name="TbPorts7" xml:space="preserve"> | ||||
|     <value>跳跃端口范围</value> | ||||
|   </data> | ||||
|   <data name="TbPorts7Tips" xml:space="preserve"> | ||||
|     <value>会覆盖端口,多组时用逗号(,)隔开</value> | ||||
|   </data> | ||||
| </root> | ||||
|  | @ -1394,4 +1394,10 @@ | |||
|   <data name="RemoveInvalidServerResultTip" xml:space="preserve"> | ||||
|     <value>移除無效測試結果 {0} 個。</value> | ||||
|   </data> | ||||
|   <data name="TbPorts7" xml:space="preserve"> | ||||
|     <value>跳躍端口範圍</value> | ||||
|   </data> | ||||
|   <data name="TbPorts7Tips" xml:space="preserve"> | ||||
|     <value>會覆蓋端口,多組時用逗號(,)隔開</value> | ||||
|   </data> | ||||
| </root> | ||||
|  | @ -730,6 +730,13 @@ namespace ServiceLib.Services.CoreConfig | |||
| 
 | ||||
|                             outbound.up_mbps = _config.HysteriaItem.UpMbps > 0 ? _config.HysteriaItem.UpMbps : null; | ||||
|                             outbound.down_mbps = _config.HysteriaItem.DownMbps > 0 ? _config.HysteriaItem.DownMbps : null; | ||||
|                             if (node.Ports.IsNotEmpty()) | ||||
|                             { | ||||
|                                 outbound.server_port = null; | ||||
|                                 outbound.server_ports = node.Ports.Split(",").ToList(); | ||||
|                                 outbound.hop_interval = _config.HysteriaItem.HopInterval > 0 ? $"{_config.HysteriaItem.HopInterval}s" : null; | ||||
|                             } | ||||
| 
 | ||||
|                             break; | ||||
|                         } | ||||
|                     case EConfigType.TUIC: | ||||
|  |  | |||
|  | @ -49,7 +49,7 @@ namespace v2rayN.Desktop.Handler | |||
|                 } | ||||
| 
 | ||||
|                 var vKey = KeyInterop.VirtualKeyFromKey((Key)item.KeyCode); | ||||
|                 var modifiers = Modifiers.NoRepeat; | ||||
|                 var modifiers = Modifiers.None; | ||||
|                 if (item.Control) | ||||
|                 { | ||||
|                     modifiers |= Modifiers.Control; | ||||
|  |  | |||
|  | @ -308,7 +308,7 @@ | |||
|                 <Grid | ||||
|                     x:Name="gridHysteria2" | ||||
|                     Grid.Row="2" | ||||
|                     ColumnDefinitions="180,Auto" | ||||
|                     ColumnDefinitions="180,Auto,Auto" | ||||
|                     IsVisible="False" | ||||
|                     RowDefinitions="Auto,Auto,Auto,Auto"> | ||||
| 
 | ||||
|  | @ -337,6 +337,25 @@ | |||
|                         Grid.Column="1" | ||||
|                         Width="400" | ||||
|                         Margin="{StaticResource Margin4}" /> | ||||
| 
 | ||||
|                     <TextBlock | ||||
|                         Grid.Row="3" | ||||
|                         Grid.Column="0" | ||||
|                         Margin="{StaticResource Margin4}" | ||||
|                         VerticalAlignment="Center" | ||||
|                         Text="{x:Static resx:ResUI.TbPorts7}" /> | ||||
|                     <TextBox | ||||
|                         x:Name="txtPorts7" | ||||
|                         Grid.Row="3" | ||||
|                         Grid.Column="1" | ||||
|                         Width="400" | ||||
|                         Margin="{StaticResource Margin4}" /> | ||||
|                     <TextBlock | ||||
|                         Grid.Row="3" | ||||
|                         Grid.Column="2" | ||||
|                         Margin="{StaticResource Margin4}" | ||||
|                         VerticalAlignment="Center" | ||||
|                         Text="{x:Static resx:ResUI.TbPorts7Tips}" /> | ||||
|                 </Grid> | ||||
|                 <Grid | ||||
|                     x:Name="gridTuic" | ||||
|  |  | |||
|  | @ -178,6 +178,7 @@ namespace v2rayN.Desktop.Views | |||
|                     case EConfigType.Hysteria2: | ||||
|                         this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId7.Text).DisposeWith(disposables); | ||||
|                         this.Bind(ViewModel, vm => vm.SelectedSource.Path, v => v.txtPath7.Text).DisposeWith(disposables); | ||||
|                         this.Bind(ViewModel, vm => vm.SelectedSource.Ports, v => v.txtPorts7.Text).DisposeWith(disposables); | ||||
|                         break; | ||||
| 
 | ||||
|                     case EConfigType.TUIC: | ||||
|  |  | |||
|  | @ -17,10 +17,11 @@ | |||
|             x:Name="txtContent" | ||||
|             Grid.Row="1" | ||||
|             Width="300" | ||||
|             MaxHeight="100" | ||||
|             Margin="{StaticResource MarginTb8}" | ||||
|             VerticalAlignment="Center" | ||||
|             IsReadOnly="True" | ||||
|             MaxLines="1" /> | ||||
|             TextWrapping="WrapWithOverflow" /> | ||||
| 
 | ||||
|     </Grid> | ||||
| </UserControl> | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| using Avalonia.Controls; | ||||
| using Avalonia.Media.Imaging; | ||||
| using Avalonia.Threading; | ||||
| 
 | ||||
| namespace v2rayN.Desktop.Views | ||||
| { | ||||
|  | @ -17,7 +18,7 @@ namespace v2rayN.Desktop.Views | |||
|             txtContent.Text = url; | ||||
|             imgQrcode.Source = GetQRCode(url); | ||||
| 
 | ||||
|             //  btnCancel.Click += (s, e) => this.Close(); | ||||
|             txtContent.GotFocus += (_, _) => Dispatcher.UIThread.Post(() => { txtContent.SelectAll(); }); | ||||
|         } | ||||
| 
 | ||||
|         private Bitmap? GetQRCode(string? url) | ||||
|  | @ -29,7 +30,9 @@ namespace v2rayN.Desktop.Views | |||
|         private Bitmap? ByteToBitmap(byte[]? bytes) | ||||
|         { | ||||
|             if (bytes is null) | ||||
|             { | ||||
|                 return null; | ||||
|             } | ||||
| 
 | ||||
|             using var ms = new MemoryStream(bytes); | ||||
|             return new Bitmap(ms); | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <reactiveui:ReactiveWindow | ||||
| <reactiveui:ReactiveWindow | ||||
|     x:Class="v2rayN.Views.AddServerWindow" | ||||
|     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||||
|     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||||
|  | @ -432,6 +432,7 @@ | |||
|                     <Grid.ColumnDefinitions> | ||||
|                         <ColumnDefinition Width="180" /> | ||||
|                         <ColumnDefinition Width="Auto" /> | ||||
|                         <ColumnDefinition Width="Auto" /> | ||||
|                     </Grid.ColumnDefinitions> | ||||
| 
 | ||||
|                     <TextBlock | ||||
|  | @ -463,6 +464,29 @@ | |||
|                         Width="400" | ||||
|                         Margin="{StaticResource Margin4}" | ||||
|                         Style="{StaticResource DefTextBox}" /> | ||||
| 
 | ||||
|                     <TextBlock | ||||
|                         Grid.Row="3" | ||||
|                         Grid.Column="0" | ||||
|                         Margin="{StaticResource Margin4}" | ||||
|                         VerticalAlignment="Center" | ||||
|                         Style="{StaticResource ToolbarTextBlock}" | ||||
|                         Text="{x:Static resx:ResUI.TbPorts7}" /> | ||||
|                     <TextBox | ||||
|                         x:Name="txtPorts7" | ||||
|                         Grid.Row="3" | ||||
|                         Grid.Column="1" | ||||
|                         Width="400" | ||||
|                         Margin="{StaticResource Margin4}" | ||||
|                         HorizontalAlignment="Left" | ||||
|                         Style="{StaticResource DefTextBox}" /> | ||||
|                     <TextBlock | ||||
|                         Grid.Row="3" | ||||
|                         Grid.Column="2" | ||||
|                         Margin="{StaticResource Margin4}" | ||||
|                         VerticalAlignment="Center" | ||||
|                         Style="{StaticResource ToolbarTextBlock}" | ||||
|                         Text="{x:Static resx:ResUI.TbPorts7Tips}" /> | ||||
|                 </Grid> | ||||
|                 <Grid | ||||
|                     x:Name="gridTuic" | ||||
|  |  | |||
|  | @ -172,6 +172,7 @@ namespace v2rayN.Views | |||
|                     case EConfigType.Hysteria2: | ||||
|                         this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId7.Text).DisposeWith(disposables); | ||||
|                         this.Bind(ViewModel, vm => vm.SelectedSource.Path, v => v.txtPath7.Text).DisposeWith(disposables); | ||||
|                         this.Bind(ViewModel, vm => vm.SelectedSource.Ports, v => v.txtPorts7.Text).DisposeWith(disposables); | ||||
|                         break; | ||||
| 
 | ||||
|                     case EConfigType.TUIC: | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue