🤞 Sync 2026-04-21 20:24:56

This commit is contained in:
github-actions[bot] committed 2026-04-21 20:24:56 +08:00
1 parent 13ee193edd
commit 57fecfdd0b
19 files changed
+987 -473

No files matched your search

+1 -1
View File
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall PKG_NAME:=luci-app-passwall
PKG_VERSION:=26.4.15 PKG_VERSION:=26.4.15
PKG_RELEASE:=86 PKG_RELEASE:=87
PKG_PO_VERSION:=$(PKG_VERSION) PKG_PO_VERSION:=$(PKG_VERSION)
PKG_CONFIG_DEPENDS:= \ PKG_CONFIG_DEPENDS:= \
@@ -380,7 +380,7 @@ if api.compare_versions(xray_version, ">=", "26.1.31") then
o:depends({ [_n("tls")] = true, [_n("reality")] = false }) o:depends({ [_n("tls")] = true, [_n("reality")] = false })
o:depends({ [_n("protocol")] = "hysteria2" }) o:depends({ [_n("protocol")] = "hysteria2" })
o.description = translate("Once set, connects only when the server’s chain fingerprint matches.") .. o.description = translate("Once set, connects only when the server’s chain fingerprint matches.") ..
string.format("<a href='#' onclick='fetchCertSha256(); return false;'>%s</a>", "[ " .. translate("Fetch Manually") .. " ]") string.format("<a href='javascript:void(0)' onclick='javascript:fetchCertSha256(this)'>%s</a>", "→ " .. translate("Fetch Manually"))
o = s:option(Value, _n("tls_CertByName"), translate("TLS Certificate Name (CertName)"), translate("TLS is used to verify the leaf certificate name.")) o = s:option(Value, _n("tls_CertByName"), translate("TLS Certificate Name (CertName)"), translate("TLS is used to verify the leaf certificate name."))
o:depends({ [_n("tls")] = true, [_n("reality")] = false }) o:depends({ [_n("tls")] = true, [_n("reality")] = false })
@@ -53,8 +53,15 @@ local api = self.api
}); });
} }
function fetchCertSha256() { function fetchCertSha256(el) {
if (el.getAttribute("data-loading") === "1") return;
el.setAttribute("data-loading", "1");
el.style.pointerEvents = "none";
el.style.color = "red";
XHR.get('<%=api.url("fetch_certsha256")%>', { id: node_id }, function(x, res) { XHR.get('<%=api.url("fetch_certsha256")%>', { id: node_id }, function(x, res) {
el.setAttribute("data-loading", "0");
el.style.pointerEvents = "";
el.style.color = "";
if (!x || x.status !== 200) { if (!x || x.status !== 200) {
alert("<%:Error%>"); alert("<%:Error%>");
return; return;
+1 -1
View File
@@ -9,7 +9,7 @@ LUCI_TITLE:=LuCI support for quickstart
LUCI_DEPENDS:=+quickstart +luci-app-ttyd +luci-i18n-ttyd-zh-cn LUCI_DEPENDS:=+quickstart +luci-app-ttyd +luci-i18n-ttyd-zh-cn
LUCI_PKGARCH:=all LUCI_PKGARCH:=all
PKG_VERSION:=0.12.6-r1 PKG_VERSION:=0.12.7-r1
# PKG_RELEASE MUST be empty for luci.mk # PKG_RELEASE MUST be empty for luci.mk
PKG_RELEASE:= PKG_RELEASE:=
@@ -1,3 +1,3 @@
var go=Object.defineProperty,vo=Object.defineProperties;var bo=Object.getOwnPropertyDescriptors;var xa=Object.getOwnPropertySymbols;var ho=Object.prototype.hasOwnProperty,_o=Object.prototype.propertyIsEnumerable;var We=(o,n,a)=>n in o?go(o,n,{enumerable:!0,configurable:!0,writable:!0,value:a}):o[n]=a,st=(o,n)=>{for(var a in n||(n={}))ho.call(n,a)&&We(o,a,n[a]);if(xa)for(var a of xa(n))_o.call(n,a)&&We(o,a,n[a]);return o},vt=(o,n)=>vo(o,bo(n));var xo=(o,n)=>()=>(n||o((n={exports:{}}).exports,n),n.exports);var ve=(o,n,a)=>(We(o,typeof n!="symbol"?n+"":n,a),a);var L=(o,n,a)=>new Promise((l,c)=>{var d=g=>{try{k(a.next(g))}catch(p){c(p)}},u=g=>{try{k(a.throw(g))}catch(p){c(p)}},k=g=>g.done?l(g.value):Promise.resolve(g.value).then(d,u);k((a=a.apply(o,n)).next())});import{a as wo,c as ko,d as we,b as I,e as Q,u as e,o as r,f as s,g as t,t as i,n as ht,h as D,i as Y,r as _t,j as lt,k as Yt,w as O,v as Rt,l as Ia,m as Z,p as V,q as E,s as $t,x as Pt,y as pt,F as U,z as tt,A as at,B as jt,C as ct,D as ut,E as ke,G as ee,T as St,H as Nt,I as ft,J as xt,K as dt,L as gt,M as Bt,N as Xe,O as Ma,P as La,Q as Oa,R as ta,S as ea,U as Na,V as aa,W as Pe,X as yo,Y as oa,Z as ye,_ as Fo,$ as Eo,a0 as na,a1 as $o,a2 as Te,a3 as Co,a4 as Ie,a5 as Do,a6 as Bo,a7 as Yo,a8 as Ao,a9 as So,aa as zo,ab as Po,ac as To}from"./vendor.js?v=4c8355cf";var sT=xo(ae=>{const Io=function(){const n=document.createElement("link").relList;if(n&&n.supports&&n.supports("modulepreload"))return;for(const c of document.querySelectorAll('link[rel="modulepreload"]'))l(c);new MutationObserver(c=>{for(const d of c)if(d.type==="childList")for(const u of d.addedNodes)u.tagName==="LINK"&&u.rel==="modulepreload"&&l(u)}).observe(document,{childList:!0,subtree:!0});function a(c){const d={};return c.integrity&&(d.integrity=c.integrity),c.referrerpolicy&&(d.referrerPolicy=c.referrerpolicy),c.crossorigin==="use-credentials"?d.credentials="include":c.crossorigin==="anonymous"?d.credentials="omit":d.credentials="same-origin",d}function l(c){if(c.ep)return;c.ep=!0;const d=a(c);fetch(c.href,d)}};Io();const Gt={language:void 0,numberFormat:new Intl.NumberFormat("en",{notation:"compact"})},Mo=o=>L(ae,null,function*(){const n=window.vue_lang;new Date().getTime();let a={};try{const d=yield wo({url:window.vue_lang_data,method:"GET"});d.data&&(a=d.data)}catch(d){console.log(d)}const l=ko({defaultLanguage:n,mutedLanguages:["zh-cn"],translations:a,setGlobalProperties:!1,provideDirective:!1,provideComponent:!1});o.use(l),Gt.language=l;const{$gettext:c}=l;window.$i18n=c;try{Gt.numberFormat=new Intl.NumberFormat(n,{notation:"compact"})}catch(d){console.error("Intl.NumberFormat unsupported lang",n,d)}}),J=()=>{if(Gt.language)return Gt.language;throw new Error("I18N Uninitialized!")},Me=()=>({$gettext:(o,n,a)=>{if(Gt.language)return Gt.language.$gettext(o,n,a);throw new Error("I18N Uninitialized!")},$ngettext:(o,n,a,l,c)=>{if(Gt.language)return Gt.language.$ngettext(o,n,a,l,c);throw new Error("I18N Uninitialized!")}}),De=o=>typeof o=="number"?Gt.numberFormat.format(o):"?",{$gettext:Lo,$ngettext:cT}=Me(),Va=(o,n)=>L(ae,null,function*(){return new Promise((a,l)=>L(ae,null,function*(){try{const c=yield fetch(o,n);if(Math.floor(c.status/100)!=2)throw c.status+" "+c.statusText;const d=st({},c);d.data=yield c.json(),a(d)}catch(c){const d=c;l(Lo("\u7F51\u7EDC\u5F02\u5E38\uFF1A")+((d==null?void 0:d.message)||c))}}))});class ia{constructor(n){ve(this,"config",{baseURL:"",headers:{}});ve(this,"useRequest",n=>n);ve(this,"useResponse",n=>n);ve(this,"useError",n=>n);n.baseURL&&(this.config.baseURL=n.baseURL),n.headers&&(this.config.headers=n.headers)}static create(n){return new ia(n)}Do(n,a){return L(this,null,function*(){return new Promise((l,c)=>L(this,null,function*(){try{const d=this.useRequest({baseURL:this.config.baseURL,headers:this.config.headers});n=`${d.baseURL||""}${n}`,a.headers==null&&(a.headers={}),d.headers&&(a.headers=st({},d.headers));const k=yield fetch(n,a),g=st({},k);g.data=yield k.json(),l(this.useResponse(g))}catch(d){this.useError(d),c(d)}}))})}TEXT(n,a){return L(this,null,function*(){return new Promise((l,c)=>L(this,null,function*(){try{const d=this.useRequest({baseURL:this.config.baseURL,headers:this.config.headers});n=`${d.baseURL||""}${n}`,a.headers==null&&(a.headers={}),d.headers&&(a.headers=st({},d.headers));const k=yield fetch(n,a),g=st({},k);g.data=yield k.text(),l(g)}catch(d){this.useError(d),c(d)}}))})}interceptors(){const n=this;return{requset:{use(a){n.useRequest=a}},response:{use(a,l){n.useResponse=a,l&&(n.useError=l)}}}}}const Ga=ia.create({});Ga.interceptors().requset.use(o=>o);Ga.interceptors().response.use(o=>(o.data&&o.data.success==null&&o.data.success==0,o));const{$gettext:ja,$ngettext:uT}=Me(),Oo="/cgi-bin/luci/istore",No="/cgi-bin/luci/admin";let Ae=!1;const W=(o,n)=>(o.indexOf("//")==-1&&(o=`${Oo}${o}`),Va(o,n).then(a=>(a!=null&&a.data&&a.data.success==-1001&&a.data.error=="Forbidden"&&(Ae||(Ae=!0,alert(ja("\u767B\u5F55\u8FC7\u671F\uFF0C\u8BF7\u91CLine truncated var go=Object.defineProperty,vo=Object.defineProperties;var bo=Object.getOwnPropertyDescriptors;var xa=Object.getOwnPropertySymbols;var ho=Object.prototype.hasOwnProperty,_o=Object.prototype.propertyIsEnumerable;var We=(o,n,a)=>n in o?go(o,n,{enumerable:!0,configurable:!0,writable:!0,value:a}):o[n]=a,st=(o,n)=>{for(var a in n||(n={}))ho.call(n,a)&&We(o,a,n[a]);if(xa)for(var a of xa(n))_o.call(n,a)&&We(o,a,n[a]);return o},vt=(o,n)=>vo(o,bo(n));var xo=(o,n)=>()=>(n||o((n={exports:{}}).exports,n),n.exports);var ve=(o,n,a)=>(We(o,typeof n!="symbol"?n+"":n,a),a);var L=(o,n,a)=>new Promise((l,u)=>{var d=g=>{try{k(a.next(g))}catch(p){u(p)}},c=g=>{try{k(a.throw(g))}catch(p){u(p)}},k=g=>g.done?l(g.value):Promise.resolve(g.value).then(d,c);k((a=a.apply(o,n)).next())});import{a as wo,c as ko,d as we,b as I,e as Q,u as e,o as r,f as s,g as t,t as i,n as ht,h as D,i as Y,r as _t,j as lt,k as Yt,w as O,v as Rt,l as Ia,m as Z,p as V,q as E,s as $t,x as Pt,y as pt,F as U,z as tt,A as at,B as jt,C as ut,D as ct,E as ke,G as ee,T as St,H as Nt,I as ft,J as xt,K as dt,L as gt,M as Bt,N as Xe,O as Ma,P as La,Q as Oa,R as ta,S as ea,U as Na,V as aa,W as Pe,X as yo,Y as oa,Z as ye,_ as Fo,$ as Eo,a0 as na,a1 as $o,a2 as Te,a3 as Co,a4 as Ie,a5 as Do,a6 as Bo,a7 as Yo,a8 as Ao,a9 as So,aa as zo,ab as Po,ac as To}from"./vendor.js?v=4c8355cf";var sT=xo(ae=>{const Io=function(){const n=document.createElement("link").relList;if(n&&n.supports&&n.supports("modulepreload"))return;for(const u of document.querySelectorAll('link[rel="modulepreload"]'))l(u);new MutationObserver(u=>{for(const d of u)if(d.type==="childList")for(const c of d.addedNodes)c.tagName==="LINK"&&c.rel==="modulepreload"&&l(c)}).observe(document,{childList:!0,subtree:!0});function a(u){const d={};return u.integrity&&(d.integrity=u.integrity),u.referrerpolicy&&(d.referrerPolicy=u.referrerpolicy),u.crossorigin==="use-credentials"?d.credentials="include":u.crossorigin==="anonymous"?d.credentials="omit":d.credentials="same-origin",d}function l(u){if(u.ep)return;u.ep=!0;const d=a(u);fetch(u.href,d)}};Io();const Gt={language:void 0,numberFormat:new Intl.NumberFormat("en",{notation:"compact"})},Mo=o=>L(ae,null,function*(){const n=window.vue_lang;new Date().getTime();let a={};try{const d=yield wo({url:window.vue_lang_data,method:"GET"});d.data&&(a=d.data)}catch(d){console.log(d)}const l=ko({defaultLanguage:n,mutedLanguages:["zh-cn"],translations:a,setGlobalProperties:!1,provideDirective:!1,provideComponent:!1});o.use(l),Gt.language=l;const{$gettext:u}=l;window.$i18n=u;try{Gt.numberFormat=new Intl.NumberFormat(n,{notation:"compact"})}catch(d){console.error("Intl.NumberFormat unsupported lang",n,d)}}),J=()=>{if(Gt.language)return Gt.language;throw new Error("I18N Uninitialized!")},Me=()=>({$gettext:(o,n,a)=>{if(Gt.language)return Gt.language.$gettext(o,n,a);throw new Error("I18N Uninitialized!")},$ngettext:(o,n,a,l,u)=>{if(Gt.language)return Gt.language.$ngettext(o,n,a,l,u);throw new Error("I18N Uninitialized!")}}),De=o=>typeof o=="number"?Gt.numberFormat.format(o):"?",{$gettext:Lo,$ngettext:uT}=Me(),Va=(o,n)=>L(ae,null,function*(){return new Promise((a,l)=>L(ae,null,function*(){try{const u=yield fetch(o,n);if(Math.floor(u.status/100)!=2)throw u.status+" "+u.statusText;const d=st({},u);d.data=yield u.json(),a(d)}catch(u){const d=u;l(Lo("\u7F51\u7EDC\u5F02\u5E38\uFF1A")+((d==null?void 0:d.message)||u))}}))});class ia{constructor(n){ve(this,"config",{baseURL:"",headers:{}});ve(this,"useRequest",n=>n);ve(this,"useResponse",n=>n);ve(this,"useError",n=>n);n.baseURL&&(this.config.baseURL=n.baseURL),n.headers&&(this.config.headers=n.headers)}static create(n){return new ia(n)}Do(n,a){return L(this,null,function*(){return new Promise((l,u)=>L(this,null,function*(){try{const d=this.useRequest({baseURL:this.config.baseURL,headers:this.config.headers});n=`${d.baseURL||""}${n}`,a.headers==null&&(a.headers={}),d.headers&&(a.headers=st({},d.headers));const k=yield fetch(n,a),g=st({},k);g.data=yield k.json(),l(this.useResponse(g))}catch(d){this.useError(d),u(d)}}))})}TEXT(n,a){return L(this,null,function*(){return new Promise((l,u)=>L(this,null,function*(){try{const d=this.useRequest({baseURL:this.config.baseURL,headers:this.config.headers});n=`${d.baseURL||""}${n}`,a.headers==null&&(a.headers={}),d.headers&&(a.headers=st({},d.headers));const k=yield fetch(n,a),g=st({},k);g.data=yield k.text(),l(g)}catch(d){this.useError(d),u(d)}}))})}interceptors(){const n=this;return{requset:{use(a){n.useRequest=a}},response:{use(a,l){n.useResponse=a,l&&(n.useError=l)}}}}}const Ga=ia.create({});Ga.interceptors().requset.use(o=>o);Ga.interceptors().response.use(o=>(o.data&&o.data.success==null&&o.data.success==0,o));const{$gettext:ja,$ngettext:cT}=Me(),Oo="/cgi-bin/luci/istore",No="/cgi-bin/luci/admin";let Ae=!1;const W=(o,n)=>(o.indexOf("//")==-1&&(o=`${Oo}${o}`),Va(o,n).then(a=>(a!=null&&a.data&&a.data.success==-1001&&a.data.error=="Forbidden"&&(Ae||(Ae=!0,alert(ja("\u767B\u5F55\u8FC7\u671F\uFF0C\u8BF7\u91CLine truncated
`+k.value+` `+k.value+`
`+d.value,disabled:""},null,8,RF)]),t("div",WF,[t("div",{class:"close",onClick:m,disabled:c.value},i(e(a)("\u5173\u95ED")),9,HF),c.value?D("",!0):(r(),s("div",{key:0,class:"next",onClick:v,disabled:c.value},i(e(a)("\u8FD0\u884C")),9,JF))])])]),_:1}))}});var KF=N(ZF,[["__scopeId","data-v-abf07ee0"]]);const QF={class:"actioner-container"},XF={class:"actioner-container_header"},tE={class:"tabs"},eE={class:"actioner-container_body"},aE={key:0,class:"table"},oE={class:"tr"},nE={class:"td left"},iE={class:"td left"},rE={class:"tr"},sE={class:"td left"},dE={class:"td left"},lE={class:"tr"},cE={class:"td left"},uE={class:"td left"},pE=["value"],fE=["value"],mE=["value"],gE={class:"actioner-container_footer"},vE=["disabled"],bE=I({props:{close:{type:Function,required:!0},disk:{type:Object,required:!0}},setup(o){const n=o,{$gettext:a,$ngettext:l}=J(),c=E(!1),d=E("info"),u=b=>{switch(d.value=b,b){case"info":break;case"attribute":m();break;case"log":p();break;case"extend":v();break}},k=()=>{c.value=!0,n.close()},g=gt({log:"",attribute:"",extend:""}),p=()=>L(this,null,function*(){try{const b=yield G.Smart.Test.Result.POST({type:"selftest",devicePath:n.disk.path||""});if(b.data){const{result:y,error:f}=b.data;y&&y.result&&(g.log=y.result),f&&(g.log=f)}}catch(b){g.log=b}}),m=()=>L(this,null,function*(){try{const b=yield G.Smart.Attribute.Result.POST({devicePath:n.disk.path||""});if(b.data){const{result:y,error:f}=b.data;y&&y.result&&(g.attribute=y.result),f&&(g.attribute=f)}}catch(b){g.attribute=b}}),v=()=>L(this,null,function*(){try{const b=yield G.Smart.Extend.Result.POST({devicePath:n.disk.path||""});if(b.data){const{result:y,error:f}=b.data;y&&y.result&&(g.extend=y.result),f&&(g.extend=f)}}catch(b){g.extend=b}});return(b,y)=>(r(),Z(je,null,{default:V(()=>[t("div",QF,[t("div",XF,[t("ul",tE,[t("li",{class:lt({"active cbi-tab":d.value=="info"}),onClick:y[0]||(y[0]=f=>u("info"))},[t("a",null,i(e(a)("\u8BBE\u5907\u4FE1\u606F")),1)],2),t("li",{class:lt({"active cbi-tab":d.value=="attribute"}),onClick:y[1]||(y[1]=f=>u("attribute"))},[t("a",null,i(e(a)("\u5C5E\u6027")),1)],2),t("li",{class:lt({"active cbi-tab":d.value=="log"}),onClick:y[2]||(y[2]=f=>u("log"))},[t("a",null,i(e(a)("\u81EA\u68C0\u65E5\u5FD7")),1)],2),t("li",{class:lt({"active cbi-tab":d.value=="extend"}),onClick:y[3]||(y[3]=f=>u("extend"))},[t("a",null,i(e(a)("\u6269\u5C55\u4FE1\u606F")),1)],2)])]),t("div",eE,[d.value=="info"?(r(),s("table",aE,[t("tr",oE,[t("td",nE,i(e(a)("\u8BBE\u5907")),1),t("td",iE,i(o.disk.path),1)]),t("tr",rE,[t("td",sE,i(e(a)("\u578B\u53F7")),1),t("td",dE,i(o.disk.model),1)]),t("tr",lE,[t("td",cE,i(e(a)("\u5E8F\u53F7")),1),t("td",uE,i(o.disk.serial),1)])])):d.value=="attribute"?(r(),s("textarea",{key:1,disabled:"",value:e(g).attribute},null,8,pE)):d.value=="log"?(r(),s("textarea",{key:2,disabled:"",value:e(g).log},null,8,fE)):d.value=="extend"?(r(),s("textarea",{key:3,disabled:"",value:e(g).extend},null,8,mE)):D("",!0)]),t("div",gE,[t("div",{class:"close",onClick:k,disabled:c.value},i(e(a)("\u5173\u95ED")),9,vE)])])]),_:1}))}});var hE=N(bE,[["__scopeId","data-v-4a646cde"]]);const _E=o=>{const n=document.createElement("div");document.body.appendChild(n);const a=Y(tF,vt(st({},o),{close:()=>{l()}})),l=()=>{n.remove()};Ie(a,n)},xE=o=>{const n=document.createElement("div");document.body.appendChild(n);const a=Y(GF,vt(st({},o),{close:()=>{l()}})),l=()=>{n.remove()};Ie(a,n)},wE=o=>{const n=document.createElement("div");document.body.appendChild(n);const a=Y(KF,vt(st({},o),{close:()=>{l()}})),l=()=>{n.remove()};Ie(a,n)},kE=o=>{const n=document.createElement("div");document.body.appendChild(n);const a=Y(hE,vt(st({},o),{close:()=>{l()}})),l=()=>{n.remove()};Ie(a,n)},yE={class:"cbi-section"},FE={class:"cbi-value"},EE={class:"cbi-value-title"},$E={class:"cbi-value-field"},CE={class:"cbi-checkbox"},DE=["value"],BE={class:"cbi-value"},YE={class:"cbi-value-title"},AE={class:"cbi-value-field"},SE={class:"cbi-checkbox"},zE={value:"never"},PE={value:"sleep"},TE={value:"standby"},IE={value:"idle"},ME={class:"cbi-value-description"},LE=t("br",null,null,-1),OE=t("br",null,null,-1),NE=t("br",null,null,-1),VE=t("br",null,null,-1),GE={class:"cbi-value"},jE={class:"cbi-value-title"},UE={class:"cbi-value-field"},qE={class:"cbi-checkbox"},RE={value:0},WE=["value"],HE={class:"cbi-value-description"},JE={class:"cbi-value"},ZE={class:"cbi-value-title"},KE={class:"cbi-value-field"},QE={class:"cbi-checkbox"},XE={value:0},t$=["value"],e$={class:"cbi-value-description"},a$={class:"cbi-section cbi-tblsection",id:"cbi-nfs-mount"},o$={class:"table cbi-section-table"},n$={class:"tr cbi-section-table-titles anonymous"},i$={class:"th cbi-section-table-cell","data-widget":"value"},r$={class:"th cbi-section-table-cell","data-widget":"value"},s$={class:"th cbi-section-table-cell","data-widget":"value"},d$={class:"th cbi-section-table-cell","data-widget":"value"},l$={class:"th cbi-section-table-cell","data-widget":"value"},c$={class:"th cbi-section-table-cell","data-widget":"value" Line truncated `+d.value,disabled:""},null,8,RF)]),t("div",WF,[t("div",{class:"close",onClick:m,disabled:u.value},i(e(a)("\u5173\u95ED")),9,HF),u.value?D("",!0):(r(),s("div",{key:0,class:"next",onClick:v,disabled:u.value},i(e(a)("\u8FD0\u884C")),9,JF))])])]),_:1}))}});var KF=N(ZF,[["__scopeId","data-v-70c3aae0"]]);const QF={class:"actioner-container"},XF={class:"actioner-container_header"},tE={class:"tabs"},eE={class:"actioner-container_body"},aE={key:0,class:"table"},oE={class:"tr"},nE={class:"td left"},iE={class:"td left"},rE={class:"tr"},sE={class:"td left"},dE={class:"td left"},lE={class:"tr"},uE={class:"td left"},cE={class:"td left"},pE=["value"],fE=["value"],mE=["value"],gE={class:"actioner-container_footer"},vE=["disabled"],bE=I({props:{close:{type:Function,required:!0},disk:{type:Object,required:!0}},setup(o){const n=o,{$gettext:a,$ngettext:l}=J(),u=E(!1),d=E("info"),c=b=>{switch(d.value=b,b){case"info":break;case"attribute":m();break;case"log":p();break;case"extend":v();break}},k=()=>{u.value=!0,n.close()},g=gt({log:"",attribute:"",extend:""}),p=()=>L(this,null,function*(){try{const b=yield G.Smart.Test.Result.POST({type:"selftest",devicePath:n.disk.path||""});if(b.data){const{result:y,error:f}=b.data;y&&y.result&&(g.log=y.result),f&&(g.log=f)}}catch(b){g.log=b}}),m=()=>L(this,null,function*(){try{const b=yield G.Smart.Attribute.Result.POST({devicePath:n.disk.path||""});if(b.data){const{result:y,error:f}=b.data;y&&y.result&&(g.attribute=y.result),f&&(g.attribute=f)}}catch(b){g.attribute=b}}),v=()=>L(this,null,function*(){try{const b=yield G.Smart.Extend.Result.POST({devicePath:n.disk.path||""});if(b.data){const{result:y,error:f}=b.data;y&&y.result&&(g.extend=y.result),f&&(g.extend=f)}}catch(b){g.extend=b}});return(b,y)=>(r(),Z(je,null,{default:V(()=>[t("div",QF,[t("div",XF,[t("ul",tE,[t("li",{class:lt({"active cbi-tab":d.value=="info"}),onClick:y[0]||(y[0]=f=>c("info"))},[t("a",null,i(e(a)("\u8BBE\u5907\u4FE1\u606F")),1)],2),t("li",{class:lt({"active cbi-tab":d.value=="attribute"}),onClick:y[1]||(y[1]=f=>c("attribute"))},[t("a",null,i(e(a)("\u5C5E\u6027")),1)],2),t("li",{class:lt({"active cbi-tab":d.value=="log"}),onClick:y[2]||(y[2]=f=>c("log"))},[t("a",null,i(e(a)("\u81EA\u68C0\u65E5\u5FD7")),1)],2),t("li",{class:lt({"active cbi-tab":d.value=="extend"}),onClick:y[3]||(y[3]=f=>c("extend"))},[t("a",null,i(e(a)("\u6269\u5C55\u4FE1\u606F")),1)],2)])]),t("div",eE,[d.value=="info"?(r(),s("table",aE,[t("tr",oE,[t("td",nE,i(e(a)("\u8BBE\u5907")),1),t("td",iE,i(o.disk.path),1)]),t("tr",rE,[t("td",sE,i(e(a)("\u578B\u53F7")),1),t("td",dE,i(o.disk.model),1)]),t("tr",lE,[t("td",uE,i(e(a)("\u5E8F\u53F7")),1),t("td",cE,i(o.disk.serial),1)])])):d.value=="attribute"?(r(),s("textarea",{key:1,disabled:"",value:e(g).attribute},null,8,pE)):d.value=="log"?(r(),s("textarea",{key:2,disabled:"",value:e(g).log},null,8,fE)):d.value=="extend"?(r(),s("textarea",{key:3,disabled:"",value:e(g).extend},null,8,mE)):D("",!0)]),t("div",gE,[t("div",{class:"close",onClick:k,disabled:u.value},i(e(a)("\u5173\u95ED")),9,vE)])])]),_:1}))}});var hE=N(bE,[["__scopeId","data-v-313197ee"]]);const _E=o=>{const n=document.createElement("div");document.body.appendChild(n);const a=Y(tF,vt(st({},o),{close:()=>{l()}})),l=()=>{n.remove()};Ie(a,n)},xE=o=>{const n=document.createElement("div");document.body.appendChild(n);const a=Y(GF,vt(st({},o),{close:()=>{l()}})),l=()=>{n.remove()};Ie(a,n)},wE=o=>{const n=document.createElement("div");document.body.appendChild(n);const a=Y(KF,vt(st({},o),{close:()=>{l()}})),l=()=>{n.remove()};Ie(a,n)},kE=o=>{const n=document.createElement("div");document.body.appendChild(n);const a=Y(hE,vt(st({},o),{close:()=>{l()}})),l=()=>{n.remove()};Ie(a,n)},yE={class:"cbi-section"},FE={class:"cbi-value"},EE={class:"cbi-value-title"},$E={class:"cbi-value-field"},CE={class:"cbi-checkbox"},DE=["value"],BE={class:"cbi-value"},YE={class:"cbi-value-title"},AE={class:"cbi-value-field"},SE={class:"cbi-checkbox"},zE={value:"never"},PE={value:"sleep"},TE={value:"standby"},IE={value:"idle"},ME={class:"cbi-value-description"},LE=t("br",null,null,-1),OE=t("br",null,null,-1),NE=t("br",null,null,-1),VE=t("br",null,null,-1),GE={class:"cbi-value"},jE={class:"cbi-value-title"},UE={class:"cbi-value-field"},qE={class:"cbi-checkbox"},RE={value:0},WE=["value"],HE={class:"cbi-value-description"},JE={class:"cbi-value"},ZE={class:"cbi-value-title"},KE={class:"cbi-value-field"},QE={class:"cbi-checkbox"},XE={value:0},t$=["value"],e$={class:"cbi-value-description"},a$={class:"cbi-section cbi-tblsection",id:"cbi-nfs-mount"},o$={class:"table cbi-section-table"},n$={class:"tr cbi-section-table-titles anonymous"},i$={class:"th cbi-section-table-cell","data-widget":"value"},r$={class:"th cbi-section-table-cell","data-widget":"value"},s$={class:"th cbi-section-table-cell","data-widget":"value"},d$={class:"th cbi-section-table-cell","data-widget":"value"},l$={class:"th cbi-section-table-cell","data-widget":"value"},u$={class:"th cbi-section-table-cell","data-widget":"value" Line truncated
@@ -1,2 +1,2 @@
@keyframes bganimation-41cbce66{0%{background-position:0% 50%}50%{background-position:100% 50%}to{background-position:0% 50%}}@keyframes rotateEnter-41cbce66{0%{transform:rotateY(180deg)}10%{transform:rotateY(198deg)}20%{transform:rotateY(216deg)}30%{transform:rotateY(234deg)}40%{transform:rotateY(252deg)}50%{transform:rotateY(270deg)}60%{transform:rotateY(288deg)}70%{transform:rotateY(306deg)}80%{transform:rotateY(324deg)}90%{transform:rotateY(342deg)}to{transform:rotateY(360deg)}}@keyframes turns-41cbce66{0%{-webkit-transform:rotate(0deg)}25%{-webkit-transform:rotate(90deg)}50%{-webkit-transform:rotate(180deg)}75%{-webkit-transform:rotate(270deg)}to{-webkit-transform:rotate(360deg)}}.rotate-enter-active[data-v-41cbce66]{animation:rotateEnter-41cbce66 .7s;position:relative}.rotate-leave-active[data-v-41cbce66]{opacity:0;display:none;position:relative;z-index:-999}.app-container[data-v-41cbce66]{width:100%;background-color:var(--card-bg-color);box-shadow:var(--card-box-shadow);padding:10px 30px;border-radius:6px;position:relative}.disk-item-tooltip[data-v-41cbce66]{position:fixed;background:rgba(0,0,0,.7);z-index:10111;color:#fff;padding:.5rem 1rem;font-size:1em;min-width:200px;line-height:24px}.disk-item-tooltip[data-v-41cbce66]:after{content:"";position:absolute;bottom:-6px;border-color:#4c4c4c rgba(0,0,0,0) rgba(0,0,0,0);left:0;right:0;text-align:center;width:0;margin:0 auto;border-width:6px 8px 0;border-style:solid}#main .app-btn,#actioner .app-btn{min-height:36px}@keyframes bganimation-2d97dedc{0%{background-position:0% 50%}50%{background-position:100% 50%}to{background-position:0% 50%}}@keyframes rotateEnter-2d97dedc{0%{transform:rotateY(180deg)}10%{transform:rotateY(198deg)}20%{transform:rotateY(216deg)}30%{transform:rotateY(234deg)}40%{transform:rotateY(252deg)}50%{transform:rotateY(270deg)}60%{transform:rotateY(288deg)}70%{transform:rotateY(306deg)}80%{transform:rotateY(324deg)}90%{transform:rotateY(342deg)}to{transform:rotateY(360deg)}}@keyframes turns-2d97dedc{0%{-webkit-transform:rotate(0deg)}25%{-webkit-transform:rotate(90deg)}50%{-webkit-transform:rotate(180deg)}75%{-webkit-transform:rotate(270deg)}to{-webkit-transform:rotate(360deg)}}.rotate-enter-active[data-v-2d97dedc]{animation:rotateEnter-2d97dedc .7s;position:relative}.rotate-leave-active[data-v-2d97dedc]{opacity:0;display:none;position:relative;z-index:-999}.app-container[data-v-2d97dedc]{width:100%;background-color:var(--card-bg-color);box-shadow:var(--card-box-shadow);padding:10px 30px;border-radius:6px;position:relative}#main[data-v-2d97dedc]{width:100%}#main[data-v-2d97dedc],#main[data-v-2d97dedc] *{-webkit-box-sizing:border-box;-webkit-tap-highlight-color:transparent;box-sizing:border-box;word-wrap:break-word;outline:none}@keyframes bganimation{0%{background-position:0% 50%}50%{background-position:100% 50%}to{background-position:0% 50%}}@keyframes rotateEnter{0%{transform:rotateY(180deg)}10%{transform:rotateY(198deg)}20%{transform:rotateY(216deg)}30%{transform:rotateY(234deg)}40%{transform:rotateY(252deg)}50%{transform:rotateY(270deg)}60%{transform:rotateY(288deg)}70%{transform:rotateY(306deg)}80%{transform:rotateY(324deg)}90%{transform:rotateY(342deg)}to{transform:rotateY(360deg)}}@keyframes turns{0%{-webkit-transform:rotate(0deg)}25%{-webkit-transform:rotate(90deg)}50%{-webkit-transform:rotate(180deg)}75%{-webkit-transform:rotate(270deg)}to{-webkit-transform:rotate(360deg)}}.rotate-enter-active{animation:rotateEnter .7s;position:relative}.rotate-leave-active{opacity:0;display:none;position:relative;z-index:-999}.app-container{width:100%;background-color:var(--card-bg-color);box-shadow:var(--card-box-shadow);padding:10px 30px;border-radius:6px;position:relative}:root{--flow-bg-color: #fff;--flow-span-color: rgba(0, 0, 0, .6);--card-bg-color: #fff;--card-box-shadow: 0 0 10px 1px #bfbfbf24;--app-container_title-color: #1e1e1e;--app-container_status-label_block: black;--item-label_key-span-color: #333;--item-label_value-span-color: #333;--app-container_status-label_bg: #f3f3f3;--item_btn-border: 1px solid #553afb;--item_btn-color: #553afb;--tit-color: #1e1e1e;--popup-bg-color: #fff;--tag-bg-color: #f5f5f5;--gradient-bg-color:linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.8) 62%, rgba(255,255,255,1) 100%);--breadcrumbs-tit-color:#d6dbf8;--breadcrumbs-tit-color1:#f1f2f9;--border-color: #e5e5e5;--SystemUpdateBanner-bg-color: #eff6ff;--SystemUpdateBanner-border-color: #bedbff;--btn-border-color: #e5e5e5;--card-txt-color: #32325d;--SystemInfo-bg-color:#f9fafd}@media (prefers-color-scheme: light){:root{--flow-bg-color: #fff;--flow-span-color: rgba(0, 0, 0, .6);--card-bg-color: #fff;--card-box-shadow: 0 0 10px 1px #bfbfbf24;--app-container_title-color: #1e1e1e;--app-container_status-label_block: black;--item-label_key-span-color: #333;--item-label_value-span-color: #333;--app-container_status-label_bg: #f3f3f3;--item_btn-border: 1px solid #553afb;--item_btn-color: #553afb;--tit-color: #1e1e1e;--popup-bg-color: #fff;--tag-Line truncated @keyframes bganimation-0698ba82{0%{background-position:0% 50%}50%{background-position:100% 50%}to{background-position:0% 50%}}@keyframes rotateEnter-0698ba82{0%{transform:rotateY(180deg)}10%{transform:rotateY(198deg)}20%{transform:rotateY(216deg)}30%{transform:rotateY(234deg)}40%{transform:rotateY(252deg)}50%{transform:rotateY(270deg)}60%{transform:rotateY(288deg)}70%{transform:rotateY(306deg)}80%{transform:rotateY(324deg)}90%{transform:rotateY(342deg)}to{transform:rotateY(360deg)}}@keyframes turns-0698ba82{0%{-webkit-transform:rotate(0deg)}25%{-webkit-transform:rotate(90deg)}50%{-webkit-transform:rotate(180deg)}75%{-webkit-transform:rotate(270deg)}to{-webkit-transform:rotate(360deg)}}.rotate-enter-active[data-v-0698ba82]{animation:rotateEnter-0698ba82 .7s;position:relative}.rotate-leave-active[data-v-0698ba82]{opacity:0;display:none;position:relative;z-index:-999}.app-container[data-v-0698ba82]{width:100%;background-color:var(--card-bg-color);box-shadow:var(--card-box-shadow);padding:10px 30px;border-radius:6px;position:relative}.disk-item-tooltip[data-v-0698ba82]{position:fixed;background:rgba(0,0,0,.7);z-index:10111;color:#fff;padding:.5rem 1rem;font-size:1em;min-width:200px;line-height:24px}.disk-item-tooltip[data-v-0698ba82]:after{content:"";position:absolute;bottom:-6px;border-color:#4c4c4c rgba(0,0,0,0) rgba(0,0,0,0);left:0;right:0;text-align:center;width:0;margin:0 auto;border-width:6px 8px 0;border-style:solid}#main .app-btn,#actioner .app-btn{min-height:36px}@keyframes bganimation-9bc295c2{0%{background-position:0% 50%}50%{background-position:100% 50%}to{background-position:0% 50%}}@keyframes rotateEnter-9bc295c2{0%{transform:rotateY(180deg)}10%{transform:rotateY(198deg)}20%{transform:rotateY(216deg)}30%{transform:rotateY(234deg)}40%{transform:rotateY(252deg)}50%{transform:rotateY(270deg)}60%{transform:rotateY(288deg)}70%{transform:rotateY(306deg)}80%{transform:rotateY(324deg)}90%{transform:rotateY(342deg)}to{transform:rotateY(360deg)}}@keyframes turns-9bc295c2{0%{-webkit-transform:rotate(0deg)}25%{-webkit-transform:rotate(90deg)}50%{-webkit-transform:rotate(180deg)}75%{-webkit-transform:rotate(270deg)}to{-webkit-transform:rotate(360deg)}}.rotate-enter-active[data-v-9bc295c2]{animation:rotateEnter-9bc295c2 .7s;position:relative}.rotate-leave-active[data-v-9bc295c2]{opacity:0;display:none;position:relative;z-index:-999}.app-container[data-v-9bc295c2]{width:100%;background-color:var(--card-bg-color);box-shadow:var(--card-box-shadow);padding:10px 30px;border-radius:6px;position:relative}#main[data-v-9bc295c2]{width:100%}#main[data-v-9bc295c2],#main[data-v-9bc295c2] *{-webkit-box-sizing:border-box;-webkit-tap-highlight-color:transparent;box-sizing:border-box;word-wrap:break-word;outline:none}@keyframes bganimation{0%{background-position:0% 50%}50%{background-position:100% 50%}to{background-position:0% 50%}}@keyframes rotateEnter{0%{transform:rotateY(180deg)}10%{transform:rotateY(198deg)}20%{transform:rotateY(216deg)}30%{transform:rotateY(234deg)}40%{transform:rotateY(252deg)}50%{transform:rotateY(270deg)}60%{transform:rotateY(288deg)}70%{transform:rotateY(306deg)}80%{transform:rotateY(324deg)}90%{transform:rotateY(342deg)}to{transform:rotateY(360deg)}}@keyframes turns{0%{-webkit-transform:rotate(0deg)}25%{-webkit-transform:rotate(90deg)}50%{-webkit-transform:rotate(180deg)}75%{-webkit-transform:rotate(270deg)}to{-webkit-transform:rotate(360deg)}}.rotate-enter-active{animation:rotateEnter .7s;position:relative}.rotate-leave-active{opacity:0;display:none;position:relative;z-index:-999}.app-container{width:100%;background-color:var(--card-bg-color);box-shadow:var(--card-box-shadow);padding:10px 30px;border-radius:6px;position:relative}:root{--flow-bg-color: #fff;--flow-span-color: rgba(0, 0, 0, .6);--card-bg-color: #fff;--card-box-shadow: 0 0 10px 1px #bfbfbf24;--app-container_title-color: #1e1e1e;--app-container_status-label_block: black;--item-label_key-span-color: #333;--item-label_value-span-color: #333;--app-container_status-label_bg: #f3f3f3;--item_btn-border: 1px solid #553afb;--item_btn-color: #553afb;--tit-color: #1e1e1e;--popup-bg-color: #fff;--tag-bg-color: #f5f5f5;--gradient-bg-color:linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.8) 62%, rgba(255,255,255,1) 100%);--breadcrumbs-tit-color:#d6dbf8;--breadcrumbs-tit-color1:#f1f2f9;--border-color: #e5e5e5;--SystemUpdateBanner-bg-color: #eff6ff;--SystemUpdateBanner-border-color: #bedbff;--btn-border-color: #e5e5e5;--card-txt-color: #32325d;--SystemInfo-bg-color:#f9fafd}@media (prefers-color-scheme: light){:root{--flow-bg-color: #fff;--flow-span-color: rgba(0, 0, 0, .6);--card-bg-color: #fff;--card-box-shadow: 0 0 10px 1px #bfbfbf24;--app-container_title-color: #1e1e1e;--app-container_status-label_block: black;--item-label_key-span-color: #333;--item-label_value-span-color: #333;--app-container_status-label_bg: #f3f3f3;--item_btn-border: 1px solid #553afb;--item_btn-color: #553afb;--tit-color: #1e1e1e;--popup-bg-color: #fff;--tag-Line truncated
.page-container>div>div>a:first-child{display:none} .page-container>div>div>a:first-child{display:none}
+1 -1
View File
@@ -4,7 +4,7 @@ LUCI_TITLE:=luci-app-ssr-plus
LUCI_PKGARCH:=all LUCI_PKGARCH:=all
PKG_NAME:=luci-app-ssr-plus PKG_NAME:=luci-app-ssr-plus
PKG_VERSION:=190 PKG_VERSION:=190
PKG_RELEASE:=11 PKG_RELEASE:=12
PKG_CONFIG_DEPENDS:= \ PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy \ CONFIG_PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy \
@@ -1674,6 +1674,65 @@ o:depends("type", "hysteria2")
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "xhttp"}) o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "xhttp"})
o:depends({type = "v2ray", v2ray_protocol = "hysteria2"}) o:depends({type = "v2ray", v2ray_protocol = "hysteria2"})
o = s:option(ListValue, "domain_resolver", translate("Domain DNS Resolve"))
o.description = translate(
"<ul>" ..
"<li>" .. translate("If the node address is a domain name, this DNS will be used for resolution.") .. "</li>" ..
"<li>" .. string.format('<font style=\'color:red;\'>%s</font>', translate("Note: For node-specific DNS only. Keep Auto to avoid extra overhead.")) .. "</li>" ..
"</ul>"
)
o:value("", translate("Auto"))
o:value("tcp", translate("TCP"))
o:value("udp", translate("UDP"))
o:value("https", translate("DoH"))
o:depends("type", "v2ray")
o = s:option(Value, "domain_resolver_dns", translate("DNS"))
o.datatype = "or(ipaddr,ipaddrport)"
o:value("114.114.114.114")
o:value("223.5.5.5:53")
o.default = "114.114.114.114"
o:depends("domain_resolver", "tcp")
o:depends("domain_resolver", "udp")
o = s:option(Value, "domain_resolver_dns_https", translate("DNS"))
o:value("https://120.53.53.53/dns-query", translate("DNSPod"))
o:value("https://223.5.5.5/dns-query", translate("AliDNS"))
o.default = "https://120.53.53.53/dns-query"
o:depends("domain_resolver", "https")
o = s:option(ListValue, "domain_strategy", translate("Domain Strategy"))
o.description = translate(
"<ul>" ..
"<li>" .. translate("If is domain name, The requested domain name will be resolved to IP before connect.") .. "</li>" ..
"<li>" .. string.format('<font style=\'color:red;\'>%s</font>', translate("Note: For node-specific DNS only. Keep Auto to avoid extra overhead.")) .. "</li>" ..
"</ul>"
)
o.default = ""
o:value("", translate("Auto"))
o:value("UseIPv4v6", translate("Prefer IPv4"))
o:value("UseIPv6v4", translate("Prefer IPv6"))
o:value("UseIPv4", translate("IPv4 Only"))
o:value("UseIPv6", translate("IPv6 Only"))
o:depends("type", "v2ray")
local v2ray_protocols = s.fields["v2ray_protocol"]
if #v2ray_protocols > 0 then
for i, v in ipairs(v2ray_protocols) do
if not v:find("^_") then
s.fields["server"]:depends({ ["v2ray_protocol"] = v })
s.fields["server_port"]:depends({ ["v2ray_protocol"] = v })
s.fields["domain_resolver"]:depends({ ["v2ray_protocol"] = v })
s.fields["domain_strategy"]:depends({ ["v2ray_protocol"] = v })
if v ~= "hysteria2" then
s.fields["fast_open"]:depends({ ["v2ray_protocol"] = v })
s.fields["mptcp"]:depends({ ["v2ray_protocol"] = v })
end
end
end
end
o = s:option(Flag, "switch_enable", translate("Enable Auto Switch")) o = s:option(Flag, "switch_enable", translate("Enable Auto Switch"))
o.rmempty = false o.rmempty = false
o.default = "1" o.default = "1"
@@ -235,6 +235,48 @@ end
o = s:option(DynamicList, "subscribe_url", translate("Subscribe URL")) o = s:option(DynamicList, "subscribe_url", translate("Subscribe URL"))
o.rmempty = true o.rmempty = true
o = s:option(ListValue, "domain_resolver", translate("Domain DNS Resolve"))
o.description = translate(
"<ul>" ..
"<li>" .. translate("If the node address is a domain name, this DNS will be used for resolution.") .. "</li>" ..
"<li>" .. string.format('<font style=\'color:red;\'>%s</font>', translate("Supports only Xray node types.")) .. "</li>" ..
"<li>" .. string.format('<font style=\'color:red;\'>%s</font>', translate("Note: For node-specific DNS only. Keep Auto to avoid extra overhead.")) .. "</li>" ..
"</ul>"
)
o:value("", translate("Auto"))
o:value("tcp", translate("TCP"))
o:value("udp", translate("UDP"))
o:value("https", translate("DoH"))
o = s:option(Value, "domain_resolver_dns", translate("DNS"))
o.datatype = "or(ipaddr,ipaddrport)"
o:value("114.114.114.114")
o:value("223.5.5.5:53")
o.default = "114.114.114.114"
o:depends("domain_resolver", "tcp")
o:depends("domain_resolver", "udp")
o = s:option(Value, "domain_resolver_dns_https", translate("DNS"))
o:value("https://120.53.53.53/dns-query", "DNSPod")
o:value("https://223.5.5.5/dns-query", "AliDNS")
o.default = o.keylist[1]
o:depends("domain_resolver", "https")
o = s:option(ListValue, "domain_strategy", translate("Domain Strategy"))
o.description = translate(
"<ul>" ..
"<li>" .. translate("If is domain name, The requested domain name will be resolved to IP before connect.") .. "</li>" ..
"<li>" .. string.format('<font style=\'color:red;\'>%s</font>', translate("Supports only Xray node types.")) .. "</li>" ..
"<li>" .. string.format('<font style=\'color:red;\'>%s</font>', translate("Note: For node-specific DNS only. Keep Auto to avoid extra overhead.")) .. "</li>" ..
"</ul>"
)
o.default = ""
o:value("", translate("Auto"))
o:value("UseIPv4v6", translate("Prefer IPv4"))
o:value("UseIPv6v4", translate("Prefer IPv6"))
o:value("UseIPv4", translate("IPv4 Only"))
o:value("UseIPv6", translate("IPv6 Only"))
o = s:option(Value, "filter_words", translate("Subscribe Filter Words")) o = s:option(Value, "filter_words", translate("Subscribe Filter Words"))
o.rmempty = true o.rmempty = true
o.description = translate("Filter Words splited by /") o.description = translate("Filter Words splited by /")
+118 -34
View File
@@ -99,9 +99,13 @@ msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1527 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1527
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1540 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1540
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1553 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1553
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1679
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1706
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:188 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:188
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:214 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:214
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:249 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:249
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:240
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:267
msgid "<ul><li>" msgid "<ul><li>"
msgstr "" msgstr ""
@@ -126,11 +130,15 @@ msgstr ""
msgid "Advertising Data" msgid "Advertising Data"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1700
msgid "AliDNS"
msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:268 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:268
msgid "AliYun Public DNS (223.5.5.5)" msgid "AliYun Public DNS (223.5.5.5)"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:325 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:367
msgid "Alias" msgid "Alias"
msgstr "" msgstr ""
@@ -150,7 +158,7 @@ msgstr ""
msgid "Allow listed only" msgid "Allow listed only"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:255 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:297
msgid "Allow subscribe Insecure nodes By default" msgid "Allow subscribe Insecure nodes By default"
msgstr "" msgstr ""
@@ -192,8 +200,8 @@ msgstr ""
msgid "Apple domains optimization" msgid "Apple domains optimization"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:357 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:399
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:363 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:405
msgid "Apply" msgid "Apply"
msgstr "" msgstr ""
@@ -207,13 +215,17 @@ msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:282 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:282
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:313 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:313
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1684
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1712
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:172 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:172
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:200 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:200
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:229 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:229
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:246
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:274
msgid "Auto" msgid "Auto"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:375 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:417
msgid "Auto Switch" msgid "Auto Switch"
msgstr "" msgstr ""
@@ -489,6 +501,10 @@ msgid "DL Backup"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1168 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1168
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1690
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1698
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:251
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:259
msgid "DNS" msgid "DNS"
msgstr "" msgstr ""
@@ -500,6 +516,10 @@ msgstr ""
msgid "DNS Query Mode For Shunt Mode" msgid "DNS Query Mode For Shunt Mode"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1699
msgid "DNSPod"
msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:267 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:267
msgid "DNSPod Public DNS (119.29.29.29)" msgid "DNSPod Public DNS (119.29.29.29)"
msgstr "" msgstr ""
@@ -561,7 +581,7 @@ msgstr ""
msgid "Delete" msgid "Delete"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:273 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:315
msgid "Delete All Subscribe Servers" msgid "Delete All Subscribe Servers"
msgstr "" msgstr ""
@@ -617,12 +637,24 @@ msgstr ""
msgid "Do you want to restore the client to default settings?" msgid "Do you want to restore the client to default settings?"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1687
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:249
msgid "DoH"
msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:230 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:230
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:259 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:259
msgid "DoT upstream (Need use wolfssl version)" msgid "DoT upstream (Need use wolfssl version)"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1677
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:238
msgid "Domain DNS Resolve"
msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:419 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:419
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1704
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:265
msgid "Domain Strategy" msgid "Domain Strategy"
msgstr "" msgstr ""
@@ -679,7 +711,7 @@ msgid "Enable Authentication"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:63 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:63
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1677 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1736
msgid "Enable Auto Switch" msgid "Enable Auto Switch"
msgstr "" msgstr ""
@@ -821,7 +853,7 @@ msgstr ""
msgid "FORCE BRUTAL" msgid "FORCE BRUTAL"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:240 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:282
msgid "Filter Words splited by /" msgid "Filter Words splited by /"
msgstr "" msgstr ""
@@ -1034,16 +1066,39 @@ msgstr ""
msgid "IP Stack Preference" msgid "IP Stack Preference"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1715
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:277
msgid "IPv4 Only"
msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1716
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:278
msgid "IPv6 Only"
msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:243 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:243
msgid "If empty, Not change Apple domains parsing DNS (Default is empty)" msgid "If empty, Not change Apple domains parsing DNS (Default is empty)"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1707
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:268
msgid ""
"If is domain name, The requested domain name will be resolved to IP before "
"connect."
msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1393 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1393
msgid "" msgid ""
"If it is not empty, it indicates that the Client has enabled Encrypted " "If it is not empty, it indicates that the Client has enabled Encrypted "
"Client, see:" "Client, see:"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1680
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:241
msgid ""
"If the node address is a domain name, this DNS will be used for resolution."
msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:865 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:865
msgid "If this option is not set, the socket behavior is platform dependent." msgid "If this option is not set, the socket behavior is platform dependent."
msgstr "" msgstr ""
@@ -1094,19 +1149,19 @@ msgstr ""
msgid "KcpTun" msgid "KcpTun"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1687 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1746
msgid "KcpTun Enable" msgid "KcpTun Enable"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1704 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1763
msgid "KcpTun Param" msgid "KcpTun Param"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1699 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1758
msgid "KcpTun Password" msgid "KcpTun Password"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1693 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1752
msgid "KcpTun Port" msgid "KcpTun Port"
msgstr "" msgstr ""
@@ -1205,7 +1260,7 @@ msgid "Listen only on the given interface or, if unspecified, on all"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:348 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:348
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1681 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1740
msgid "Local Port" msgid "Local Port"
msgstr "" msgstr ""
@@ -1387,8 +1442,8 @@ msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1140 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1140
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1152 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1152
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1162 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1162
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:322 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:364
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:327 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:369
msgid "None" msgid "None"
msgstr "" msgstr ""
@@ -1405,6 +1460,13 @@ msgstr ""
msgid "Not exist" msgid "Not exist"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1681
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1708
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:243
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:270
msgid "Note: For node-specific DNS only. Keep Auto to avoid extra overhead."
msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua:27 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua:27
msgid "" msgid ""
"Note: Restoring configurations across different versions may cause " "Note: Restoring configurations across different versions may cause "
@@ -1516,7 +1578,7 @@ msgstr ""
msgid "Permit Without Stream" msgid "Permit Without Stream"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:351 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:393
msgid "Ping Latency" msgid "Ping Latency"
msgstr "" msgstr ""
@@ -1548,6 +1610,16 @@ msgstr ""
msgid "Pre-shared key" msgid "Pre-shared key"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1713
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:275
msgid "Prefer IPv4"
msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1714
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:276
msgid "Prefer IPv6"
msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:93 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:93
msgid "Prefer firewall tools" msgid "Prefer firewall tools"
msgstr "" msgstr ""
@@ -1627,7 +1699,7 @@ msgstr ""
msgid "Really reset all changes?" msgid "Really reset all changes?"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:361 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:403
msgid "Reapply" msgid "Reapply"
msgstr "" msgstr ""
@@ -1744,7 +1816,7 @@ msgstr ""
msgid "Save Order" msgid "Save Order"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:244 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:286
msgid "Save Words splited by /" msgid "Save Words splited by /"
msgstr "" msgstr ""
@@ -1782,7 +1854,7 @@ msgstr ""
msgid "Server Address" msgid "Server Address"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:275 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:317
msgid "Server Count" msgid "Server Count"
msgstr "" msgstr ""
@@ -1793,7 +1865,7 @@ msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:469 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:469
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:96 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:96
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:112 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:112
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:330 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:372
msgid "Server Port" msgid "Server Port"
msgstr "" msgstr ""
@@ -1873,7 +1945,7 @@ msgstr ""
msgid "Short ID" msgid "Short ID"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:335 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:377
msgid "Socket Connected" msgid "Socket Connected"
msgstr "" msgstr ""
@@ -1914,15 +1986,15 @@ msgstr ""
msgid "Status" msgid "Status"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:260 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:302
msgid "Subscribe Default Auto-Switch" msgid "Subscribe Default Auto-Switch"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:238 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:280
msgid "Subscribe Filter Words" msgid "Subscribe Filter Words"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:242 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:284
msgid "Subscribe Save Words" msgid "Subscribe Save Words"
msgstr "" msgstr ""
@@ -1930,11 +2002,11 @@ msgstr ""
msgid "Subscribe URL" msgid "Subscribe URL"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:262 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:304
msgid "Subscribe new add server default Auto-Switch on" msgid "Subscribe new add server default Auto-Switch on"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:257 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:299
msgid "Subscribe nodes allows insecure connection as TLS client (insecure)" msgid "Subscribe nodes allows insecure connection as TLS client (insecure)"
msgstr "" msgstr ""
@@ -1946,10 +2018,20 @@ msgstr ""
msgid "Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5." msgid "Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5."
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:242
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:269
msgid "Supports only Xray node types."
msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:67 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:67
msgid "Switch check cycly(second)" msgid "Switch check cycly(second)"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1685
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:247
msgid "TCP"
msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:729 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:729
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1667 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1667
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:149 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:149
@@ -2069,11 +2151,11 @@ msgstr ""
msgid "The keep-alive period.(Unit:second)" msgid "The keep-alive period.(Unit:second)"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:265 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:307
msgid "Through proxy update" msgid "Through proxy update"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:267 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:309
msgid "Through proxy update list, Not Recommended" msgid "Through proxy update list, Not Recommended"
msgstr "" msgstr ""
@@ -2118,11 +2200,13 @@ msgid "Trojan"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:412 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:412
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:320 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:362
msgid "Type" msgid "Type"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:622 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:622
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1686
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:248
msgid "UDP" msgid "UDP"
msgstr "" msgstr ""
@@ -2154,7 +2238,7 @@ msgstr ""
msgid "UL Restore" msgid "UL Restore"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:280 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:322
msgid "URL Test Address" msgid "URL Test Address"
msgstr "" msgstr ""
@@ -2167,12 +2251,12 @@ msgstr ""
msgid "Unknown" msgid "Unknown"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:269 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:311
#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe.htm:16 #: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe.htm:16
msgid "Update All Subscribe Servers" msgid "Update All Subscribe Servers"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:246 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:288
msgid "Update Subscribe List" msgid "Update Subscribe List"
msgstr "" msgstr ""
@@ -2180,7 +2264,7 @@ msgstr ""
msgid "Update cycle (Day/Week)" msgid "Update cycle (Day/Week)"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:248 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:290
msgid "Update subscribe url list first" msgid "Update subscribe url list first"
msgstr "" msgstr ""
@@ -2252,7 +2336,7 @@ msgid "User cancelled."
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1268 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1268
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:290 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:332
msgid "User-Agent" msgid "User-Agent"
msgstr "" msgstr ""
+118 -34
View File
@@ -103,9 +103,13 @@ msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1527 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1527
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1540 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1540
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1553 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1553
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1679
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1706
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:188 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:188
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:214 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:214
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:249 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:249
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:240
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:267
msgid "<ul><li>" msgid "<ul><li>"
msgstr "" msgstr ""
@@ -130,11 +134,15 @@ msgstr "高级设置"
msgid "Advertising Data" msgid "Advertising Data"
msgstr "【广告屏蔽】数据库" msgstr "【广告屏蔽】数据库"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1700
msgid "AliDNS"
msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:268 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:268
msgid "AliYun Public DNS (223.5.5.5)" msgid "AliYun Public DNS (223.5.5.5)"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:325 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:367
msgid "Alias" msgid "Alias"
msgstr "别名" msgstr "别名"
@@ -154,7 +162,7 @@ msgstr "除列表外主机皆允许"
msgid "Allow listed only" msgid "Allow listed only"
msgstr "仅允许列表内主机" msgstr "仅允许列表内主机"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:255 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:297
msgid "Allow subscribe Insecure nodes By default" msgid "Allow subscribe Insecure nodes By default"
msgstr "订阅节点允许不验证 TLS 证书" msgstr "订阅节点允许不验证 TLS 证书"
@@ -196,8 +204,8 @@ msgstr "Apple 域名更新 URL"
msgid "Apple domains optimization" msgid "Apple domains optimization"
msgstr "Apple 域名解析优化" msgstr "Apple 域名解析优化"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:357 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:399
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:363 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:405
msgid "Apply" msgid "Apply"
msgstr "应用" msgstr "应用"
@@ -211,13 +219,17 @@ msgstr "是否真的要恢复客户端默认配置?"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:282 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:282
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:313 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:313
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1684
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1712
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:172 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:172
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:200 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:200
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:229 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:229
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:246
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:274
msgid "Auto" msgid "Auto"
msgstr "自动" msgstr "自动"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:375 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:417
msgid "Auto Switch" msgid "Auto Switch"
msgstr "自动切换" msgstr "自动切换"
@@ -498,6 +510,10 @@ msgid "DL Backup"
msgstr "下载备份" msgstr "下载备份"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1168 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1168
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1690
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1698
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:251
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:259
msgid "DNS" msgid "DNS"
msgstr "" msgstr ""
@@ -509,6 +525,10 @@ msgstr "DNS 防污染服务"
msgid "DNS Query Mode For Shunt Mode" msgid "DNS Query Mode For Shunt Mode"
msgstr "分流模式下的 DNS 查询模式" msgstr "分流模式下的 DNS 查询模式"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1699
msgid "DNSPod"
msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:267 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:267
msgid "DNSPod Public DNS (119.29.29.29)" msgid "DNSPod Public DNS (119.29.29.29)"
msgstr "" msgstr ""
@@ -574,7 +594,7 @@ msgstr "延迟(ms)"
msgid "Delete" msgid "Delete"
msgstr "删除" msgstr "删除"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:273 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:315
msgid "Delete All Subscribe Servers" msgid "Delete All Subscribe Servers"
msgstr "删除所有订阅服务器节点" msgstr "删除所有订阅服务器节点"
@@ -630,12 +650,24 @@ msgstr "执行重置"
msgid "Do you want to restore the client to default settings?" msgid "Do you want to restore the client to default settings?"
msgstr "是否要恢复客户端默认配置?" msgstr "是否要恢复客户端默认配置?"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1687
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:249
msgid "DoH"
msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:230 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:230
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:259 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:259
msgid "DoT upstream (Need use wolfssl version)" msgid "DoT upstream (Need use wolfssl version)"
msgstr "DoT 上游(需使用 wolfssl 版本)" msgstr "DoT 上游(需使用 wolfssl 版本)"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1677
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:238
msgid "Domain DNS Resolve"
msgstr "域名 DNS 解析"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:419 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:419
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1704
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:265
msgid "Domain Strategy" msgid "Domain Strategy"
msgstr "域名解析策略" msgstr "域名解析策略"
@@ -692,7 +724,7 @@ msgid "Enable Authentication"
msgstr "启用用户名/密码认证" msgstr "启用用户名/密码认证"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:63 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:63
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1677 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1736
msgid "Enable Auto Switch" msgid "Enable Auto Switch"
msgstr "启用自动切换" msgstr "启用自动切换"
@@ -834,7 +866,7 @@ msgstr "分流服务器(前置)代理"
msgid "FORCE BRUTAL" msgid "FORCE BRUTAL"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:240 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:282
msgid "Filter Words splited by /" msgid "Filter Words splited by /"
msgstr "命中关键字的节点将被丢弃。多个关键字用 / 分隔" msgstr "命中关键字的节点将被丢弃。多个关键字用 / 分隔"
@@ -1047,16 +1079,39 @@ msgstr "绕过中国大陆 IP 模式"
msgid "IP Stack Preference" msgid "IP Stack Preference"
msgstr "IP 栈优先级" msgstr "IP 栈优先级"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1715
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:277
msgid "IPv4 Only"
msgstr "仅 IPv4"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1716
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:278
msgid "IPv6 Only"
msgstr "仅 IPv6"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:243 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:243
msgid "If empty, Not change Apple domains parsing DNS (Default is empty)" msgid "If empty, Not change Apple domains parsing DNS (Default is empty)"
msgstr "如果为空,则不更改 Apple 域名解析 DNS(默认为空)" msgstr "如果为空,则不更改 Apple 域名解析 DNS(默认为空)"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1707
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:268
msgid ""
"If is domain name, The requested domain name will be resolved to IP before "
"connect."
msgstr "如果是域名,域名将在请求发出之前解析为 IP。"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1393 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1393
msgid "" msgid ""
"If it is not empty, it indicates that the Client has enabled Encrypted " "If it is not empty, it indicates that the Client has enabled Encrypted "
"Client, see:" "Client, see:"
msgstr "如果不为空,表示客户端已启用加密客户端,具体请参见:" msgstr "如果不为空,表示客户端已启用加密客户端,具体请参见:"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1680
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:241
msgid ""
"If the node address is a domain name, this DNS will be used for resolution."
msgstr "如果节点地址是域名,则将使用此 DNS 进行解析。"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:865 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:865
msgid "If this option is not set, the socket behavior is platform dependent." msgid "If this option is not set, the socket behavior is platform dependent."
msgstr "如果未设置此选项,则 Socket 行为依赖于平台。" msgstr "如果未设置此选项,则 Socket 行为依赖于平台。"
@@ -1108,19 +1163,19 @@ msgstr "无效的格式。"
msgid "KcpTun" msgid "KcpTun"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1687 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1746
msgid "KcpTun Enable" msgid "KcpTun Enable"
msgstr "KcpTun 启用" msgstr "KcpTun 启用"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1704 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1763
msgid "KcpTun Param" msgid "KcpTun Param"
msgstr "KcpTun 参数" msgstr "KcpTun 参数"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1699 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1758
msgid "KcpTun Password" msgid "KcpTun Password"
msgstr "KcpTun 密码" msgstr "KcpTun 密码"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1693 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1752
msgid "KcpTun Port" msgid "KcpTun Port"
msgstr "KcpTun 端口" msgstr "KcpTun 端口"
@@ -1219,7 +1274,7 @@ msgid "Listen only on the given interface or, if unspecified, on all"
msgstr "仅监听指定的接口,未指定则监听全部。" msgstr "仅监听指定的接口,未指定则监听全部。"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:348 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:348
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1681 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1740
msgid "Local Port" msgid "Local Port"
msgstr "本地端口" msgstr "本地端口"
@@ -1403,8 +1458,8 @@ msgstr "噪声"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1140 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1140
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1152 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1152
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1162 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1162
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:322 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:364
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:327 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:369
msgid "None" msgid "None"
msgstr "" msgstr ""
@@ -1421,6 +1476,13 @@ msgstr "未运行"
msgid "Not exist" msgid "Not exist"
msgstr "未安装可执行文件" msgstr "未安装可执行文件"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1681
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1708
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:243
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:270
msgid "Note: For node-specific DNS only. Keep Auto to avoid extra overhead."
msgstr "注意:仅用于节点专用 DNS,通常请保持自动,以免增加开销。"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua:27 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua:27
msgid "" msgid ""
"Note: Restoring configurations across different versions may cause " "Note: Restoring configurations across different versions may cause "
@@ -1532,7 +1594,7 @@ msgstr "执行重置"
msgid "Permit Without Stream" msgid "Permit Without Stream"
msgstr "允许无数据流" msgstr "允许无数据流"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:351 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:393
msgid "Ping Latency" msgid "Ping Latency"
msgstr "Ping 延迟" msgstr "Ping 延迟"
@@ -1564,6 +1626,16 @@ msgstr "预连接"
msgid "Pre-shared key" msgid "Pre-shared key"
msgstr "预共享密钥" msgstr "预共享密钥"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1713
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:275
msgid "Prefer IPv4"
msgstr "IPv4 优先"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1714
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:276
msgid "Prefer IPv6"
msgstr "IPv6 优先"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:93 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:93
msgid "Prefer firewall tools" msgid "Prefer firewall tools"
msgstr "首选防火墙工具" msgstr "首选防火墙工具"
@@ -1643,7 +1715,7 @@ msgstr "读取缓冲区大小"
msgid "Really reset all changes?" msgid "Really reset all changes?"
msgstr "真的重置所有更改吗?" msgstr "真的重置所有更改吗?"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:361 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:403
msgid "Reapply" msgid "Reapply"
msgstr "重新应用" msgstr "重新应用"
@@ -1760,7 +1832,7 @@ msgstr "与全局服务器相同"
msgid "Save Order" msgid "Save Order"
msgstr "保存当前顺序" msgstr "保存当前顺序"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:244 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:286
msgid "Save Words splited by /" msgid "Save Words splited by /"
msgstr "" msgstr ""
"命中关键字的节点将被保留。多个关键字用 / 分隔。此项为空则不启用保留匹配" "命中关键字的节点将被保留。多个关键字用 / 分隔。此项为空则不启用保留匹配"
@@ -1799,7 +1871,7 @@ msgstr "服务器"
msgid "Server Address" msgid "Server Address"
msgstr "服务器地址" msgstr "服务器地址"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:275 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:317
msgid "Server Count" msgid "Server Count"
msgstr "服务器节点数量" msgstr "服务器节点数量"
@@ -1810,7 +1882,7 @@ msgstr "服务器节点类型"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:469 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:469
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:96 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:96
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:112 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:112
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:330 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:372
msgid "Server Port" msgid "Server Port"
msgstr "端口" msgstr "端口"
@@ -1890,7 +1962,7 @@ msgstr ""
msgid "Short ID" msgid "Short ID"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:335 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:377
msgid "Socket Connected" msgid "Socket Connected"
msgstr "连接测试" msgstr "连接测试"
@@ -1931,15 +2003,15 @@ msgstr "专门用于编辑 DNSPROXY 的 DNS 解析文件。"
msgid "Status" msgid "Status"
msgstr "状态" msgstr "状态"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:260 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:302
msgid "Subscribe Default Auto-Switch" msgid "Subscribe Default Auto-Switch"
msgstr "订阅新节点自动切换设置" msgstr "订阅新节点自动切换设置"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:238 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:280
msgid "Subscribe Filter Words" msgid "Subscribe Filter Words"
msgstr "订阅节点关键字过滤" msgstr "订阅节点关键字过滤"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:242 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:284
msgid "Subscribe Save Words" msgid "Subscribe Save Words"
msgstr "订阅节点关键字保留检查" msgstr "订阅节点关键字保留检查"
@@ -1947,11 +2019,11 @@ msgstr "订阅节点关键字保留检查"
msgid "Subscribe URL" msgid "Subscribe URL"
msgstr "SS/SSR/V2/TROJAN/HY2/TUIC 订阅 URL" msgstr "SS/SSR/V2/TROJAN/HY2/TUIC 订阅 URL"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:262 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:304
msgid "Subscribe new add server default Auto-Switch on" msgid "Subscribe new add server default Auto-Switch on"
msgstr "订阅加入的新节点默认开启自动切换" msgstr "订阅加入的新节点默认开启自动切换"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:257 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:299
msgid "Subscribe nodes allows insecure connection as TLS client (insecure)" msgid "Subscribe nodes allows insecure connection as TLS client (insecure)"
msgstr "订阅节点强制开启 不验证TLS客户端证书 (insecure)" msgstr "订阅节点强制开启 不验证TLS客户端证书 (insecure)"
@@ -1963,10 +2035,20 @@ msgstr "同时支持 AdGuard Home 和 DNSMASQ 格式的过滤列表"
msgid "Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5." msgid "Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5."
msgstr "支持固定值或随机范围(如 30 或 5-30),最小 5 秒。" msgstr "支持固定值或随机范围(如 30 或 5-30),最小 5 秒。"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:242
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:269
msgid "Supports only Xray node types."
msgstr "仅支持 Xray 类型节点。"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:67 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:67
msgid "Switch check cycly(second)" msgid "Switch check cycly(second)"
msgstr "自动切换检查周期(秒)" msgstr "自动切换检查周期(秒)"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1685
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:247
msgid "TCP"
msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:729 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:729
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1667 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1667
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:149 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:149
@@ -2088,11 +2170,11 @@ msgstr "输入的内容不正确!"
msgid "The keep-alive period.(Unit:second)" msgid "The keep-alive period.(Unit:second)"
msgstr "心跳包发送间隔(单位:秒)" msgstr "心跳包发送间隔(单位:秒)"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:265 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:307
msgid "Through proxy update" msgid "Through proxy update"
msgstr "通过代理更新" msgstr "通过代理更新"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:267 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:309
msgid "Through proxy update list, Not Recommended" msgid "Through proxy update list, Not Recommended"
msgstr "通过路由器自身代理更新订阅" msgstr "通过路由器自身代理更新订阅"
@@ -2137,11 +2219,13 @@ msgid "Trojan"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:412 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:412
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:320 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:362
msgid "Type" msgid "Type"
msgstr "类型" msgstr "类型"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:622 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:622
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1686
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:248
msgid "UDP" msgid "UDP"
msgstr "" msgstr ""
@@ -2173,7 +2257,7 @@ msgstr "UDP/TCP 上游"
msgid "UL Restore" msgid "UL Restore"
msgstr "上传恢复" msgstr "上传恢复"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:280 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:322
msgid "URL Test Address" msgid "URL Test Address"
msgstr "URL 测试地址" msgstr "URL 测试地址"
@@ -2186,12 +2270,12 @@ msgstr "无法复制 SSR 网址到剪贴板。"
msgid "Unknown" msgid "Unknown"
msgstr "未知" msgstr "未知"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:269 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:311
#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe.htm:16 #: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe.htm:16
msgid "Update All Subscribe Servers" msgid "Update All Subscribe Servers"
msgstr "更新所有订阅服务器节点" msgstr "更新所有订阅服务器节点"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:246 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:288
msgid "Update Subscribe List" msgid "Update Subscribe List"
msgstr "更新订阅 URL 列表" msgstr "更新订阅 URL 列表"
@@ -2199,7 +2283,7 @@ msgstr "更新订阅 URL 列表"
msgid "Update cycle (Day/Week)" msgid "Update cycle (Day/Week)"
msgstr "更新周期(天/周)" msgstr "更新周期(天/周)"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:248 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:290
msgid "Update subscribe url list first" msgid "Update subscribe url list first"
msgstr "修改订阅 URL 和节点关键字后,请先点击更新" msgstr "修改订阅 URL 和节点关键字后,请先点击更新"
@@ -2271,7 +2355,7 @@ msgid "User cancelled."
msgstr "用户已取消。" msgstr "用户已取消。"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1268 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1268
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:290 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:332
msgid "User-Agent" msgid "User-Agent"
msgstr "用户代理(User-Agent)" msgstr "用户代理(User-Agent)"
@@ -2,6 +2,7 @@
require "luci.sys" require "luci.sys"
local ucursor = require "luci.model.uci".cursor() local ucursor = require "luci.model.uci".cursor()
local datatypes = require "luci.cbi.datatypes"
local json = require "luci.jsonc" local json = require "luci.jsonc"
local server_section = arg[1] local server_section = arg[1]
@@ -10,7 +11,28 @@ local local_port = arg[3] or "0"
local socks_port = arg[4] or "0" local socks_port = arg[4] or "0"
local chain = arg[5] or "0" local chain = arg[5] or "0"
local chain_local_port = string.split(chain, "/")[2] or "0"
local GLOBAL = {
DNS_SERVER = {},
DNS_HOSTNAME = {},
VPS_EXCLUDE = {}
}
-- 辅助函数:拆分字符串(若 luci.util 未加载则定义)
local function split(str, pat)
local t = {}
local last = 1
while true do
local pos = str:find(pat, last, true)
if not pos then break end
table.insert(t, str:sub(last, pos - 1))
last = pos + 1
end
table.insert(t, str:sub(last))
return t
end
local chain_local_port = split(chain, "/")[2] or "0"
local server = ucursor:get_all("shadowsocksr", server_section) local server = ucursor:get_all("shadowsocksr", server_section)
local socks_server = ucursor:get_all("shadowsocksr", "@socks5_proxy[0]") or {} local socks_server = ucursor:get_all("shadowsocksr", "@socks5_proxy[0]") or {}
@@ -25,6 +47,16 @@ local remarks = server.alias or ""
local b64decode = nixio.bin.b64decode local b64decode = nixio.bin.b64decode
local b64encode = nixio.bin.b64encode local b64encode = nixio.bin.b64encode
-- 解析 URL(简单实现,仅用于 DoH)
local function parseURL(url)
if not url then return nil end
local schema, rest = url:match("^(https?)://(.*)$")
if not schema then return nil end
local host, port_str = rest:match("^([^:]+):?(%d*)/?.*$")
local port = tonumber(port_str) or (schema == "https" and 443 or 80)
return { host = host, port = port, schema = schema }
end
if server.type == "ss-rust" or server.type == "ss-libev" then if server.type == "ss-rust" or server.type == "ss-libev" then
server.type = "ss" server.type = "ss"
end end
@@ -254,6 +286,10 @@ settings:handleIndex(server.v2ray_protocol)
local Xray = { local Xray = {
log = { log = {
-- error = "/var/ssrplus.log", -- error = "/var/ssrplus.log",
-- loglevel = "debug",
-- dnsLog = true,
-- access = "/var/log/ssrplus-access.log",
-- error = "/var/log/ssrplus-error.log"
loglevel = "warning" loglevel = "warning"
}, },
@@ -327,313 +363,329 @@ if proto and proto:find("tcp") and socks_port ~= "0" then
}) })
end end
-- 传出连接 -- 传出连接
Xray.outbounds = { Xray.outbounds = {
{ {
protocol = (server.v2ray_protocol == "hysteria2") and "hysteria" or server.v2ray_protocol, protocol = (server.v2ray_protocol == "hysteria2") and "hysteria" or server.v2ray_protocol,
settings = outbound_settings, settings = outbound_settings,
-- 底层传输配置 tag = (remarks ~= nil and remarks ~= "") and (node_id .. ":" .. remarks) or node_id,
streamSettings = (server.v2ray_protocol ~= "wireguard") and { -- 底层传输配置
network = (server.v2ray_protocol == "hysteria2") and "hysteria" or (server.transport or "raw"), streamSettings = (server.v2ray_protocol ~= "wireguard") and {
security = (server.xtls == '1') and "xtls" or (server.tls == '1') and "tls" or (server.reality == '1') and "reality" or nil, network = (server.v2ray_protocol == "hysteria2") and "hysteria" or (server.transport or "raw"),
tlsSettings = (server.tls == '1') and { security = (server.xtls == '1') and "xtls" or (server.tls == '1') and "tls" or (server.reality == '1') and "reality" or nil,
-- tls tlsSettings = (server.tls == '1') and {
alpn = (server.tls_alpn and server.tls_alpn ~= "") and (function() -- tls
local alpn = {} alpn = (server.tls_alpn and server.tls_alpn ~= "") and (function()
string.gsub(server.tls_alpn, '[^,]+', function(w) local alpn = {}
table.insert(alpn, w) string.gsub(server.tls_alpn, '[^,]+', function(w)
end) table.insert(alpn, w)
if #alpn > 0 then end)
return alpn if #alpn > 0 then
else return alpn
return nil else
end
end)() or nil,
fingerprint = server.fingerprint,
allowInsecure = (function()
if server.tls_CertSha and server.tls_CertSha ~= "" then return nil end
if os.date("%Y.%m.%d") < "2026.06.01" then
return server.insecure == "1"
end
return nil return nil
end)(), end
serverName = server.tls_host, end)() or nil,
certificates = server.certificate and { fingerprint = server.fingerprint,
usage = "verify", allowInsecure = (function()
certificateFile = server.certpath if server.tls_CertSha and server.tls_CertSha ~= "" then return nil end
} or nil, if os.date("%Y.%m.%d") < "2026.06.01" then
pinnedPeerCertSha256 = (function() return server.insecure == "1"
if xray_version_val < 260131 then return nil end end
if not server.tls_CertSha then return "" end return nil
return server.tls_CertSha end)(),
end)(), serverName = server.tls_host,
verifyPeerCertByName = (function() certificates = server.certificate and {
if xray_version_val < 260131 then return nil end usage = "verify",
if not server.tls_CertByName then return "" end certificateFile = server.certpath
return server.tls_CertByName
end)(),
echConfigList = (server.enable_ech == "1") and server.ech_config or nil,
echForceQuery = (server.enable_ech == "1") and (server.ech_ForceQuery or "full") or nil
} or nil, } or nil,
xtlsSettings = (server.xtls == '1') and server.tls_host and { pinnedPeerCertSha256 = (function()
-- xtls if xray_version_val < 260131 then return nil end
allowInsecure = (server.insecure == "1") and true or nil, if not server.tls_CertSha then return "" end
serverName = server.tls_host, return server.tls_CertSha
minVersion = "1.3" end)(),
} or nil, verifyPeerCertByName = (function()
realitySettings = (server.reality == '1') and { if xray_version_val < 260131 then return nil end
publicKey = server.reality_publickey, if not server.tls_CertByName then return "" end
shortId = server.reality_shortid or "", return server.tls_CertByName
spiderX = server.reality_spiderx or "", end)(),
fingerprint = server.fingerprint, echConfigList = (server.enable_ech == "1") and server.ech_config or nil,
mldsa65Verify = (server.enable_mldsa65verify == '1') and server.reality_mldsa65verify or nil, echForceQuery = (server.enable_ech == "1") and (server.ech_ForceQuery or "full") or nil
serverName = server.tls_host } or nil,
} or nil, xtlsSettings = (server.xtls == '1') and server.tls_host and {
rawSettings = ((server.transport == "raw" or server.transport == "tcp") -- xtls
and (server.tcp_guise and server.tcp_guise ~= "none")) and { allowInsecure = (server.insecure == "1") and true or nil,
-- tcp serverName = server.tls_host,
header = { minVersion = "1.3"
type = server.tcp_guise, } or nil,
request = (server.tcp_guise == "http") and { realitySettings = (server.reality == '1') and {
path = server.http_path and (function() publicKey = server.reality_publickey,
local t, r = server.http_path, {} shortId = server.reality_shortid or "",
if type(t) == "string" then t = {t} end spiderX = server.reality_spiderx or "",
for _, v in ipairs(t) do fingerprint = server.fingerprint,
r[#r + 1] = (v == "" and "/" or v) mldsa65Verify = (server.enable_mldsa65verify == '1') and server.reality_mldsa65verify or nil,
end serverName = server.tls_host
return r } or nil,
end)() or {"/"}, rawSettings = ((server.transport == "raw" or server.transport == "tcp")
headers = (server.http_path or server.user_agent) and { and (server.tcp_guise and server.tcp_guise ~= "none")) and {
Host = (type(server.http_host) == "string") and {server.http_host} or server.http_host, -- tcp
["User-Agent"] = server.user_agent and {server.user_agent} or nil header = {
} or nil type = server.tcp_guise,
request = (server.tcp_guise == "http") and {
path = server.http_path and (function()
local t, r = server.http_path, {}
if type(t) == "string" then t = {t} end
for _, v in ipairs(t) do
r[#r + 1] = (v == "" and "/" or v)
end
return r
end)() or {"/"},
headers = (server.http_path or server.user_agent) and {
Host = (type(server.http_host) == "string") and {server.http_host} or server.http_host,
["User-Agent"] = server.user_agent and {server.user_agent} or nil
} or nil } or nil
}
} or nil,
kcpSettings = (server.transport == "kcp") and {
-- kcp
mtu = tonumber(server.mtu),
tti = tonumber(server.tti),
uplinkCapacity = tonumber(server.uplink_capacity),
downlinkCapacity = tonumber(server.downlink_capacity),
congestion = (server.congestion == "1") and true or false,
readBufferSize = tonumber(server.read_buffer_size),
writeBufferSize = tonumber(server.write_buffer_size)
} or nil,
wsSettings = (server.transport == "ws") and (server.ws_path or server.ws_host or server.tls_host) and {
-- ws
host = server.ws_host or server.tls_host or nil,
path = server.ws_path or "/",
headers = server.user_agent and {
["User-Agent"] = server.user_agent
} or nil,
maxEarlyData = tonumber(server.ws_ed) or nil,
earlyDataHeaderName = server.ws_ed_header or nil,
heartbeatPeriod = tonumber(server.ws_heartbeatPeriod) or nil
} or nil,
httpupgradeSettings = (server.transport == "httpupgrade") and {
-- httpupgrade
host = (server.httpupgrade_host or server.tls_host) or nil,
path = server.httpupgrade_path or "",
headers = server.user_agent and {
["User-Agent"] = server.user_agent
} or nil } or nil
}
} or nil,
kcpSettings = (server.transport == "kcp") and {
-- kcp
mtu = tonumber(server.mtu),
tti = tonumber(server.tti),
uplinkCapacity = tonumber(server.uplink_capacity),
downlinkCapacity = tonumber(server.downlink_capacity),
congestion = (server.congestion == "1") and true or false,
readBufferSize = tonumber(server.read_buffer_size),
writeBufferSize = tonumber(server.write_buffer_size)
} or nil,
wsSettings = (server.transport == "ws") and (server.ws_path or server.ws_host or server.tls_host) and {
-- ws
host = server.ws_host or server.tls_host or nil,
path = server.ws_path or "/",
headers = server.user_agent and {
["User-Agent"] = server.user_agent
} or nil, } or nil,
xhttpSettings = (server.transport == "xhttp" or server.transport == "splithttp") and { maxEarlyData = tonumber(server.ws_ed) or nil,
-- xhttp earlyDataHeaderName = server.ws_ed_header or nil,
mode = server.xhttp_mode or "auto", heartbeatPeriod = tonumber(server.ws_heartbeatPeriod) or nil
host = (server.xhttp_host or server.tls_host) or nil, } or nil,
path = server.xhttp_path or "/", httpupgradeSettings = (server.transport == "httpupgrade") and {
extra = (function() -- httpupgrade
local extra = {} host = (server.httpupgrade_host or server.tls_host) or nil,
-- 解析 xhttp_extra(Base64 编码的 JSON) path = server.httpupgrade_path or "",
if (server.enable_xhttp_extra == "1" and server.xhttp_extra) then headers = server.user_agent and {
local ok, parsed = pcall(json.parse, base64Decode(server.xhttp_extra)) ["User-Agent"] = server.user_agent
if ok and type(parsed) == "table" then } or nil
extra = parsed.extra or parsed -- 取 "extra" 节,若无则整个 parsed } or nil,
end xhttpSettings = (server.transport == "xhttp" or server.transport == "splithttp") and {
-- xhttp
mode = server.xhttp_mode or "auto",
host = (server.xhttp_host or server.tls_host) or nil,
path = server.xhttp_path or "/",
extra = (function()
local extra = {}
-- 解析 xhttp_extra(Base64 编码的 JSON)
if (server.enable_xhttp_extra == "1" and server.xhttp_extra) then
local ok, parsed = pcall(json.parse, base64Decode(server.xhttp_extra))
if ok and type(parsed) == "table" then
extra = parsed.extra or parsed -- 取 "extra" 节,若无则整个 parsed
end end
-- 处理 User-Agent end
if server.user_agent and server.user_agent ~= "" then -- 处理 User-Agent
extra.headers = extra.headers or {} if server.user_agent and server.user_agent ~= "" then
if not extra.headers["User-Agent"] and not extra.headers["user-agent"] then extra.headers = extra.headers or {}
extra.headers["User-Agent"] = server.user_agent if not extra.headers["User-Agent"] and not extra.headers["user-agent"] then
end extra.headers["User-Agent"] = server.user_agent
end end
-- 递归清理空表(如空 headers 会被删除) end
return cleanEmptyTables(extra) -- 递归清理空表(如空 headers 会被删除)
end)() return cleanEmptyTables(extra)
} or nil, end)()
httpSettings = (server.transport == "h2") and { } or nil,
-- h2 httpSettings = (server.transport == "h2") and {
path = server.h2_path or "", -- h2
host = {server.h2_host} or nil, path = server.h2_path or "",
read_idle_timeout = tonumber(server.read_idle_timeout) or nil, host = {server.h2_host} or nil,
health_check_timeout = tonumber(server.health_check_timeout) or nil read_idle_timeout = tonumber(server.read_idle_timeout) or nil,
} or nil, health_check_timeout = tonumber(server.health_check_timeout) or nil
quicSettings = (server.transport == "quic") and { } or nil,
-- quic quicSettings = (server.transport == "quic") and {
security = server.quic_security, -- quic
key = server.quic_key, security = server.quic_security,
header = {type = server.quic_guise} key = server.quic_key,
} or nil, header = {type = server.quic_guise}
grpcSettings = (server.transport == "grpc") and { } or nil,
-- grpc grpcSettings = (server.transport == "grpc") and {
serviceName = (server.serviceName and server.serviceName ~= "") and server.serviceName or nil, -- grpc
multiMode = (server.grpc_mode == "multi") and true or nil, serviceName = (server.serviceName and server.serviceName ~= "") and server.serviceName or nil,
idle_timeout = server.idle_timeout and (tonumber(server.idle_timeout) < 10 and 10 or tonumber(server.idle_timeout)) or nil, multiMode = (server.grpc_mode == "multi") and true or nil,
health_check_timeout = server.health_check_timeout and tonumber(server.health_check_timeout) or nil, idle_timeout = server.idle_timeout and (tonumber(server.idle_timeout) < 10 and 10 or tonumber(server.idle_timeout)) or nil,
permit_without_stream = (server.permit_without_stream == "1") and true or nil, health_check_timeout = server.health_check_timeout and tonumber(server.health_check_timeout) or nil,
initial_windows_size = server.initial_windows_size and tonumber(server.initial_windows_size) or nil, permit_without_stream = (server.permit_without_stream == "1") and true or nil,
user_agent = server.user_agent initial_windows_size = server.initial_windows_size and tonumber(server.initial_windows_size) or nil,
} or nil, user_agent = server.user_agent
hysteriaSettings = (server.v2ray_protocol == "hysteria2") and { } or nil,
-- hysteria2 hysteriaSettings = (server.v2ray_protocol == "hysteria2") and {
version = 2, -- hysteria2
auth = server.hy2_auth version = 2,
} or nil, auth = server.hy2_auth
finalmask = (function() } or nil,
local finalmask = {} finalmask = (function()
local PT = server.v2ray_protocol local finalmask = {}
local TP = server.transport local PT = server.v2ray_protocol
if server.transport == "kcp" then local TP = server.transport
local map = {none = "none", srtp = "header-srtp", utp = "header-utp", ["wechat-video"] = "header-wechat", if server.transport == "kcp" then
dtls = "header-dtls", wireguard = "header-wireguard", dns = "header-dns"} local map = {none = "none", srtp = "header-srtp", utp = "header-utp", ["wechat-video"] = "header-wechat",
local udp = {} dtls = "header-dtls", wireguard = "header-wireguard", dns = "header-dns"}
if server.kcp_guise and server.kcp_guise ~= "none" then local udp = {}
local g = { type = map[server.kcp_guise] } if server.kcp_guise and server.kcp_guise ~= "none" then
if server.kcp_guise == "dns" and server.kcp_domain and server.kcp_domain ~= "" then local g = { type = map[server.kcp_guise] }
g.settings = { domain = server.kcp_domain } if server.kcp_guise == "dns" and server.kcp_domain and server.kcp_domain ~= "" then
end g.settings = { domain = server.kcp_domain }
udp[#udp+1] = g
end end
local c = { type = (server.seed and server.seed ~= "") and "mkcp-aes128gcm" or "mkcp-original" } udp[#udp+1] = g
if server.seed and server.seed ~= "" then end
c.settings = { password = server.seed } local c = { type = (server.seed and server.seed ~= "") and "mkcp-aes128gcm" or "mkcp-original" }
end if server.seed and server.seed ~= "" then
udp[#udp+1] = c c.settings = { password = server.seed }
finalmask.udp = udp end
elseif PT == "hysteria2" then udp[#udp+1] = c
if (server.flag_obfs == "1" and (server.obfs_type and server.obfs_type ~= "")) then finalmask.udp = udp
finalmask.udp = {{ elseif PT == "hysteria2" then
type = server.obfs_type, if (server.flag_obfs == "1" and (server.obfs_type and server.obfs_type ~= "")) then
settings = server.salamander and { finalmask.udp = {{
password = server.salamander type = server.obfs_type,
} or nil settings = server.salamander and {
}} password = server.salamander
end } or nil
local up = tonumber(server.uplink_capacity) or 0 }}
local down = tonumber(server.downlink_capacity) or 0 end
finalmask.quicParams = { local up = tonumber(server.uplink_capacity) or 0
congestion = server.hy2_tcpcongestion or nil, local down = tonumber(server.downlink_capacity) or 0
brutalUp = up > 0 and (up .. "mbps") or nil, finalmask.quicParams = {
brutalDown = down > 0 and (down .. "mbps") or nil, congestion = server.hy2_tcpcongestion or nil,
udpHop = (server.flag_port_hopping == "1") and { brutalUp = up > 0 and (up .. "mbps") or nil,
ports = string.gsub(server.port_range, ":", "-"), brutalDown = down > 0 and (down .. "mbps") or nil,
interval = (function(v) udpHop = (server.flag_port_hopping == "1") and {
if not v then return 30 end ports = string.gsub(server.port_range, ":", "-"),
if v:find("-", 1, true) then interval = (function(v)
local min, max = v:match("^(%d+)%-(%d+)$") if not v then return 30 end
min = tonumber(min) if v:find("-", 1, true) then
max = tonumber(max) local min, max = v:match("^(%d+)%-(%d+)$")
if min and max then min = tonumber(min)
min = (min >= 5) and min or 5 max = tonumber(max)
max = (max >= min) and max or min if min and max then
return min .. "-" .. max min = (min >= 5) and min or 5
end max = (max >= min) and max or min
return 30 return min .. "-" .. max
end end
v = tonumber((v or "30"):match("^%d+")) return 30
return (v and v >= 5) and v or 30 end
end)(server.hopinterval) v = tonumber((v or "30"):match("^%d+"))
} or nil, return (v and v >= 5) and v or 30
initStreamReceiveWindow = (server.flag_quicparam == "1" and server.initstreamreceivewindow) and tonumber(server.initstreamreceivewindow) or nil, end)(server.hopinterval)
maxStreamReceiveWindow = (server.flag_quicparam == "1" and server.maxstreamreceivewindow) and tonumber(server.maxstreamreceivewindow) or nil, } or nil,
initConnectionReceiveWindow = (server.flag_quicparam == "1" and server.initconnreceivewindow) and tonumber(server.initconnreceivewindow) or nil, initStreamReceiveWindow = (server.flag_quicparam == "1" and server.initstreamreceivewindow) and tonumber(server.initstreamreceivewindow) or nil,
maxConnectionReceiveWindow = (server.flag_quicparam == "1" and server.maxconnreceivewindow) and tonumber(server.maxconnreceivewindow) or nil, maxStreamReceiveWindow = (server.flag_quicparam == "1" and server.maxstreamreceivewindow) and tonumber(server.maxstreamreceivewindow) or nil,
maxIdleTimeout = (server.flag_quicparam == "1" and (function(t) initConnectionReceiveWindow = (server.flag_quicparam == "1" and server.initconnreceivewindow) and tonumber(server.initconnreceivewindow) or nil,
t = tonumber(tostring(t or "30"):match("^%d+")) maxConnectionReceiveWindow = (server.flag_quicparam == "1" and server.maxconnreceivewindow) and tonumber(server.maxconnreceivewindow) or nil,
return (t and t >= 4 and t <= 120) and t or 30 maxIdleTimeout = (server.flag_quicparam == "1" and (function(t)
end)(server.maxidletimeout) or 30), t = tonumber(tostring(t or "30"):match("^%d+"))
keepAlivePeriod = (server.flag_quicparam == "1" and server.keepaliveperiod) and tonumber(server.keepaliveperiod) or nil, return (t and t >= 4 and t <= 120) and t or 30
disablePathMTUDiscovery = (server.flag_quicparam == "1" and tostring(server.disablepathmtudiscovery) == "1") and true or nil end)(server.maxidletimeout) or 30),
keepAlivePeriod = (server.flag_quicparam == "1" and server.keepaliveperiod) and tonumber(server.keepaliveperiod) or nil,
disablePathMTUDiscovery = (server.flag_quicparam == "1" and tostring(server.disablepathmtudiscovery) == "1") and true or nil
}
end
if xray_fragment.fragment == "1" and ({raw=1, ws=1, httpupgrade=1, grpc=1, xhttp=1})[TP] then
local n_packets = xray_fragment.fragment_packets
local n_length = xray_fragment.fragment_length
local n_delay = xray_fragment.fragment_delay
local n_maxsplit = xray_fragment.fragment_maxSplit
--local domainstr = xray_noise.domainStrategy
finalmask.tcp = finalmask.tcp or {}
finalmask.tcp[#finalmask.tcp + 1] = {
type = "fragment",
settings = {
--domainStrategy = (xray_fragment.noise == "1" and xray_noise.enabled == "1") and domainstr or nil,
packets = (n_packets and n_packets ~= "") and n_packets or nil,
length = (n_length and n_length ~= "") and n_length or nil,
delay = (type(n_delay) == "string" and string.find(n_delay, "-")) and n_delay or (n_delay and tonumber(n_delay)),
maxSplit = (n_maxsplit and n_maxsplit ~= "") and n_maxsplit or nil
} }
end }
if xray_fragment.fragment == "1" and ({raw=1, ws=1, httpupgrade=1, grpc=1, xhttp=1})[TP] then end
local n_packets = xray_fragment.fragment_packets if xray_fragment.noise == "1" and (TP == "kcp" or (TP == "xhttp" and (server.tls_alpn == "h3" or server.tls_alpn == "h3,h2"))) then
local n_length = xray_fragment.fragment_length if xray_noise.enabled == "1" then
local n_delay = xray_fragment.fragment_delay local n_type = xray_noise.type
local n_maxsplit = xray_fragment.fragment_maxSplit local n_delay = xray_noise.delay
--local domainstr = xray_noise.domainStrategy local n_packet = xray_noise.packet
finalmask.tcp = finalmask.tcp or {} finalmask.udp = finalmask.udp or {}
finalmask.tcp[#finalmask.tcp + 1] = { finalmask.udp[#finalmask.udp + 1] = {
type = "fragment", type = "noise",
settings = { settings = {
--domainStrategy = (xray_fragment.noise == "1" and xray_noise.enabled == "1") and domainstr or nil, reset = 0,
packets = (n_packets and n_packets ~= "") and n_packets or nil, noise = {
length = (n_length and n_length ~= "") and n_length or nil, {
delay = (type(n_delay) == "string" and string.find(n_delay, "-")) and n_delay or (n_delay and tonumber(n_delay)), rand = (n_type == "rand") and (n_packet and (type(n_packet) == "string" and (n_packet:find("-")) and n_packet or tonumber(n_packet))) or nil,
maxSplit = (n_maxsplit and n_maxsplit ~= "") and n_maxsplit or nil type = (type(n_type) == "string" and n_type ~= "rand") and n_type or nil,
} packet = (n_type ~= "rand") and ((n_packet and type(n_packet) == "string") and ((n_type == "hex" and hexEncode(n_packet)) or (n_type == "base64" and base64Encode(n_packet))) or n_packet) or nil,
} delay = (type(n_delay) == "string" and string.find(n_delay, "-")) and n_delay or (n_delay and tonumber(n_delay))
end
if xray_fragment.noise == "1" and (TP == "kcp" or (TP == "xhttp" and (server.tls_alpn == "h3" or server.tls_alpn == "h3,h2"))) then
if xray_noise.enabled == "1" then
local n_type = xray_noise.type
local n_delay = xray_noise.delay
local n_packet = xray_noise.packet
finalmask.udp = finalmask.udp or {}
finalmask.udp[#finalmask.udp + 1] = {
type = "noise",
settings = {
reset = 0,
noise = {
{
rand = (n_type == "rand") and (n_packet and (type(n_packet) == "string" and (n_packet:find("-")) and n_packet or tonumber(n_packet))) or nil,
type = (type(n_type) == "string" and n_type ~= "rand") and n_type or nil,
packet = (n_type ~= "rand") and ((n_packet and type(n_packet) == "string") and ((n_type == "hex" and hexEncode(n_packet)) or (n_type == "base64" and base64Encode(n_packet))) or n_packet) or nil,
delay = (type(n_delay) == "string" and string.find(n_delay, "-")) and n_delay or (n_delay and tonumber(n_delay))
}
} }
} }
} }
end }
end end
if server.finalmask and server.finalmask ~= "" then end
local ok, fm = pcall(json.parse, base64Decode(server.finalmask)) if server.finalmask and server.finalmask ~= "" then
if ok and type(fm) == "table" then local ok, fm = pcall(json.parse, base64Decode(server.finalmask))
finalmask = fm if ok and type(fm) == "table" then
end finalmask = fm
end end
return cleanEmptyTables(finalmask) end
end)(), return cleanEmptyTables(finalmask)
sockopt = { end)(),
mark = 255, sockopt = {
tcpFastOpen = (function() mark = 255,
if server.transport == "xhttp" then domainStrategy = server.domain_strategy or "UseIP",
return (server.fast_open == "1") and true or false tcpFastOpen = (function()
elseif server.v2ray_protocol == "hysteria2" then if server.transport == "xhttp" then
return (server.fast_open == "1") and true or nil return (server.fast_open == "1") and true or false
else elseif server.v2ray_protocol == "hysteria2" then
return nil return (server.fast_open == "1") and true or nil
end else
end)(), -- XHTTP Tcp Fast Open return nil
tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP end
Penetrate = (server.mptcp == "1") and true or nil, -- Penetrate MPTCP end)(), -- XHTTP Tcp Fast Open
tcpcongestion = server.custom_tcpcongestion, -- 连接服务器节点的 TCP 拥塞控制算法 tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP
dialerProxy = (xray_fragment.fragment == "1" or xray_fragment.noise == "1") and Penetrate = (server.mptcp == "1") and true or nil, -- Penetrate MPTCP
((remarks ~= nil and remarks ~= "") and (node_id .. "." .. remarks) or node_id) or nil tcpcongestion = server.custom_tcpcongestion, -- 连接服务器节点的 TCP 拥塞控制算法
} -- 出站的 dialerProxy(与 fragment 中的 tag 保持一致)
} or nil, dialerProxy = (xray_fragment.fragment == "1" or xray_fragment.noise == "1") and
mux = (server.v2ray_protocol ~= "hysteria2" and server.v2ray_protocol ~= "wireguard") and { ((remarks ~= nil and remarks ~= "") and (node_id .. "." .. remarks) or node_id) or nil
-- mux }
enabled = (server.mux == "1"), -- Mux } or nil,
concurrency = (server.mux == "1" and (tonumber(server.concurrency) or -1)) or nil, -- TCP 最大并发连接数 mux = (server.v2ray_protocol ~= "hysteria2" and server.v2ray_protocol ~= "wireguard") and {
xudpConcurrency = (server.mux == "1" and (tonumber(server.xudpConcurrency) or 16)) or nil, -- UDP 最大并发连接数 -- mux
xudpProxyUDP443 = (server.mux == "1" and (server.xudpProxyUDP443 or "reject")) or nil -- 对被代理的 UDP/443 流量处理方式 enabled = (server.mux == "1"), -- Mux
} or nil concurrency = (server.mux == "1" and (tonumber(server.concurrency) or -1)) or nil, -- TCP 最大并发连接数
xudpConcurrency = (server.mux == "1" and (tonumber(server.xudpConcurrency) or 16)) or nil, -- UDP 最大并发连接数
xudpProxyUDP443 = (server.mux == "1" and (server.xudpProxyUDP443 or "reject")) or nil -- 对被代理的 UDP/443 流量处理方式
} or nil
}
}
table.insert(Xray.outbounds, {
protocol = "freedom",
tag = "direct",
settings = {
domainStrategy = server.domain_strategy or "UseIP" -- 可根据需要改为 direct_dns_query_strategy
},
streamSettings = {
sockopt = {
mark = 255
} }
} }
})
-- 添加带有 fragment 设置的 dialerproxy 配置 -- 添加带有 fragment 设置的 dialerproxy 配置
if xray_fragment.fragment ~= "0" or (xray_fragment.noise ~= "0" and xray_noise.enabled ~= "0") then if xray_fragment.fragment ~= "0" or (xray_fragment.noise ~= "0" and xray_noise.enabled ~= "0") then
@@ -664,6 +716,121 @@ if xray_fragment.fragment ~= "0" or (xray_fragment.noise ~= "0" and xray_noise.e
}) })
end end
-- Xray DNS 解析配置
if datatypes.hostname(server.server) and server.domain_resolver and (server.domain_resolver_dns or server.domain_resolver_dns_https) then
-- 解析 DNS 服务器配置
local dns_proto = server.domain_resolver
local config_address
local config_port
if dns_proto == "https" then
local _a = parseURL(server.domain_resolver_dns_https)
if _a then
config_address = server.domain_resolver_dns_https
config_port = _a.port or 443
if _a.hostname and datatypes.hostname(_a.hostname) then
GLOBAL.DNS_HOSTNAME[_a.hostname] = true
end
end
else
local server_address = server.domain_resolver_dns
config_port = 53
local parts = split(server_address, ":")
if #parts > 1 then
server_address = parts[1]
config_port = tonumber(parts[#parts])
end
config_address = server_address
if dns_proto == "tcp" then
config_address = dns_proto .. "://" .. server_address .. ":" .. config_port
end
end
-- 存入 GLOBAL.DNS_SERVER(去重)
local dns_key = dns_proto .. "|" .. config_address .. "|" .. tostring(config_port)
if not GLOBAL.DNS_SERVER[dns_key] then
GLOBAL.DNS_SERVER[dns_key] = {
tag = "dns-node-" .. node_id,
address = config_address,
port = config_port,
finalQuery = true,
disableCache = false,
serveStale = true,
serveExpiredTTL = 30,
domains = {}
}
end
-- 添加当前节点域名到该 DNS 服务器的 domains 列表
local domain = "full:" .. server.server
local exists
for _, d in ipairs(GLOBAL.DNS_SERVER[dns_key].domains) do
if d == domain then exists = true; break end
end
if not exists then
table.insert(GLOBAL.DNS_SERVER[dns_key].domains, domain)
end
GLOBAL.VPS_EXCLUDE[server.server] = true
-- 构建 Xray.dns
local dns_servers = { "localhost" }
for key, dns_server in pairs(GLOBAL.DNS_SERVER) do
table.insert(dns_servers, {
tag = dns_server.tag,
address = dns_server.address,
port = dns_server.port,
domains = dns_server.domains,
finalQuery = dns_server.finalQuery,
serveStale = dns_server.serveStale,
serveExpiredTTL = dns_server.serveExpiredTTL,
disableCache = dns_server.disableCache
})
end
Xray.dns = {
servers = dns_servers,
disableFallback = true,
disableFallbackIfMatch = true,
useSystemHosts = true,
queryStrategy = "UseIP",
disableCache = false,
tag = "dns-global" -- 用于 routing
}
end
-- 代理出站的 tag(与 outbound 中的 tag 保持一致)
local proxy_tag = (remarks ~= nil and remarks ~= "") and (node_id .. ":" .. remarks) or node_id
-- 构建 routing 规则表
local routing_rules = {}
-- 1. 为每个自定义 DNS 服务器添加直连规则(inboundTag 匹配 dns-node-xxx)
if GLOBAL.DNS_SERVER and next(GLOBAL.DNS_SERVER) then
for _, dns_server in pairs(GLOBAL.DNS_SERVER) do
table.insert(routing_rules, {
inboundTag = { dns_server.tag },
outboundTag = "direct"
})
end
end
-- 2. 添加全局 DNS 直连规则(需要 Xray.dns 中已设置 tag = "dns-global")
if Xray.dns and Xray.dns.tag then
table.insert(routing_rules, {
inboundTag = { "dns-global" },
outboundTag = "direct"
})
end
-- 3. 添加默认规则:所有 TCP/UDP 流量走代理
table.insert(routing_rules, {
network = "tcp,udp",
ruleTag = "default",
outboundTag = proxy_tag
})
-- 构建 routing 对象
Xray.routing = {
rules = routing_rules,
domainStrategy = "AsIs"
}
local cipher = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA" local cipher = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA"
local cipher13 = "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384" local cipher13 = "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384"
local trojan = { local trojan = {
@@ -851,7 +1018,7 @@ local shadowtls = {
strict = (server.strict == "1") and true or false strict = (server.strict == "1") and true or false
} }
local chain_sslocal = { local chain_sslocal = {
locals = local_port ~= "0" and { locals = local_port ~= "0" and {
{ {
local_address = "0.0.0.0", local_address = "0.0.0.0",
local_port = (chain_local_port == "0" and tonumber(server.local_port) or tonumber(chain_local_port)), local_port = (chain_local_port == "0" and tonumber(server.local_port) or tonumber(chain_local_port)),
@@ -867,93 +1034,94 @@ local chain_sslocal = {
local_port = tonumber(socks_port) local_port = tonumber(socks_port)
} or nil } or nil
} or {{ } or {{
protocol = "socks", protocol = "socks",
local_address = "0.0.0.0", local_address = "0.0.0.0",
local_port = tonumber(socks_port) local_port = tonumber(socks_port)
}}, }},
servers = { servers = {
{ {
server = "127.0.0.1", server = "127.0.0.1",
server_port = (tonumber(local_port) == 0 and tonumber(chain_local_port) or tonumber(local_port)), server_port = (tonumber(local_port) == 0 and tonumber(chain_local_port) or tonumber(local_port)),
method = server.sslocal_method, method = server.sslocal_method,
password = server.sslocal_password password = server.sslocal_password
}
} }
}
} }
local chain_vmess = { local chain_vmess = {
inbounds = (local_port ~= "0") and { inbounds = (local_port ~= "0") and {
{ {
port = (chain_local_port == "0" and tonumber(server.local_port) or tonumber(chain_local_port)), port = (chain_local_port == "0" and tonumber(server.local_port) or tonumber(chain_local_port)),
protocol = "dokodemo-door", protocol = "dokodemo-door",
settings = { settings = {
network = proto, network = proto,
followRedirect = true followRedirect = true
},
streamSettings = {
sockopt = {tproxy = "redirect"}
},
sniffing = {
enable = true,
destOverride = {"http","tls"}
}
}, },
streamSettings = {
sockopt = {tproxy = "redirect"}
},
sniffing = {
enable = true,
destOverride = {"http","tls"}
}
},
(proto:find("tcp") and socks_port ~= "0") and { (proto:find("tcp") and socks_port ~= "0") and {
protocol = "socks", protocol = "socks",
port = tonumber(socks_port) port = tonumber(socks_port)
} or nil } or nil
} or { protocol = "socks",port = tonumber(socks_port) }, } or { protocol = "socks", port = tonumber(socks_port) },
outbound = { outbound = {
protocol = "vmess", protocol = "vmess",
settings = { settings = {
vnext = {{ vnext = {{
address = "127.0.0.1", address = "127.0.0.1",
port = (tonumber(local_port) == 0 and tonumber(chain_local_port) or tonumber(local_port)), port = (tonumber(local_port) == 0 and tonumber(chain_local_port) or tonumber(local_port)),
users = {{ users = {{
id = (server.vmess_uuid), id = (server.vmess_uuid),
security = server.vmess_method, security = server.vmess_method,
level = 0 level = 0
}} }}
}} }}
} }
} }
} }
local tuic = { local tuic = {
relay = { relay = {
server = server.server_port and server.server .. ":" .. server.server_port, server = server.server_port and server.server .. ":" .. server.server_port,
ip = server.tuic_ip, ip = server.tuic_ip,
uuid = server.tuic_uuid, uuid = server.tuic_uuid,
password = server.tuic_passwd, password = server.tuic_passwd,
certificates = server.certificate and { server.certpath } or nil, certificates = server.certificate and { server.certpath } or nil,
udp_relay_mode = server.udp_relay_mode, udp_relay_mode = server.udp_relay_mode,
congestion_control = server.congestion_control, congestion_control = server.congestion_control,
heartbeat = server.heartbeat and tonumber(server.heartbeat) .. "s" or nil, heartbeat = server.heartbeat and tonumber(server.heartbeat) .. "s" or nil,
timeout = server.timeout and tonumber(server.timeout) .. "s" or nil, timeout = server.timeout and tonumber(server.timeout) .. "s" or nil,
gc_interval = server.gc_interval and tonumber(server.gc_interval) .. "s" or nil, gc_interval = server.gc_interval and tonumber(server.gc_interval) .. "s" or nil,
gc_lifetime = server.gc_lifetime and tonumber(server.gc_lifetime) .. "s" or nil, gc_lifetime = server.gc_lifetime and tonumber(server.gc_lifetime) .. "s" or nil,
alpn = (server.tuic_alpn and server.tuic_alpn ~= "") and (function() alpn = (server.tuic_alpn and server.tuic_alpn ~= "") and (function()
local alpn = {} local alpn = {}
string.gsub(server.tuic_alpn, '[^,]+', function(w) string.gsub(server.tuic_alpn, '[^,]+', function(w)
table.insert(alpn, w) table.insert(alpn, w)
end) end)
if #alpn > 0 then if #alpn > 0 then
return alpn return alpn
else else
return nil return nil
end end
end)() or nil, end)() or nil,
ipstack_prefer = (server.tuic_dual_stack == "1") and server.ipstack_prefer or nil, ipstack_prefer = (server.tuic_dual_stack == "1") and server.ipstack_prefer or nil,
skip_cert_verify = (server.insecure == "1" or server.insecure == true or server.insecure == "true"), skip_cert_verify = (server.insecure == "1" or server.insecure == true or server.insecure == "true"),
disable_sni = (server.disable_sni == "1") and true or false, disable_sni = (server.disable_sni == "1") and true or false,
zero_rtt_handshake = (server.zero_rtt_handshake == "1") and true or false, zero_rtt_handshake = (server.zero_rtt_handshake == "1") and true or false,
send_window = tonumber(server.send_window), send_window = tonumber(server.send_window),
receive_window = tonumber(server.receive_window) receive_window = tonumber(server.receive_window)
}, },
["local"] = { ["local"] = {
server = tonumber(socks_port) and "[::]:" .. (socks_port == "0" and local_port or tonumber(socks_port)), server = tonumber(socks_port) and "[::]:" .. (socks_port == "0" and local_port or tonumber(socks_port)),
dual_stack = (server.tuic_dual_stack == "1") and true or nil, dual_stack = (server.tuic_dual_stack == "1") and true or nil,
max_packet_size = tonumber(server.tuic_max_package_size) max_packet_size = tonumber(server.tuic_max_package_size)
} }
} }
local config = {} local config = {}
function config:new(o) function config:new(o)
o = o or {} o = o or {}
@@ -1013,10 +1181,10 @@ function config:handleIndex(index)
end end
} }
local ChainType = server.chain_type local ChainType = server.chain_type
if chain_switch[ChainType] then if chain_switch[ChainType] then
chain_switch[ChainType]() chain_switch[ChainType]()
end end
end, end,
tuic = function() tuic = function()
print(json.stringify(tuic, 1)) print(json.stringify(tuic, 1))
end end
@@ -23,20 +23,24 @@ local nodeResult = setmetatable({}, {__index = cache}) -- update result
local name = 'shadowsocksr' local name = 'shadowsocksr'
local uciType = 'servers' local uciType = 'servers'
local ucic = require "luci.model.uci".cursor() local ucic = require "luci.model.uci".cursor()
local proxy = ucic:get_first(name, 'server_subscribe', 'proxy', '0') local proxy = ucic:get_first(name, 'server_subscribe', 'proxy') or '0'
local switch = ucic:get_first(name, 'server_subscribe', 'switch', '1') local switch = ucic:get_first(name, 'server_subscribe', 'switch') or '1'
local allow_insecure = ucic:get_first(name, 'server_subscribe', 'allow_insecure', '0') local allow_insecure = ucic:get_first(name, 'server_subscribe', 'allow_insecure') or '0'
local subscribe_url = ucic:get_first(name, 'server_subscribe', 'subscribe_url', {}) local subscribe_url = ucic:get_first(name, 'server_subscribe', 'subscribe_url') or {}
local filter_words = ucic:get_first(name, 'server_subscribe', 'filter_words', '过期时间/剩余流量') local filter_words = ucic:get_first(name, 'server_subscribe', 'filter_words') or '过期时间/剩余流量'
local save_words = ucic:get_first(name, 'server_subscribe', 'save_words', '') local save_words = ucic:get_first(name, 'server_subscribe', 'save_words') or ''
local user_agent = ucic:get_first(name, 'server_subscribe', 'user_agent', 'v2rayN/9.99') local user_agent = ucic:get_first(name, 'server_subscribe', 'user_agent') or 'v2rayN/9.99'
local domain_resolver = ucic:get_first(name, 'server_subscribe', 'domain_resolver') or ''
local domain_resolver_dns = ucic:get_first(name, 'server_subscribe', 'domain_resolver_dns') or ''
local domain_resolver_dns_https = ucic:get_first(name, 'server_subscribe', 'domain_resolver_dns_https') or ''
local domain_strategy = ucic:get_first(name, 'server_subscribe', 'domain_strategy') or ''
-- 读取 ss_type 设置 -- 读取 ss_type 设置
local ss_type = ucic:get_first(name, 'server_subscribe', 'ss_type') local ss_type = ucic:get_first(name, 'server_subscribe', 'ss_type') or ''
-- 读取 xray_hy2_type 设置 -- 读取 xray_hy2_type 设置
local xray_hy2_type = ucic:get_first(name, 'server_subscribe', 'xray_hy2_type') local xray_hy2_type = ucic:get_first(name, 'server_subscribe', 'xray_hy2_type') or ''
-- 读取 xray_tj_type 设置 -- 读取 xray_tj_type 设置
local xray_tj_type = ucic:get_first(name, 'server_subscribe', 'xray_tj_type') local xray_tj_type = ucic:get_first(name, 'server_subscribe', 'xray_tj_type') or ''
local has_ss_rust = luci.sys.exec('type -t -p sslocal 2>/dev/null || type -t -p ssserver 2>/dev/null') ~= "" local has_ss_rust = luci.sys.exec('type -t -p sslocal 2>/dev/null || type -t -p ssserver 2>/dev/null') ~= ""
local has_ss_libev = luci.sys.exec('type -t -p ss-redir 2>/dev/null || type -t -p ss-local 2>/dev/null') ~= "" local has_ss_libev = luci.sys.exec('type -t -p ss-redir 2>/dev/null || type -t -p ss-local 2>/dev/null') ~= ""
@@ -1755,6 +1759,24 @@ local execute = function()
if section then if section then
ucic:tset(name, section, vv) ucic:tset(name, section, vv)
ucic:set(name, section, "switch_enable", switch) ucic:set(name, section, "switch_enable", switch)
-- 为 Xray 节点添加域名解析配置
if vv.type == "v2ray" then
if domain_resolver and domain_resolver ~= "" then
ucic:set(name, section, "domain_resolver", domain_resolver)
if domain_resolver == "https" then
if domain_resolver_dns_https and domain_resolver_dns_https ~= "" then
ucic:set(name, section, "domain_resolver_dns_https", domain_resolver_dns_https)
end
else
if domain_resolver_dns and domain_resolver_dns ~= "" then
ucic:set(name, section, "domain_resolver_dns", domain_resolver_dns)
end
end
end
if domain_strategy and domain_strategy ~= "" then
ucic:set(name, section, "domain_strategy", domain_strategy)
end
end
add = add + 1 add = add + 1
end end
end end
+1 -1
View File
@@ -9,7 +9,7 @@ LUCI_TITLE:=Design Theme
LUCI_DEPENDS:= LUCI_DEPENDS:=
PKG_LICENSE:=Apache-2.0 PKG_LICENSE:=Apache-2.0
PKG_VERSION:=7.1 PKG_VERSION:=7.1
PKG_RELEASE:=3 PKG_RELEASE:=4
LUCI_MINIFY_CSS:= LUCI_MINIFY_CSS:=
CONFIG_LUCI_CSSTIDY:= CONFIG_LUCI_CSSTIDY:=
@@ -65,6 +65,18 @@
}); });
} }
function getOverviewPortColumns(width, cardCount) {
if (width <= 480) {
return 1;
}
if (width <= 768) {
return Math.min(cardCount, 2);
}
return Math.min(cardCount, 8);
}
function syncOverviewPortStatus() { function syncOverviewPortStatus() {
var view = document.getElementById('view'); var view = document.getElementById('view');
var portGroups = new Map(); var portGroups = new Map();
@@ -186,7 +198,7 @@
portGroups.forEach(function (cards, parent) { portGroups.forEach(function (cards, parent) {
var width = window.innerWidth || document.documentElement.clientWidth || 1280; var width = window.innerWidth || document.documentElement.clientWidth || 1280;
var columns; var columns = getOverviewPortColumns(width, cards.length);
cards.forEach(function (card) { cards.forEach(function (card) {
var body = card.querySelector('.ifacebox-body'); var body = card.querySelector('.ifacebox-body');
@@ -220,18 +232,6 @@
} }
}); });
if (width <= 480) {
columns = 1;
} else if (width <= 768) {
columns = Math.min(cards.length, 2);
} else if (cards.length <= 4) {
columns = cards.length;
} else if (cards.length <= 6) {
columns = 3;
} else {
columns = 4;
}
parent.style.setProperty('display', 'grid', 'important'); parent.style.setProperty('display', 'grid', 'important');
parent.style.setProperty('grid-template-columns', 'repeat(' + columns + ', minmax(0, 1fr))', 'important'); parent.style.setProperty('grid-template-columns', 'repeat(' + columns + ', minmax(0, 1fr))', 'important');
parent.style.setProperty('align-items', 'stretch', 'important'); parent.style.setProperty('align-items', 'stretch', 'important');
@@ -258,6 +258,8 @@
childList: true, childList: true,
subtree: true subtree: true
}); });
window.addEventListener('resize', syncOverviewPortStatus);
} }
function syncNetworkInterfaceIcons() { function syncNetworkInterfaceIcons() {
@@ -1,5 +1,6 @@
'use strict'; 'use strict';
'require baseclass'; 'require baseclass';
'require fs';
'require request'; 'require request';
'require ui'; 'require ui';
@@ -15,15 +16,60 @@ return baseclass.extend({
window.location.hash); window.location.hash);
} }
this.dynamicMenuTargets = {};
this.syncConditionalMenuCache() this.syncConditionalMenuCache()
.then(L.bind(function(reloading) { .then(L.bind(function(reloading) {
if (reloading) if (reloading)
return; return;
return ui.menu.load().then(L.bind(this.render, this)); return this.resolveDynamicMenuTargets()
.then(L.bind(function() {
return ui.menu.load().then(L.bind(this.render, this));
}, this));
}, this)); }, this));
}, },
resolveDynamicMenuTargets: function() {
this.dynamicMenuTargets = {};
if (!document.body.classList.contains('logged-in'))
return Promise.resolve();
return this.resolveFirewallMenuTarget().then(L.bind(function(target) {
if (target)
this.dynamicMenuTargets['admin/status/nftables'] = target;
}, this));
},
resolveFirewallMenuTarget: function() {
return L.resolveDefault(fs.exec_direct('/usr/sbin/nft', [ '--terse', '--json', 'list', 'ruleset' ], 'json'), null).then(function(nft) {
var hasTables = false;
if (!Array.isArray(nft && nft.nftables))
return null;
for (var i = 0; i < nft.nftables.length; i++) {
if (nft.nftables[i] && nft.nftables[i].hasOwnProperty('table')) {
hasTables = true;
break;
}
}
return hasTables ? null : 'admin/status/nftables/iptables';
});
},
getMenuHref: function(url, child) {
var path = [ url, child.name ].filter(Boolean).join('/'),
target = this.dynamicMenuTargets[path];
if (target)
return L.url.apply(L, target.split('/'));
return L.url(url, child.name);
},
reloadPageWithMenuFlush: function() { reloadPageWithMenuFlush: function() {
var url = new URL(window.location.href); var url = new URL(window.location.href);
@@ -180,11 +226,11 @@ return baseclass.extend({
ul.classList.add('active'); ul.classList.add('active');
slideClass += " active"; slideClass += " active";
menuClass += " active"; menuClass += " active";
} }
ul.appendChild(E('li', { 'class': slideClass }, [ ul.appendChild(E('li', { 'class': slideClass }, [
E('a', { E('a', {
'href': L.url(url, children[i].name), 'href': this.getMenuHref(url, children[i]),
'click': (l == 1) ? ui.createHandlerFn(this, 'handleMenuExpand') : null, 'click': (l == 1) ? ui.createHandlerFn(this, 'handleMenuExpand') : null,
'class': menuClass, 'class': menuClass,
'data-title': hasChildren ? children[i].title.replace(" ", "_") : children[i].title.replace(" ", "_"), 'data-title': hasChildren ? children[i].title.replace(" ", "_") : children[i].title.replace(" ", "_"),
+3 -3
View File
@@ -2,13 +2,13 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=mihomo-alpha PKG_NAME:=mihomo-alpha
PKG_VERSION:=2026.04.20 PKG_VERSION:=2026.04.20
PKG_RELEASE:=4 PKG_RELEASE:=5
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE_PROTO:=git PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/MetaCubeX/mihomo.git PKG_SOURCE_URL:=https://github.com/MetaCubeX/mihomo.git
PKG_SOURCE_VERSION:=a84724665eb7f989809abe463c05f5723bd24975 PKG_SOURCE_VERSION:=c59c99a051c5c4fb3c2a7454d7c00fea9a8ee4bb
PKG_MIRROR_HASH:=skip PKG_MIRROR_HASH:=skip
PKG_LICENSE:=GPL3.0+ PKG_LICENSE:=GPL3.0+
@@ -18,7 +18,7 @@ PKG_BUILD_DEPENDS:=golang/host
PKG_BUILD_PARALLEL:=1 PKG_BUILD_PARALLEL:=1
PKG_BUILD_FLAGS:=no-mips16 PKG_BUILD_FLAGS:=no-mips16
PKG_BUILD_VERSION:=alpha-a8472466 PKG_BUILD_VERSION:=alpha-c59c99a0
PKG_BUILD_TIME:=$(shell date -u -Iseconds) PKG_BUILD_TIME:=$(shell date -u -Iseconds)
GO_PKG:=github.com/metacubex/mihomo GO_PKG:=github.com/metacubex/mihomo
+4 -4
View File
@@ -1,14 +1,14 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=mihomo-meta PKG_NAME:=mihomo-meta
PKG_VERSION:=1.19.23 PKG_VERSION:=1.19.24
PKG_RELEASE:=2 PKG_RELEASE:=3
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE_PROTO:=git PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/MetaCubeX/mihomo.git PKG_SOURCE_URL:=https://github.com/MetaCubeX/mihomo.git
PKG_SOURCE_VERSION:=v1.19.23 PKG_SOURCE_VERSION:=v1.19.24
PKG_MIRROR_HASH:=skip PKG_MIRROR_HASH:=skip
PKG_LICENSE:=GPL3.0+ PKG_LICENSE:=GPL3.0+
@@ -18,7 +18,7 @@ PKG_BUILD_DEPENDS:=golang/host
PKG_BUILD_PARALLEL:=1 PKG_BUILD_PARALLEL:=1
PKG_BUILD_FLAGS:=no-mips16 PKG_BUILD_FLAGS:=no-mips16
PKG_BUILD_VERSION:=v1.19.23 PKG_BUILD_VERSION:=v1.19.24
PKG_BUILD_TIME:=$(shell date -u -Iseconds) PKG_BUILD_TIME:=$(shell date -u -Iseconds)
GO_PKG:=github.com/metacubex/mihomo GO_PKG:=github.com/metacubex/mihomo
+2 -2
View File
@@ -10,8 +10,8 @@ include $(TOPDIR)/rules.mk
PKG_ARCH_quickstart:=$(ARCH) PKG_ARCH_quickstart:=$(ARCH)
PKG_NAME:=quickstart PKG_NAME:=quickstart
PKG_VERSION:=0.11.15 PKG_VERSION:=0.12.1
PKG_RELEASE:=2 PKG_RELEASE:=3
PKG_SOURCE:=$(PKG_NAME)-binary-$(PKG_VERSION).tar.gz PKG_SOURCE:=$(PKG_NAME)-binary-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/linkease/istore-packages/releases/download/prebuilt/ PKG_SOURCE_URL:=https://github.com/linkease/istore-packages/releases/download/prebuilt/
PKG_HASH:=skip PKG_HASH:=skip