mirror of
https://github.com/KOP-XIAO/QuantumultX.git
synced 2026-01-25 17:15:09 +00:00
vless support
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
☑️ 资源解析器 ©𝐒𝐡𝐚𝐰𝐧 ⟦2024-01-10 09:30⟧
|
☑️ 资源解析器 ©𝐒𝐡𝐚𝐰𝐧 ⟦2024-01-17 21:30⟧
|
||||||
----------------------------------------------------------
|
----------------------------------------------------------
|
||||||
🛠 发现 𝐁𝐔𝐆 请反馈: https://t.me/Shawn_Parser_Bot
|
🛠 发现 𝐁𝐔𝐆 请反馈: https://t.me/Shawn_Parser_Bot
|
||||||
⛳️ 关注 🆃🅶 相关频道: https://t.me/QuanX_API
|
⛳️ 关注 🆃🅶 相关频道: https://t.me/QuanX_API
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
🤖 主要功能:
|
🤖 主要功能:
|
||||||
❶ 将其它格式的⟦服务器订阅⟧解析成 𝐐𝐮𝐚𝐧𝐭𝐮𝐦𝐮𝐥𝐭 𝐗 格式
|
❶ 将其它格式的⟦服务器订阅⟧解析成 𝐐𝐮𝐚𝐧𝐭𝐮𝐦𝐮𝐥𝐭 𝐗 格式
|
||||||
☑︎ 支持 𝐕2𝐫𝐚𝐲𝐍/𝗦𝗦(𝗥/𝗗)/𝗛𝗧𝗧𝗣(𝗦)/𝗧𝗿𝗼𝗷𝗮𝗻/𝗤𝘂𝗮𝗻𝘁𝘂𝗺𝘂𝗹𝘁(𝗫)/𝗦𝘂𝗿𝗴𝗲/𝐂𝐥𝐚𝐬𝐡/𝐒𝐡𝐚𝐝𝐨𝐰𝐫𝐨𝐜𝐤𝐞𝐭/𝐋𝐨𝐨𝐧 格式
|
☑︎ 支持 𝐕2𝐫𝐚𝐲𝐍/𝗦𝗦(𝗥/𝗗)/𝗛𝗧𝗧𝗣(𝗦)/𝗧𝗿𝗼𝗷𝗮𝗻/𝐕𝐋𝗲𝐬𝐬/𝗤𝘂𝗮𝗻𝘁𝘂𝗺𝘂𝗹𝘁(𝗫)/𝗦𝘂𝗿𝗴𝗲/𝐂𝐥𝐚𝐬𝐡/𝐒𝐡𝐚𝐝𝐨𝐰𝐫𝐨𝐜𝐤𝐞𝐭/𝐋𝐨𝐨𝐧 格式
|
||||||
☑︎ 提供说明 1⃣️ 中的可选个性化参数(筛选、重命名 等)
|
☑︎ 提供说明 1⃣️ 中的可选个性化参数(筛选、重命名 等)
|
||||||
❷ 𝗿𝗲𝘄𝗿𝗶𝘁𝗲(重写) & 𝗳𝗶𝗹𝘁𝗲𝗿(分流) 的 转换 & 筛选
|
❷ 𝗿𝗲𝘄𝗿𝗶𝘁𝗲(重写) & 𝗳𝗶𝗹𝘁𝗲𝗿(分流) 的 转换 & 筛选
|
||||||
☑︎ 用于禁用/修改远程引用中某(几)项 𝗿𝗲𝘄𝗿𝗶𝘁𝗲/𝗵𝗼𝘀𝘁𝗻𝗮𝗺𝗲/𝗳𝗶𝗹𝘁𝗲𝗿
|
☑︎ 用于禁用/修改远程引用中某(几)项 𝗿𝗲𝘄𝗿𝗶𝘁𝗲/𝗵𝗼𝘀𝘁𝗻𝗮𝗺𝗲/𝗳𝗶𝗹𝘁𝗲𝗿
|
||||||
@@ -449,7 +449,7 @@ function ResourceParse() {
|
|||||||
} else if (type0 == "JS-0") {
|
} else if (type0 == "JS-0") {
|
||||||
total = ""
|
total = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
//开始处理
|
//开始处理
|
||||||
if (flag == 1) { //server 类型统一处理
|
if (flag == 1) { //server 类型统一处理
|
||||||
total = isQuanX(total.filter(Boolean).join("\n"))
|
total = isQuanX(total.filter(Boolean).join("\n"))
|
||||||
@@ -581,7 +581,7 @@ function Type_Check(subs) {
|
|||||||
var ClashK = ["proxies:"]
|
var ClashK = ["proxies:"]
|
||||||
var SubK = ["dm1lc3M", "c3NyOi8v", "CnNzOi8", "dHJvamFu", "c3M6Ly", "c3NkOi8v", "c2hhZG93", "aHR0cDovLw", "aHR0cHM6L", "CnRyb2phbjo", "aHR0cD0", "aHR0cCA","U1RBVFVT"];
|
var SubK = ["dm1lc3M", "c3NyOi8v", "CnNzOi8", "dHJvamFu", "c3M6Ly", "c3NkOi8v", "c2hhZG93", "aHR0cDovLw", "aHR0cHM6L", "CnRyb2phbjo", "aHR0cD0", "aHR0cCA","U1RBVFVT"];
|
||||||
var RewriteK = [" url 302", " url 307", " url reject", " url script", " url req", " url res", " url echo", " url-and-header 302", " url-and-header 307", " url-and-header reject", " url-and-header script", " url-and-header req", " url-and-header res", " url-and-header echo"] // quantumult X 类型 rewrite
|
var RewriteK = [" url 302", " url 307", " url reject", " url script", " url req", " url res", " url echo", " url-and-header 302", " url-and-header 307", " url-and-header reject", " url-and-header script", " url-and-header req", " url-and-header res", " url-and-header echo"] // quantumult X 类型 rewrite
|
||||||
var SubK2 = ["ss://", "vmess://", "ssr://", "trojan://", "ssd://", "\nhttps://", "\nhttp://","socks://","ssocks://"];
|
var SubK2 = ["ss://", "vmess://", "ssr://", "trojan://", "ssd://", "\nhttps://", "\nhttp://","socks://","ssocks://","vless://"];
|
||||||
var ModuleK = ["[Script]", "[Rule]", "[URL Rewrite]", "[Map Local]", "\nhttp-r", "script-path"]
|
var ModuleK = ["[Script]", "[Rule]", "[URL Rewrite]", "[Map Local]", "\nhttp-r", "script-path"]
|
||||||
var QXProfile = ["[filter_local]","[filter_remote]","[server_local]","[server_remote]"]
|
var QXProfile = ["[filter_local]","[filter_remote]","[server_local]","[server_remote]"]
|
||||||
var html = "DOCTYPE html"
|
var html = "DOCTYPE html"
|
||||||
@@ -1553,7 +1553,7 @@ function Subs2QX(subs, Pudp, Ptfo, Pcert0, PTls13) {
|
|||||||
const NodeCheck1 = (item) => listi.toLowerCase().indexOf(item) == 0;
|
const NodeCheck1 = (item) => listi.toLowerCase().indexOf(item) == 0;
|
||||||
try {
|
try {
|
||||||
if (Pdbg) {$notify(i, type, list0[i])}
|
if (Pdbg) {$notify(i, type, list0[i])}
|
||||||
if (type == "vmess" && (list0[i].indexOf("remark=") == -1 && list0[i].indexOf("remarks=") == -1) && !/(obfs|alterId|type)\=/.test(list0[i])) {
|
if (type == "vmess" && (list0[i].indexOf("remark=") == -1 && list0[i].indexOf("remarks=") == -1) && !/(obfs|alterId|type|\@)\=/.test(list0[i])) {
|
||||||
var bnode = Base64.decode(list0[i].split("vmess://")[1])
|
var bnode = Base64.decode(list0[i].split("vmess://")[1])
|
||||||
if (bnode.indexOf("over-tls=") == -1) { //v2rayN
|
if (bnode.indexOf("over-tls=") == -1) { //v2rayN
|
||||||
node = V2QX(list0[i], Pudp, Ptfo, Pcert0, PTls13)
|
node = V2QX(list0[i], Pudp, Ptfo, Pcert0, PTls13)
|
||||||
@@ -1561,7 +1561,7 @@ function Subs2QX(subs, Pudp, Ptfo, Pcert0, PTls13) {
|
|||||||
node = VQ2QX(list0[i], Pudp, Ptfo, Pcert0, PTls13)
|
node = VQ2QX(list0[i], Pudp, Ptfo, Pcert0, PTls13)
|
||||||
}
|
}
|
||||||
node = tag0 != "" ? URI_TAG(node, tag0) : node
|
node = tag0 != "" ? URI_TAG(node, tag0) : node
|
||||||
} else if (type == "vmess" && ( list0[i].indexOf("remark=") != -1 || list0[i].indexOf("remarks=") != -1 || /(obfs|alterId|type)\=/.test(list0[i]))) { //shadowrocket 类型
|
} else if (type == "vmess" && ( list0[i].indexOf("remark=") != -1 || list0[i].indexOf("remarks=") != -1 || /(obfs|alterId|type|\@)\=/.test(list0[i]))) { //shadowrocket 类型
|
||||||
node = VR2QX(list0[i], Pudp, Ptfo, Pcert0, PTls13)
|
node = VR2QX(list0[i], Pudp, Ptfo, Pcert0, PTls13)
|
||||||
node = tag0 != "" ? URI_TAG(node, tag0) : node
|
node = tag0 != "" ? URI_TAG(node, tag0) : node
|
||||||
} else if (type == "socks" && list0[i].indexOf("remarks=") != -1) { //shadowrocket socks5 类型
|
} else if (type == "socks" && list0[i].indexOf("remarks=") != -1) { //shadowrocket socks5 类型
|
||||||
@@ -1591,16 +1591,18 @@ function Subs2QX(subs, Pudp, Ptfo, Pcert0, PTls13) {
|
|||||||
node = HPS2QX(listh, Ptfo, Pcert0, PTls13)
|
node = HPS2QX(listh, Ptfo, Pcert0, PTls13)
|
||||||
node = tag0 != "" ? URI_TAG(node, tag0) : node
|
node = tag0 != "" ? URI_TAG(node, tag0) : node
|
||||||
}
|
}
|
||||||
|
} else if (type == "vless" && version<821) {
|
||||||
|
Perror = 1 ; // 无需反馈
|
||||||
|
$notify("⚠️ Quantumult X 暂未支持 Vless 类型节点","请 ⚠️不要⚠️ 跑来 解析器🤖️ 反馈",list0[i])
|
||||||
|
} else if (type == "vless" ) { // version 150 support vless
|
||||||
|
node=VL2QX(list0[i], Pudp, Ptfo, Pcert0, PTls13)
|
||||||
} else if (QuanXK.some(NodeCheck1)) {
|
} else if (QuanXK.some(NodeCheck1)) {
|
||||||
node = QX_TLS(isQuanX(list0[i])[0], Pcert0, PTls13)
|
node = QX_TLS(isQuanX(list0[i])[0], Pcert0, PTls13)
|
||||||
} else if (SurgeK.some(NodeCheck)) {
|
} else if (SurgeK.some(NodeCheck)) {
|
||||||
node = QX_TLS(Surge2QX(list0[i])[0], Pcert0, PTls13)
|
node = QX_TLS(Surge2QX(list0[i])[0], Pcert0, PTls13)
|
||||||
} else if (LoonK.some(NodeCheck)) {
|
} else if (LoonK.some(NodeCheck)) {
|
||||||
node = Loon2QX(list0[i])
|
node = Loon2QX(list0[i])
|
||||||
} else if (type == "vless") {
|
}
|
||||||
Perror = 1 ; // 无需反馈
|
|
||||||
$notify("⚠️ Quantumult X 暂未支持 Vless 类型节点","请 ⚠️不要⚠️ 跑来 解析器🤖️ 反馈",list0[i])
|
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
failedList.push(`<<<\nContent: ${list0[i]}\nError: ${e}`)
|
failedList.push(`<<<\nContent: ${list0[i]}\nError: ${e}`)
|
||||||
}
|
}
|
||||||
@@ -1842,9 +1844,10 @@ function S5R2QX(cnt,tlsp="false") {
|
|||||||
var QX = nss.filter(Boolean).join(",");
|
var QX = nss.filter(Boolean).join(",");
|
||||||
return QX
|
return QX
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//V2RayN uri转换成 QUANX 格式
|
//V2RayN uri 转换成 QUANX 格式
|
||||||
function V2QX(subs, Pudp, Ptfo, Pcert0, PTls13) {
|
function V2QX(subs, Pudp, Ptfo, Pcert0, PTls13) {
|
||||||
//console.log("v2 type",subs)
|
//console.log("v2 type",subs)
|
||||||
var cert = Pcert0
|
var cert = Pcert0
|
||||||
@@ -2044,6 +2047,55 @@ function SSR2QX(subs, Pudp, Ptfo) {
|
|||||||
return QX;
|
return QX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vless uri 转换成 QUANX 格式
|
||||||
|
// vless://pwd@a.b.c.gq:443?encryption=none&security=tls&type=ws&host=a.b.c.d&path=dsjdaaaaj#VLESS_WSS
|
||||||
|
//;vless=example.com:443, method=none, password=23ad6b10-8d1a-40f7-8ad0-e3e35cd32291, obfs=wss, obfs-uri=/ws, fast-open=false, udp-relay=false, tag=vless-ws-tls-01
|
||||||
|
|
||||||
|
function VL2QX(subs, Pudp, Ptfo, Pcert0, PTls13) {
|
||||||
|
var nvless = []
|
||||||
|
var cnt = subs.split("vless://")[1]
|
||||||
|
type = "vless=";
|
||||||
|
ip = cnt.split("@")[1].split("encry")[0].split("?")[0];
|
||||||
|
pwd = cnt.split("@")[0]? "password=" + cnt.split("@")[0]:"";
|
||||||
|
mtd= "method=none"
|
||||||
|
obfs=""
|
||||||
|
pcert = cnt.indexOf("allowInsecure=0") != -1 ? "tls-verification=true" : "tls-verification=false";
|
||||||
|
thost = cnt.indexOf("sni=") != -1? "tls-host="+cnt.split("sni=")[1].split(/&|#/)[0]:""
|
||||||
|
thost = cnt.indexOf("peer=") != -1? "tls-host="+cnt.split("peer=")[1].split(/&|#/)[0]:thost
|
||||||
|
ptls13 = PTls13 == 1 ? "tls13=true" : "tls13=false"
|
||||||
|
puri = ""
|
||||||
|
if (Pcert0 == 0) {
|
||||||
|
pcert = "tls-verification=false"
|
||||||
|
} else if (Pcert0 == 1) {
|
||||||
|
pcert = "tls-verification=true"
|
||||||
|
}
|
||||||
|
pudp = (Pudp == 1 || cnt.indexOf("udp=1")!=-1) ? "udp-relay=true" : "udp-relay=false";
|
||||||
|
ptfo = (Ptfo == 1 || cnt.indexOf("tfo=1")!=-1)? "fast-open=true" : "fast-open=false";
|
||||||
|
//ptfo = cnt.indexOf("tfo=1") != -1? "fast-open=true" : ptfo
|
||||||
|
tag = cnt.indexOf("#") != -1 ? "tag=" + decodeURIComponent(cnt.split("#").slice(-1)[0]) : "tag= [vless]" + ip
|
||||||
|
if (cnt.indexOf("&plugin=obfs-local")!=-1) {//小火箭内的websocket写法
|
||||||
|
obfs = cnt.indexOf("obfs=websocket") != -1? "obfs=wss" : obfs
|
||||||
|
thost=cnt.indexOf("obfs-host=") == -1? thost : "obfs-host=" + decodeURIComponent(cnt.split("obfs-host=")[1].split(";")[0].split("#")[0])
|
||||||
|
puri = cnt.indexOf("path=") == -1? puri : "obfs-uri=" + decodeURIComponent(cnt.split("path=")[1].split(";")[0].split("#")[0])
|
||||||
|
} else if (cnt.indexOf("&type=ws")!=-1 || cnt.indexOf("?type=ws")!=-1 || cnt.indexOf("type=http")!=-1 || cnt.indexOf("security=tls")!=-1) {//v2rayN uri
|
||||||
|
if(cnt.indexOf("type=http") != -1) {
|
||||||
|
obfs="obfs=http"
|
||||||
|
} else if (cnt.indexOf("type=ws") != -1) {
|
||||||
|
obfs = cnt.indexOf("security=tls") != -1? "obfs=wss" : "obfs=ws"
|
||||||
|
} else if(cnt.indexOf("security=tls")!=-1) {
|
||||||
|
obfs = "obfs=over-tls"
|
||||||
|
}
|
||||||
|
thost=cnt.indexOf("&host=") == -1? thost : "obfs-host=" + decodeURIComponent(cnt.split("&host=")[1].split("&")[0].split("#")[0])
|
||||||
|
puri = cnt.indexOf("&path=") == -1? puri : "obfs-uri=" + decodeURIComponent(cnt.split("&path=")[1].split("&")[0].split("#")[0])
|
||||||
|
} else if(cnt.indexOf("type=")!=-1 || cnt.indexOf("security=xtls")!=-1) { //暂不支持类型
|
||||||
|
type="NS"
|
||||||
|
}
|
||||||
|
nvless.push(type + ip, pwd, mtd, obfs, pcert, thost, puri, pudp, ptfo, tag)
|
||||||
|
QX = type!="NS"? nvless.filter(Boolean).join(", ") : ""
|
||||||
|
//$notify("VLESS","subtitle",QX)
|
||||||
|
return QX
|
||||||
|
}
|
||||||
|
|
||||||
//Trojan 类型 URI 转换成 QX, 包含小火箭类型
|
//Trojan 类型 URI 转换成 QX, 包含小火箭类型
|
||||||
function TJ2QX(subs, Pudp, Ptfo, Pcert0, PTls13) {
|
function TJ2QX(subs, Pudp, Ptfo, Pcert0, PTls13) {
|
||||||
var ntrojan = []
|
var ntrojan = []
|
||||||
@@ -2222,12 +2274,12 @@ function isQuanX(content) {
|
|||||||
var cnti = cnts[i];
|
var cnti = cnts[i];
|
||||||
if (cnti.indexOf("=") != -1 && cnti.indexOf("tag") != -1) {
|
if (cnti.indexOf("=") != -1 && cnti.indexOf("tag") != -1) {
|
||||||
var cnt = cnti.split("=")[0].trim()
|
var cnt = cnti.split("=")[0].trim()
|
||||||
if (cnt == "http" || cnt == "shadowsocks" || cnt == "trojan" || cnt == "vmess"|| cnt == "socks5") {
|
if (cnt == "http" || cnt == "shadowsocks" || cnt == "trojan" || cnt == "vmess" || cnt == "socks5" || cnt == "vless") {
|
||||||
nlist.push(QXFix(cnti))
|
nlist.push(QXFix(cnti))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nlist
|
return nlist
|
||||||
}
|
}
|
||||||
|
|
||||||
//surge script/quanx-rewrite - > quanx
|
//surge script/quanx-rewrite - > quanx
|
||||||
@@ -2574,7 +2626,11 @@ function get_emoji(emojip, sname) {
|
|||||||
"🇸🇷": ["苏里南","蘇里南"],
|
"🇸🇷": ["苏里南","蘇里南"],
|
||||||
"🇲🇨": ["摩纳哥","摩納哥"],
|
"🇲🇨": ["摩纳哥","摩納哥"],
|
||||||
"🇯🇲": ["牙买加","牙買加 "],
|
"🇯🇲": ["牙买加","牙買加 "],
|
||||||
"🌏": ["亚洲","Asia"]
|
"🌏": ["亚洲","Asia"],
|
||||||
|
"🇹🇬": ["多哥"],
|
||||||
|
"🇵🇸": ["巴勒斯坦"],
|
||||||
|
"🇬🇫": ["法屬圭亞那","法属圭亚那"],
|
||||||
|
"🇹🇹": ["特立尼达和多巴哥","特立尼達和多巴哥"]
|
||||||
}
|
}
|
||||||
str1 = JSON.stringify(Lmoji)
|
str1 = JSON.stringify(Lmoji)
|
||||||
aa = JSON.parse(str1)
|
aa = JSON.parse(str1)
|
||||||
|
|||||||
Reference in New Issue
Block a user