diff --git a/Netch/3rd/NFSDK2/nfapinet.cs b/Netch/3rd/NFSDK2/nfapinet.cs index b19e1639..fcd5e029 100644 --- a/Netch/3rd/NFSDK2/nfapinet.cs +++ b/Netch/3rd/NFSDK2/nfapinet.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Runtime.InteropServices; @@ -14,34 +15,33 @@ namespace nfapinet public enum NF_DIRECTION { - NF_D_IN = 1, // Incoming TCP connection or UDP packet - NF_D_OUT = 2, // Outgoing TCP connection or UDP packet - NF_D_BOTH = 3 // Any direction + NF_D_IN = 1, // Incoming TCP connection or UDP packet + NF_D_OUT = 2, // Outgoing TCP connection or UDP packet + NF_D_BOTH = 3 // Any direction }; public enum NF_FILTERING_FLAG { - NF_ALLOW = 0, // Allow the activity without filtering transmitted packets - NF_BLOCK = 1, // Block the activity - NF_FILTER = 2, // Filter the transmitted packets - NF_SUSPENDED = 4, // Suspend receives from server and sends from client - NF_OFFLINE = 8, // Emulate establishing a TCP connection with remote server - NF_INDICATE_CONNECT_REQUESTS = 16, // Indicate outgoing connect requests to API + NF_ALLOW = 0, // Allow the activity without filtering transmitted packets + NF_BLOCK = 1, // Block the activity + NF_FILTER = 2, // Filter the transmitted packets + NF_SUSPENDED = 4, // Suspend receives from server and sends from client + NF_OFFLINE = 8, // Emulate establishing a TCP connection with remote server + NF_INDICATE_CONNECT_REQUESTS = 16, // Indicate outgoing connect requests to API NF_DISABLE_REDIRECT_PROTECTION = 32, // Disable blocking indicating connect requests for outgoing connections of local proxies - NF_PEND_CONNECT_REQUEST = 64, // Pend outgoing connect request to complete it later using nf_complete(TCP|UDP)ConnectRequest - NF_FILTER_AS_IP_PACKETS = 128, // Indicate the traffic as IP packets via ipSend/ipReceive - NF_READONLY = 256, // Don't block the IP packets and indicate them to ipSend/ipReceive only for monitoring - NF_CONTROL_FLOW = 512, // Use the flow limit rules even without NF_FILTER flag + NF_PEND_CONNECT_REQUEST = 64, // Pend outgoing connect request to complete it later using nf_complete(TCP|UDP)ConnectRequest + NF_FILTER_AS_IP_PACKETS = 128, // Indicate the traffic as IP packets via ipSend/ipReceive + NF_READONLY = 256, // Don't block the IP packets and indicate them to ipSend/ipReceive only for monitoring + NF_CONTROL_FLOW = 512, // Use the flow limit rules even without NF_FILTER flag }; public enum NF_FLAGS { NFF_NONE = 0, - NFF_DONT_DISABLE_TEREDO = 1, // Don't disable Teredo + NFF_DONT_DISABLE_TEREDO = 1, // Don't disable Teredo NFF_DONT_DISABLE_TCP_OFFLOADING = 2 // Don't disable TCP offloading }; - public enum NF_CONSTS { NF_MAX_ADDRESS_LENGTH = 28, @@ -61,30 +61,30 @@ namespace nfapinet [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct NF_RULE { - public int protocol; // IPPROTO_TCP or IPPROTO_UDP - public UInt32 processId; // Process identifier - public Byte direction; // See NF_DIRECTION - public ushort localPort; // Local port - public ushort remotePort; // Remote port - public ushort ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6 + public int protocol; // IPPROTO_TCP or IPPROTO_UDP + public UInt32 processId; // Process identifier + public Byte direction; // See NF_DIRECTION + public ushort localPort; // Local port + public ushort remotePort; // Remote port + public ushort ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6 // Local IP (or network if localIpAddressMask is not zero) - [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int) NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] public byte[] localIpAddress; // Local IP mask - [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int) NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] public byte[] localIpAddressMask; // Remote IP (or network if remoteIpAddressMask is not zero) - [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int) NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] public byte[] remoteIpAddress; // Remote IP mask - [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int) NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] public byte[] remoteIpAddressMask; - public UInt32 filteringFlag; // See NF_FILTERING_FLAG + public UInt32 filteringFlag; // See NF_FILTERING_FLAG }; /** @@ -93,30 +93,30 @@ namespace nfapinet [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)] public struct NF_RULE_EX { - public int protocol; // IPPROTO_TCP or IPPROTO_UDP - public UInt32 processId; // Process identifier - public Byte direction; // See NF_DIRECTION - public ushort localPort; // Local port - public ushort remotePort; // Remote port - public ushort ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6 + public int protocol; // IPPROTO_TCP or IPPROTO_UDP + public UInt32 processId; // Process identifier + public Byte direction; // See NF_DIRECTION + public ushort localPort; // Local port + public ushort remotePort; // Remote port + public ushort ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6 // Local IP (or network if localIpAddressMask is not zero) - [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int) NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] public byte[] localIpAddress; // Local IP mask - [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int) NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] public byte[] localIpAddressMask; // Remote IP (or network if remoteIpAddressMask is not zero) - [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int) NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] public byte[] remoteIpAddress; // Remote IP mask - [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int) NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] public byte[] remoteIpAddressMask; - public UInt32 filteringFlag; // See NF_FILTERING_FLAG + public UInt32 filteringFlag; // See NF_FILTERING_FLAG // Tail part of the process path mask [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] @@ -129,17 +129,17 @@ namespace nfapinet [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct NF_TCP_CONN_INFO { - public UInt32 filteringFlag; // See NF_FILTERING_FLAG - public UInt32 processId; // Process identifier - public Byte direction; // See NF_DIRECTION - public ushort ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6 + public UInt32 filteringFlag; // See NF_FILTERING_FLAG + public UInt32 processId; // Process identifier + public Byte direction; // See NF_DIRECTION + public ushort ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6 // Local address as sockaddr_in for IPv4 and sockaddr_in6 for IPv6 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_ADDRESS_LENGTH)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int) NF_CONSTS.NF_MAX_ADDRESS_LENGTH)] public byte[] localAddress; // Remote address as sockaddr_in for IPv4 and sockaddr_in6 for IPv6 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_ADDRESS_LENGTH)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int) NF_CONSTS.NF_MAX_ADDRESS_LENGTH)] public byte[] remoteAddress; }; @@ -149,11 +149,11 @@ namespace nfapinet [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct NF_UDP_CONN_INFO { - public UInt32 processId; // Process identifier - public ushort ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6 + public UInt32 processId; // Process identifier + public ushort ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6 // Local address as sockaddr_in for IPv4 and sockaddr_in6 for IPv6 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_ADDRESS_LENGTH)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int) NF_CONSTS.NF_MAX_ADDRESS_LENGTH)] public byte[] localAddress; }; @@ -175,35 +175,35 @@ namespace nfapinet [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct NF_UDP_CONN_REQUEST { - public UInt32 filteringFlag; // See NF_FILTERING_FLAG - public UInt32 processId; // Process identifier - public ushort ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6 + public UInt32 filteringFlag; // See NF_FILTERING_FLAG + public UInt32 processId; // Process identifier + public ushort ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6 // Local address as sockaddr_in for IPv4 and sockaddr_in6 for IPv6 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_ADDRESS_LENGTH)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int) NF_CONSTS.NF_MAX_ADDRESS_LENGTH)] public byte[] localAddress; // Remote address as sockaddr_in for IPv4 and sockaddr_in6 for IPv6 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_ADDRESS_LENGTH)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int) NF_CONSTS.NF_MAX_ADDRESS_LENGTH)] public byte[] remoteAddress; }; public enum NF_IP_FLAG { - NFIF_NONE = 0, // No flags - NFIF_READONLY = 1, // The packet was not blocked and indicated only for monitoring in read-only mode - // (see NF_READ_ONLY flags from NF_FILTERING_FLAG). + NFIF_NONE = 0, // No flags + NFIF_READONLY = 1, // The packet was not blocked and indicated only for monitoring in read-only mode + // (see NF_READ_ONLY flags from NF_FILTERING_FLAG). }; [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct NF_IP_PACKET_OPTIONS { - public ushort ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6 - public UInt32 ipHeaderSize; // Size in bytes of IP header - public UInt32 compartmentId; // Network routing compartment identifier (can be zero) - public UInt32 interfaceIndex; // Index of the interface on which the original packet data was received (irrelevant to outgoing packets) - public UInt32 subInterfaceIndex; // Index of the subinterface on which the original packet data was received (irrelevant to outgoing packets) - public UInt32 flags; // Can be a combination of flags from NF_IP_FLAG enumeration + public ushort ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6 + public UInt32 ipHeaderSize; // Size in bytes of IP header + public UInt32 compartmentId; // Network routing compartment identifier (can be zero) + public UInt32 interfaceIndex; // Index of the interface on which the original packet data was received (irrelevant to outgoing packets) + public UInt32 subInterfaceIndex; // Index of the subinterface on which the original packet data was received (irrelevant to outgoing packets) + public UInt32 flags; // Can be a combination of flags from NF_IP_FLAG enumeration }; [StructLayout(LayoutKind.Sequential, Pack = 1)] @@ -257,15 +257,15 @@ namespace nfapinet public ushort ip_family; // Local IP (or network if localIpAddressMask is not zero) - [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int) NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] public byte[] localIpAddress; // Local IP mask - [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int) NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] public byte[] localIpAddressMask; // Redirect bind request to this IP - [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int) NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)] public byte[] newLocalIpAddress; // Redirect bind request to this port, if it is not zero @@ -277,38 +277,55 @@ namespace nfapinet [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void cbd_threadStart(); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void cbd_threadEnd(); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void cbd_tcpConnectRequest(ulong id, ref NF_TCP_CONN_INFO pConnInfo); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void cbd_tcpConnected(ulong id, ref NF_TCP_CONN_INFO pConnInfo); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void cbd_tcpClosed(ulong id, ref NF_TCP_CONN_INFO pConnInfo); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void cbd_tcpReceive(ulong id, IntPtr buf, int len); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void cbd_tcpSend(ulong id, IntPtr buf, int len); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void cbd_tcpCanReceive(ulong id); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void cbd_tcpCanSend(ulong id); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void cbd_udpCreated(ulong id, ref NF_UDP_CONN_INFO pConnInfo); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void cbd_udpConnectRequest(ulong id, ref NF_UDP_CONN_REQUEST pConnReq); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void cbd_udpClosed(ulong id, ref NF_UDP_CONN_INFO pConnInfo); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void cbd_udpReceive(ulong id, IntPtr remoteAddress, IntPtr buf, int len, IntPtr options); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void cbd_udpSend(ulong id, IntPtr remoteAddress, IntPtr buf, int len, IntPtr options); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void cbd_udpCanReceive(ulong id); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void cbd_udpCanSend(ulong id); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void cbd_ipReceive(IntPtr buf, int len, ref NF_IP_PACKET_OPTIONS ipOptions); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void cbd_ipSend(IntPtr buf, int len, ref NF_IP_PACKET_OPTIONS ipOptions); @@ -355,80 +372,95 @@ namespace nfapinet { m_pEventHandler.threadStart(); } + public static void threadEnd() { m_pEventHandler.threadEnd(); } + public static void tcpConnectRequest(ulong id, ref NF_TCP_CONN_INFO pConnInfo) { m_pEventHandler.tcpConnectRequest(id, ref pConnInfo); } + public static void tcpConnected(ulong id, ref NF_TCP_CONN_INFO pConnInfo) { m_pEventHandler.tcpConnected(id, pConnInfo); } + public static void tcpClosed(ulong id, ref NF_TCP_CONN_INFO pConnInfo) { m_pEventHandler.tcpClosed(id, pConnInfo); } + public static void tcpReceive(ulong id, IntPtr buf, int len) { m_pEventHandler.tcpReceive(id, buf, len); } + public static void tcpSend(ulong id, IntPtr buf, int len) { m_pEventHandler.tcpSend(id, buf, len); } + public static void tcpCanReceive(ulong id) { m_pEventHandler.tcpCanReceive(id); } + public static void tcpCanSend(ulong id) { m_pEventHandler.tcpCanSend(id); } + public static void udpCreated(ulong id, ref NF_UDP_CONN_INFO pConnInfo) { m_pEventHandler.udpCreated(id, pConnInfo); } + public static void udpConnectRequest(ulong id, ref NF_UDP_CONN_REQUEST pConnReq) { m_pEventHandler.udpConnectRequest(id, ref pConnReq); } + public static void udpClosed(ulong id, ref NF_UDP_CONN_INFO pConnInfo) { m_pEventHandler.udpClosed(id, pConnInfo); } + public static void udpReceive(ulong id, IntPtr remoteAddress, IntPtr buf, int len, IntPtr options) { if (options.ToInt64() != 0) { - NF_UDP_OPTIONS optionsCopy = (NF_UDP_OPTIONS)Marshal.PtrToStructure((IntPtr)options, typeof(NF_UDP_OPTIONS)); + NF_UDP_OPTIONS optionsCopy = (NF_UDP_OPTIONS) Marshal.PtrToStructure((IntPtr) options, typeof(NF_UDP_OPTIONS)); int optionsLen = 8 + optionsCopy.optionsLength; m_pEventHandler.udpReceive(id, remoteAddress, buf, len, options, optionsLen); } else { - m_pEventHandler.udpReceive(id, remoteAddress, buf, len, (IntPtr)null, 0); + m_pEventHandler.udpReceive(id, remoteAddress, buf, len, (IntPtr) null, 0); } } + public static void udpSend(ulong id, IntPtr remoteAddress, IntPtr buf, int len, IntPtr options) { if (options.ToInt64() != 0) { - NF_UDP_OPTIONS optionsCopy = (NF_UDP_OPTIONS)Marshal.PtrToStructure((IntPtr)options, typeof(NF_UDP_OPTIONS)); + NF_UDP_OPTIONS optionsCopy = (NF_UDP_OPTIONS) Marshal.PtrToStructure((IntPtr) options, typeof(NF_UDP_OPTIONS)); int optionsLen = 8 + optionsCopy.optionsLength; m_pEventHandler.udpSend(id, remoteAddress, buf, len, options, optionsLen); } else { - m_pEventHandler.udpSend(id, remoteAddress, buf, len, (IntPtr)null, 0); + m_pEventHandler.udpSend(id, remoteAddress, buf, len, (IntPtr) null, 0); } } + public static void udpCanReceive(ulong id) { m_pEventHandler.udpCanReceive(id); } + public static void udpCanSend(ulong id) { m_pEventHandler.udpCanSend(id); @@ -446,6 +478,7 @@ namespace nfapinet { m_pEventHandler.ipReceive(buf, len, ref ipOptions); } + public static void ipSend(IntPtr buf, int len, ref NF_IP_PACKET_OPTIONS ipOptions) { m_pEventHandler.ipSend(buf, len, ref ipOptions); @@ -489,9 +522,9 @@ namespace nfapinet // Managed wrapper over API public class NFAPI { - private static IntPtr m_pEventHandlerRaw = (IntPtr)null; + private static IntPtr m_pEventHandlerRaw = (IntPtr) null; private static NF_EventHandlerInternal m_pEventHandler; - private static IntPtr m_pIPEventHandlerRaw = (IntPtr)null; + private static IntPtr m_pIPEventHandlerRaw = (IntPtr) null; private static NF_IPEventHandlerInternal m_pIPEventHandler; /** @@ -554,7 +587,6 @@ namespace nfapinet [DllImport("bin\\nfapinet", CallingConvention = CallingConvention.Cdecl)] public static extern NF_STATUS nf_unRegisterDriver(String driverName); - // // TCP control routines // @@ -612,10 +644,7 @@ namespace nfapinet * @param len Buffer length **/ [DllImport("bin\\nfapinet", CallingConvention = CallingConvention.Cdecl)] - public static extern NF_STATUS nf_udpPostSend(ulong id, - IntPtr remoteAddress, - IntPtr buf, int len, - IntPtr options); + public static extern NF_STATUS nf_udpPostSend(ulong id, IntPtr remoteAddress, IntPtr buf, int len, IntPtr options); /** * Indicates the buffer to local process via specified socket. @@ -625,10 +654,7 @@ namespace nfapinet * @param len Buffer length **/ [DllImport("bin\\nfapinet", CallingConvention = CallingConvention.Cdecl)] - public static extern NF_STATUS nf_udpPostReceive(ulong id, - IntPtr remoteAddress, - IntPtr buf, int len, - IntPtr options); + public static extern NF_STATUS nf_udpPostReceive(ulong id, IntPtr remoteAddress, IntPtr buf, int len, IntPtr options); /** * Indicates a packet to TCP/IP stack @@ -637,9 +663,7 @@ namespace nfapinet * @param options IP options **/ [DllImport("bin\\nfapinet", CallingConvention = CallingConvention.Cdecl)] - public static extern NF_STATUS nf_ipPostReceive( - IntPtr buf, int len, - ref NF_IP_PACKET_OPTIONS options); + public static extern NF_STATUS nf_ipPostReceive(IntPtr buf, int len, ref NF_IP_PACKET_OPTIONS options); /** * Sends a packet to remote IP @@ -648,9 +672,7 @@ namespace nfapinet * @param options IP options **/ [DllImport("bin\\nfapinet", CallingConvention = CallingConvention.Cdecl)] - public static extern NF_STATUS nf_ipPostSend( - IntPtr buf, int len, - ref NF_IP_PACKET_OPTIONS options); + public static extern NF_STATUS nf_ipPostSend(IntPtr buf, int len, ref NF_IP_PACKET_OPTIONS options); // // Filtering rules @@ -668,13 +690,13 @@ namespace nfapinet { if (buf == null) { - buf = new byte[(int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH]; + buf = new byte[(int) NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH]; } else { - if (buf.Length < (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH) + if (buf.Length < (int) NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH) { - Array.Resize(ref buf, (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH); + Array.Resize(ref buf, (int) NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH); } } } @@ -853,9 +875,9 @@ namespace nfapinet fixed (char* p = buf) { - if (nf_getProcessNameFromKernel(processId, (IntPtr)p, buf.Length)) + if (nf_getProcessNameFromKernel(processId, (IntPtr) p, buf.Length)) { - return Marshal.PtrToStringUni((IntPtr)p); + return Marshal.PtrToStringUni((IntPtr) p); } } @@ -871,9 +893,9 @@ namespace nfapinet fixed (char* p = buf) { - if (nf_getProcessNameW(processId, (IntPtr)p, buf.Length)) + if (nf_getProcessNameW(processId, (IntPtr) p, buf.Length)) { - return Marshal.PtrToStringUni((IntPtr)p); + return Marshal.PtrToStringUni((IntPtr) p); } } @@ -983,11 +1005,9 @@ namespace nfapinet * Add binding rule to driver */ [DllImport("bin\\nfapinet", CallingConvention = CallingConvention.Cdecl)] - private static extern NF_STATUS - nf_addBindingRule(ref NF_BINDING_RULE pRule, int toHead); + private static extern NF_STATUS nf_addBindingRule(ref NF_BINDING_RULE pRule, int toHead); - public static NF_STATUS - nf_addBindingRule(NF_BINDING_RULE pRule, int toHead) + public static NF_STATUS nf_addBindingRule(NF_BINDING_RULE pRule, int toHead) { updateAddressLength(ref pRule.localIpAddress); updateAddressLength(ref pRule.localIpAddressMask); @@ -1000,15 +1020,12 @@ namespace nfapinet * Delete all binding rules from driver */ [DllImport("bin\\nfapinet", CallingConvention = CallingConvention.Cdecl)] - public static extern NF_STATUS - nf_deleteBindingRules(); + public static extern NF_STATUS nf_deleteBindingRules(); /** * Returns the type of attached driver (DT_WFP, DT_TDI or DT_UNKNOWN) */ [DllImport("bin\\nfapinet", CallingConvention = CallingConvention.Cdecl)] - public static extern UInt32 - nf_getDriverType(); + public static extern UInt32 nf_getDriverType(); }; - -} +} \ No newline at end of file diff --git a/Netch/Controllers/DNSController.cs b/Netch/Controllers/DNSController.cs index ccf59a7a..62fa6a89 100644 --- a/Netch/Controllers/DNSController.cs +++ b/Netch/Controllers/DNSController.cs @@ -34,7 +34,7 @@ namespace Netch.Controllers #region NativeMethods [DllImport("aiodns.bin", CallingConvention = CallingConvention.Cdecl)] - public static extern bool aiodns_dial(int name, byte[] value); + public static extern bool aiodns_dial(int name, byte[]? value); [DllImport("aiodns.bin", CallingConvention = CallingConvention.Cdecl)] public static extern bool aiodns_init(); diff --git a/Netch/Controllers/Guard.cs b/Netch/Controllers/Guard.cs index 22d6e36d..78633713 100644 --- a/Netch/Controllers/Guard.cs +++ b/Netch/Controllers/Guard.cs @@ -16,31 +16,32 @@ namespace Netch.Controllers public abstract class Guard { private readonly Timer _flushFileStreamTimer = new(300) {AutoReset = true}; - private FileStream _logFileStream; /// /// 日志文件(重定向输出文件) /// - private string _logPath; + private string LogPath => Path.Combine(Global.NetchDir, $"logging\\{Name}.log"); - private StreamWriter _logStreamWriter; + private FileStream? _logFileStream; + + private StreamWriter? _logStreamWriter; /// /// 成功启动关键词 /// - protected virtual IEnumerable StartedKeywords { get; } = null; + protected virtual IEnumerable StartedKeywords { get; } = new List(); /// /// 启动失败关键词 /// - protected virtual IEnumerable StoppedKeywords { get; } = null; + protected virtual IEnumerable StoppedKeywords { get; } = new List(); - public virtual string Name { get; } + public abstract string Name { get; } /// /// 主程序名 /// - public virtual string MainFile { get; protected set; } + public abstract string MainFile { get; protected set; } protected State State { get; set; } = State.Waiting; @@ -52,13 +53,12 @@ namespace Netch.Controllers /// /// 进程实例 /// - public Process Instance { get; private set; } + public Process? Instance { get; private set; } /// /// 程序输出的编码, - /// 调用于基类的 /// - protected virtual Encoding InstanceOutputEncoding { get; } = null; + protected virtual Encoding? InstanceOutputEncoding { get; } = null; public abstract void Stop(); @@ -120,12 +120,11 @@ namespace Netch.Controllers State = State.Starting; // 初始化程序 InitInstance(argument); - Instance.EnableRaisingEvents = true; + Instance!.EnableRaisingEvents = true; if (RedirectStd) { // 清理日志 - _logPath ??= Path.Combine(Global.NetchDir, $"logging\\{Name}.log"); - _logFileStream = File.Open(_logPath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read); + _logFileStream = File.Open(LogPath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read); _logStreamWriter = new StreamWriter(_logFileStream); } @@ -149,7 +148,7 @@ namespace Netch.Controllers // 启动日志重定向 _flushFileStreamTimer.Elapsed += FlushFileStreamTimerEvent; _flushFileStreamTimer.Enabled = true; - if (!(StartedKeywords?.Any() ?? false)) + if (!StartedKeywords.Any()) { State = State.Started; return; @@ -165,7 +164,7 @@ namespace Netch.Controllers return; case State.Stopped: Stop(); - Utils.Utils.Open(_logPath); + Utils.Utils.Open(LogPath); throw new MessageException($"{Name} 控制器启动失败"); } } @@ -176,20 +175,15 @@ namespace Netch.Controllers private void OnExited(object sender, EventArgs e) { - if (RedirectStd) - _flushFileStreamTimer.Enabled = false; - - _logStreamWriter?.Close(); - State = State.Stopped; } protected void ReadOutput(TextReader reader) { - string line; + string? line; while ((line = reader.ReadLine()) != null) { - Write(line); + _logStreamWriter!.WriteLine(line); // 检查启动 if (State == State.Starting) @@ -200,6 +194,11 @@ namespace Netch.Controllers State = State.Stopped; } } + + _flushFileStreamTimer.Enabled = false; + _logStreamWriter!.Close(); + _logFileStream!.Close(); + _logStreamWriter = _logStreamWriter = null; } /// @@ -211,22 +210,12 @@ namespace Netch.Controllers { try { - _logStreamWriter.Flush(); + _logStreamWriter!.Flush(); } catch (Exception exception) { Logging.Warning($"写入 {Name} 日志错误:\n" + exception.Message); } } - - /// - /// 写入日志文件缓冲 - /// - /// - /// 转码后的字符串 - private void Write(string info) - { - _logStreamWriter.WriteLine(info); - } } } \ No newline at end of file diff --git a/Netch/Controllers/HTTPController.cs b/Netch/Controllers/HTTPController.cs index 890cd1c1..40c0f27e 100644 --- a/Netch/Controllers/HTTPController.cs +++ b/Netch/Controllers/HTTPController.cs @@ -12,9 +12,9 @@ namespace Netch.Controllers { public class HTTPController : IModeController { - public PrivoxyController pPrivoxyController = new(); + public readonly PrivoxyController PrivoxyController = new(); - private string prevBypass, prevHTTP, prevPAC; + private string prevBypass = "", prevHTTP = "", prevPAC = ""; private bool prevEnabled; public string Name { get; } = "HTTP"; @@ -28,8 +28,8 @@ namespace Netch.Controllers { RecordPrevious(); - pPrivoxyController.Start(MainController.Server); - Global.Job.AddProcess(pPrivoxyController.Instance); + PrivoxyController.Start(MainController.Server!); + Global.Job.AddProcess(PrivoxyController.Instance!); if (mode.Type == 3) { @@ -58,7 +58,7 @@ namespace Netch.Controllers { var tasks = new[] { - Task.Run(pPrivoxyController.Stop), + Task.Run(PrivoxyController.Stop), Task.Run(() => { using var service = new ProxyService(); diff --git a/Netch/Controllers/IServerController.cs b/Netch/Controllers/IServerController.cs index 8b135026..93c9b34f 100644 --- a/Netch/Controllers/IServerController.cs +++ b/Netch/Controllers/IServerController.cs @@ -6,7 +6,7 @@ namespace Netch.Controllers { public ushort? Socks5LocalPort { get; set; } - public string LocalAddress { get; set; } + public string? LocalAddress { get; set; } /// /// 启动 diff --git a/Netch/Controllers/MainController.cs b/Netch/Controllers/MainController.cs index a8dafebe..9658ac20 100644 --- a/Netch/Controllers/MainController.cs +++ b/Netch/Controllers/MainController.cs @@ -12,36 +12,36 @@ namespace Netch.Controllers { public static class MainController { - public static Mode Mode; + public static Mode? Mode; /// TCP or Both Server - public static Server Server; + public static Server? Server; - private static Server _udpServer; + private static Server? _udpServer; public static readonly NTTController NTTController = new(); - private static IServerController _serverController; - private static IServerController _udpServerController; + private static IServerController? _serverController; + private static IServerController? _udpServerController; - public static IServerController ServerController + public static IServerController? ServerController { get => _serverController; private set => _serverController = value; } - public static IServerController UdpServerController + public static IServerController? UdpServerController { get => _udpServerController ?? _serverController; set => _udpServerController = value; } - public static Server UdpServer + public static Server? UdpServer { get => _udpServer ?? Server; set => _udpServer = value; } - public static IModeController ModeController { get; private set; } + public static IModeController? ModeController { get; private set; } /// /// 启动 @@ -130,7 +130,7 @@ namespace Netch.Controllers Task.Run(() => { Thread.Sleep(1000); - Global.Job.AddProcess(guard.Instance); + Global.Job.AddProcess(guard.Instance!); }); if (server is Socks5 socks5) @@ -158,7 +158,7 @@ namespace Netch.Controllers ModeController.Start(mode); if (ModeController is Guard {Instance: { }} guard) - Global.Job.AddProcess(guard.Instance); + Global.Job.AddProcess(guard.Instance!); } /// @@ -166,6 +166,9 @@ namespace Netch.Controllers /// public static async Task Stop() { + if (_serverController == null && ModeController == null) + return; + StatusPortInfoText.Reset(); _ = Task.Run(() => NTTController.Stop()); diff --git a/Netch/Controllers/NFController.cs b/Netch/Controllers/NFController.cs index 4c89dde8..6273c469 100644 --- a/Netch/Controllers/NFController.cs +++ b/Netch/Controllers/NFController.cs @@ -20,7 +20,7 @@ namespace Netch.Controllers private static readonly string BinDriver = string.Empty; private static readonly string SystemDriver = $"{Environment.SystemDirectory}\\drivers\\netfilter2.sys"; - private static string _sysDns; + private static string _sysDns = string.Empty; static NFController() { @@ -204,14 +204,14 @@ namespace Netch.Controllers if (portType == PortType.UDP) { offset = UdpNameListOffset; - server = MainController.UdpServer; - controller = MainController.UdpServerController; + server = MainController.UdpServer!; + controller = MainController.UdpServerController!; } else { offset = 0; - server = MainController.Server; - controller = MainController.ServerController; + server = MainController.Server!; + controller = MainController.ServerController!; } if (server is Socks5 socks5) diff --git a/Netch/Controllers/NTTController.cs b/Netch/Controllers/NTTController.cs index 6814142f..a09689da 100644 --- a/Netch/Controllers/NTTController.cs +++ b/Netch/Controllers/NTTController.cs @@ -21,17 +21,14 @@ namespace Netch.Controllers /// 启动 NatTypeTester /// /// - public async Task<(string, string, string)> Start() + public async Task<(string?, string?, string?)> Start() { - string localEnd = null; - string publicEnd = null; - string result = null; - string bindingTest = null; + string? localEnd = null, publicEnd = null, result = null, bindingTest = null; try { InitInstance($" {Global.Settings.STUN_Server} {Global.Settings.STUN_Server_Port}"); - Instance.Start(); + Instance!.Start(); var output = await Instance.StandardOutput.ReadToEndAsync(); var error = await Instance.StandardError.ReadToEndAsync(); diff --git a/Netch/Controllers/TUNTAPController.cs b/Netch/Controllers/TUNTAPController.cs index 9da5d402..b960f18b 100644 --- a/Netch/Controllers/TUNTAPController.cs +++ b/Netch/Controllers/TUNTAPController.cs @@ -21,7 +21,7 @@ namespace Netch.Controllers /// /// 服务器 IP 地址 /// - private IPAddress _serverAddresses; + private IPAddress? _serverAddresses; /// /// 本地 DNS 服务控制器 @@ -40,9 +40,9 @@ namespace Netch.Controllers public void Start(in Mode mode) { - var server = MainController.Server; + var server = MainController.Server!; // 查询服务器 IP 地址 - _serverAddresses = DNS.Lookup(server.Hostname); + _serverAddresses = DNS.Lookup(server.Hostname)!; // 查找出口适配器 Utils.Utils.SearchOutboundAdapter(); @@ -178,7 +178,7 @@ namespace Netch.Controllers #endregion Logging.Info("绕行 → 服务器 IP"); - if (!IPAddress.IsLoopback(_serverAddresses)) + if (!IPAddress.IsLoopback(_serverAddresses!)) RouteAction(Action.Create, $"{_serverAddresses}/32", RouteType.Outbound); Logging.Info("绕行 → 全局绕过 IP"); @@ -209,7 +209,7 @@ namespace Netch.Controllers try { InitInstance("-h"); - Instance.Start(); + Instance!.Start(); return Instance.StandardError.ReadToEnd().Contains("-fakeDns"); } catch @@ -270,7 +270,7 @@ namespace Netch.Controllers switch (routeType) { case RouteType.Outbound: - gateway = Global.Outbound.Gateway.ToString(); + gateway = Global.Outbound.Gateway!.ToString(); index = Global.Outbound.Index; break; case RouteType.TUNTAP: diff --git a/Netch/Controllers/UpdateChecker.cs b/Netch/Controllers/UpdateChecker.cs index 965dfea7..4a48994c 100644 --- a/Netch/Controllers/UpdateChecker.cs +++ b/Netch/Controllers/UpdateChecker.cs @@ -24,15 +24,15 @@ namespace Netch.Controllers public static readonly string Version = $"{AssemblyVersion}{(string.IsNullOrEmpty(Suffix) ? "" : $"-{Suffix}")}"; - public static string LatestVersionNumber; - public static string LatestVersionUrl; - public static Release LatestRelease; + public static string? LatestVersionNumber; + public static string? LatestVersionUrl; + public static Release? LatestRelease; - public static event EventHandler NewVersionFound; + public static event EventHandler? NewVersionFound; - public static event EventHandler NewVersionFoundFailed; + public static event EventHandler? NewVersionFoundFailed; - public static event EventHandler NewVersionNotFound; + public static event EventHandler? NewVersionNotFound; public static async void Check(bool isPreRelease) { @@ -74,13 +74,13 @@ namespace Netch.Controllers { using WebClient client = new(); - var latestVersionDownloadUrl = LatestRelease.assets[0].browser_download_url; - var tagPage = await client.DownloadStringTaskAsync(LatestVersionUrl); + var latestVersionDownloadUrl = LatestRelease!.assets[0].browser_download_url; + var tagPage = await client.DownloadStringTaskAsync(LatestVersionUrl!); var match = Regex.Match(tagPage, @"(?.*)", RegexOptions.Singleline); // TODO Replace with regex get basename and sha256 var fileName = Path.GetFileName(new Uri(latestVersionDownloadUrl).LocalPath); - fileName = fileName.Insert(fileName.LastIndexOf('.'), LatestVersionNumber); + fileName = fileName.Insert(fileName.LastIndexOf('.'), LatestVersionNumber!); var fileFullPath = Path.Combine(Global.NetchDir, "data", fileName); var sha256 = match.Groups["sha256"].Value; diff --git a/Netch/Forms/GlobalBypassIPForm.cs b/Netch/Forms/GlobalBypassIPForm.cs index fd44f5cb..5baa2d78 100644 --- a/Netch/Forms/GlobalBypassIPForm.cs +++ b/Netch/Forms/GlobalBypassIPForm.cs @@ -53,7 +53,7 @@ namespace Netch.Forms { Global.Settings.BypassIPs.Clear(); foreach (var ip in IPListBox.Items) - Global.Settings.BypassIPs.Add(ip as string); + Global.Settings.BypassIPs.Add((string) ip); Configuration.Save(); MessageBoxX.Show(i18N.Translate("Saved")); diff --git a/Netch/Forms/MainForm.cs b/Netch/Forms/MainForm.cs index da3e1cc0..d726cda3 100644 --- a/Netch/Forms/MainForm.cs +++ b/Netch/Forms/MainForm.cs @@ -50,7 +50,7 @@ namespace Netch.Forms // 监听电源事件 SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; - ModeComboBox.KeyUp += (sender, args) => + ModeComboBox.KeyUp += (_, args) => { switch (args.KeyData) { @@ -149,8 +149,8 @@ namespace Netch.Forms { switch (component) { - case TextBoxBase _: - case ListControl _: + case TextBoxBase: + case ListControl: break; case Control c: _mainFormText.Add(c.Name, c.Text); @@ -179,8 +179,8 @@ namespace Netch.Forms { switch (component) { - case TextBoxBase _: - case ListControl _: + case TextBoxBase: + case ListControl: break; case Control c: if (_mainFormText.ContainsKey(c.Name)) @@ -201,7 +201,7 @@ namespace Netch.Forms return string.Empty; if (value is object[] values) - return i18N.TranslateFormat(values.First() as string, values.Skip(1).ToArray()); + return i18N.TranslateFormat((string) values.First(), values.Skip(1).ToArray()); return i18N.Translate(value); } @@ -316,10 +316,14 @@ namespace Netch.Forms MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ProfileGroupBox.Enabled = ControlButton.Enabled = v; } - if (useProxy && ServerComboBox.SelectedIndex == -1) + var server = ServerComboBox.SelectedItem as Server; + if (useProxy) { - MessageBoxX.Show(i18N.Translate("Please select a server first")); - return; + if (server == null) + { + MessageBoxX.Show(i18N.Translate("Please select a server first")); + return; + } } if (Global.Settings.SubscribeLink.Count <= 0) @@ -332,7 +336,7 @@ namespace Netch.Forms DisableItems(false); try { - string proxyServer = null; + string? proxyServer = null; if (useProxy) { var mode = new Models.Mode @@ -341,7 +345,7 @@ namespace Netch.Forms Type = 5 }; - await MainController.Start(ServerComboBox.SelectedItem as Server, mode); + await MainController.Start(server!, mode); proxyServer = $"http://127.0.0.1:{Global.Settings.HTTPLocalPort}"; } @@ -437,25 +441,27 @@ namespace Netch.Forms private async void UpdateACL(bool useProxy) { - if (useProxy && ServerComboBox.SelectedIndex == -1) - { - MessageBoxX.Show(i18N.Translate("Please select a server first")); - return; - } - Enabled = false; StatusText(i18N.TranslateFormat("Updating {0}", "ACL")); try { if (useProxy) { - var mode = new Models.Mode + if (!(ServerComboBox.SelectedItem is Server server)) { - Remark = "ProxyUpdate", - Type = 5 - }; + MessageBoxX.Show(i18N.Translate("Please select a server first")); + return; + } + else + { + var mode = new Models.Mode + { + Remark = "ProxyUpdate", + Type = 5 + }; - await MainController.Start(ServerComboBox.SelectedItem as Server, mode); + await MainController.Start(server, mode); + } } var req = WebUtil.CreateRequest(Global.Settings.ACL); @@ -582,7 +588,7 @@ namespace Netch.Forms #region ControlButton - private async void ControlButton_Click(object sender, EventArgs e) + private async void ControlButton_Click(object? sender, EventArgs? e) { if (!IsWaiting()) { @@ -795,13 +801,13 @@ namespace Netch.Forms private void DeleteServerPictureBox_Click(object sender, EventArgs e) { // 当前 ServerComboBox 中至少有一项 - if (ServerComboBox.SelectedIndex == -1) + if (!(ServerComboBox.SelectedItem is Server server)) { MessageBoxX.Show(i18N.Translate("Please select a server first")); return; } - Global.Settings.Server.Remove(ServerComboBox.SelectedItem as Server); + Global.Settings.Server.Remove(server); LoadServers(); } @@ -860,7 +866,7 @@ namespace Netch.Forms var mode = (Models.Mode) ModeComboBox.SelectedItem; if (ModifierKeys == Keys.Control) { - Utils.Utils.Open(ModeHelper.GetFullPath(mode.RelativePath)); + Utils.Utils.Open(ModeHelper.GetFullPath(mode.RelativePath!)); return; } @@ -878,7 +884,7 @@ namespace Netch.Forms Show(); break; default: - Utils.Utils.Open(ModeHelper.GetFullPath(mode.RelativePath)); + Utils.Utils.Open(ModeHelper.GetFullPath(mode.RelativePath!)); break; } } @@ -989,7 +995,7 @@ namespace Netch.Forms var mode = (Models.Mode) ModeComboBox.SelectedItem; var name = ProfileNameText.Text; - Profile profile; + Profile? profile; if ((profile = Global.Settings.Profiles.SingleOrDefault(p => p.Index == index)) != null) Global.Settings.Profiles.Remove(profile); @@ -1001,7 +1007,7 @@ namespace Netch.Forms private async void ProfileButton_Click(object sender, EventArgs e) { var profileButton = (Button) sender; - var profile = (Profile) profileButton.Tag; + var profile = (Profile?) profileButton.Tag; var index = ProfileTable.Controls.IndexOf(profileButton); switch (ModifierKeys) @@ -1156,7 +1162,7 @@ namespace Netch.Forms /// 更新状态栏文本 /// /// - public void StatusText(string text = null) + public void StatusText(string? text = null) { if (InvokeRequired) { @@ -1184,7 +1190,7 @@ namespace Netch.Forms UsedBandwidthLabel.Visible /*= UploadSpeedLabel.Visible*/ = DownloadSpeedLabel.Visible = state; } - public void NatTypeStatusText(string text = "", string country = "") + public void NatTypeStatusText(string? text = null, string? country = null) { if (InvokeRequired) { @@ -1201,7 +1207,7 @@ namespace Netch.Forms if (!string.IsNullOrEmpty(text)) { - NatTypeStatusLabel.Text = $"NAT{i18N.Translate(": ")}{text} {(country != string.Empty ? $"[{country}]" : "")}"; + NatTypeStatusLabel.Text = $"NAT{i18N.Translate(": ")}{text} {(!country.IsNullOrEmpty() ? $"[{country}]" : "")}"; UpdateNatTypeLight(int.TryParse(text, out var natType) ? natType : -1); } @@ -1222,25 +1228,14 @@ namespace Netch.Forms if (natType > 0 && natType < 5) { NatTypeStatusLightLabel.Visible = Global.Flags.IsWindows10Upper; - Color c; - switch (natType) - { - case 1: - c = Color.LimeGreen; - break; - case 2: - c = Color.Yellow; - break; - case 3: - c = Color.Red; - break; - case 4: - c = Color.Black; - break; - default: - c = Color.Black; - break; - } + var c = natType switch + { + 1 => Color.LimeGreen, + 2 => Color.Yellow, + 3 => Color.Red, + 4 => Color.Black, + _ => throw new ArgumentOutOfRangeException(nameof(natType), natType, null) + }; NatTypeStatusLightLabel.ForeColor = c; } @@ -1263,7 +1258,7 @@ namespace Netch.Forms /// public void NatTest() { - if (!MainController.Mode.TestNatRequired()) + if (!MainController.Mode!.TestNatRequired()) return; NttTested = false; @@ -1275,7 +1270,7 @@ namespace Netch.Forms if (!string.IsNullOrEmpty(publicEnd)) { - var country = Utils.Utils.GetCityCode(publicEnd); + var country = Utils.Utils.GetCityCode(publicEnd!); NatTypeStatusText(result, country); } else @@ -1417,9 +1412,9 @@ namespace Netch.Forms private async void NewVersionLabel_Click(object sender, EventArgs e) { - if (!UpdateChecker.LatestRelease.assets.Any()) + if (!UpdateChecker.LatestRelease!.assets.Any()) { - Utils.Utils.Open(UpdateChecker.LatestVersionUrl); + Utils.Utils.Open(UpdateChecker.LatestVersionUrl!); return; } @@ -1508,7 +1503,7 @@ namespace Netch.Forms Exit(); } - private void NotifyIcon_MouseDoubleClick(object sender, MouseEventArgs e) + private void NotifyIcon_MouseDoubleClick(object? sender, MouseEventArgs? e) { if (WindowState == FormWindowState.Minimized) { diff --git a/Netch/Forms/MessageBoxX.cs b/Netch/Forms/MessageBoxX.cs index b896d4fc..312adb6e 100644 --- a/Netch/Forms/MessageBoxX.cs +++ b/Netch/Forms/MessageBoxX.cs @@ -18,7 +18,7 @@ namespace Netch.Forms LogLevel level = LogLevel.INFO, string title = "", bool confirm = false, - IWin32Window owner = null) + IWin32Window? owner = null) { MessageBoxIcon msgIcon; if (string.IsNullOrWhiteSpace(title)) diff --git a/Netch/Forms/Mode/Process.cs b/Netch/Forms/Mode/Process.cs index 15eecdf1..658bd521 100644 --- a/Netch/Forms/Mode/Process.cs +++ b/Netch/Forms/Mode/Process.cs @@ -16,13 +16,13 @@ namespace Netch.Forms.Mode /// /// 被编辑的模式 /// - private readonly Models.Mode _mode; + private readonly Models.Mode? _mode; /// /// 编辑模式 /// /// 模式 - public Process(Models.Mode mode = null) + public Process(Models.Mode? mode = null) { if (mode != null && mode.Type is not 0) throw new ArgumentOutOfRangeException(); diff --git a/Netch/Forms/Mode/Route.cs b/Netch/Forms/Mode/Route.cs index d6f44f02..20b81414 100644 --- a/Netch/Forms/Mode/Route.cs +++ b/Netch/Forms/Mode/Route.cs @@ -15,7 +15,7 @@ namespace Netch.Forms.Mode public Item(int value, string text) { - Text = text; + _text = text; Value = value; } @@ -28,11 +28,11 @@ namespace Netch.Forms.Mode public int Value { get; set; } } - private Item[] _items = {new(1, "Proxy Rule IPs"), new(2, "Bypass Rule IPs")}; + private readonly Item[] _items = {new(1, "Proxy Rule IPs"), new(2, "Bypass Rule IPs")}; - private readonly Models.Mode _mode; + private readonly Models.Mode? _mode; - public Route(Models.Mode mode = null) + public Route(Models.Mode? mode = null) { if (mode != null && mode.Type is not (1 or 2)) throw new ArgumentOutOfRangeException(); diff --git a/Netch/Forms/ServerForm.cs b/Netch/Forms/ServerForm.cs index b58f3770..ff452f48 100644 --- a/Netch/Forms/ServerForm.cs +++ b/Netch/Forms/ServerForm.cs @@ -1,4 +1,5 @@ -using System; +#nullable disable +using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; diff --git a/Netch/Forms/SettingForm.cs b/Netch/Forms/SettingForm.cs index d74e3f4d..c368867d 100644 --- a/Netch/Forms/SettingForm.cs +++ b/Netch/Forms/SettingForm.cs @@ -201,7 +201,7 @@ namespace Netch.Forms #endregion } - private void TUNTAPUseCustomDNSCheckBox_CheckedChanged(object sender, EventArgs e) + private void TUNTAPUseCustomDNSCheckBox_CheckedChanged(object? sender, EventArgs? e) { if (UseCustomDNSCheckBox.Checked) TUNTAPDNSTextBox.Text = Global.Settings.TUNTAP.DNS.Any() ? DNS.Join(Global.Settings.TUNTAP.DNS) : "1.1.1.1"; diff --git a/Netch/Global.cs b/Netch/Global.cs index 03bdde50..172e25a8 100644 --- a/Netch/Global.cs +++ b/Netch/Global.cs @@ -30,7 +30,7 @@ namespace Netch /// /// 主窗体的静态实例 /// - public static MainForm MainForm; + private static MainForm? _mainForm; public static readonly Mutex Mutex = new(false, "Global\\Netch"); @@ -77,14 +77,14 @@ namespace Netch /// /// 网关 /// - public static IPAddress Gateway; + public static IPAddress? Gateway; - public static NetworkInterface Adapter; + public static NetworkInterface? Adapter; /// /// 地址 /// - public static IPAddress Address => Adapter.GetIPProperties() + public static IPAddress Address => Adapter!.GetIPProperties() .UnicastAddresses.First(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork) .Address; } @@ -97,7 +97,7 @@ namespace Netch /// /// 适配器 /// - public static NetworkInterface Adapter; + public static NetworkInterface? Adapter; /// /// 索引 @@ -109,5 +109,10 @@ namespace Netch /// public static string ComponentID = string.Empty; } + + /// + /// 主窗体的静态实例 + /// + public static MainForm MainForm => _mainForm ??= new MainForm(); } } \ No newline at end of file diff --git a/Netch/Models/GitHubRelease/Asset.cs b/Netch/Models/GitHubRelease/Asset.cs index a1e2f2b1..244a74e1 100644 --- a/Netch/Models/GitHubRelease/Asset.cs +++ b/Netch/Models/GitHubRelease/Asset.cs @@ -1,4 +1,5 @@ -using System; +#nullable disable +using System; namespace Netch.Models.GitHubRelease { diff --git a/Netch/Models/GitHubRelease/GitHubUser.cs b/Netch/Models/GitHubRelease/GitHubUser.cs index 7964ca77..ad7d9bbb 100644 --- a/Netch/Models/GitHubRelease/GitHubUser.cs +++ b/Netch/Models/GitHubRelease/GitHubUser.cs @@ -1,4 +1,5 @@ -namespace Netch.Models.GitHubRelease +#nullable disable +namespace Netch.Models.GitHubRelease { public class GitHubUser { diff --git a/Netch/Models/GitHubRelease/Release.cs b/Netch/Models/GitHubRelease/Release.cs index 8c8b0324..ad3ff78e 100644 --- a/Netch/Models/GitHubRelease/Release.cs +++ b/Netch/Models/GitHubRelease/Release.cs @@ -1,4 +1,5 @@ -using System; +#nullable disable +using System; namespace Netch.Models.GitHubRelease { diff --git a/Netch/Models/GitHubRelease/VersionComparer.cs b/Netch/Models/GitHubRelease/VersionComparer.cs index 744f404f..368ad20c 100644 --- a/Netch/Models/GitHubRelease/VersionComparer.cs +++ b/Netch/Models/GitHubRelease/VersionComparer.cs @@ -6,7 +6,7 @@ namespace Netch.Models.GitHubRelease { public int Compare(object x, object y) { - return VersionUtil.CompareVersion(x?.ToString(), y?.ToString()); + return VersionUtil.CompareVersion(x.ToString(), y.ToString()); } } } \ No newline at end of file diff --git a/Netch/Models/Mode.cs b/Netch/Models/Mode.cs index f2193e5d..da5d6386 100644 --- a/Netch/Models/Mode.cs +++ b/Netch/Models/Mode.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; @@ -8,7 +9,7 @@ namespace Netch.Models { public class Mode { - public readonly string FullName; + public readonly string? FullName; /// /// 规则 @@ -18,11 +19,12 @@ namespace Netch.Models /// /// 绕过中国(0. 不绕过 1. 绕过) /// - public bool BypassChina = false; + public bool BypassChina { get; set; } + /// /// 备注 /// - public string Remark; + public string Remark { get; set; } = ""; /// /// 类型 @@ -54,7 +56,7 @@ namespace Netch.Models /// /// 文件相对路径(必须是存在的文件) /// - public string RelativePath => ModeHelper.GetRelativePath(FullName); + public string? RelativePath => FullName == null ? null : ModeHelper.GetRelativePath(FullName); public List FullRule { @@ -76,7 +78,7 @@ namespace Netch.Models relativePath.Replace(">", ""); relativePath.Replace(".h", ".txt"); - var mode = Global.Modes.FirstOrDefault(m => m.RelativePath.Equals(relativePath.ToString())); + var mode = Global.Modes.FirstOrDefault(m => m!.FullName != null && m.RelativePath!.Equals(relativePath.ToString())); if (mode == null) { @@ -111,14 +113,17 @@ namespace Netch.Models } } - public void WriteFile() + public void WriteFile(string? fullName = null) { - var dir = Path.GetDirectoryName(FullName); + if (fullName != null) + throw new NotImplementedException(); + + var dir = Path.GetDirectoryName(FullName)!; if (!Directory.Exists(dir)) Directory.CreateDirectory(dir); // 写入到模式文件里 - File.WriteAllText(FullName, ToFileString()); + File.WriteAllText(FullName!, ToFileString()); } /// diff --git a/Netch/Models/Profile.cs b/Netch/Models/Profile.cs index 109188d6..a67727a8 100644 --- a/Netch/Models/Profile.cs +++ b/Netch/Models/Profile.cs @@ -14,12 +14,5 @@ ProfileName = name; Index = index; } - - /// - /// Return a dummy one. - /// - public Profile() - { - } } } \ No newline at end of file diff --git a/Netch/Models/Server.cs b/Netch/Models/Server.cs index 4e269ffc..cacdc941 100644 --- a/Netch/Models/Server.cs +++ b/Netch/Models/Server.cs @@ -21,7 +21,7 @@ namespace Netch.Models /// /// 地址 /// - public string Hostname { get; set; } + public string Hostname { get; set; } = string.Empty; /// /// 端口 @@ -36,12 +36,12 @@ namespace Netch.Models /// /// 备注 /// - public string Remark { get; set; } + public string Remark { get; set; } = ""; /// /// 代理类型 /// - public virtual string Type { get; } = "WTF"; + public virtual string Type { get; } = null!; public object Clone() { @@ -107,7 +107,7 @@ namespace Netch.Models { public static string AutoResolveHostname(this Server server) { - return Global.Settings.ResolveServerHostname ? DNS.Lookup(server.Hostname).ToString() : server.Hostname; + return Global.Settings.ResolveServerHostname ? DNS.Lookup(server.Hostname)!.ToString() : server.Hostname; } } } \ No newline at end of file diff --git a/Netch/Models/SubscribeLink.cs b/Netch/Models/SubscribeLink.cs index eae203e5..1c9c1107 100644 --- a/Netch/Models/SubscribeLink.cs +++ b/Netch/Models/SubscribeLink.cs @@ -10,16 +10,16 @@ /// /// 链接 /// - public string Link; + public string Link = ""; /// /// 备注 /// - public string Remark; + public string Remark = ""; /// /// User Agent /// - public string UserAgent; + public string UserAgent = ""; } } \ No newline at end of file diff --git a/Netch/Netch.cs b/Netch/Netch.cs index 77a1d9cf..f9a53a42 100644 --- a/Netch/Netch.cs +++ b/Netch/Netch.cs @@ -84,7 +84,7 @@ namespace Netch Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - Application.Run(Global.MainForm = new MainForm()); + Application.Run(Global.MainForm); } public static void Application_OnException(object sender, ThreadExceptionEventArgs e) diff --git a/Netch/Netch.csproj b/Netch/Netch.csproj index b02bcde7..784c0b96 100644 --- a/Netch/Netch.csproj +++ b/Netch/Netch.csproj @@ -13,6 +13,7 @@ false latest false + enable diff --git a/Netch/Servers/Shadowsocks/Form/ShadowsocksForm.cs b/Netch/Servers/Shadowsocks/Form/ShadowsocksForm.cs index 068135a2..fb7bcc3a 100644 --- a/Netch/Servers/Shadowsocks/Form/ShadowsocksForm.cs +++ b/Netch/Servers/Shadowsocks/Form/ShadowsocksForm.cs @@ -4,7 +4,7 @@ namespace Netch.Servers.Shadowsocks.Form { public class ShadowsocksForm : ServerForm { - public ShadowsocksForm(Shadowsocks server = default) + public ShadowsocksForm(Shadowsocks? server = default) { server ??= new Shadowsocks(); Server = server; diff --git a/Netch/Servers/Shadowsocks/Models/SSD/Main.cs b/Netch/Servers/Shadowsocks/Models/SSD/Main.cs index 6ae0e586..ff36fd0d 100644 --- a/Netch/Servers/Shadowsocks/Models/SSD/Main.cs +++ b/Netch/Servers/Shadowsocks/Models/SSD/Main.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +#nullable disable +using System.Collections.Generic; namespace Netch.Servers.Shadowsocks.Models.SSD { diff --git a/Netch/Servers/Shadowsocks/Models/SSD/SSDServer.cs b/Netch/Servers/Shadowsocks/Models/SSD/SSDServer.cs index 80d2cbb3..316bfe67 100644 --- a/Netch/Servers/Shadowsocks/Models/SSD/SSDServer.cs +++ b/Netch/Servers/Shadowsocks/Models/SSD/SSDServer.cs @@ -1,4 +1,5 @@ -namespace Netch.Servers.Shadowsocks.Models.SSD +#nullable disable +namespace Netch.Servers.Shadowsocks.Models.SSD { public class SSDServer { diff --git a/Netch/Servers/Shadowsocks/Models/ShadowsocksConfig.cs b/Netch/Servers/Shadowsocks/Models/ShadowsocksConfig.cs index 753f1e1a..e8b5d172 100644 --- a/Netch/Servers/Shadowsocks/Models/ShadowsocksConfig.cs +++ b/Netch/Servers/Shadowsocks/Models/ShadowsocksConfig.cs @@ -1,3 +1,4 @@ +#nullable disable namespace Netch.Servers.Shadowsocks.Models { public class ShadowsocksConfig diff --git a/Netch/Servers/Shadowsocks/SSController.cs b/Netch/Servers/Shadowsocks/SSController.cs index 951bf4a4..0a8092e1 100644 --- a/Netch/Servers/Shadowsocks/SSController.cs +++ b/Netch/Servers/Shadowsocks/SSController.cs @@ -22,7 +22,7 @@ namespace Netch.Servers.Shadowsocks public ushort? Socks5LocalPort { get; set; } - public string LocalAddress { get; set; } + public string? LocalAddress { get; set; } public void Start(in Server s, in Mode mode) { diff --git a/Netch/Servers/Shadowsocks/SSUtil.cs b/Netch/Servers/Shadowsocks/SSUtil.cs index 541f6258..88878238 100644 --- a/Netch/Servers/Shadowsocks/SSUtil.cs +++ b/Netch/Servers/Shadowsocks/SSUtil.cs @@ -61,7 +61,7 @@ namespace Netch.Servers.Shadowsocks if (text.StartsWith("ssd://")) return ParseSsdUri(text); - return null; + throw new FormatException(); } public bool CheckServer(Server s) @@ -102,93 +102,82 @@ namespace Netch.Servers.Shadowsocks var data = new Shadowsocks(); text = text.Replace("/?", "?"); - try + if (text.Contains("#")) { - if (text.Contains("#")) - { - data.Remark = HttpUtility.UrlDecode(text.Split('#')[1]); - text = text.Split('#')[0]; - } - - if (text.Contains("?")) - { - var finder = new Regex(@"^(?.+?)\?(.+)$"); - var match = finder.Match(text); - - if (match.Success) - { - var plugins = HttpUtility.UrlDecode(HttpUtility.ParseQueryString(new Uri(text).Query).Get("plugin")); - if (plugins != null) - { - var plugin = plugins.Substring(0, plugins.IndexOf(";", StringComparison.Ordinal)); - var pluginopts = plugins.Substring(plugins.IndexOf(";", StringComparison.Ordinal) + 1); - switch (plugin) - { - case "obfs-local": - case "simple-obfs": - plugin = "simple-obfs"; - if (!pluginopts.Contains("obfs=")) - pluginopts = "obfs=http;obfs-host=" + pluginopts; - - break; - case "simple-obfs-tls": - plugin = "simple-obfs"; - if (!pluginopts.Contains("obfs=")) - pluginopts = "obfs=tls;obfs-host=" + pluginopts; - - break; - } - - data.Plugin = plugin; - data.PluginOption = pluginopts; - } - - text = match.Groups["data"].Value; - } - else - { - throw new FormatException(); - } - } - - if (text.Contains("@")) - { - var finder = new Regex(@"^ss://(?.+?)@(?.+):(?\d+)"); - var parser = new Regex(@"^(?.+?):(?.+)$"); - var match = finder.Match(text); - if (!match.Success) - throw new FormatException(); - - data.Hostname = match.Groups["server"].Value; - data.Port = ushort.Parse(match.Groups["port"].Value); - - var base64 = ShareLink.URLSafeBase64Decode(match.Groups["base64"].Value); - match = parser.Match(base64); - if (!match.Success) - throw new FormatException(); - - data.EncryptMethod = match.Groups["method"].Value; - data.Password = match.Groups["password"].Value; - } - else - { - var parser = new Regex(@"^((?.+?):(?.+)@(?.+):(?\d+))"); - var match = parser.Match(ShareLink.URLSafeBase64Decode(text.Replace("ss://", ""))); - if (!match.Success) - throw new FormatException(); - - data.Hostname = match.Groups["server"].Value; - data.Port = ushort.Parse(match.Groups["port"].Value); - data.EncryptMethod = match.Groups["method"].Value; - data.Password = match.Groups["password"].Value; - } - - return CheckServer(data) ? data : null; + data.Remark = HttpUtility.UrlDecode(text.Split('#')[1]); + text = text.Split('#')[0]; } - catch (FormatException) + + if (text.Contains("?")) { - return null; + var finder = new Regex(@"^(?.+?)\?(.+)$"); + var match = finder.Match(text); + + if (!match.Success) + throw new FormatException(); + + var plugins = HttpUtility.UrlDecode(HttpUtility.ParseQueryString(new Uri(text).Query).Get("plugin")); + if (plugins != null) + { + var plugin = plugins.Substring(0, plugins.IndexOf(";", StringComparison.Ordinal)); + var pluginopts = plugins.Substring(plugins.IndexOf(";", StringComparison.Ordinal) + 1); + switch (plugin) + { + case "obfs-local": + case "simple-obfs": + plugin = "simple-obfs"; + if (!pluginopts.Contains("obfs=")) + pluginopts = "obfs=http;obfs-host=" + pluginopts; + + break; + case "simple-obfs-tls": + plugin = "simple-obfs"; + if (!pluginopts.Contains("obfs=")) + pluginopts = "obfs=tls;obfs-host=" + pluginopts; + + break; + } + + data.Plugin = plugin; + data.PluginOption = pluginopts; + } + + text = match.Groups["data"].Value; } + + if (text.Contains("@")) + { + var finder = new Regex(@"^ss://(?.+?)@(?.+):(?\d+)"); + var parser = new Regex(@"^(?.+?):(?.+)$"); + var match = finder.Match(text); + if (!match.Success) + throw new FormatException(); + + data.Hostname = match.Groups["server"].Value; + data.Port = ushort.Parse(match.Groups["port"].Value); + + var base64 = ShareLink.URLSafeBase64Decode(match.Groups["base64"].Value); + match = parser.Match(base64); + if (!match.Success) + throw new FormatException(); + + data.EncryptMethod = match.Groups["method"].Value; + data.Password = match.Groups["password"].Value; + } + else + { + var parser = new Regex(@"^((?.+?):(?.+)@(?.+):(?\d+))"); + var match = parser.Match(ShareLink.URLSafeBase64Decode(text.Replace("ss://", ""))); + if (!match.Success) + throw new FormatException(); + + data.Hostname = match.Groups["server"].Value; + data.Port = ushort.Parse(match.Groups["port"].Value); + data.EncryptMethod = match.Groups["method"].Value; + data.Password = match.Groups["password"].Value; + } + + return CheckServer(data) ? data : throw new FormatException(); } } } \ No newline at end of file diff --git a/Netch/Servers/Shadowsocks/Shadowsocks.cs b/Netch/Servers/Shadowsocks/Shadowsocks.cs index bc023217..80176b37 100644 --- a/Netch/Servers/Shadowsocks/Shadowsocks.cs +++ b/Netch/Servers/Shadowsocks/Shadowsocks.cs @@ -15,17 +15,17 @@ namespace Netch.Servers.Shadowsocks /// /// 密码 /// - public string Password { get; set; } + public string? Password { get; set; } /// /// 插件 /// - public string Plugin { get; set; } + public string? Plugin { get; set; } /// /// 插件参数 /// - public string PluginOption { get; set; } + public string? PluginOption { get; set; } public bool HasPlugin() { diff --git a/Netch/Servers/ShadowsocksR/Form/ShadowsocksRForm.cs b/Netch/Servers/ShadowsocksR/Form/ShadowsocksRForm.cs index 5a855ada..a6ca3a13 100644 --- a/Netch/Servers/ShadowsocksR/Form/ShadowsocksRForm.cs +++ b/Netch/Servers/ShadowsocksR/Form/ShadowsocksRForm.cs @@ -4,7 +4,7 @@ namespace Netch.Servers.ShadowsocksR.Form { public class ShadowsocksRForm : ServerForm { - public ShadowsocksRForm(ShadowsocksR server = default) + public ShadowsocksRForm(ShadowsocksR? server = default) { server ??= new ShadowsocksR(); Server = server; diff --git a/Netch/Servers/ShadowsocksR/SSRController.cs b/Netch/Servers/ShadowsocksR/SSRController.cs index 7ce85a66..58263cdc 100644 --- a/Netch/Servers/ShadowsocksR/SSRController.cs +++ b/Netch/Servers/ShadowsocksR/SSRController.cs @@ -18,7 +18,7 @@ namespace Netch.Servers.ShadowsocksR public ushort? Socks5LocalPort { get; set; } - public string LocalAddress { get; set; } + public string? LocalAddress { get; set; } public void Start(in Server s, in Mode mode) { diff --git a/Netch/Servers/ShadowsocksR/ShadowsocksR.cs b/Netch/Servers/ShadowsocksR/ShadowsocksR.cs index 91d57ad0..faa200e6 100644 --- a/Netch/Servers/ShadowsocksR/ShadowsocksR.cs +++ b/Netch/Servers/ShadowsocksR/ShadowsocksR.cs @@ -20,12 +20,12 @@ namespace Netch.Servers.ShadowsocksR /// /// 混淆参数 /// - public string OBFSParam { get; set; } + public string? OBFSParam { get; set; } /// /// 密码 /// - public string Password { get; set; } + public string Password { get; set; } = string.Empty; /// /// 协议 @@ -35,7 +35,7 @@ namespace Netch.Servers.ShadowsocksR /// /// 协议参数 /// - public string ProtocolParam { get; set; } + public string? ProtocolParam { get; set; } } public class SSRGlobal diff --git a/Netch/Servers/Socks5/Form/Socks5Form.cs b/Netch/Servers/Socks5/Form/Socks5Form.cs index 46fb7e97..e96e456a 100644 --- a/Netch/Servers/Socks5/Form/Socks5Form.cs +++ b/Netch/Servers/Socks5/Form/Socks5Form.cs @@ -4,7 +4,7 @@ namespace Netch.Servers.Socks5.Form { public class Socks5Form : ServerForm { - public Socks5Form(Socks5 server = default) + public Socks5Form(Socks5? server = default) { server ??= new Socks5(); Server = server; diff --git a/Netch/Servers/Socks5/S5Util.cs b/Netch/Servers/Socks5/S5Util.cs index 9302ccc2..3d2560b4 100644 --- a/Netch/Servers/Socks5/S5Util.cs +++ b/Netch/Servers/Socks5/S5Util.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using Netch.Controllers; using Netch.Models; @@ -57,7 +58,7 @@ namespace Netch.Servers.Socks5 .ToDictionary(splited => splited[0], splited => splited[1]); if (!dict.ContainsKey("server") || !dict.ContainsKey("port")) - return null; + throw new FormatException(); var data = new Socks5 { diff --git a/Netch/Servers/Socks5/Socks5.cs b/Netch/Servers/Socks5/Socks5.cs index 2c97729c..963e4f29 100644 --- a/Netch/Servers/Socks5/Socks5.cs +++ b/Netch/Servers/Socks5/Socks5.cs @@ -7,12 +7,12 @@ namespace Netch.Servers.Socks5 /// /// 密码 /// - public string Password; + public string? Password; /// /// 账号 /// - public string Username; + public string? Username; public override string Type { get; } = "Socks5"; diff --git a/Netch/Servers/Trojan/Form/TrojanForm.cs b/Netch/Servers/Trojan/Form/TrojanForm.cs index c2a4ec07..4e1050f3 100644 --- a/Netch/Servers/Trojan/Form/TrojanForm.cs +++ b/Netch/Servers/Trojan/Form/TrojanForm.cs @@ -4,7 +4,7 @@ namespace Netch.Servers.Trojan.Form { public class TrojanForm : ServerForm { - public TrojanForm(Trojan server = default) + public TrojanForm(Trojan? server = default) { server ??= new Trojan(); Server = server; diff --git a/Netch/Servers/Trojan/Models/TrojanConfig.cs b/Netch/Servers/Trojan/Models/TrojanConfig.cs index c725b20b..755e6f01 100644 --- a/Netch/Servers/Trojan/Models/TrojanConfig.cs +++ b/Netch/Servers/Trojan/Models/TrojanConfig.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +#nullable disable +using System.Collections.Generic; namespace Netch.Servers.Trojan.Models { diff --git a/Netch/Servers/Trojan/Trojan.cs b/Netch/Servers/Trojan/Trojan.cs index 80994bcc..0cb6556b 100644 --- a/Netch/Servers/Trojan/Trojan.cs +++ b/Netch/Servers/Trojan/Trojan.cs @@ -9,11 +9,11 @@ namespace Netch.Servers.Trojan /// /// 密码 /// - public string Password { get; set; } + public string Password { get; set; } = string.Empty; /// /// 伪装域名 /// - public string Host { get; set; } + public string? Host { get; set; } } } \ No newline at end of file diff --git a/Netch/Servers/Trojan/TrojanController.cs b/Netch/Servers/Trojan/TrojanController.cs index 9eca8a31..f7c225e4 100644 --- a/Netch/Servers/Trojan/TrojanController.cs +++ b/Netch/Servers/Trojan/TrojanController.cs @@ -19,7 +19,7 @@ namespace Netch.Servers.Trojan public ushort? Socks5LocalPort { get; set; } - public string LocalAddress { get; set; } + public string? LocalAddress { get; set; } public void Start(in Server s, in Mode mode) { diff --git a/Netch/Servers/Trojan/TrojanUtil.cs b/Netch/Servers/Trojan/TrojanUtil.cs index 3eb8c15d..179b172a 100644 --- a/Netch/Servers/Trojan/TrojanUtil.cs +++ b/Netch/Servers/Trojan/TrojanUtil.cs @@ -52,49 +52,38 @@ namespace Netch.Servers.Trojan var data = new Trojan(); text = text.Replace("/?", "?"); - try + if (text.Contains("#")) { - if (text.Contains("#")) - { - data.Remark = HttpUtility.UrlDecode(text.Split('#')[1]); - text = text.Split('#')[0]; - } + data.Remark = HttpUtility.UrlDecode(text.Split('#')[1]); + text = text.Split('#')[0]; + } - if (text.Contains("?")) - { - var reg = new Regex(@"^(?.+?)\?(.+)$"); - var regmatch = reg.Match(text); + if (text.Contains("?")) + { + var reg = new Regex(@"^(?.+?)\?(.+)$"); + var regmatch = reg.Match(text); - if (regmatch.Success) - { - var peer = HttpUtility.UrlDecode(HttpUtility.ParseQueryString(new Uri(text).Query).Get("peer")); - - if (peer != null) - data.Host = peer; - - text = regmatch.Groups["data"].Value; - } - else - { - throw new FormatException(); - } - } - - var finder = new Regex(@"^trojan://(?.+?)@(?.+):(?\d+)"); - var match = finder.Match(text); - if (!match.Success) + if (!regmatch.Success) throw new FormatException(); - data.Password = match.Groups["psk"].Value; - data.Hostname = match.Groups["server"].Value; - data.Port = ushort.Parse(match.Groups["port"].Value); + var peer = HttpUtility.UrlDecode(HttpUtility.ParseQueryString(new Uri(text).Query).Get("peer")); - return new[] {data}; - } - catch (FormatException) - { - return null; + if (peer != null) + data.Host = peer; + + text = regmatch.Groups["data"].Value; } + + var finder = new Regex(@"^trojan://(?.+?)@(?.+):(?\d+)"); + var match = finder.Match(text); + if (!match.Success) + throw new FormatException(); + + data.Password = match.Groups["psk"].Value; + data.Hostname = match.Groups["server"].Value; + data.Port = ushort.Parse(match.Groups["port"].Value); + + return new[] {data}; } public bool CheckServer(Server s) diff --git a/Netch/Servers/V2ray/Models/V2rayConfig.cs b/Netch/Servers/V2ray/Models/V2rayConfig.cs index fd7b1329..678e8fee 100644 --- a/Netch/Servers/V2ray/Models/V2rayConfig.cs +++ b/Netch/Servers/V2ray/Models/V2rayConfig.cs @@ -1,14 +1,15 @@ -using System.Collections.Generic; +#nullable disable +using System.Collections.Generic; namespace Netch.Servers.V2ray.Models { public class V2rayConfig { - public List inbounds { get; set; } + public List inbounds { get; } = new(); - public List outbounds { get; set; } + public List outbounds { get; } = new(); - public Routing routing { get; set; } + public Routing routing { get; } = new(); } public class Inbounds @@ -160,7 +161,7 @@ namespace Netch.Servers.V2ray.Models { public string domainStrategy { get; set; } - public List rules { get; set; } + public List rules { get; } = new(); } public class StreamSettings diff --git a/Netch/Servers/V2ray/Utils/V2rayConfigUtils.cs b/Netch/Servers/V2ray/Utils/V2rayConfigUtils.cs index 2d0d40f9..c2386a45 100644 --- a/Netch/Servers/V2ray/Utils/V2rayConfigUtils.cs +++ b/Netch/Servers/V2ray/Utils/V2rayConfigUtils.cs @@ -11,24 +11,17 @@ namespace Netch.Servers.V2ray.Utils { public static string GenerateClientConfig(Server server, Mode mode) { - try - { - var v2rayConfig = new V2rayConfig(); + var v2rayConfig = new V2rayConfig(); - inbound(server, ref v2rayConfig); + inbound(server, ref v2rayConfig); - routing(server, mode, ref v2rayConfig); + routing(server, mode, ref v2rayConfig); - outbound(server, mode, ref v2rayConfig); + outbound(server, mode, ref v2rayConfig); - return JsonConvert.SerializeObject(v2rayConfig, - Formatting.Indented, - new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore}); - } - catch - { - return ""; - } + return JsonConvert.SerializeObject(v2rayConfig, + Formatting.Indented, + new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore}); } private static void inbound(Server server, ref V2rayConfig v2rayConfig) @@ -46,10 +39,7 @@ namespace Netch.Servers.V2ray.Utils } }; - v2rayConfig.inbounds = new List - { - inbound - }; + v2rayConfig.inbounds.Add(inbound); } catch { @@ -99,18 +89,13 @@ namespace Netch.Servers.V2ray.Utils if (mode.Type is 0 or 1 or 2) blockRuleObject.ip.Add("geoip:private"); - v2rayConfig.routing = new Routing - { - rules = new List() - }; - static bool CheckRuleItem(ref RulesItem rulesItem) { bool ipResult, domainResult; - if (!(ipResult = rulesItem.ip.Any())) + if (!(ipResult = rulesItem.ip?.Any() ?? false)) rulesItem.ip = null; - if (!(domainResult = rulesItem.domain.Any())) + if (!(domainResult = rulesItem.domain?.Any() ?? false)) rulesItem.domain = null; return ipResult || domainResult; @@ -242,7 +227,7 @@ namespace Netch.Servers.V2ray.Utils } } - v2rayConfig.outbounds = new List + v2rayConfig.outbounds.AddRange(new[] { outbound, new() @@ -253,7 +238,7 @@ namespace Netch.Servers.V2ray.Utils { tag = "block", protocol = "blackhole" } - }; + }); } catch { @@ -321,7 +306,7 @@ namespace Netch.Servers.V2ray.Utils { host = new List { - string.IsNullOrWhiteSpace(server.Host) ? server.Hostname : server.Host + string.IsNullOrWhiteSpace(server.Host) ? server.Hostname : server.Host! }, path = server.Path }; diff --git a/Netch/Servers/V2ray/V2rayController.cs b/Netch/Servers/V2ray/V2rayController.cs index 16733fd7..14ffb465 100644 --- a/Netch/Servers/V2ray/V2rayController.cs +++ b/Netch/Servers/V2ray/V2rayController.cs @@ -18,7 +18,7 @@ namespace Netch.Servers.V2ray public ushort? Socks5LocalPort { get; set; } - public string LocalAddress { get; set; } + public string? LocalAddress { get; set; } public virtual void Start(in Server s, in Mode mode) { @@ -35,7 +35,7 @@ namespace Netch.Servers.V2ray { base.InitInstance(argument); if (!Global.Settings.V2RayConfig.XrayCone) - Instance.StartInfo.Environment["XRAY_CONE_DISABLED"] = "true"; + Instance!.StartInfo.Environment["XRAY_CONE_DISABLED"] = "true"; } } } \ No newline at end of file diff --git a/Netch/Servers/V2ray/V2rayUtils.cs b/Netch/Servers/V2ray/V2rayUtils.cs index c1fef0cf..79828af9 100644 --- a/Netch/Servers/V2ray/V2rayUtils.cs +++ b/Netch/Servers/V2ray/V2rayUtils.cs @@ -8,77 +8,66 @@ using Netch.Utils; namespace Netch.Servers.V2ray { - internal static class V2rayUtils + public static class V2rayUtils { public static IEnumerable ParseVUri(string text) { var scheme = ShareLink.GetUriScheme(text).ToLower(); - try + var server = scheme switch {"vmess" => new VMess.VMess(), "vless" => new VLESS.VLESS(), _ => throw new ArgumentOutOfRangeException()}; + if (text.Contains("#")) { - var server = scheme switch {"vmess" => new VMess.VMess(), "vless" => new VLESS.VLESS(), _ => throw new ArgumentOutOfRangeException()}; - if (text.Contains("#")) + server.Remark = Uri.UnescapeDataString(text.Split('#')[1]); + text = text.Split('#')[0]; + } + + if (text.Contains("?")) + { + var parameter = HttpUtility.ParseQueryString(text.Split('?')[1]); + text = text.Substring(0, text.IndexOf("?", StringComparison.Ordinal)); + server.TransferProtocol = parameter.Get("type") ?? "tcp"; + server.EncryptMethod = parameter.Get("encryption") ?? scheme switch {"vless" => "none", _ => "auto"}; + switch (server.TransferProtocol) { - server.Remark = Uri.UnescapeDataString(text.Split('#')[1]); - text = text.Split('#')[0]; + case "tcp": + break; + case "kcp": + server.FakeType = parameter.Get("headerType") ?? "none"; + server.Path = Uri.UnescapeDataString(parameter.Get("seed") ?? ""); + break; + case "ws": + server.Path = Uri.UnescapeDataString(parameter.Get("path") ?? "/"); + server.Host = Uri.UnescapeDataString(parameter.Get("host") ?? ""); + break; + case "h2": + server.Path = Uri.UnescapeDataString(parameter.Get("path") ?? "/"); + server.Host = Uri.UnescapeDataString(parameter.Get("host") ?? ""); + break; + case "quic": + server.QUICSecure = parameter.Get("quicSecurity") ?? "none"; + server.QUICSecret = parameter.Get("key") ?? ""; + server.FakeType = parameter.Get("headerType") ?? "none"; + break; } - if (text.Contains("?")) + server.TLSSecureType = parameter.Get("security") ?? "none"; + if (server.TLSSecureType != "none") { - var parameter = HttpUtility.ParseQueryString(text.Split('?')[1]); - text = text.Substring(0, text.IndexOf("?", StringComparison.Ordinal)); - server.TransferProtocol = parameter.Get("type") ?? "tcp"; - server.EncryptMethod = parameter.Get("encryption") ?? scheme switch {"vless" => "none", _ => "auto"}; - switch (server.TransferProtocol) - { - case "tcp": - break; - case "kcp": - server.FakeType = parameter.Get("headerType") ?? "none"; - server.Path = Uri.UnescapeDataString(parameter.Get("seed") ?? ""); - break; - case "ws": - server.Path = Uri.UnescapeDataString(parameter.Get("path") ?? "/"); - server.Host = Uri.UnescapeDataString(parameter.Get("host") ?? ""); - break; - case "h2": - server.Path = Uri.UnescapeDataString(parameter.Get("path") ?? "/"); - server.Host = Uri.UnescapeDataString(parameter.Get("host") ?? ""); - break; - case "quic": - server.QUICSecure = parameter.Get("quicSecurity") ?? "none"; - server.QUICSecret = parameter.Get("key") ?? ""; - server.FakeType = parameter.Get("headerType") ?? "none"; - break; - } - - server.TLSSecureType = parameter.Get("security") ?? "none"; - if (server.TLSSecureType != "none") - { - server.Host = parameter.Get("sni") ?? ""; - if (server.TLSSecureType == "xtls") - ((VLESS.VLESS) server).Flow = parameter.Get("flow") ?? ""; - } + server.Host = parameter.Get("sni") ?? ""; + if (server.TLSSecureType == "xtls") + ((VLESS.VLESS) server).Flow = parameter.Get("flow") ?? ""; } - - var finder = new Regex(@$"^{scheme}://(?.+?)@(?.+):(?\d+)"); - var match = finder.Match(text.Split('?')[0]); - if (!match.Success) - throw new FormatException(); - - server.UserID = match.Groups["guid"].Value; - server.Hostname = match.Groups["server"].Value; - server.Port = ushort.Parse(match.Groups["port"].Value); - - return new[] - { - server - }; - } - catch (FormatException e) - { - Logging.Error(e.ToString()); - return null; } + + var finder = new Regex(@$"^{scheme}://(?.+?)@(?.+):(?\d+)"); + var match = finder.Match(text.Split('?')[0]); + if (!match.Success) + throw new FormatException(); + + server.UserID = match.Groups["guid"].Value; + server.Hostname = match.Groups["server"].Value; + server.Port = ushort.Parse(match.Groups["port"].Value); + + return new[] {server}; } public static string GetVShareLink(Server s, string scheme = "vmess") @@ -102,26 +91,27 @@ namespace Netch.Servers.V2ray parameter.Add("headerType", server.FakeType); if (!server.Path.IsNullOrWhiteSpace()) - parameter.Add("seed", Uri.EscapeDataString(server.Path)); + parameter.Add("seed", Uri.EscapeDataString(server.Path!)); break; case "ws": - parameter.Add("path", Uri.EscapeDataString(server.Path.IsNullOrWhiteSpace() ? "/" : server.Path)); + parameter.Add("path", Uri.EscapeDataString(server.Path.IsNullOrWhiteSpace() ? "/" : server.Path!)); if (!server.Host.IsNullOrWhiteSpace()) - parameter.Add("host", Uri.EscapeDataString(server.Host)); + parameter.Add("host", Uri.EscapeDataString(server.Host!)); break; case "h2": - parameter.Add("path", Uri.EscapeDataString(server.Path.IsNullOrWhiteSpace() ? "/" : server.Path)); + parameter.Add("path", Uri.EscapeDataString(server.Path.IsNullOrWhiteSpace() ? "/" : server.Path!)); if (!server.Host.IsNullOrWhiteSpace()) - parameter.Add("host", Uri.EscapeDataString(server.Host)); + parameter.Add("host", Uri.EscapeDataString(server.Host!)); break; case "quic": - if (server.QUICSecure != "none") + if (server.QUICSecure is not (null or "none")) { parameter.Add("quicSecurity", server.QUICSecure); - parameter.Add("key", server.QUICSecret); + parameter.Add("key", server.QUICSecret!); + // TODO Import and Create null value Check } if (server.FakeType != "none") @@ -135,13 +125,13 @@ namespace Netch.Servers.V2ray parameter.Add("security", server.TLSSecureType); if (!server.Host.IsNullOrWhiteSpace()) - parameter.Add("sni", server.Host); + parameter.Add("sni", server.Host!); if (server.TLSSecureType == "xtls") { - var flow = ((VLESS.VLESS) server).Flow.Replace("-udp443", ""); + var flow = ((VLESS.VLESS) server).Flow; if (!flow.IsNullOrWhiteSpace()) - parameter.Add("flow", flow); + parameter.Add("flow", flow!.Replace("-udp443", "")); } } diff --git a/Netch/Servers/VLESS/VLESS.cs b/Netch/Servers/VLESS/VLESS.cs index 4b6b0fa6..17856364 100644 --- a/Netch/Servers/VLESS/VLESS.cs +++ b/Netch/Servers/VLESS/VLESS.cs @@ -24,7 +24,7 @@ namespace Netch.Servers.VLESS /// /// - public string Flow { get; set; } + public string? Flow { get; set; } } public class VLESSGlobal diff --git a/Netch/Servers/VLESS/VLESSForm/VLESSForm.cs b/Netch/Servers/VLESS/VLESSForm/VLESSForm.cs index 85213fa0..f0d75424 100644 --- a/Netch/Servers/VLESS/VLESSForm/VLESSForm.cs +++ b/Netch/Servers/VLESS/VLESSForm/VLESSForm.cs @@ -5,7 +5,7 @@ namespace Netch.Servers.VLESS.VLESSForm { internal class VLESSForm : ServerForm { - public VLESSForm(VLESS server = default) + public VLESSForm(VLESS? server = default) { server ??= new VLESS(); Server = server; diff --git a/Netch/Servers/VLESS/VLESSUtil.cs b/Netch/Servers/VLESS/VLESSUtil.cs index c63f143a..3a20447b 100644 --- a/Netch/Servers/VLESS/VLESSUtil.cs +++ b/Netch/Servers/VLESS/VLESSUtil.cs @@ -50,7 +50,6 @@ namespace Netch.Servers.VLESS public bool CheckServer(Server s) { - // TODO return true; } } diff --git a/Netch/Servers/VMess/Form/VMessForm.cs b/Netch/Servers/VMess/Form/VMessForm.cs index 5a7eae0d..572f61c9 100644 --- a/Netch/Servers/VMess/Form/VMessForm.cs +++ b/Netch/Servers/VMess/Form/VMessForm.cs @@ -5,7 +5,7 @@ namespace Netch.Servers.VMess.Form { public class VMessForm : ServerForm { - public VMessForm(VMess server = default) + public VMessForm(VMess? server = default) { server ??= new VMess(); Server = server; diff --git a/Netch/Servers/VMess/VMess.cs b/Netch/Servers/VMess/VMess.cs index 949c08fd..ba91cb5c 100644 --- a/Netch/Servers/VMess/VMess.cs +++ b/Netch/Servers/VMess/VMess.cs @@ -12,7 +12,7 @@ namespace Netch.Servers.VMess /// /// 用户 ID /// - public string UserID { get; set; } + public string UserID { get; set; } = string.Empty; /// /// 额外 ID @@ -37,22 +37,22 @@ namespace Netch.Servers.VMess /// /// 伪装域名 /// - public string Host { get; set; } + public string? Host { get; set; } /// /// 传输路径 /// - public string Path { get; set; } + public string? Path { get; set; } /// /// QUIC 加密方式 /// - public string QUICSecure { get; set; } = VMessGlobal.QUIC[0]; + public string? QUICSecure { get; set; } = VMessGlobal.QUIC[0]; /// /// QUIC 加密密钥 /// - public string QUICSecret { get; set; } = string.Empty; + public string? QUICSecret { get; set; } = string.Empty; /// /// TLS 底层传输安全 diff --git a/Netch/Servers/VMess/VMessUtil.cs b/Netch/Servers/VMess/VMessUtil.cs index 83be6488..4449881d 100644 --- a/Netch/Servers/VMess/VMessUtil.cs +++ b/Netch/Servers/VMess/VMessUtil.cs @@ -24,16 +24,7 @@ namespace Netch.Servers.VMess public Server ParseJObject(in JObject j) { - // TODO Remove Migrate code - var server = j.ToObject(); - if (server == null) - return null; - - string quic; - if ((quic = j.GetValue("QUIC")?.ToString()) != null) - server.QUICSecure = quic; - - return server; + return j.ToObject(); } public void Edit(Server s) @@ -117,31 +108,11 @@ namespace Netch.Servers.VMess data.TLSSecureType = vmess.tls; data.EncryptMethod = "auto"; // V2Ray 加密方式不包括在链接中,主动添加一个 - return CheckServer(data) ? new[] {data} : null; + return new[] {data}; } public bool CheckServer(Server s) { - var server = (VMess) s; - if (!VMessGlobal.TransferProtocols.Contains(server.TransferProtocol)) - { - Logging.Error($"不支持的 VMess 传输协议:{server.TransferProtocol}"); - return false; - } - - if (server.FakeType.Length != 0 && !VMessGlobal.FakeTypes.Contains(server.FakeType)) - { - Logging.Error($"不支持的 VMess 伪装类型:{server.FakeType}"); - return false; - } - - if (server.TransferProtocol == "quic") - if (!VMessGlobal.QUIC.Contains(server.QUICSecure)) - { - Logging.Error($"不支持的 VMess QUIC 加密方式:{server.QUICSecure}"); - return false; - } - return true; } } diff --git a/Netch/Updater/Updater.cs b/Netch/Updater/Updater.cs index 8babda7c..188eae1f 100644 --- a/Netch/Updater/Updater.cs +++ b/Netch/Updater/Updater.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; @@ -44,7 +43,7 @@ namespace Netch.Updater Global.MainForm.Exit(true); } - private static int Extract(string archiveFileName, string destDirName, bool overwrite, string tempFolder = null) + private static int Extract(string archiveFileName, string destDirName, bool overwrite, string? tempFolder = null) { tempFolder ??= Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); var temp7za = Path.Combine(tempFolder, "7za.exe"); @@ -74,39 +73,6 @@ namespace Netch.Updater return process?.ExitCode ?? 2; } - public static FileInfo FindFile(string filename, string directory) - { - var DirStack = new Stack(); - DirStack.Push(directory); - - while (DirStack.Count > 0) - { - var DirInfo = new DirectoryInfo(DirStack.Pop()); - try - { - foreach (var DirChildInfo in DirInfo.GetDirectories()) - DirStack.Push(DirChildInfo.FullName); - } - catch - { - // ignored - } - - try - { - foreach (var FileChildInfo in DirInfo.GetFiles()) - if (FileChildInfo.Name == filename) - return FileChildInfo; - } - catch - { - // ignored - } - } - - return null; - } - private static void MoveDirectory(string sourceDirName, string destDirName, bool overwrite) { sourceDirName = Path.GetFullPath(sourceDirName); @@ -133,19 +99,6 @@ namespace Netch.Updater } } - private static bool TestFileFree(string FileName) - { - try - { - File.Move(FileName, FileName); - return true; - } - catch - { - return false; - } - } - public static void CleanOld() { foreach (var f in Directory.GetFiles(Global.NetchDir, "*.old", SearchOption.AllDirectories)) diff --git a/Netch/Utils/Bandwidth.cs b/Netch/Utils/Bandwidth.cs index 7dcbd2e5..ade5c7a9 100644 --- a/Netch/Utils/Bandwidth.cs +++ b/Netch/Utils/Bandwidth.cs @@ -13,7 +13,7 @@ namespace Netch.Utils public static class Bandwidth { public static ulong received; - public static TraceEventSession tSession; + public static TraceEventSession? tSession; private static readonly string[] Suffix = {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"}; @@ -57,7 +57,7 @@ namespace Netch.Utils { case null: break; - case SSController ssController when ssController.DllFlag: + case SSController {DllFlag: true}: instances.Add(Process.GetCurrentProcess()); break; case Guard instanceController: @@ -73,13 +73,13 @@ namespace Netch.Utils case null: break; case HTTPController httpController: - instances.Add(httpController.pPrivoxyController.Instance); + instances.Add(httpController.PrivoxyController.Instance!); break; case NFController _: instances.Add(Process.GetCurrentProcess()); break; case Guard instanceController: - instances.Add(instanceController.Instance); + instances.Add(instanceController.Instance!); break; } diff --git a/Netch/Utils/Configuration.cs b/Netch/Utils/Configuration.cs index 0efebba8..280dfc65 100644 --- a/Netch/Utils/Configuration.cs +++ b/Netch/Utils/Configuration.cs @@ -27,19 +27,20 @@ namespace Netch.Utils { try { - var settingJObject = (JObject) JsonConvert.DeserializeObject(File.ReadAllText(SETTINGS_JSON)); + var settingJObject = (JObject) JsonConvert.DeserializeObject(File.ReadAllText(SETTINGS_JSON))!; Global.Settings = settingJObject?.ToObject() ?? new Setting(); Global.Settings.Server.Clear(); if (settingJObject?["Server"] != null) - foreach (JObject server in settingJObject["Server"]) + foreach (JObject server in settingJObject["Server"]!) { var serverResult = ServerHelper.ParseJObject(server); if (serverResult != null) Global.Settings.Server.Add(serverResult); } - if (settingJObject?["Profiles"] != null && Global.Settings.Profiles.Any() && settingJObject["Profiles"].First()?["Index"] == null) + if (settingJObject?["Profiles"] != null && Global.Settings.Profiles.Any() && + settingJObject["Profiles"]!.First()?["Index"] == null) foreach (var profile in Global.Settings.Profiles) profile.Index = Global.Settings.Profiles.IndexOf(profile); } diff --git a/Netch/Utils/DNS.cs b/Netch/Utils/DNS.cs index 6ce62a38..7d5bfc17 100644 --- a/Netch/Utils/DNS.cs +++ b/Netch/Utils/DNS.cs @@ -40,7 +40,7 @@ namespace Netch.Utils /// /// 主机名 /// - public static IPAddress Lookup(string hostname) + public static IPAddress? Lookup(string hostname) { try { @@ -69,8 +69,8 @@ namespace Netch.Utils if (Global.Outbound.Adapter == null) Utils.SearchOutboundAdapter(); - return Registry.LocalMachine.OpenSubKey($@"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{Global.Outbound.Adapter.Id}", - write); + return Registry.LocalMachine.OpenSubKey($@"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{Global.Outbound.Adapter!.Id}", + write)!; } public static IEnumerable Split(string dns) diff --git a/Netch/Utils/HttpProxyHandler/HttpWebServer.cs b/Netch/Utils/HttpProxyHandler/HttpWebServer.cs index 08074a32..30c4ccbe 100644 --- a/Netch/Utils/HttpProxyHandler/HttpWebServer.cs +++ b/Netch/Utils/HttpProxyHandler/HttpWebServer.cs @@ -7,8 +7,8 @@ namespace Netch.Utils.HttpProxyHandler { public class HttpWebServer { - private HttpListener _listener; - private readonly Func _responderMethod; + private HttpListener? _listener; + private readonly Func? _responderMethod; public HttpWebServer(string[] prefixes, Func method) { @@ -51,13 +51,13 @@ namespace Netch.Utils.HttpProxyHandler Logging.Info("Webserver running..."); try { - while (_listener.IsListening) + while (_listener!.IsListening) ThreadPool.QueueUserWorkItem(c => { - var ctx = c as HttpListenerContext; + var ctx = (HttpListenerContext) c; try { - var rstr = _responderMethod(ctx.Request); + var rstr = _responderMethod!(ctx.Request); var buf = Encoding.UTF8.GetBytes(rstr); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "application/x-ns-proxy-autoconfig"; @@ -66,10 +66,10 @@ namespace Netch.Utils.HttpProxyHandler } catch { - } // suppress any exceptions + // ignored + } finally { - // always close the stream ctx.Response.OutputStream.Close(); } }, @@ -77,9 +77,8 @@ namespace Netch.Utils.HttpProxyHandler } catch (Exception ex) { - //Logging.Error(ex.Message, ex); Logging.Error(ex.Message); - } // suppress any exceptions + } }); } diff --git a/Netch/Utils/ModeHelper.cs b/Netch/Utils/ModeHelper.cs index 735e24af..77eed669 100644 --- a/Netch/Utils/ModeHelper.cs +++ b/Netch/Utils/ModeHelper.cs @@ -141,7 +141,7 @@ namespace Netch.Utils }; } - public static IModeController GetModeControllerByType(int type, out ushort? port, out string portName, out PortType portType) + public static IModeController? GetModeControllerByType(int type, out ushort? port, out string portName, out PortType portType) { port = null; portName = string.Empty; diff --git a/Netch/Utils/OnlyInstance.cs b/Netch/Utils/OnlyInstance.cs index c28d745f..09f4a6e1 100644 --- a/Netch/Utils/OnlyInstance.cs +++ b/Netch/Utils/OnlyInstance.cs @@ -13,7 +13,7 @@ namespace Netch.Utils Exit } - public static event EventHandler Called; + public static event EventHandler? Called; private static void OnCalled(Commands e) { diff --git a/Netch/Utils/ServerHelper.cs b/Netch/Utils/ServerHelper.cs index 87d5bd11..86add0c1 100644 --- a/Netch/Utils/ServerHelper.cs +++ b/Netch/Utils/ServerHelper.cs @@ -59,7 +59,7 @@ namespace Netch.Utils return value != 0 && Range.InRange(value); } - public static event EventHandler TestDelayFinished; + public static event EventHandler? TestDelayFinished; public static void TestAllDelay() { @@ -98,37 +98,41 @@ namespace Netch.Utils public static readonly IEnumerable ServerUtils; - public static Server ParseJObject(JObject o) + public static Server? ParseJObject(JObject o) { - var handle = GetUtilByTypeName((string) o["Type"]); - if (handle == null) + try { - Logging.Warning($"不支持的服务器类型: {o["Type"]}"); + var type = (string) o["Type"]!; + var handle = GetUtilByTypeName(type); + + return handle.ParseJObject(o); + } + catch (Exception e) + { + Console.WriteLine($"读取服务器错误: {e}\n错误项: {o}"); return null; } - - return handle.ParseJObject(o); } public static IServerUtil GetUtilByTypeName(string typeName) { if (string.IsNullOrEmpty(typeName)) - return null; + throw new ArgumentNullException(); - return ServerUtils.FirstOrDefault(i => (i.TypeName ?? "").Equals(typeName)); + return ServerUtils.Single(i => i.TypeName.Equals(typeName)); } public static IServerUtil GetUtilByFullName(string fullName) { if (string.IsNullOrEmpty(fullName)) - return null; + throw new ArgumentNullException(); - return ServerUtils.FirstOrDefault(i => (i.FullName ?? "").Equals(fullName)); + return ServerUtils.Single(i => i.FullName.Equals(fullName)); } - public static IServerUtil GetUtilByUriScheme(string typeName) + public static IServerUtil? GetUtilByUriScheme(string typeName) { - return ServerUtils.FirstOrDefault(i => i.UriScheme.Any(s => s.Equals(typeName))); + return ServerUtils.SingleOrDefault(i => i.UriScheme.Any(s => s.Equals(typeName))); } #endregion diff --git a/Netch/Utils/ShareLink.cs b/Netch/Utils/ShareLink.cs index b3cf4f17..d7ff964f 100644 --- a/Netch/Utils/ShareLink.cs +++ b/Netch/Utils/ShareLink.cs @@ -85,13 +85,13 @@ namespace Netch.Utils catch (Exception e) { Logging.Error(e.ToString()); + Utils.Open(Logging.LogFile); } - foreach (var node in list) - if (!node.Remark.IsNullOrWhiteSpace()) - node.Remark = RemoveEmoji(node.Remark); + foreach (var node in list.Where(node => !node.Remark.IsNullOrWhiteSpace())) + node.Remark = RemoveEmoji(node.Remark); - return list.Where(s => s != null); + return list; } public static string GetUriScheme(string text) @@ -105,29 +105,13 @@ namespace Netch.Utils private static Server ParseNetchUri(string text) { - try - { - text = text.Substring(8); + text = text.Substring(8); - var NetchLink = (JObject) JsonConvert.DeserializeObject(URLSafeBase64Decode(text)); - if (NetchLink == null) - return null; + var jObject = (JObject) JsonConvert.DeserializeObject(URLSafeBase64Decode(text))!; - if (string.IsNullOrEmpty((string) NetchLink["Hostname"])) - return null; - - if (!ushort.TryParse((string) NetchLink["Port"], out _)) - return null; - - var type = (string) NetchLink["Type"]; - var s = ServerHelper.GetUtilByTypeName(type).ParseJObject(NetchLink); - return ServerHelper.GetUtilByTypeName(s.Type).CheckServer(s) ? s : null; - } - catch (Exception e) - { - Logging.Warning(e.ToString()); - return null; - } + var type = (string) jObject["Type"]!; + var s = ServerHelper.GetUtilByTypeName(type).ParseJObject(jObject); + return ServerHelper.GetUtilByTypeName(s.Type).CheckServer(s) ? s : throw new FormatException(); } public static string GetNetchLink(Server s) @@ -209,7 +193,7 @@ namespace Netch.Utils public static IEnumerable GetLines(this string str, bool removeEmptyLines = true) { using var sr = new StringReader(str); - string line; + string? line; while ((line = sr.ReadLine()) != null) { if (removeEmptyLines && string.IsNullOrWhiteSpace(line)) diff --git a/Netch/Utils/StringExtension.cs b/Netch/Utils/StringExtension.cs index 14c4bb45..d8138360 100644 --- a/Netch/Utils/StringExtension.cs +++ b/Netch/Utils/StringExtension.cs @@ -8,12 +8,12 @@ namespace Netch.Utils { public static class StringExtension { - public static bool IsNullOrEmpty(this string value) + public static bool IsNullOrEmpty(this string? value) { return string.IsNullOrEmpty(value); } - public static bool IsNullOrWhiteSpace(this string value) + public static bool IsNullOrWhiteSpace(this string? value) { return string.IsNullOrWhiteSpace(value); } @@ -28,20 +28,12 @@ namespace Netch.Utils public static bool IsWhiteSpace(this string value) { - foreach (var c in value) - { - if (char.IsWhiteSpace(c)) - continue; - - return false; - } - - return true; + return value.All(char.IsWhiteSpace); } public static IEnumerable NonWhiteSpaceLines(this TextReader reader) { - string line; + string? line; while ((line = reader.ReadLine()) != null) { if (line.IsWhiteSpace()) diff --git a/Netch/Utils/Subscription.cs b/Netch/Utils/Subscription.cs index 75e94d7d..85e2c403 100644 --- a/Netch/Utils/Subscription.cs +++ b/Netch/Utils/Subscription.cs @@ -11,12 +11,12 @@ namespace Netch.Utils { private static readonly object ServerLock = new(); - public static async Task UpdateServersAsync(string proxyServer = default) + public static async Task UpdateServersAsync(string? proxyServer = default) { await Task.WhenAll(Global.Settings.SubscribeLink.Select(item => Task.Run(() => UpdateServer(item, proxyServer))).ToArray()); } - public static void UpdateServer(SubscribeLink item, string proxyServer) + public static void UpdateServer(SubscribeLink item, string? proxyServer) { try { diff --git a/Netch/Utils/Utils.cs b/Netch/Utils/Utils.cs index ca70e5fe..82ae87e1 100644 --- a/Netch/Utils/Utils.cs +++ b/Netch/Utils/Utils.cs @@ -74,31 +74,31 @@ namespace Netch.Utils if (Hostname.Contains(":")) Hostname = Hostname.Split(':')[0]; - string Country; + string? country = null; try { var databaseReader = new DatabaseReader("bin\\GeoLite2-Country.mmdb"); if (IPAddress.TryParse(Hostname, out _)) { - Country = databaseReader.Country(Hostname).Country.IsoCode; + country = databaseReader.Country(Hostname).Country.IsoCode; } else { - var DnsResult = DNS.Lookup(Hostname); + var dnsResult = DNS.Lookup(Hostname); - if (DnsResult != null) - Country = databaseReader.Country(DnsResult).Country.IsoCode; - else - Country = "Unknown"; + if (dnsResult != null) + country = databaseReader.Country(dnsResult).Country.IsoCode; } } - catch (Exception) + catch { - Country = "Unknown"; + // ignored } - return Country == null ? "Unknown" : Country; + country ??= "Unknown"; + + return country; } public static string SHA256CheckSum(string filePath) @@ -173,12 +173,6 @@ namespace Netch.Utils } } - public static void LoggingAdapters(string id) - { - var adapter = NetworkInterface.GetAllNetworkInterfaces().First(adapter => adapter.Id == id); - Logging.Warning($"检索此网卡信息出错: {adapter.Name} {adapter.Id} {adapter.Description}"); - } - public static void DrawCenterComboBox(object sender, DrawItemEventArgs e) { if (sender is ComboBox cbx) diff --git a/Netch/Utils/WebUtil.cs b/Netch/Utils/WebUtil.cs index 2ead5298..5757d74b 100644 --- a/Netch/Utils/WebUtil.cs +++ b/Netch/Utils/WebUtil.cs @@ -18,10 +18,10 @@ namespace Netch.Utils private static int DefaultGetTimeout => Global.Settings.RequestTimeout; - public static HttpWebRequest CreateRequest(string url, int? timeout = null, string userAgent = null) + public static HttpWebRequest CreateRequest(string url, int? timeout = null, string? userAgent = null) { var req = (HttpWebRequest) WebRequest.Create(url); - req.UserAgent = string.IsNullOrEmpty(userAgent) ? DefaultUserAgent : userAgent; + req.UserAgent = string.IsNullOrWhiteSpace(userAgent) ? DefaultUserAgent : userAgent; req.Accept = "*/*"; req.KeepAlive = true; req.Timeout = timeout ?? DefaultGetTimeout; diff --git a/Netch/Utils/i18N.cs b/Netch/Utils/i18N.cs index f4e9d2da..dd053bd6 100644 --- a/Netch/Utils/i18N.cs +++ b/Netch/Utils/i18N.cs @@ -24,7 +24,7 @@ namespace Netch.Utils /// public static Hashtable Data = new(); - public static string LangCode { get; private set; } + public static string LangCode { get; private set; } = "en-US"; /// /// 加载 @@ -59,8 +59,11 @@ namespace Netch.Utils var dictionary = JsonConvert.DeserializeObject>(text); - if (dictionary == null) + if (!dictionary.Any()) + { + Logging.Error($"{LangCode} 语言文件错误"); return; + } Data = new Hashtable(); foreach (var v in dictionary) @@ -119,17 +122,17 @@ namespace Netch.Utils { switch (component) { - case TextBoxBase _: - case ListControl _: + case TextBoxBase: + case ListControl: break; - case Control c: - c.Text = Translate(c.Text); + case Control control: + control.Text = Translate(control.Text); break; - case ToolStripItem c: - c.Text = Translate(c.Text); + case ToolStripItem toolStripItem: + toolStripItem.Text = Translate(toolStripItem.Text); break; - case ColumnHeader c: - c.Text = Translate(c.Text); + case ColumnHeader columnHeader: + columnHeader.Text = Translate(columnHeader.Text); break; } }); diff --git a/UnitTest/Tests.cs b/UnitTest/Tests.cs deleted file mode 100644 index f9319540..00000000 --- a/UnitTest/Tests.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Windows.Forms; -using Netch.Servers.VMess.Form; -using Netch.Utils; - -namespace UnitTest -{ - public class Tests : TestBase - { - public static void TestServerForm() - { - i18N.Load("zh-CN"); - - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new VMessForm()); - } - } -} \ No newline at end of file