mirror of
https://github.com/netchx/netch.git
synced 2026-05-11 23:45:06 +08:00
Compare commits
7 Commits
v1.4.1-Bet
...
v1.4.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bdaab4f1ac | ||
|
|
9ad5e16f47 | ||
|
|
c861ed4116 | ||
|
|
c39b758fe6 | ||
|
|
e1901587a5 | ||
|
|
8aea21a2c6 | ||
|
|
d97d461354 |
@@ -127,14 +127,18 @@ namespace Netch.Controllers
|
|||||||
enabled = server.UseMux
|
enabled = server.UseMux
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new Models.Information.VMess.Outbounds
|
//此处修复一个诡异的BUG 感谢@ColinWood Tap模式 Mux不能为Null 否则Netch内存占用极大
|
||||||
|
/*new Models.Information.VMess.Outbounds
|
||||||
{
|
{
|
||||||
tag = "direct",
|
tag = "direct",
|
||||||
protocol = "freedom",
|
protocol = "freedom",
|
||||||
settings = null,
|
settings = null,
|
||||||
streamSettings = null,
|
streamSettings = null,
|
||||||
|
*//*mux = new Models.Information.VMess.OutboundMux(){
|
||||||
|
enabled = true
|
||||||
|
}*//*
|
||||||
mux = null
|
mux = null
|
||||||
}
|
}*/
|
||||||
},
|
},
|
||||||
routing = new Models.Information.VMess.Routing
|
routing = new Models.Information.VMess.Routing
|
||||||
{
|
{
|
||||||
@@ -147,7 +151,7 @@ namespace Netch.Controllers
|
|||||||
{
|
{
|
||||||
"geoip:cn",
|
"geoip:cn",
|
||||||
"geoip:private"
|
"geoip:private"
|
||||||
|
|
||||||
},
|
},
|
||||||
domain = new List<string>
|
domain = new List<string>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1254,7 +1254,15 @@ namespace Netch.Forms
|
|||||||
if (ServerComboBox.SelectedIndex != -1)
|
if (ServerComboBox.SelectedIndex != -1)
|
||||||
{
|
{
|
||||||
var selectedMode = (Models.Server)ServerComboBox.SelectedItem;
|
var selectedMode = (Models.Server)ServerComboBox.SelectedItem;
|
||||||
Clipboard.SetText(Utils.ShareLink.GetShareLink(selectedMode));
|
try
|
||||||
|
{
|
||||||
|
//听说巨硬BUG经常会炸,所以Catch一下 :D
|
||||||
|
Clipboard.SetText(Utils.ShareLink.GetShareLink(selectedMode));
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
8
Netch/Forms/SettingForm.Designer.cs
generated
8
Netch/Forms/SettingForm.Designer.cs
generated
@@ -329,7 +329,7 @@
|
|||||||
// BypassModeCheckBox
|
// BypassModeCheckBox
|
||||||
//
|
//
|
||||||
this.BypassModeCheckBox.AutoSize = true;
|
this.BypassModeCheckBox.AutoSize = true;
|
||||||
this.BypassModeCheckBox.Location = new System.Drawing.Point(276, 232);
|
this.BypassModeCheckBox.Location = new System.Drawing.Point(276, 236);
|
||||||
this.BypassModeCheckBox.Name = "BypassModeCheckBox";
|
this.BypassModeCheckBox.Name = "BypassModeCheckBox";
|
||||||
this.BypassModeCheckBox.Size = new System.Drawing.Size(135, 21);
|
this.BypassModeCheckBox.Size = new System.Drawing.Size(135, 21);
|
||||||
this.BypassModeCheckBox.TabIndex = 14;
|
this.BypassModeCheckBox.TabIndex = 14;
|
||||||
@@ -340,7 +340,7 @@
|
|||||||
// Redirector2checkBox
|
// Redirector2checkBox
|
||||||
//
|
//
|
||||||
this.Redirector2checkBox.AutoSize = true;
|
this.Redirector2checkBox.AutoSize = true;
|
||||||
this.Redirector2checkBox.Location = new System.Drawing.Point(152, 232);
|
this.Redirector2checkBox.Location = new System.Drawing.Point(152, 235);
|
||||||
this.Redirector2checkBox.Name = "Redirector2checkBox";
|
this.Redirector2checkBox.Name = "Redirector2checkBox";
|
||||||
this.Redirector2checkBox.Size = new System.Drawing.Size(118, 21);
|
this.Redirector2checkBox.Size = new System.Drawing.Size(118, 21);
|
||||||
this.Redirector2checkBox.TabIndex = 11;
|
this.Redirector2checkBox.TabIndex = 11;
|
||||||
@@ -350,7 +350,7 @@
|
|||||||
// ExperimentalFunction_Label
|
// ExperimentalFunction_Label
|
||||||
//
|
//
|
||||||
this.ExperimentalFunction_Label.AutoSize = true;
|
this.ExperimentalFunction_Label.AutoSize = true;
|
||||||
this.ExperimentalFunction_Label.Location = new System.Drawing.Point(6, 233);
|
this.ExperimentalFunction_Label.Location = new System.Drawing.Point(6, 236);
|
||||||
this.ExperimentalFunction_Label.Name = "ExperimentalFunction_Label";
|
this.ExperimentalFunction_Label.Name = "ExperimentalFunction_Label";
|
||||||
this.ExperimentalFunction_Label.Size = new System.Drawing.Size(133, 17);
|
this.ExperimentalFunction_Label.Size = new System.Drawing.Size(133, 17);
|
||||||
this.ExperimentalFunction_Label.TabIndex = 13;
|
this.ExperimentalFunction_Label.TabIndex = 13;
|
||||||
@@ -358,7 +358,7 @@
|
|||||||
//
|
//
|
||||||
// STUN_ServerPortTextBox
|
// STUN_ServerPortTextBox
|
||||||
//
|
//
|
||||||
this.STUN_ServerPortTextBox.Location = new System.Drawing.Point(117, 203);
|
this.STUN_ServerPortTextBox.Location = new System.Drawing.Point(117, 206);
|
||||||
this.STUN_ServerPortTextBox.Name = "STUN_ServerPortTextBox";
|
this.STUN_ServerPortTextBox.Name = "STUN_ServerPortTextBox";
|
||||||
this.STUN_ServerPortTextBox.Size = new System.Drawing.Size(294, 23);
|
this.STUN_ServerPortTextBox.Size = new System.Drawing.Size(294, 23);
|
||||||
this.STUN_ServerPortTextBox.TabIndex = 8;
|
this.STUN_ServerPortTextBox.TabIndex = 8;
|
||||||
|
|||||||
@@ -147,12 +147,12 @@ namespace Netch.Models
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// STUN测试服务器
|
/// STUN测试服务器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string STUN_Server = "stun.stunprotocol.org";
|
public string STUN_Server = "stun.l.google.com";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// STUN测试服务器
|
/// STUN测试服务器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int STUN_Server_Port = 3478;
|
public int STUN_Server_Port = 19302;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否切换为2号核心
|
/// 是否切换为2号核心
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ namespace Netch.Override
|
|||||||
protected override WebRequest GetWebRequest(Uri address)
|
protected override WebRequest GetWebRequest(Uri address)
|
||||||
{
|
{
|
||||||
var request = base.GetWebRequest(address);
|
var request = base.GetWebRequest(address);
|
||||||
request.Timeout = 4000;
|
request.Timeout = 10000;
|
||||||
((HttpWebRequest)request).ReadWriteTimeout = 4000;
|
((HttpWebRequest)request).ReadWriteTimeout = 10000;
|
||||||
|
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -290,80 +290,88 @@ namespace Netch.Utils
|
|||||||
}
|
}
|
||||||
else if (text.StartsWith("ssr://"))
|
else if (text.StartsWith("ssr://"))
|
||||||
{
|
{
|
||||||
var data = new Server();
|
|
||||||
data.Type = "SSR";
|
|
||||||
|
|
||||||
text = text.Substring(6);
|
list.Add(SsrServerFromLink(text));
|
||||||
|
|
||||||
var parser = new Regex(@"^(?<server>.+):(?<port>(-?\d+?)):(?<protocol>.+?):(?<method>.+?):(?<obfs>.+?):(?<password>.+?)/\?(?<info>.*)$");
|
/* var data = new Server();
|
||||||
var match = parser.Match(URLSafeBase64Decode(text));
|
data.Type = "SSR";
|
||||||
|
|
||||||
if (match.Success)
|
text = text.Substring(6);
|
||||||
{
|
|
||||||
data.Hostname = match.Groups["server"].Value;
|
|
||||||
data.Port = int.Parse(match.Groups["port"].Value);
|
|
||||||
if (data.Port < 0)
|
|
||||||
{
|
|
||||||
data.Port += 65536;
|
|
||||||
}
|
|
||||||
data.Password = URLSafeBase64Decode(match.Groups["password"].Value);
|
|
||||||
|
|
||||||
data.EncryptMethod = match.Groups["method"].Value;
|
var parser = new Regex(@"^(?<server>.+):(?<port>(-?\d+?)):(?<protocol>.+?):(?<method>.+?):(?<obfs>.+?):(?<password>.+?)/\?(?<info>.*)$");
|
||||||
if (!Global.EncryptMethods.SSR.Contains(data.EncryptMethod))
|
var parser2 = new Regex(@"^(?<server>.+):(?<port>(-?\d+?)):(?<protocol>.+?):(?<method>.+?):(?<obfs>.+?):(?<password>.+?)/$");
|
||||||
{
|
var match = parser2.Match(URLSafeBase64Decode(text));
|
||||||
Logging.Info(string.Format("不支持的 SSR 加密方式:{0}", data.EncryptMethod));
|
if (!match.Success)
|
||||||
return null;
|
{
|
||||||
}
|
match = parser2.Match(UnBase64String(text));
|
||||||
|
}
|
||||||
|
|
||||||
data.Protocol = match.Groups["protocol"].Value;
|
if (match.Success)
|
||||||
if (!Global.Protocols.Contains(data.Protocol))
|
{
|
||||||
{
|
data.Hostname = match.Groups["server"].Value;
|
||||||
Logging.Info(string.Format("不支持的 SSR 协议:{0}", data.Protocol));
|
data.Port = int.Parse(match.Groups["port"].Value);
|
||||||
return null;
|
if (data.Port < 0)
|
||||||
}
|
{
|
||||||
|
data.Port += 65536;
|
||||||
|
}
|
||||||
|
data.Password = URLSafeBase64Decode(match.Groups["password"].Value);
|
||||||
|
|
||||||
data.OBFS = match.Groups["obfs"].Value;
|
data.EncryptMethod = match.Groups["method"].Value;
|
||||||
if (data.OBFS == @"tls1.2_ticket_fastauth")
|
if (!Global.EncryptMethods.SSR.Contains(data.EncryptMethod))
|
||||||
{
|
{
|
||||||
data.OBFS = @"tls1.2_ticket_auth";
|
Logging.Info(string.Format("不支持的 SSR 加密方式:{0}", data.EncryptMethod));
|
||||||
}
|
return null;
|
||||||
if (!Global.OBFSs.Contains(data.OBFS))
|
}
|
||||||
{
|
|
||||||
Logging.Info(string.Format("不支持的 SSR 混淆:{0}", data.OBFS));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var info = match.Groups["info"].Value;
|
data.Protocol = match.Groups["protocol"].Value;
|
||||||
var dict = new Dictionary<string, string>();
|
if (!Global.Protocols.Contains(data.Protocol))
|
||||||
foreach (var str in info.Split('&'))
|
{
|
||||||
{
|
Logging.Info(string.Format("不支持的 SSR 协议:{0}", data.Protocol));
|
||||||
var splited = str.Split('=');
|
return null;
|
||||||
dict.Add(splited[0], splited[1]);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (dict.ContainsKey("remarks"))
|
data.OBFS = match.Groups["obfs"].Value;
|
||||||
{
|
if (data.OBFS == @"tls1.2_ticket_fastauth")
|
||||||
data.Remark = URLSafeBase64Decode(dict["remarks"]);
|
{
|
||||||
}
|
data.OBFS = @"tls1.2_ticket_auth";
|
||||||
|
}
|
||||||
|
if (!Global.OBFSs.Contains(data.OBFS))
|
||||||
|
{
|
||||||
|
Logging.Info(string.Format("不支持的 SSR 混淆:{0}", data.OBFS));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (dict.ContainsKey("protoparam"))
|
var info = match.Groups["info"].Value;
|
||||||
{
|
var dict = new Dictionary<string, string>();
|
||||||
data.ProtocolParam = URLSafeBase64Decode(dict["protoparam"]);
|
foreach (var str in info.Split('&'))
|
||||||
}
|
{
|
||||||
|
var splited = str.Split('=');
|
||||||
|
dict.Add(splited[0], splited[1]);
|
||||||
|
}
|
||||||
|
|
||||||
if (dict.ContainsKey("obfsparam"))
|
if (dict.ContainsKey("remarks"))
|
||||||
{
|
{
|
||||||
data.OBFSParam = URLSafeBase64Decode(dict["obfsparam"]);
|
data.Remark = URLSafeBase64Decode(dict["remarks"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Global.EncryptMethods.SS.Contains(data.EncryptMethod) && data.Protocol == "origin" && data.OBFS == "plain")
|
if (dict.ContainsKey("protoparam"))
|
||||||
{
|
{
|
||||||
data.OBFS = "";
|
data.ProtocolParam = URLSafeBase64Decode(dict["protoparam"]);
|
||||||
data.Type = "SS";
|
}
|
||||||
}
|
|
||||||
}
|
if (dict.ContainsKey("obfsparam"))
|
||||||
|
{
|
||||||
|
data.OBFSParam = URLSafeBase64Decode(dict["obfsparam"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Global.EncryptMethods.SS.Contains(data.EncryptMethod) && data.Protocol == "origin" && data.OBFS == "plain")
|
||||||
|
{
|
||||||
|
data.OBFS = "";
|
||||||
|
data.Type = "SS";
|
||||||
|
}
|
||||||
|
list.Add(data);
|
||||||
|
}*/
|
||||||
|
|
||||||
list.Add(data);
|
|
||||||
}
|
}
|
||||||
else if (text.StartsWith("vmess://"))
|
else if (text.StartsWith("vmess://"))
|
||||||
{
|
{
|
||||||
@@ -517,5 +525,123 @@ namespace Netch.Utils
|
|||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
public static string UnBase64String(string value)
|
||||||
|
{
|
||||||
|
if (value == null || value == "")
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
byte[] bytes = Convert.FromBase64String(value);
|
||||||
|
return Encoding.UTF8.GetString(bytes);
|
||||||
|
}
|
||||||
|
public static string ToBase64String(string value)
|
||||||
|
{
|
||||||
|
if (value == null || value == "")
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
byte[] bytes = Encoding.UTF8.GetBytes(value);
|
||||||
|
return Convert.ToBase64String(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// SSR链接解析器
|
||||||
|
/// Copy From https://github.com/HMBSbige/ShadowsocksR-Windows/blob/d9dc8d032a6e04c14b9dc6c8f673c9cc5aa9f607/shadowsocks-csharp/Model/Server.cs#L428
|
||||||
|
/// Thx :D
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ssrUrl"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Server SsrServerFromLink(string ssrUrl)
|
||||||
|
{
|
||||||
|
// ssr://host:port:protocol:method:obfs:base64pass/?obfsparam=base64&remarks=base64&group=base64&udpport=0&uot=1
|
||||||
|
var ssr = Regex.Match(ssrUrl, "ssr://([A-Za-z0-9_-]+)", RegexOptions.IgnoreCase);
|
||||||
|
if (!ssr.Success)
|
||||||
|
throw new FormatException();
|
||||||
|
|
||||||
|
var data = URLSafeBase64Decode(ssr.Groups[1].Value);
|
||||||
|
var params_dict = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
var param_start_pos = data.IndexOf("?", StringComparison.Ordinal);
|
||||||
|
if (param_start_pos > 0)
|
||||||
|
{
|
||||||
|
params_dict = ParseParam(data.Substring(param_start_pos + 1));
|
||||||
|
data = data.Substring(0, param_start_pos);
|
||||||
|
}
|
||||||
|
if (data.IndexOf("/", StringComparison.Ordinal) >= 0)
|
||||||
|
{
|
||||||
|
data = data.Substring(0, data.LastIndexOf("/", StringComparison.Ordinal));
|
||||||
|
}
|
||||||
|
|
||||||
|
var UrlFinder = new Regex("^(.+):([^:]+):([^:]*):([^:]+):([^:]*):([^:]+)");
|
||||||
|
var match = UrlFinder.Match(data);
|
||||||
|
|
||||||
|
if (match == null || !match.Success)
|
||||||
|
throw new FormatException();
|
||||||
|
|
||||||
|
var serverAddr = match.Groups[1].Value;
|
||||||
|
var Server_Port = ushort.Parse(match.Groups[2].Value);
|
||||||
|
var Protocol = match.Groups[3].Value.Length == 0 ? "origin" : match.Groups[3].Value;
|
||||||
|
Protocol = Protocol.Replace("_compatible", "");
|
||||||
|
var Method = match.Groups[4].Value;
|
||||||
|
var obfs = match.Groups[5].Value.Length == 0 ? "plain" : match.Groups[5].Value;
|
||||||
|
obfs = obfs.Replace("_compatible", "");
|
||||||
|
var Password = URLSafeBase64Decode(match.Groups[6].Value);
|
||||||
|
var ProtocolParam = "";
|
||||||
|
var ObfsParam = "";
|
||||||
|
var Remarks = "";
|
||||||
|
var Group = "";
|
||||||
|
|
||||||
|
if (params_dict.ContainsKey("protoparam"))
|
||||||
|
{
|
||||||
|
ProtocolParam = URLSafeBase64Decode(params_dict["protoparam"]);
|
||||||
|
}
|
||||||
|
if (params_dict.ContainsKey("obfsparam"))
|
||||||
|
{
|
||||||
|
ObfsParam = URLSafeBase64Decode(params_dict["obfsparam"]);
|
||||||
|
}
|
||||||
|
if (params_dict.ContainsKey("remarks"))
|
||||||
|
{
|
||||||
|
Remarks = URLSafeBase64Decode(params_dict["remarks"]);
|
||||||
|
}
|
||||||
|
Group = params_dict.ContainsKey("group") ? URLSafeBase64Decode(params_dict["group"]) : string.Empty;
|
||||||
|
|
||||||
|
/*if (params_dict.ContainsKey("uot"))
|
||||||
|
{
|
||||||
|
UdpOverTcp = int.Parse(params_dict["uot"]) != 0;
|
||||||
|
}
|
||||||
|
if (params_dict.ContainsKey("udpport"))
|
||||||
|
{
|
||||||
|
Server_Udp_Port = ushort.Parse(params_dict["udpport"]);
|
||||||
|
}*/
|
||||||
|
Server server = new Server();
|
||||||
|
server.Type = "SSR";
|
||||||
|
server.Hostname = serverAddr;
|
||||||
|
server.Port = Server_Port;
|
||||||
|
server.Protocol = Protocol;
|
||||||
|
server.EncryptMethod = Method;
|
||||||
|
server.OBFS = obfs;
|
||||||
|
server.Password = Password;
|
||||||
|
server.ProtocolParam = ProtocolParam;
|
||||||
|
server.OBFSParam = ObfsParam;
|
||||||
|
server.Remark = Remarks;
|
||||||
|
server.Group = Group;
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
private static Dictionary<string, string> ParseParam(string paramStr)
|
||||||
|
{
|
||||||
|
var paramsDict = new Dictionary<string, string>();
|
||||||
|
var obfsParams = paramStr.Split('&');
|
||||||
|
foreach (var p in obfsParams)
|
||||||
|
{
|
||||||
|
if (p.IndexOf('=') > 0)
|
||||||
|
{
|
||||||
|
var index = p.IndexOf('=');
|
||||||
|
var key = p.Substring(0, index);
|
||||||
|
var val = p.Substring(index + 1);
|
||||||
|
paramsDict[key] = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return paramsDict;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
modes
2
modes
Submodule modes updated: 0062332e64...de2c3c7cf1
Reference in New Issue
Block a user