Skip to content

Commit

Permalink
Merge pull request #32 from InvisibleManVPN/develop
Browse files Browse the repository at this point in the history
InvisibleMan XRay version 0.3.0
  • Loading branch information
InvisibleManVPN authored Mar 18, 2023
2 parents aa286ad + cbd68fe commit 494c0c3
Show file tree
Hide file tree
Showing 4 changed files with 241 additions and 2 deletions.
2 changes: 2 additions & 0 deletions InvisibleMan-XRay/Handlers/TemplateHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ void RegisterTemplates()
{
templates.Add("vmess", typeof(Vmess));
templates.Add("vless", typeof(Vless));
templates.Add("trojan", typeof(Trojan));
templates.Add("ss", typeof(Shadowsocks));
}
}

Expand Down
4 changes: 2 additions & 2 deletions InvisibleMan-XRay/InvisibleMan-XRay.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
<PackageId>InvisibleMan XRay</PackageId>
<Company>InvisibleMan</Company>
<Copyright>Copyright (C) 2023 Invisible Man</Copyright>
<Version>0.1.0.0</Version>
<AssemblyVersion>0.1.0.0</AssemblyVersion>
<Version>0.3.0.0</Version>
<AssemblyVersion>0.3.0.0</AssemblyVersion>
<Nullable>enable</Nullable>
<NoWarn>0108;8600;8601;8602;8603;8604;8618;8625;8762</NoWarn>
<UseWPF>true</UseWPF>
Expand Down
102 changes: 102 additions & 0 deletions InvisibleMan-XRay/Models/Templates/Shadowsocks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
using System;
using System.Linq;
using System.Text;

namespace InvisibleManXRay.Models.Templates
{
using Values;

public class Shadowsocks : Template
{
public class Data
{
public Uri uri;
public string security;
public string id;
public string remark;

public Data(string url)
{
this.uri = new Uri(url);
this.remark = url.Split("#")[1];
}
}

private Data data;
private readonly string[] validSecurity = new[] {
"aes-256-gcm",
"aes-128-gcm",
"chacha20-poly1305",
"chacha20-ietf-poly1305",
"xchacha20-poly1305",
"xchacha20-ietf-poly1305",
"none",
"plain",
"2022-blake3-aes-128-gcm",
"2022-blake3-aes-256-gcm",
"2022-blake3-chacha20-poly1305"
};

public override Status FetchDataFromLink(string link)
{
try
{
data = new Data(link);
FetchRemark();
MapDecodedLinkToData(decodedString: DecodeBase64Link());

return new Status(Code.SUCCESS, SubCode.SUCCESS, null);
}
catch(Exception)
{
return new Status(
code: Code.ERROR,
subCode: SubCode.INVALID_CONFIG,
content: Message.INVALID_CONFIG
);
}

string DecodeBase64Link()
{
string base64String = link.Split("@").FirstOrDefault().Replace("ss://", "");
byte[] dataBytes = Convert.FromBase64String(base64String);

return Encoding.UTF8.GetString(dataBytes);
}

void MapDecodedLinkToData(string decodedString)
{
string[] stringArray = decodedString.Split(":");
data.security = stringArray[0];
data.id = stringArray[1];
}

void FetchRemark()
{
data.remark = Uri.UnescapeDataString(data.uri.ToString().Split("#")[1]);
}
}

protected override Adapter Adapter => new Adapter() {
type = "shadowsocks",
remark = data.remark,
address = data.uri.IdnHost,
port = data.uri.Port,
id = data.id,
security = data.security
};

protected override V2Ray.Outbound.Settings OutboundSettings => new V2Ray.Outbound.Settings() {
servers = new V2Ray.Outbound.Settings.Server[] {
new V2Ray.Outbound.Settings.Server() {
address = Adapter.address,
port = Adapter.port,
password = Adapter.id,
ota = false,
level = 1,
method = validSecurity.Contains(Adapter.security) ? Adapter.security : "none"
}
}
};
}
}
135 changes: 135 additions & 0 deletions InvisibleMan-XRay/Models/Templates/Trojan.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
using System;
using System.Web;
using System.Collections.Specialized;

