Skip to content

Commit 299dd2e

Browse files
authored
Merge pull request #1875 from zxlhhyccc/tuic
luci-app-ssr-plus: Add Xray Hysteria2 protocol configuration import and subscribe.
2 parents 497671a + b50cc11 commit 299dd2e

File tree

8 files changed

+907
-737
lines changed

8 files changed

+907
-737
lines changed

luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,12 @@ local function set_apply_on_parse(map)
141141
end
142142
end
143143

144+
local has_xray = is_finded("xray")
145+
local has_hysteria2 = is_finded("hysteria")
146+
147+
-- 读取当前存储的 xray_hy2_type
148+
local xray_hy2_type = uci:get_first("shadowsocksr", "server_subscribe", "xray_hy2_type")
149+
144150
local has_ss_rust = is_finded("sslocal") or is_finded("ssserver")
145151
local has_ss_libev = is_finded("ss-redir") or is_finded("ss-local")
146152

@@ -269,6 +275,43 @@ o.rawhtml = true
269275
o.template = "shadowsocksr/ssrurl"
270276
o.value = sid
271277

278+
-- 新增一个选择框,用于选择 Xray 或 Hysteria2 核心
279+
o = s:option(ListValue, "xray_hy2_type", string.format("<b><span style='color:red;'>%s</span></b>", translatef("%s Node Use Type", "Hysteria2")))
280+
o.description = translate("The configured type also applies to the core specified when manually importing nodes.")
281+
-- 设置默认 Xray 或 Hysteria2 核心
282+
-- 动态添加选项
283+
if has_xray then
284+
o:value("xray", translate("Xray"))
285+
end
286+
if has_hysteria2 then
287+
o:value("hysteria2", translate("Hysteria2"))
288+
end
289+
-- 设置默认值
290+
if xray_hy2_type == "xray" then
291+
o.default = "xray"
292+
elseif xray_hy2_type == "hysteria2" then
293+
o.default = "hysteria2"
294+
end
295+
o.write = function(self, section, value)
296+
-- 更新 Hysteria 节点的 xray_hy2_type
297+
uci:foreach("shadowsocksr", "servers", function(s)
298+
local node_type = uci:get("shadowsocksr", s[".name"], "type") -- 获取节点类型
299+
if node_type == "hysteria2" then -- 仅修改 Hysteria 节点
300+
local old_value = uci:get("shadowsocksr", s[".name"], "xray_hy2_type")
301+
if old_value ~= value then
302+
uci:set("shadowsocksr", s[".name"], "xray_hy2_type", value)
303+
end
304+
end
305+
end)
306+
-- 更新 server_subscribe 的 xray_hy2_type
307+
local old_value = uci:get("shadowsocksr", "server_subscribe", "xray_hy2_type")
308+
if old_value ~= value then
309+
uci:set("shadowsocksr", "@server_subscribe[0]", "xray_hy2_type", value)
310+
end
311+
-- 更新当前 section 的 xray_hy2_type
312+
ListValue.write(self, section, value)
313+
end
314+
272315
o = s:option(ListValue, "type", translate("Server Node Type"))
273316
if is_finded("xray") or is_finded("v2ray") then
274317
o:value("v2ray", translate("V2Ray/XRay"))
@@ -315,7 +358,7 @@ o:depends("type", "tun")
315358
o.description = translate("Redirect traffic to this network interface")
316359

317360
-- 新增一个选择框,用于选择 Shadowsocks 版本
318-
o = s:option(ListValue, "has_ss_type", string.format("<b><span style='color:red;'>%s</span></b>", translate("ShadowSocks Node Use Version")))
361+
o = s:option(ListValue, "has_ss_type", string.format("<b><span style='color:red;'>%s</span></b>", translatef("%s Node Use Version", "ShadowSocks")))
319362
o.description = translate("Selection ShadowSocks Node Use Version.")
320363
-- 设置默认 Shadowsocks 版本
321364
-- 动态添加选项
@@ -343,15 +386,13 @@ o.write = function(self, section, value)
343386
end
344387
end
345388
end)
346-
347389
-- 更新 server_subscribe 的 ss_type
348390
local old_value = uci:get("shadowsocksr", "server_subscribe", "ss_type")
349391
if old_value ~= value then
350392
uci:set("shadowsocksr", "@server_subscribe[0]", "ss_type", value)
351393
end
352-
353394
-- 更新当前 section 的 has_ss_type
354-
Value.write(self, section, value)
395+
ListValue.write(self, section, value)
355396
end
356397

