Compare commits

..

4 Commits

Author SHA1 Message Date
xream
6afec4f668 feat: Egern 增加 TUIC
Some checks failed
build / build (push) Has been cancelled
2025-01-23 08:22:48 +08:00
xream
b1874e510d feat: 支持 VLESS XHTTP extra
Some checks are pending
build / build (push) Waiting to run
2025-01-22 09:43:43 +08:00
xream
48aaaf5c99 doc: README 2025-01-21 12:02:49 +08:00
xream
7385e17a4c fix: 修复 Base64 合法性判断
Some checks failed
build / build (push) Has been cancelled
2025-01-17 16:34:30 +08:00
6 changed files with 33 additions and 5 deletions

View File

@@ -28,7 +28,7 @@ Core functionalities:
> ⚠️ Do not use `Shadowrocket` to export URI and then import it as input. It is not a standard URI.
- [x] Normal Proxy(`socks5`, `socks5+tls`, `http`, `https`(it's ok))
- [x] Proxy URI Scheme(`socks5`, `socks5+tls`, `http`, `https`(it's ok))
example: `socks5+tls://user:pass@ip:port#name`

View File

@@ -1,6 +1,6 @@
{
"name": "sub-store",
"version": "2.16.17",
"version": "2.16.20",
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.",
"main": "src/main.js",
"scripts": {

View File

@@ -596,6 +596,9 @@ function URI_VLESS() {
// mKCP 的伪装头部类型。当前可选值有 none / srtp / utp / wechat-video / dtls / wireguard。省略时默认值为 none即不使用伪装头部但不可以为空字符串。
proxy.headerType = params.headerType || 'none';
}
if (params.extra) {
proxy.extra = params.extra;
}
}
return proxy;

View File

@@ -37,7 +37,7 @@ function Base64Encoded() {
};
const parse = function (raw) {
const decoded = Base64.decode(raw);
if (!/^\w+:\/\/\w+/m.test(decoded)) {
if (!/^\w+(:\/\/|\s*?=\s*?)\w+/m.test(decoded)) {
$.error(
`Base64 Pre-processor error: decoded line does not start with protocol`,
);

View File

@@ -14,6 +14,7 @@ export default function Egern_Producer() {
'hysteria2',
'vless',
'vmess',
'tuic',
].includes(proxy.type) ||
(proxy.type === 'ss' &&
((proxy.plugin === 'obfs' &&
@@ -71,7 +72,10 @@ export default function Egern_Producer() {
(typeof proxy.flow !== 'undefined' ||
proxy['reality-opts'] ||
(!['http', 'ws', 'tcp'].includes(proxy.network) &&
proxy.network)))
proxy.network))) ||
(proxy.type === 'tuic' &&
proxy.token &&
proxy.token.length !== 0)
) {
return false;
}
@@ -152,6 +156,23 @@ export default function Egern_Producer() {
proxy.obfs = 'salamander';
proxy.obfs_password = proxy['obfs-password'];
}
} else if (proxy.type === 'tuic') {
proxy = {
type: 'tuic',
name: proxy.name,
server: proxy.server,
port: proxy.port,
uuid: proxy.uuid,
password: proxy.password,
next_hop: proxy.next_hop,
sni: proxy.sni,
alpn: Array.isArray(proxy.alpn)
? proxy.alpn
: [proxy.alpn || 'h3'],
skip_tls_verify: proxy['skip-cert-verify'],
port_hopping: proxy.ports,
port_hopping_interval: proxy['hop-interval'],
};
} else if (proxy.type === 'trojan') {
if (proxy.network === 'ws') {
proxy.websocket = {

View File

@@ -188,6 +188,10 @@ export default function URI_Producer() {
if (proxy.flow) {
flow = `&flow=${encodeURIComponent(proxy.flow)}`;
}
let extra = '';
if (proxy.extra) {
extra = `&extra=${encodeURIComponent(proxy.extra)}`;
}
let vlessType = proxy.network;
if (
proxy.network === 'ws' &&
@@ -254,7 +258,7 @@ export default function URI_Producer() {
proxy.port
}?security=${encodeURIComponent(
security,
)}${vlessTransport}${alpn}${allowInsecure}${sni}${fp}${flow}${sid}${pbk}#${encodeURIComponent(
)}${vlessTransport}${alpn}${allowInsecure}${sni}${fp}${flow}${sid}${pbk}${extra}#${encodeURIComponent(
proxy.name,
)}`;
break;