namespace InvisibleManXRay.Models.Templates
{
using Values;

public class Trojan : Template
{
public class Data
{
public Uri uri;
public NameValueCollection query;

public Data(string url)
{
this.uri = new Uri(url);
this.query = HttpUtility.ParseQueryString(uri.Query);
}
}

private Data data;

public override Status FetchDataFromLink(string link)
{
data = new Data(link);

if (IsInvalidLink())
return new Status(
code: Code.ERROR,
subCode: SubCode.INVALID_CONFIG,
content: Message.INVALID_CONFIG
);

return new Status(Code.SUCCESS, SubCode.SUCCESS, null);

bool IsInvalidLink() => data.query.Count == 0;
}

protected override Adapter Adapter
{
get
{
Adapter adapter = new Adapter() {
type = "trojan",
remark = data.uri.GetComponents(UriComponents.Fragment, UriFormat.Unescaped),
address = data.uri.IdnHost,
port = data.uri.Port,
id = data.uri.UserInfo,
security = data.query["encryption"] ?? "none",
streamNetwork = data.query["type"] ?? "tcp",
streamSecurity = data.query["security"] ?? "",
flow = data.query["flow"] ?? "",
sni = data.query["sni"] ?? "",
alpn = HttpUtility.UrlDecode(data.query["alpn"] ?? ""),
fingerprint = HttpUtility.UrlDecode(data.query["fp"] ?? "")
};

switch (adapter.streamNetwork)
{
case "tcp":
adapter.headerType = data.query["headerType"] ?? "none";
adapter.requestHost = HttpUtility.UrlDecode(data.query["host"] ?? "");
break;
case "kcp":
adapter.headerType = data.query["headerType"] ?? "none";
adapter.path = HttpUtility.UrlDecode(data.query["seed"] ?? "");
break;
case "ws":
adapter.requestHost = HttpUtility.UrlDecode(data.query["host"] ?? "");
adapter.path = HttpUtility.UrlDecode(data.query["path"] ?? "/");
break;
case "http":
case "h2":
adapter.streamNetwork = "h2";
adapter.requestHost = HttpUtility.UrlDecode(data.query["host"] ?? "");
adapter.path = HttpUtility.UrlDecode(data.query["path"] ?? "/");
break;
case "quic":
adapter.headerType = data.query["headerType"] ?? "none";
adapter.requestHost = data.query["quicSecurity"] ?? "none";
adapter.path = HttpUtility.UrlDecode(data.query["key"] ?? "");
break;
case "grpc":
adapter.path = HttpUtility.UrlDecode(data.query["serviceName"] ?? "");
adapter.headerType = HttpUtility.UrlDecode(data.query["mode"] ?? "gun");
break;
default:
break;
}

return adapter;
}
}

protected override V2Ray.Outbound.Settings OutboundSettings
{
get
{
if (Adapter.streamSecurity == Global.StreamSecurity.XTLS)
{
if (string.IsNullOrEmpty(Adapter.flow))
Adapter.flow = "xtls-rprx-origin";
else
Adapter.flow = Adapter.flow.Replace("splice", "direct");
}

return new V2Ray.Outbound.Settings() {
servers = new V2Ray.Outbound.Settings.Server[] {
new V2Ray.Outbound.Settings.Server() {
address = Adapter.address,
port = Adapter.port,
password = Adapter.id,
ota = false,
level = 1,
flow = SetServerFlow()
}
}
};

string SetServerFlow()
{
if (Adapter.streamSecurity != "xtls")
return string.Empty;

if (string.IsNullOrEmpty(Adapter.flow))
return "xtls-rprx-origin";

return Adapter.flow.Replace("splice", "direct");
}
}
}
}
}

0 comments on commit 494c0c3

Please sign in to comment.