357398
o = s:option(ListValue, "v2ray_protocol", translate("V2Ray/XRay protocol"))
@@ -363,7 +404,7 @@ if is_finded("xray") then
363404
o:value("wireguard", translate("WireGuard"))
364405
end
365406
if is_finded("xray") then
366-
o:value("hysteria2", translate("hysteria2"))
407+
o:value("hysteria2", translate("Hysteria2"))
367408
end
368409
o:value("socks", translate("Socks"))
369410
o:value("http", translate("HTTP"))

luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,27 @@ local function optimize_cbi_ui()
3939
]])
4040
end
4141

42+
local has_xray = is_finded("xray")
43+
local has_hysteria2 = is_finded("hysteria")
44+
45+
local hy2_type_list = {}
46+
47+
if has_xray then
48+
table.insert(hy2_type_list, { id = "xray", name = translate("Xray") })
49+
end
50+
if has_hysteria2 then
51+
table.insert(hy2_type_list, { id = "hysteria2", name = translate("Hysteria2") })
52+
end
53+
54+
-- 如果用户没有手动设置,则自动选择
55+
if not xray_hy2_type or xray_hy2_type == "" then
56+
if has_hysteria2 then
57+
xray_hy2_type = "hysteria2"
58+
elseif has_xray then
59+
xray_hy2_type = "xray"
60+
end
61+
end
62+
4263
local has_ss_rust = is_finded("sslocal") or is_finded("ssserver")
4364
local has_ss_libev = is_finded("ss-redir") or is_finded("ss-local")
4465

@@ -52,7 +73,7 @@ if has_ss_libev then
5273
end
5374

5475
-- 如果用户没有手动设置,则自动选择
55-
if ss_type == "" then
76+
if not ss_type or ss_type == "" then
5677
if has_ss_rust then
5778
ss_type = "ss-rust"
5879
elseif has_ss_libev then
@@ -103,9 +124,33 @@ o.default = 30
103124
o.rmempty = true
104125
o:depends("auto_update", "1")
105126

127+
-- 确保 hy2_type_list 不为空
128+
if #hy2_type_list > 0 then
129+
o = s:option(ListValue, "xray_hy2_type", string.format("<b><span style='color:red;'>%s</span></b>", translatef("%s Node Use Type", "Hysteria2")))
130+
o.description = translate("The configured type also applies to the core specified when manually importing nodes.")
131+
for _, v in ipairs(hy2_type_list) do
132+
o:value(v.id, v.name) -- 存储 "Xray" / "Hysteria2",但 UI 显示完整名称
133+
end
134+
o.default = xray_hy2_type -- 设置默认值
135+
o.write = function(self, section, value)
136+
-- 更新 Hysteria 节点的 xray_hy2_type
137+
uci:foreach("shadowsocksr", "servers", function(s)
138+
local node_type = uci:get("shadowsocksr", s[".name"], "type") -- 获取节点类型
139+
if node_type == "hysteria2" then -- 仅修改 Hysteria 节点
140+
local old_value = uci:get("shadowsocksr", s[".name"], "xray_hy2_type")
141+
if old_value ~= value then
142+
uci:set("shadowsocksr", s[".name"], "xray_hy2_type", value)
143+
end
144+
end
145+
end)
146+
-- 更新当前 section 的 xray_hy2_type
147+
ListValue.write(self, section, value)
148+
end
149+
end
150+
106151
-- 确保 ss_type_list 不为空
107152
if #ss_type_list > 0 then
108-
o = s:option(ListValue, "ss_type", string.format("<b><span style='color:red;'>%s</span></b>", translate("ShadowSocks Node Use Version")))
153+
o = s:option(ListValue, "ss_type", string.format("<b><span style='color:red;'>%s</span></b>", translatef("%s Node Use Version", "ShadowSocks")))
109154
o.description = translate("Selection ShadowSocks Node Use Version.")
110155
for _, v in ipairs(ss_type_list) do
111156
o:value(v.id, v.name) -- 存储 "ss-libev" / "ss-rust",但 UI 显示完整名称
@@ -123,7 +168,7 @@ if #ss_type_list > 0 then
123168
end
124169
end)
125170
-- 更新当前 section 的 ss_type
126-
Value.write(self, section, value)
171+
ListValue.write(self, section, value)
127172
end
128173
end
129174

luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
<%
33
local map = self.map
44
local ss_type = map:get("@server_subscribe[0]", "ss_type")
5+
local xray_hy2_type = map:get("@server_subscribe[0]", "xray_hy2_type")
56
-%>
67
<script type="text/javascript">
78
//<![CDATA[
89
let ss_type = "<%=ss_type%>"
10+
let xray_hy2_type = "<%=xray_hy2_type%>"
911

1012
function padright(str, cnt, pad) {
1113
return str + Array(cnt + 1).join(pad);
@@ -110,8 +112,26 @@
110112
return false;
111113
}
112114

113-
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = (ssu[0] === "hy2") ? "hysteria2" : ssu[0];
114-
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
115+
if (xray_hy2_type === "hysteria2") {
116+
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = (ssu[0] === "hy2") ? "hysteria2" : ssu[0];
117+
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
118+
119+
if (params.get("protocol")) {
120+
document.getElementsByName('cbid.shadowsocksr.' + sid + '.flag_transport')[0].checked = true; // 设置 flag_transport 为 true
121+
document.getElementsByName('cbid.shadowsocksr.' + sid + '.flag_transport')[0].dispatchEvent(event); // 触发事件
122+
123+
document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport_protocol')[0].value = params.get("protocol") || "udp";
124+
}
125+
126+
if (params.get("pinSHA256")) {
127+
document.getElementsByName('cbid.shadowsocksr.' + sid + '.pinsha256')[0].value = params.get("pinSHA256") || "";
128+
}
129+
} else {
130+
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = "v2ray"
131+
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
132+
document.getElementsByName('cbid.shadowsocksr.' + sid + '.v2ray_protocol')[0].value = (ssu[0] === "hy2") ? "hysteria2" : ssu[0];
133+
document.getElementsByName('cbid.shadowsocksr.' + sid + '.v2ray_protocol')[0].dispatchEvent(event);
134+
}
115135
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = url.hostname;
116136
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = url.port || "443";
117137
if (params.get("lazy") === "1") {
@@ -124,12 +144,6 @@
124144

125145
document.getElementsByName('cbid.shadowsocksr.' + sid + '.port_range')[0].value = params.get("mport") || "";
126146
}
127-
if (params.get("protocol")) {
128-
document.getElementsByName('cbid.shadowsocksr.' + sid + '.flag_transport')[0].checked = true; // 设置 flag_transport 为 true
129-
document.getElementsByName('cbid.shadowsocksr.' + sid + '.flag_transport')[0].dispatchEvent(event); // 触发事件
130-
131-
document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport_protocol')[0].value = params.get("protocol") || "udp";
132-
}
133147
document.getElementsByName('cbid.shadowsocksr.' + sid + '.hy2_auth')[0].value = decodeURIComponent(url.username);
134148
document.getElementsByName('cbid.shadowsocksr.' + sid + '.hy2_auth')[0].dispatchEvent(event);
135149
document.getElementsByName('cbid.shadowsocksr.' + sid + '.uplink_capacity')[0].value =
@@ -143,7 +157,7 @@
143157
document.getElementsByName('cbid.shadowsocksr.' + sid + '.obfs_type')[0].value = params.get("obfs");
144158
document.getElementsByName('cbid.shadowsocksr.' + sid + '.salamander')[0].value = params.get("obfs-password") || params.get("obfs_password");
145159
}
146-
if (params.get("sni") || params.get("alpn")) {
160+
if (params.get("security") === "tls" || params.get("sni") || params.get("alpn")) {
147161
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].checked = true; // 设置 flag_obfs 为 true
148162
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event); // 触发事件
149163
if (params.get("sni")) {
@@ -157,9 +171,6 @@
157171
document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].checked = true;
158172
document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].dispatchEvent(event);
159173
}
160-
if (params.get("pinSHA256")) {
161-
document.getElementsByName('cbid.shadowsocksr.' + sid + '.pinsha256')[0].value = params.get("pinSHA256") || "";
162-
}
163174
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = url.hash ? decodeURIComponent(url.hash.slice(1)) : "";
164175

165176
s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";

0 commit comments

Comments
 (0)