luci-app-openclash: sync upstream

last commit: 39a3dbb789
This commit is contained in:
gitea-action 2025-02-15 10:30:29 +08:00
parent 897fe1da14
commit d83a3195d2
71 changed files with 12977 additions and 11824 deletions

View File

@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-openclash PKG_NAME:=luci-app-openclash
PKG_VERSION:=0.46.064 PKG_VERSION:=0.46.075
PKG_MAINTAINER:=vernesong <https://github.com/vernesong/OpenClash> PKG_MAINTAINER:=vernesong <https://github.com/vernesong/OpenClash>
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
@ -42,8 +42,8 @@ define Package/$(PKG_NAME)
SUBMENU:=3. Applications SUBMENU:=3. Applications
TITLE:=LuCI support for clash TITLE:=LuCI support for clash
PKGARCH:=all PKGARCH:=all
DEPENDS:=+dnsmasq-full +coreutils +coreutils-nohup +bash +curl +ca-certificates +ip-full \ DEPENDS:=+dnsmasq-full +bash +curl +ca-bundle +ip-full \
+libcap +libcap-bin +ruby +ruby-yaml +kmod-tun +unzip +ruby +ruby-yaml +kmod-tun +unzip
MAINTAINER:=vernesong MAINTAINER:=vernesong
endef endef
@ -122,9 +122,9 @@ endef
define Package/$(PKG_NAME)/postrm define Package/$(PKG_NAME)/postrm
#!/bin/sh #!/bin/sh
DEFAULT_DNSMASQ_CFGID="$$(uci -q show "dhcp.@dnsmasq[0]" | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}')" DEFAULT_DNSMASQ_CFGID="$$(uci -q show "dhcp.@dnsmasq[0]" | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}' 2>/dev/null)"
if [ -f "/tmp/etc/dnsmasq.conf.$DEFAULT_DNSMASQ_CFGID" ]; then if [ -f "/tmp/etc/dnsmasq.conf.$DEFAULT_DNSMASQ_CFGID" ]; then
DNSMASQ_CONF_DIR="$$(awk -F '=' '/^conf-dir=/ {print $2}' "/tmp/etc/dnsmasq.conf.$DEFAULT_DNSMASQ_CFGID")" DNSMASQ_CONF_DIR="$$(awk -F '=' '/^conf-dir=/ {print $2}' "/tmp/etc/dnsmasq.conf.$DEFAULT_DNSMASQ_CFGID" 2>/dev/null)"
else else
DNSMASQ_CONF_DIR="/tmp/dnsmasq.d" DNSMASQ_CONF_DIR="/tmp/dnsmasq.d"
fi fi

View File

@ -31,6 +31,7 @@ function index()
entry({"admin", "services", "openclash", "opupdate"},call("action_opupdate")) entry({"admin", "services", "openclash", "opupdate"},call("action_opupdate"))
entry({"admin", "services", "openclash", "coreupdate"},call("action_coreupdate")) entry({"admin", "services", "openclash", "coreupdate"},call("action_coreupdate"))
entry({"admin", "services", "openclash", "flush_fakeip_cache"}, call("action_flush_fakeip_cache")) entry({"admin", "services", "openclash", "flush_fakeip_cache"}, call("action_flush_fakeip_cache"))
entry({"admin", "services", "openclash", "update_config"}, call("action_update_config"))
entry({"admin", "services", "openclash", "download_rule"}, call("action_download_rule")) entry({"admin", "services", "openclash", "download_rule"}, call("action_download_rule"))
entry({"admin", "services", "openclash", "restore"}, call("action_restore_config")) entry({"admin", "services", "openclash", "restore"}, call("action_restore_config"))
entry({"admin", "services", "openclash", "backup"}, call("action_backup")) entry({"admin", "services", "openclash", "backup"}, call("action_backup"))
@ -252,7 +253,7 @@ local function opcv()
if fs.access("/bin/opkg") then if fs.access("/bin/opkg") then
return luci.sys.exec("rm -f /var/lock/opkg.lock && opkg status luci-app-openclash 2>/dev/null |grep 'Version' |awk -F 'Version: ' '{print \"v\"$2}'") return luci.sys.exec("rm -f /var/lock/opkg.lock && opkg status luci-app-openclash 2>/dev/null |grep 'Version' |awk -F 'Version: ' '{print \"v\"$2}'")
elseif fs.access("/usr/bin/apk") then elseif fs.access("/usr/bin/apk") then
return "v" .. luci.sys.exec("apk list luci-app-openclash 2>/dev/null |grep 'installed' | grep -oE '\\d+(\\.\\d+)*' | head -1") return "v" .. luci.sys.exec("apk list luci-app-openclash 2>/dev/null|grep 'installed' | grep -oE '[0-9]+(\\.[0-9]+)*' | head -1")
end end
end end
end end
@ -347,14 +348,19 @@ function action_flush_fakeip_cache()
local dase = dase() or "" local dase = dase() or ""
local cn_port = cn_port() local cn_port = cn_port()
if not daip or not cn_port then return end if not daip or not cn_port then return end
state = luci.sys.exec(string.format('curl -sL -m 3 -H "Content-Type: application/json" -H "Authorization: Bearer %s" -XPOST http://"%s":"%s"/cache/fakeip/flush', dase, daip, cn_port)) state = luci.sys.exec(string.format('curl -sL -m 3 -H "Content-Type: application/json" -H "Authorization: Bearer %s" -XPOST http://"%s":"%s"/cache/fakeip/flush', dase, daip, cn_port))
end end
luci.http.prepare_content("application/json") luci.http.prepare_content("application/json")
luci.http.write_json({ luci.http.write_json({
flush_status = state; flush_status = state;
}) })
end end
function action_update_config()
local filename = luci.http.formvalue("filename") or "config"
luci.sys.exec(string.format("/usr/share/openclash/openclash.sh '%s' >/dev/null 2>&1 &", filename))
end
function action_restore_config() function action_restore_config()
uci:set("openclash", "config", "enable", "0") uci:set("openclash", "config", "enable", "0")
uci:commit("openclash") uci:commit("openclash")
@ -364,6 +370,8 @@ function action_restore_config()
luci.sys.call("cp /usr/share/openclash/backup/openclash_force_sniffing* /etc/openclash/custom/ >/dev/null 2>&1 &") luci.sys.call("cp /usr/share/openclash/backup/openclash_force_sniffing* /etc/openclash/custom/ >/dev/null 2>&1 &")
luci.sys.call("cp /usr/share/openclash/backup/openclash_sniffing* /etc/openclash/custom/ >/dev/null 2>&1 &") luci.sys.call("cp /usr/share/openclash/backup/openclash_sniffing* /etc/openclash/custom/ >/dev/null 2>&1 &")
luci.sys.call("cp /usr/share/openclash/backup/yml_change.sh /usr/share/openclash/yml_change.sh >/dev/null 2>&1 &") luci.sys.call("cp /usr/share/openclash/backup/yml_change.sh /usr/share/openclash/yml_change.sh >/dev/null 2>&1 &")
luci.sys.call("cp /usr/share/openclash/backup/china_ip_route.ipset /etc/openclash/china_ip_route.ipset >/dev/null 2>&1 &")
luci.sys.call("cp /usr/share/openclash/backup/china_ip6_route.ipset /etc/openclash/china_ip6_route.ipset >/dev/null 2>&1 &")
luci.sys.call("rm -rf /etc/openclash/history/* >/dev/null 2>&1 &") luci.sys.call("rm -rf /etc/openclash/history/* >/dev/null 2>&1 &")
end end

View File

@ -79,11 +79,11 @@ if a then
btnis.template="openclash/other_button" btnis.template="openclash/other_button"
btnis.render=function(o,t,a) btnis.render=function(o,t,a)
if not e[t] then return false end if not e[t] then return false end
if IsYamlFile(e[t].name) or IsYmlFile(e[t].name) then if IsYamlFile(e[t].name) or IsYmlFile(e[t].name) then
a.display="" a.display=""
else else
a.display="none" a.display="none"
end end
o.inputstyle="apply" o.inputstyle="apply"
Button.render(o,t,a) Button.render(o,t,a)
end end
@ -95,6 +95,20 @@ if a then
SYS.call("/etc/init.d/openclash restart >/dev/null 2>&1 &") SYS.call("/etc/init.d/openclash restart >/dev/null 2>&1 &")
HTTP.redirect(luci.dispatcher.build_url("admin", "services", "openclash", "client")) HTTP.redirect(luci.dispatcher.build_url("admin", "services", "openclash", "client"))
end end
up=tb:option(DummyValue, "name", translate("Update"))
up.template = "openclash/update_config"
up.render = function(o,t,a)
local display = "none"
uci:foreach("openclash", "config_subscribe",
function(s)
if s.name == fs.filename(e[t].name) then
display = ""
end
end)
o.display = display
DummyValue.render(o,t,a)
end
end end
if not a then if not a then
@ -152,6 +166,7 @@ o.inputstyle = "reset"
o.write = function() o.write = function()
uci:set("openclash", "config", "enable", 0) uci:set("openclash", "config", "enable", 0)
uci:commit("openclash") uci:commit("openclash")
SYS.call("ps | grep openclash | grep -v grep | awk '{print $1}' | xargs -r kill -9 >/dev/null 2>&1")
SYS.call("/etc/init.d/openclash stop >/dev/null 2>&1 &") SYS.call("/etc/init.d/openclash stop >/dev/null 2>&1 &")
end end

View File

@ -280,7 +280,7 @@ o.description = font_red..bold_on..translate("Change The Delay Calculation Metho
o.default = "0" o.default = "0"
o = s:taboption("meta", ListValue, "find_process_mode", translate("Enable Process Rule")) o = s:taboption("meta", ListValue, "find_process_mode", translate("Enable Process Rule"))
o.description = translate("Whether to Enable Process Rules, If You Are Not Sure, Please Choose off Which Useful in Router Environment") o.description = translate("Whether to Enable Process Rules, Only Works on Routerself, If You Are Not Sure, Please Choose off Which Useful in Router Environment, Depend on kmod-inet-diag")
o:value("0", translate("Disable")) o:value("0", translate("Disable"))
o:value("off", translate("OFF ")) o:value("off", translate("OFF "))
o:value("always", translate("Always ")) o:value("always", translate("Always "))

View File

@ -180,7 +180,7 @@ o:depends("sub_convert", "1")
---- custom params ---- custom params
o = s:option(DynamicList, "custom_params", translate("Custom Params")) o = s:option(DynamicList, "custom_params", translate("Custom Params"))
o.description = font_red..bold_on..translate("eg: \"rename=\\s+([2-9])[xX]@ (HIGH:$1)\"")..bold_off..font_off o.description = font_red..bold_on..translate("eg: \"rename=match@replace\" , \"rename=\\s+([2-9])[xX]@ (HIGH:$1)\"")..bold_off..font_off
o.rmempty = false o.rmempty = false
o:depends("sub_convert", "1") o:depends("sub_convert", "1")

View File

@ -111,6 +111,10 @@ function o.cfgvalue(...)
end end
end end
---- update
o = s:option(DummyValue, "name", translate("Update"))
o.template = "openclash/update_config"
local t = { local t = {
{Commit, Apply} {Commit, Apply}
} }

View File

@ -259,7 +259,7 @@ btnrn.template="openclash/input_rename"
btnrn.rawhtml = true btnrn.rawhtml = true
btnrn.render=function(c,t,a) btnrn.render=function(c,t,a)
c.value = e[t].name c.value = e[t].name
Button.render(c,t,a) DummyValue.render(c,t,a)
end end
btndl = tb:option(Button,"download",translate("Download Config")) btndl = tb:option(Button,"download",translate("Download Config"))

View File

@ -100,16 +100,6 @@ o = s:option(Value, "policy_filter", translate("Provider Filter"))
o.rmempty = true o.rmempty = true
o.placeholder = "bgp|sg" o.placeholder = "bgp|sg"
-- [[ interface-name ]]--
o = s:option(Value, "interface_name", translate("interface-name"))
o.rmempty = true
o.placeholder = translate("eth0")
-- [[ routing-mark ]]--
o = s:option(Value, "routing_mark", translate("routing-mark"))
o.rmempty = true
o.placeholder = translate("2333")
o = s:option(DynamicList, "other_group", translate("Other Group (Support Regex)")) o = s:option(DynamicList, "other_group", translate("Other Group (Support Regex)"))
o.description = font_red..bold_on..translate("The Added Proxy Groups Must Exist Except 'DIRECT' & 'REJECT'")..bold_off..font_off o.description = font_red..bold_on..translate("The Added Proxy Groups Must Exist Except 'DIRECT' & 'REJECT'")..bold_off..font_off
o:value("all", translate("All Groups")) o:value("all", translate("All Groups"))

View File

@ -59,6 +59,7 @@ o.rmempty = true
o.description = translate("Choose The Provider Type") o.description = translate("Choose The Provider Type")
o:value("http") o:value("http")
o:value("file") o:value("file")
o:value("inline")
o = s:option(Value, "name", translate("Provider Name")) o = s:option(Value, "name", translate("Provider Name"))
o.rmempty = false o.rmempty = false
@ -134,7 +135,16 @@ function o.cfgvalue(self, section)
"# proxy-name:\n".. "# proxy-name:\n"..
"# - pattern: \"IPLC-(.*?)倍\"\n".. "# - pattern: \"IPLC-(.*?)倍\"\n"..
"# target: \"iplc x $1\"\n".. "# target: \"iplc x $1\"\n"..
"# exclude-type: \"ss|http\"" "# exclude-type: \"ss|http\"\n"..
"\n"..
"# inline Example:\n"..
"# payload:\n"..
"# - name: \"ss1\"\n"..
"# type: ss\n"..
"# server: server\n"..
"# port: 443\n"..
"# cipher: chacha20-ietf-poly1305\n"..
"# password: \"password\""
else else
return Value.cfgvalue(self, section) return Value.cfgvalue(self, section)
end end

View File

@ -57,22 +57,25 @@ o.default = "Rule-provider - "..sid
o = s:option(ListValue, "type", translate("Rule Providers Type")) o = s:option(ListValue, "type", translate("Rule Providers Type"))
o.rmempty = true o.rmempty = true
o.description = translate("Choose The Rule Providers Type") o.description = translate("Choose The Rule Providers Type")
o:value("http", translate("http")) o:value("http")
o:value("file", translate("file")) o:value("file")
o:value("inline")
o = s:option(ListValue, "format", translate("Rule Format"))
o.rmempty = true
o.description = translate("Choose The Rule File Format, For More Info:").." ".."<a href='javascript:void(0)' onclick='javascript:return winOpen(\"https://wiki.metacubex.one/config/rule-providers/content/\")'>https://wiki.metacubex.one/config/rule-providers/content/</a>"
o:value("yaml")
o:value("text")
o:value("mrs")
o:depends("type", "file")
o:depends("type", "http")
o = s:option(ListValue, "behavior", translate("Rule Behavior")) o = s:option(ListValue, "behavior", translate("Rule Behavior"))
o.rmempty = true o.rmempty = true
o.description = translate("Choose The Rule Behavior") o.description = translate("Choose The Rule Behavior")
o:value("domain") o:value("domain")
o:value("ipcidr") o:value("ipcidr")
o:value("classical") o:value("classical", translate("classical").." "..translate("(Not Support mrs Format)"))
o = s:option(ListValue, "format", translate("Rule Format")..translate("(TUN&Meta Core)"))
o.rmempty = true
o.description = translate("Choose The Rule File Format, For More Info:").." ".."<a href='javascript:void(0)' onclick='javascript:return winOpen(\"https://wiki.metacubex.one/config/rule-providers/content/\")'>https://wiki.metacubex.one/config/rule-providers/content/</a>"
o:value("yaml")
o:value("text")
o:value("mrs")
o = s:option(ListValue, "path", translate("Rule Providers Path")) o = s:option(ListValue, "path", translate("Rule Providers Path"))
o.description = translate("Update Your Rule Providers File From Config Luci Page") o.description = translate("Update Your Rule Providers File From Config Luci Page")
@ -136,6 +139,36 @@ m.uci:foreach("openclash", "groups",
o:value("DIRECT") o:value("DIRECT")
o:value("REJECT") o:value("REJECT")
-- [[ other-setting ]]--
o = s:option(Value, "other_parameters", translate("Other Parameters"))
o.template = "cbi/tvalue"
o.rows = 20
o.wrap = "off"
o.description = font_red..bold_on..translate("Edit Your Other Parameters Here")..bold_off..font_off
o.rmempty = true
function o.cfgvalue(self, section)
if self.map:get(section, "other_parameters") == nil then
return "# Example:\n"..
"# Only support YAML, four spaces need to be reserved at the beginning of each line to maintain formatting alignment\n"..
"# 示例:\n"..
"# 仅支持 YAML, 每行行首需要多保留四个空格以使脚本处理后能够与上方配置保持格式对齐\n"..
"# inline Example:\n"..
"# payload:\n"..
"# - '.blogger.com'\n"..
"# - '*.*.microsoft.com'\n"..
"# - 'books.itunes.apple.com'\n"
else
return Value.cfgvalue(self, section)
end
end
function o.validate(self, value)
if value then
value = value:gsub("\r\n?", "\n")
value = value:gsub("%c*$", "")
end
return value
end
local t = { local t = {
{Commit, Back} {Commit, Back}
} }
@ -159,4 +192,5 @@ o.write = function()
end end
m:append(Template("openclash/toolbar_show")) m:append(Template("openclash/toolbar_show"))
m:append(Template("openclash/config_editor"))
return m return m

View File

@ -143,6 +143,7 @@ o:value("hysteria2", translate("Hysteria2 ")..translate("(Only Meta Core)"))
o:value("wireguard", translate("WireGuard")..translate("(Only Meta Core)")) o:value("wireguard", translate("WireGuard")..translate("(Only Meta Core)"))
o:value("tuic", translate("Tuic")..translate("(Only Meta Core)")) o:value("tuic", translate("Tuic")..translate("(Only Meta Core)"))
o:value("snell", translate("Snell")) o:value("snell", translate("Snell"))
o:value("mieru", translate("Mieru"))
o:value("socks5", translate("Socks5")) o:value("socks5", translate("Socks5"))
o:value("http", translate("HTTP(S)")) o:value("http", translate("HTTP(S)"))
@ -182,6 +183,35 @@ o:depends("type", "ss")
o:depends("type", "ssr") o:depends("type", "ssr")
o:depends("type", "trojan") o:depends("type", "trojan")
o:depends("type", "hysteria2") o:depends("type", "hysteria2")
o:depends("type", "mieru")
-- [[ Mieru ]]--
o = s:option(Value, "port_range", translate("Port Range"))
o.datatype = "portrange"
o.rmempty = true
o.default = "20000-40000"
o.placeholder = translate("20000-40000")
o:depends("type", "mieru")
o = s:option(Value, "username", translate("Username"))
o.rmempty = false
o.placeholder = "user"
o:depends("type", "mieru")
o = s:option(ListValue, "transport", translate("Transport"))
o.rmempty = false
o.default = "TCP"
o:value("TCP")
o:depends("type", "mieru")
o = s:option(ListValue, "multiplexing", translate("Multiplexing"))
o.rmempty = false
o.default = "MULTIPLEXING_LOW"
o:value("MULTIPLEXING_OFF")
o:value("MULTIPLEXING_LOW")
o:value("MULTIPLEXING_MIDDLE")
o:value("MULTIPLEXING_HIGH")
o:depends("type", "mieru")
-- [[ Tuic ]]-- -- [[ Tuic ]]--
o = s:option(Value, "tc_ip", translate("Server IP")) o = s:option(Value, "tc_ip", translate("Server IP"))
@ -706,6 +736,7 @@ o:depends("type", "hysteria2")
-- [[ recv_window_conn ]]-- -- [[ recv_window_conn ]]--
o = s:option(Flag, "flag_quicparam", translate("Hysterir QUIC parameters")) o = s:option(Flag, "flag_quicparam", translate("Hysterir QUIC parameters"))
o:depends("type", "hysteria") o:depends("type", "hysteria")
o:depends("type", "hysteria2")
o.rmempty = true o.rmempty = true
o.default = "0" o.default = "0"
@ -722,6 +753,34 @@ o.placeholder = translate("QUIC connection receive window")
o.datatype = "uinteger" o.datatype = "uinteger"
o:depends({type = "hysteria", flag_quicparam = true}) o:depends({type = "hysteria", flag_quicparam = true})
-- [[ initial_stream_receive_window ]]--
o = s:option(Value, "initial_stream_receive_window", translate("initial_stream_receive_window"))
o.rmempty = true
o.placeholder = translate("QUIC init stream receive window")
o.datatype = "uinteger"
o:depends({type = "hysteria2", flag_quicparam = true})
-- [[ max_stream_receive_window ]]--
o = s:option(Value, "max_stream_receive_window", translate("max_stream_receive_window"))
o.rmempty = true
o.placeholder = translate("QUIC max stream receive window")
o.datatype = "uinteger"
o:depends({type = "hysteria2", flag_quicparam = true})
-- [[ initial_connection_receive_window ]]--
o = s:option(Value, "initial_connection_receive_window", translate("initial_connection_receive_window"))
o.rmempty = true
o.placeholder = translate("QUIC init connection receive window")
o.datatype = "uinteger"
o:depends({type = "hysteria2", flag_quicparam = true})
-- [[ max_connection_receive_window ]]--
o = s:option(Value, "max_connection_receive_window", translate("max_connection_receive_window"))
o.rmempty = true
o.placeholder = translate("QUIC max connection receive window")
o.datatype = "uinteger"
o:depends({type = "hysteria2", flag_quicparam = true})
-- [[ hop_interval ]]-- -- [[ hop_interval ]]--
o = s:option(Value, "hop_interval", translate("Hop Interval (Unit:second)")) o = s:option(Value, "hop_interval", translate("Hop Interval (Unit:second)"))
o.rmempty = true o.rmempty = true
@ -806,6 +865,7 @@ o:depends({type = "vmess", obfs_vmess = "grpc"})
o = s:option(ListValue, "client_fingerprint", translate("Client Fingerprint")..translate("(Only Meta Core)")) o = s:option(ListValue, "client_fingerprint", translate("Client Fingerprint")..translate("(Only Meta Core)"))
o.rmempty = true o.rmempty = true
o:value("none") o:value("none")
o:value("random")
o:value("chrome") o:value("chrome")
o:value("firefox") o:value("firefox")
o:value("safari") o:value("safari")
@ -836,6 +896,7 @@ o.rmempty = false
o:value("true") o:value("true")
o:value("false") o:value("false")
o.default = "false" o.default = "false"
o:depends({type = "ss", obfs = "none"})
o = s:option(ListValue, "multiplex_protocol", translate("Protocol")) o = s:option(ListValue, "multiplex_protocol", translate("Protocol"))
o.rmempty = true o.rmempty = true

View File

@ -14,7 +14,7 @@ font_off = [[</b>]]
bold_on = [[<strong>]] bold_on = [[<strong>]]
bold_off = [[</strong>]] bold_off = [[</strong>]]
local op_mode = string.sub(luci.sys.exec('uci get openclash.config.operation_mode 2>/dev/null'),0,-2) local op_mode = uci:get("openclash", "config", "operation_mode")
if not op_mode then op_mode = "redir-host" end if not op_mode then op_mode = "redir-host" end
local lan_ip = fs.lanip() local lan_ip = fs.lanip()
m = Map("openclash", translate("Plugin Settings")) m = Map("openclash", translate("Plugin Settings"))
@ -99,6 +99,10 @@ o = s:taboption("op_mode", Flag, "bypass_gateway_compatible", translate("Bypass
o.description = translate("If The Network Cannot be Connected in Bypass Gateway Mode, Please Try to Enable.")..font_red..bold_on..translate("Suggestion: If The Device Does Not Have WLAN, Please Disable The Lan Interface's Bridge Option")..bold_off..font_off o.description = translate("If The Network Cannot be Connected in Bypass Gateway Mode, Please Try to Enable.")..font_red..bold_on..translate("Suggestion: If The Device Does Not Have WLAN, Please Disable The Lan Interface's Bridge Option")..bold_off..font_off
o.default = 0 o.default = 0
o = s:taboption("op_mode", Flag, "disable_quic_go_gso", translate("Disable quic-go GSO Support"))
o.description = font_red..bold_on..translate("Suggestion: If Encountering Issues With QUIC UDP on The Linux Kernel Version Above 6.6, Please Try to Enable.")..bold_off..font_off
o.default = 0
o = s:taboption("op_mode", Flag, "small_flash_memory", translate("Small Flash Memory")) o = s:taboption("op_mode", Flag, "small_flash_memory", translate("Small Flash Memory"))
o.description = translate("Move Core And GEOIP Data File To /tmp/etc/openclash For Small Flash Memory Device") o.description = translate("Move Core And GEOIP Data File To /tmp/etc/openclash For Small Flash Memory Device")
o.default = 0 o.default = 0
@ -120,12 +124,6 @@ o = s:taboption("dns", DummyValue, "flush_fakeip_cache", translate("Flush Fake-I
o.template = "openclash/flush_fakeip_cache" o.template = "openclash/flush_fakeip_cache"
end end
o = s:taboption("dns", Flag, "disable_masq_cache", translate("Disable Dnsmasq's DNS Cache"))
o.description = translate("Recommended Enabled For Avoiding Some Connection Errors")..font_red..bold_on..translate("(Maybe Incompatible For Your Firmware)")..bold_off..font_off
o.default = 0
o:depends("enable_redirect_dns", "1")
o:depends("enable_redirect_dns", "0")
o = s:taboption("dns", Flag, "enable_custom_domain_dns_server", translate("Enable Specify DNS Server")) o = s:taboption("dns", Flag, "enable_custom_domain_dns_server", translate("Enable Specify DNS Server"))
o.default = 0 o.default = 0
o:depends("enable_redirect_dns", "1") o:depends("enable_redirect_dns", "1")
@ -216,9 +214,10 @@ o.cfgvalue = function(...)
end end
ip_ac = s2:option(Value, "src_ip", translate("Internal addresses")) ip_ac = s2:option(Value, "src_ip", translate("Internal addresses"))
ip_ac.datatype = "ipmask" ip_ac.datatype = "or(ipmask, string)"
ip_ac.placeholder = "0.0.0.0/0" ip_ac.placeholder = "0.0.0.0/0"
ip_ac.rmempty = false ip_ac.rmempty = true
ip_ac:value("localnetwork", translate("Local Network"))
o = s2:option(Value, "src_port", translate("Internal ports")) o = s2:option(Value, "src_port", translate("Internal ports"))
o.datatype = "or(port, portrange)" o.datatype = "or(port, portrange)"
@ -240,8 +239,9 @@ o.default = "tcp"
o.rmempty = false o.rmempty = false
o = s2:option(ListValue, "target", translate("Target")) o = s2:option(ListValue, "target", translate("Target"))
o:value("return", translate("Return")) o:value("return", translate("RETURN"))
o:value("accept", translate("Accept")) o:value("accept", translate("ACCEPT"))
o:value("drop", translate("DROP"))
o.rmempty = false o.rmempty = false
luci.ip.neighbors({ family = 4 }, function(n) luci.ip.neighbors({ family = 4 }, function(n)
@ -375,6 +375,7 @@ o = s:taboption("stream_enhance", Value, "stream_auto_select_interval", translat
o.default = "30" o.default = "30"
o.datatype = "uinteger" o.datatype = "uinteger"
o:depends("stream_auto_select", "1") o:depends("stream_auto_select", "1")
o.rmempty = true
o = s:taboption("stream_enhance", ListValue, "stream_auto_select_logic", font_red..bold_on..translate("Auto Select Logic")..bold_off..font_off) o = s:taboption("stream_enhance", ListValue, "stream_auto_select_logic", font_red..bold_on..translate("Auto Select Logic")..bold_off..font_off)
o.default = "urltest" o.default = "urltest"
@ -398,27 +399,21 @@ o.default = 0
o:depends("stream_auto_select", "1") o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_netflix", translate("Group Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_netflix", translate("Group Filter"))
o.default = "Netflix|奈飞"
o.placeholder = "Netflix|奈飞" o.placeholder = "Netflix|奈飞"
o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails") o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
o:depends("stream_auto_select_netflix", "1") o:depends("stream_auto_select_netflix", "1")
o.rmempty = true
o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_netflix", translate("Unlock Region Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_netflix", translate("Unlock Region Filter"))
o.default = ""
o.placeholder = "HK|SG|TW" o.placeholder = "HK|SG|TW"
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex") o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_netflix", "1") o:depends("stream_auto_select_netflix", "1")
function o.validate(self, value) o.rmempty = true
if value ~= m.uci:get("openclash", "config", "stream_auto_select_region_key_netflix") then
fs.unlink("/tmp/openclash_Netflix_region")
end
return value
end
o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_netflix", translate("Unlock Nodes Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_netflix", translate("Unlock Nodes Filter"))
o.default = ""
o.description = translate("It Will Be Selected Nodes According To The Regex") o.description = translate("It Will Be Selected Nodes According To The Regex")
o:depends("stream_auto_select_netflix", "1") o:depends("stream_auto_select_netflix", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "Netflix", translate("Manual Test")) o = s:taboption("stream_enhance", DummyValue, "Netflix", translate("Manual Test"))
o.rawhtml = true o.rawhtml = true
@ -432,27 +427,21 @@ o.default = 0
o:depends("stream_auto_select", "1") o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_disney", translate("Group Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_disney", translate("Group Filter"))
o.default = "Disney|迪士尼"
o.placeholder = "Disney|迪士尼" o.placeholder = "Disney|迪士尼"
o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails") o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
o:depends("stream_auto_select_disney", "1") o:depends("stream_auto_select_disney", "1")
o.rmempty = true
o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_disney", translate("Unlock Region Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_disney", translate("Unlock Region Filter"))
o.default = ""
o.placeholder = "HK|SG|TW" o.placeholder = "HK|SG|TW"
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex") o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_disney", "1") o:depends("stream_auto_select_disney", "1")
function o.validate(self, value) o.rmempty = true
if value ~= m.uci:get("openclash", "config", "stream_auto_select_region_key_disney") then
fs.unlink("/tmp/openclash_Disney Plus_region")
end
return value
end
o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_disney", translate("Unlock Nodes Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_disney", translate("Unlock Nodes Filter"))
o.default = ""
o.description = translate("It Will Be Selected Nodes According To The Regex") o.description = translate("It Will Be Selected Nodes According To The Regex")
o:depends("stream_auto_select_disney", "1") o:depends("stream_auto_select_disney", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "Disney Plus", translate("Manual Test")) o = s:taboption("stream_enhance", DummyValue, "Disney Plus", translate("Manual Test"))
o.rawhtml = true o.rawhtml = true
@ -466,27 +455,21 @@ o.default = 0
o:depends("stream_auto_select", "1") o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_ytb", translate("Group Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_ytb", translate("Group Filter"))
o.default = "YouTube|油管"
o.placeholder = "YouTube|油管" o.placeholder = "YouTube|油管"
o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails") o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
o:depends("stream_auto_select_ytb", "1") o:depends("stream_auto_select_ytb", "1")
o.rmempty = true
o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_ytb", translate("Unlock Region Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_ytb", translate("Unlock Region Filter"))
o.default = ""
o.placeholder = "HK|US" o.placeholder = "HK|US"
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex") o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_ytb", "1") o:depends("stream_auto_select_ytb", "1")
function o.validate(self, value) o.rmempty = true
if value ~= m.uci:get("openclash", "config", "stream_auto_select_region_key_ytb") then
fs.unlink("/tmp/openclash_YouTube Premium_region")
end
return value
end
o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_ytb", translate("Unlock Nodes Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_ytb", translate("Unlock Nodes Filter"))
o.default = ""
o.description = translate("It Will Be Selected Nodes According To The Regex") o.description = translate("It Will Be Selected Nodes According To The Regex")
o:depends("stream_auto_select_ytb", "1") o:depends("stream_auto_select_ytb", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "YouTube Premium", translate("Manual Test")) o = s:taboption("stream_enhance", DummyValue, "YouTube Premium", translate("Manual Test"))
o.rawhtml = true o.rawhtml = true
@ -500,27 +483,21 @@ o.default = 0
o:depends("stream_auto_select", "1") o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_prime_video", translate("Group Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_prime_video", translate("Group Filter"))
o.default = "Amazon|Prime Video"
o.placeholder = "Amazon|Prime Video" o.placeholder = "Amazon|Prime Video"
o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails") o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
o:depends("stream_auto_select_prime_video", "1") o:depends("stream_auto_select_prime_video", "1")
o.rmempty = true
o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_prime_video", translate("Unlock Region Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_prime_video", translate("Unlock Region Filter"))
o.default = ""
o.placeholder = "HK|US|SG" o.placeholder = "HK|US|SG"
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex") o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_prime_video", "1") o:depends("stream_auto_select_prime_video", "1")
function o.validate(self, value) o.rmempty = true
if value ~= m.uci:get("openclash", "config", "stream_auto_select_region_key_prime_video") then
fs.unlink("/tmp/openclash_Amazon Prime Video_region")
end
return value
end
o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_prime_video", translate("Unlock Nodes Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_prime_video", translate("Unlock Nodes Filter"))
o.default = ""
o.description = translate("It Will Be Selected Nodes According To The Regex") o.description = translate("It Will Be Selected Nodes According To The Regex")
o:depends("stream_auto_select_prime_video", "1") o:depends("stream_auto_select_prime_video", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "Amazon Prime Video", translate("Manual Test")) o = s:taboption("stream_enhance", DummyValue, "Amazon Prime Video", translate("Manual Test"))
o.rawhtml = true o.rawhtml = true
@ -534,27 +511,21 @@ o.default = 0
o:depends("stream_auto_select", "1") o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_hbo_max", translate("Group Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_hbo_max", translate("Group Filter"))
o.default = "HBO|HBOMax|HBO Max"
o.placeholder = "HBO|HBOMax|HBO Max" o.placeholder = "HBO|HBOMax|HBO Max"
o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails") o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
o:depends("stream_auto_select_hbo_max", "1") o:depends("stream_auto_select_hbo_max", "1")
o.rmempty = true
o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_hbo_max", translate("Unlock Region Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_hbo_max", translate("Unlock Region Filter"))
o.default = ""
o.placeholder = "US" o.placeholder = "US"
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex") o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_hbo_max", "1") o:depends("stream_auto_select_hbo_max", "1")
function o.validate(self, value) o.rmempty = true
if value ~= m.uci:get("openclash", "config", "stream_auto_select_region_key_hbo_max") then
fs.unlink("/tmp/openclash_HBO Max_region")
end
return value
end
o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_hbo_max", translate("Unlock Nodes Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_hbo_max", translate("Unlock Nodes Filter"))
o.default = ""
o.description = translate("It Will Be Selected Nodes According To The Regex") o.description = translate("It Will Be Selected Nodes According To The Regex")
o:depends("stream_auto_select_hbo_max", "1") o:depends("stream_auto_select_hbo_max", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "HBO Max", translate("Manual Test")) o = s:taboption("stream_enhance", DummyValue, "HBO Max", translate("Manual Test"))
o.rawhtml = true o.rawhtml = true
@ -568,27 +539,21 @@ o.default = 0
o:depends("stream_auto_select", "1") o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_tvb_anywhere", translate("Group Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_tvb_anywhere", translate("Group Filter"))
o.default = "TVB"
o.placeholder = "TVB" o.placeholder = "TVB"
o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails") o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
o:depends("stream_auto_select_tvb_anywhere", "1") o:depends("stream_auto_select_tvb_anywhere", "1")
o.rmempty = true
o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_tvb_anywhere", translate("Unlock Region Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_tvb_anywhere", translate("Unlock Region Filter"))
o.default = ""
o.placeholder = "HK|SG|TW" o.placeholder = "HK|SG|TW"
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex") o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_tvb_anywhere", "1") o:depends("stream_auto_select_tvb_anywhere", "1")
function o.validate(self, value) o.rmempty = true
if value ~= m.uci:get("openclash", "config", "stream_auto_select_region_key_tvb_anywhere") then
fs.unlink("/tmp/openclash_TVB Anywhere+_region")
end
return value
end
o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_tvb_anywhere", translate("Unlock Nodes Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_tvb_anywhere", translate("Unlock Nodes Filter"))
o.default = ""
o.description = translate("It Will Be Selected Nodes According To The Regex") o.description = translate("It Will Be Selected Nodes According To The Regex")
o:depends("stream_auto_select_tvb_anywhere", "1") o:depends("stream_auto_select_tvb_anywhere", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "TVB Anywhere+", translate("Manual Test")) o = s:taboption("stream_enhance", DummyValue, "TVB Anywhere+", translate("Manual Test"))
o.rawhtml = true o.rawhtml = true
@ -602,27 +567,21 @@ o.default = 0
o:depends("stream_auto_select", "1") o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_dazn", translate("Group Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_dazn", translate("Group Filter"))
o.default = "DAZN"
o.placeholder = "DAZN" o.placeholder = "DAZN"
o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails") o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
o:depends("stream_auto_select_dazn", "1") o:depends("stream_auto_select_dazn", "1")
o.rmempty = true
o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_dazn", translate("Unlock Region Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_dazn", translate("Unlock Region Filter"))
o.default = ""
o.placeholder = "DE" o.placeholder = "DE"
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex") o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_dazn", "1") o:depends("stream_auto_select_dazn", "1")
function o.validate(self, value) o.rmempty = true
if value ~= m.uci:get("openclash", "config", "stream_auto_select_region_key_dazn") then
fs.unlink("/tmp/openclash_DAZN_region")
end
return value
end
o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_dazn", translate("Unlock Nodes Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_dazn", translate("Unlock Nodes Filter"))
o.default = ""
o.description = translate("It Will Be Selected Nodes According To The Regex") o.description = translate("It Will Be Selected Nodes According To The Regex")
o:depends("stream_auto_select_dazn", "1") o:depends("stream_auto_select_dazn", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "DAZN", translate("Manual Test")) o = s:taboption("stream_enhance", DummyValue, "DAZN", translate("Manual Test"))
o.rawhtml = true o.rawhtml = true
@ -636,27 +595,21 @@ o.default = 0
o:depends("stream_auto_select", "1") o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_paramount_plus", translate("Group Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_paramount_plus", translate("Group Filter"))
o.default = "Paramount"
o.placeholder = "Paramount" o.placeholder = "Paramount"
o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails") o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
o:depends("stream_auto_select_paramount_plus", "1") o:depends("stream_auto_select_paramount_plus", "1")
o.rmempty = true
o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_paramount_plus", translate("Unlock Region Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_paramount_plus", translate("Unlock Region Filter"))
o.default = ""
o.placeholder = "US" o.placeholder = "US"
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex") o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_paramount_plus", "1") o:depends("stream_auto_select_paramount_plus", "1")
function o.validate(self, value) o.rmempty = true
if value ~= m.uci:get("openclash", "config", "stream_auto_select_region_key_paramount_plus") then
fs.unlink("/tmp/openclash_Paramount Plus_region")
end
return value
end
o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_paramount_plus", translate("Unlock Nodes Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_paramount_plus", translate("Unlock Nodes Filter"))
o.default = ""
o.description = translate("It Will Be Selected Nodes According To The Regex") o.description = translate("It Will Be Selected Nodes According To The Regex")
o:depends("stream_auto_select_paramount_plus", "1") o:depends("stream_auto_select_paramount_plus", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "Paramount Plus", translate("Manual Test")) o = s:taboption("stream_enhance", DummyValue, "Paramount Plus", translate("Manual Test"))
o.rawhtml = true o.rawhtml = true
@ -670,27 +623,21 @@ o.default = 0
o:depends("stream_auto_select", "1") o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_discovery_plus", translate("Group Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_discovery_plus", translate("Group Filter"))
o.default = "Discovery"
o.placeholder = "Discovery" o.placeholder = "Discovery"
o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails") o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
o:depends("stream_auto_select_discovery_plus", "1") o:depends("stream_auto_select_discovery_plus", "1")
o.rmempty = true
o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_discovery_plus", translate("Unlock Region Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_discovery_plus", translate("Unlock Region Filter"))
o.default = ""
o.placeholder = "US" o.placeholder = "US"
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex") o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_discovery_plus", "1") o:depends("stream_auto_select_discovery_plus", "1")
function o.validate(self, value) o.rmempty = true
if value ~= m.uci:get("openclash", "config", "stream_auto_select_region_key_discovery_plus") then
fs.unlink("/tmp/openclash_Discovery Plus_region")
end
return value
end
o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_discovery_plus", translate("Unlock Nodes Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_discovery_plus", translate("Unlock Nodes Filter"))
o.default = ""
o.description = translate("It Will Be Selected Nodes According To The Regex") o.description = translate("It Will Be Selected Nodes According To The Regex")
o:depends("stream_auto_select_discovery_plus", "1") o:depends("stream_auto_select_discovery_plus", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "Discovery Plus", translate("Manual Test")) o = s:taboption("stream_enhance", DummyValue, "Discovery Plus", translate("Manual Test"))
o.rawhtml = true o.rawhtml = true
@ -704,10 +651,10 @@ o.default = 0
o:depends("stream_auto_select", "1") o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_bilibili", translate("Group Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_bilibili", translate("Group Filter"))
o.default = "Bilibili"
o.placeholder = "Bilibili" o.placeholder = "Bilibili"
o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails") o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
o:depends("stream_auto_select_bilibili", "1") o:depends("stream_auto_select_bilibili", "1")
o.rmempty = true
o = s:taboption("stream_enhance", ListValue, "stream_auto_select_region_key_bilibili", translate("Unlock Region Filter")) o = s:taboption("stream_enhance", ListValue, "stream_auto_select_region_key_bilibili", translate("Unlock Region Filter"))
o.default = "CN" o.default = "CN"
@ -716,17 +663,12 @@ o:value("HK/MO/TW", translate("Hongkong/Macau/Taiwan"))
o:value("TW", translate("Taiwan Only")) o:value("TW", translate("Taiwan Only"))
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex") o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_bilibili", "1") o:depends("stream_auto_select_bilibili", "1")
function o.validate(self, value) o.rmempty = false
if value ~= m.uci:get("openclash", "config", "stream_auto_select_region_key_bilibili") then
fs.unlink("/tmp/openclash_Bilibili_region")
end
return value
end
o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_bilibili", translate("Unlock Nodes Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_bilibili", translate("Unlock Nodes Filter"))
o.default = ""
o.description = translate("It Will Be Selected Nodes According To The Regex") o.description = translate("It Will Be Selected Nodes According To The Regex")
o:depends("stream_auto_select_bilibili", "1") o:depends("stream_auto_select_bilibili", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "Bilibili", translate("Manual Test")) o = s:taboption("stream_enhance", DummyValue, "Bilibili", translate("Manual Test"))
o.rawhtml = true o.rawhtml = true
@ -740,15 +682,15 @@ o.default = 0
o:depends("stream_auto_select", "1") o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_google_not_cn", translate("Group Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_google_not_cn", translate("Group Filter"))
o.default = "Google"
o.placeholder = "Google" o.placeholder = "Google"
o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails") o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
o:depends("stream_auto_select_google_not_cn", "1") o:depends("stream_auto_select_google_not_cn", "1")
o.rmempty = true
o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_google_not_cn", translate("Unlock Nodes Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_google_not_cn", translate("Unlock Nodes Filter"))
o.default = ""
o.description = translate("It Will Be Selected Nodes According To The Regex") o.description = translate("It Will Be Selected Nodes According To The Regex")
o:depends("stream_auto_select_google_not_cn", "1") o:depends("stream_auto_select_google_not_cn", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "Google", translate("Manual Test")) o = s:taboption("stream_enhance", DummyValue, "Google", translate("Manual Test"))
o.rawhtml = true o.rawhtml = true
@ -762,27 +704,21 @@ o.default = 0
o:depends("stream_auto_select", "1") o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_openai", translate("Group Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_openai", translate("Group Filter"))
o.default = "OpenAI|ChatGPT"
o.placeholder = "OpenAI|ChatGPT|AI" o.placeholder = "OpenAI|ChatGPT|AI"
o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails") o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
o:depends("stream_auto_select_openai", "1") o:depends("stream_auto_select_openai", "1")
o.rmempty = true
o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_openai", translate("Unlock Region Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_openai", translate("Unlock Region Filter"))
o.default = ""
o.placeholder = "US" o.placeholder = "US"
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex") o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_openai", "1") o:depends("stream_auto_select_openai", "1")
function o.validate(self, value) o.rmempty = true
if value ~= m.uci:get("openclash", "config", "stream_auto_select_region_key_openai") then
fs.unlink("/tmp/openclash_OpenAI_region")
end
return value
end
o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_openai", translate("Unlock Nodes Filter")) o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_openai", translate("Unlock Nodes Filter"))
o.default = ""
o.description = translate("It Will Be Selected Nodes According To The Regex") o.description = translate("It Will Be Selected Nodes According To The Regex")
o:depends("stream_auto_select_openai", "1") o:depends("stream_auto_select_openai", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "OpenAI", translate("Manual Test")) o = s:taboption("stream_enhance", DummyValue, "OpenAI", translate("Manual Test"))
o.rawhtml = true o.rawhtml = true
@ -1068,6 +1004,10 @@ o = s:taboption("dashboard", DummyValue, "Metacubexd", translate("Update Metacub
o.template="openclash/switch_dashboard" o.template="openclash/switch_dashboard"
o.rawhtml = true o.rawhtml = true
o = s:taboption("dashboard", DummyValue, "zashboard", translate("Update zashboard Version"))
o.template="openclash/switch_dashboard"
o.rawhtml = true
---- ipv6 ---- ipv6
o = s:taboption("ipv6", Flag, "ipv6_enable", translate("Proxy IPv6 Traffic")) o = s:taboption("ipv6", Flag, "ipv6_enable", translate("Proxy IPv6 Traffic"))
o.description = font_red..bold_on..translate("The Gateway and DNS of The Connected Device Must be The Router IP, Disable IPv6 DHCP To Avoid Abnormal Connection If You Do Not Use")..bold_off..font_off o.description = font_red..bold_on..translate("The Gateway and DNS of The Connected Device Must be The Router IP, Disable IPv6 DHCP To Avoid Abnormal Connection If You Do Not Use")..bold_off..font_off

View File

@ -247,8 +247,11 @@ unlink = fs.unlink
readlink = fs.readlink readlink = fs.readlink
function filename(str) function filename(str)
if not str then
return nil
end
local idx = str:match(".+()%.%w+$") local idx = str:match(".+()%.%w+$")
if(idx) then if idx then
return str:sub(1, idx-1) return str:sub(1, idx-1)
else else
return str return str

View File

@ -28,6 +28,7 @@
</style> </style>
<link rel="stylesheet" href="/luci-static/resources/openclash/lib/codemirror.css"/> <link rel="stylesheet" href="/luci-static/resources/openclash/lib/codemirror.css"/>
<link rel="stylesheet" href="/luci-static/resources/openclash/theme/material.css"/> <link rel="stylesheet" href="/luci-static/resources/openclash/theme/material.css"/>
<link rel="stylesheet" href="/luci-static/resources/openclash/theme/material-log.css"/>
<link rel="stylesheet" href="/luci-static/resources/openclash/theme/idea.css"/> <link rel="stylesheet" href="/luci-static/resources/openclash/theme/idea.css"/>
<link rel="stylesheet" href="/luci-static/resources/openclash/addon/fold/foldgutter.css"/> <link rel="stylesheet" href="/luci-static/resources/openclash/addon/fold/foldgutter.css"/>
<link rel="stylesheet" href="/luci-static/resources/openclash/addon/lint/lint.css"> <link rel="stylesheet" href="/luci-static/resources/openclash/addon/lint/lint.css">
@ -87,6 +88,33 @@ local sconf = "/etc/openclash/"..conf_name
</table> </table>
<script type="text/javascript">//<![CDATA[ <script type="text/javascript">//<![CDATA[
function isDarkBackground(element) {
var style = window.getComputedStyle(element);
var bgColor = style.backgroundColor;
let r, g, b;
if (/rgb\(/.test(bgColor)) {
var rgb = bgColor.match(/\d+/g);
r = parseInt(rgb);
g = parseInt(rgb);
b = parseInt(rgb);
} else if (/#/.test(bgColor)) {
if (bgColor.length === 4) {
r = parseInt(bgColor + bgColor, 16);
g = parseInt(bgColor + bgColor, 16);
b = parseInt(bgColor + bgColor, 16);
} else {
r = parseInt(bgColor.slice(1, 3), 16);
g = parseInt(bgColor.slice(3, 5), 16);
b = parseInt(bgColor.slice(5, 7), 16);
}
} else {
return false;
}
var luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;
return luminance < 128;
};
function merge_editor(id, id2, target, target2, readOnly, readOnly2, wid, height) function merge_editor(id, id2, target, target2, readOnly, readOnly2, wid, height)
{ {
var value, orig1, orig2, merge_editor, descr, gap, vscrollbar, vscrollbar_oc, panes = 2, highlight = true, connect = null, collapse = false; var value, orig1, orig2, merge_editor, descr, gap, vscrollbar, vscrollbar_oc, panes = 2, highlight = true, connect = null, collapse = false;
@ -438,6 +466,10 @@ if (core_log && oc_log) {
core_editor.setOption("readOnly","true"); core_editor.setOption("readOnly","true");
oc_editor.setSize("100%", "540px"); oc_editor.setSize("100%", "540px");
oc_editor.setOption("readOnly","true"); oc_editor.setOption("readOnly","true");
if (isDarkBackground(document.body)) {
core_editor.setOption('theme', 'material-log');
oc_editor.setOption('theme', 'material-log');
};
}; };
var proxy_mg = document.getElementById('cbi-table-1-proxy_mg'); var proxy_mg = document.getElementById('cbi-table-1-proxy_mg');

View File

@ -4,207 +4,245 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no,minimal-ui"> <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no,minimal-ui">
<style> <style>
.center { :root[data-darkmode="true"] {
top: 50%; .card {
left: 50%; background: linear-gradient(rgb(0, 0, 0), rgb(70, 70, 70));
min-width: 800px; }
}
.card { .card .additional {
width: 100%; background: linear-gradient(#337ab7, rgb(70, 70, 70));
height: 250px; }
background-color: #fff;
background: linear-gradient(#f8f8f8, #fff); .card .general .dler-title{
box-shadow: 0 8px 16px -8px rgba(0,0,0,0.4); color: #bbbbbb;
border-radius: 6px; }
position: relative;
}
.card h1 { .card .general .dler-result{
text-align: center; color: #bbbbbb;
} }
.card .additional { .card .general .dler-result2{
position: absolute; color: #bbbbbb;
width: 100%; }
height: 100%;
background: linear-gradient(#337ab7, #fefefe);
transition: width 0.5s;
overflow: hidden;
z-index: 2;
}
.card .additional .user-card { .card .general h1 {
width: 150px; color: #bbbbbb;
height: 100%; }
position: relative;
float: left;
}
.card .additional .user-card::after { .card .additional .user-card::after {
content: ""; border-left: 2px solid #bbbbbb;
display: block; }
position: absolute;
top: 10%;
right: -2px;
height: 80%;
border-left: 2px solid rgba(0,0,0,0.025);*/
}
.card .additional .user-card img { .card .additional .more-info h1 {
color: #bbbbbb;
}
left: 20%; .card .additional .coords {
bottom: 30%; color: #bbbbbb;
width: 60%; }
border-radius: 60%; }
position: absolute;
} .center {
top: 50%;
left: 50%;
min-width: 800px;
}
.card .additional .more-info { .card {
position: relative; width: 100%;
top: 28%; height: 250px;
height: 50%; background-color: #fff;
margin: 0 auto; background: linear-gradient(#f8f8f8, #fff);
width: 50%; box-shadow: 0 8px 16px -8px rgba(0,0,0,0.4);
padding-left: 150px; border-radius: 6px;
padding-top: 1%; position: relative;
} }
.card .additional .more-info h1 { .card h1 {
color: #fff; text-align: center;
margin-bottom: 0; }
margin: 0 1rem;
font-size: 2rem;
position: relative;
}
.card .additional .coords { .card .additional {
margin: 0 1rem; position: absolute;
color: #fff; width: 100%;
font-size: 1rem; height: 100%;
position: relative; background: linear-gradient(#337ab7, #fefefe);
top: 10%; transition: width 0.5s;
text-align: center; overflow: hidden;
overflow: hidden; z-index: 2;
line-height: 20px; }
}
.card .general { .card .additional .user-card {
width: auto; width: 150px;
height: 100%; height: 100%;
position: relative; position: relative;
margin-left: 150px; float: left;
top: 0; }
right: 0;
z-index: 1;
box-sizing: border-box;
overflow: hidden;
padding-top: 0;
}
.card .general h1 { .card .additional .user-card::after {
font-size: 30px; content: "";
text-align: center; display: block;
padding-top: 5px; position: absolute;
margin: 0 0 0 -12%; top: 10%;
line-height: 35px; right: -2px;
color: black; height: 80%;
} border-left: 2px solid rgba(0,0,0,0.025);
}
.card .general .dler-info { .card .additional .user-card img {
top: 22%;
width: 90%;
height: 70%;
display: flex;
position: absolute;
margin: 0 0 0 8%;
}
.card .general .dler-info p { left: 20%;
padding: 8px !important; bottom: 30%;
text-align: center; width: 60%;
margin-bottom: 0; border-radius: 60%;
} position: absolute;
.card .general .dler-info div { }
position: relative;
}
.card .general .dler-title { .card .additional .more-info {
font-weight: bold; position: relative;
color: #444; top: 28%;
font-size: 15px; height: 50%;
display: inline-block; margin: 0 auto;
width: 45%; width: 50%;
overflow: hidden; padding-left: 150px;
vertical-align:bottom; padding-top: 1%;
white-space: nowrap; }
text-overflow: ellipsis;
line-height: 25px;
height: 25px;
text-align: left;
}
.card .general .dler-result {
color: #444;
font-size:16px;
white-space: nowrap;
display: inline-block;
width: 55%;
overflow: hidden;
text-overflow: ellipsis;
vertical-align:bottom;
text-align: right;
line-height: 25px;
height: 25px;
}
.card .general .dler-result2 { .card .additional .more-info h1 {
color: #444; color: #fff;
font-size:16px; margin-bottom: 0;
white-space: nowrap; margin: 0 1rem;
display: inline-block; font-size: 2rem;
width: 55%; position: relative;
overflow: hidden; }
text-overflow: ellipsis;
vertical-align:bottom;
text-align: right;
line-height: 25px;
height: 25px;
}
.card .general .btn { .card .additional .coords {
color: #fff; margin: 0 1rem;
border-color: #337ab7 !important; color: #fff;
background: #1473e6; font-size: 1rem;
background-color: #1473e6 !important; position: relative;
box-shadow: 0 8px 16px -8px rgba(0,0,0,0.4); top: 10%;
border-radius: 6px; text-align: center;
width: 90px; overflow: hidden;
height: 90px !important; line-height: 20px;
font-size: 15px; }
font-weight: bold;
display: inline-block;
overflow: hidden;
-webkit-appearance:button;
}
.card .general .more { .card .general {
float: right; width: auto;
top: 88%; height: 100%;
right: 0; position: relative;
font-size: 15px; margin-left: 150px;
line-height: 20px; top: 0;
padding: 0; right: 0;
position: absolute; z-index: 1;
display: inline-block; box-sizing: border-box;
overflow: hidden; overflow: hidden;
margin: 0 3% 0.5% 0; padding-top: 0;
} }
</style>
.card .general h1 {
font-size: 30px;
text-align: center;
padding-top: 5px;
margin: 0 0 0 -12%;
line-height: 35px;
color: black;
}
.card .general .dler-info {
top: 22%;
width: 90%;
height: 70%;
display: flex;
position: absolute;
margin: 0 0 0 8%;
}
.card .general .dler-info p {
padding: 8px !important;
text-align: center;
margin-bottom: 0;
}
.card .general .dler-info div {
position: relative;
}
.card .general .dler-title {
font-weight: bold;
color: #444;
font-size: 15px;
display: inline-block;
width: 45%;
overflow: hidden;
vertical-align:bottom;
white-space: nowrap;
text-overflow: ellipsis;
line-height: 25px;
height: 25px;
text-align: left;
}
.card .general .dler-result {
color: #444;
font-size:16px;
white-space: nowrap;
display: inline-block;
width: 55%;
overflow: hidden;
text-overflow: ellipsis;
vertical-align:bottom;
text-align: right;
line-height: 25px;
height: 25px;
}
.card .general .dler-result2 {
color: #444;
font-size:16px;
white-space: nowrap;
display: inline-block;
width: 55%;
overflow: hidden;
text-overflow: ellipsis;
vertical-align:bottom;
text-align: right;
line-height: 25px;
height: 25px;
}
.card .general .btn {
color: #fff;
border-color: #337ab7 !important;
background: #1473e6;
background-color: #1473e6 !important;
box-shadow: 0 8px 16px -8px rgba(0,0,0,0.4);
border-radius: 6px;
width: 90px;
height: 90px !important;
font-size: 15px;
font-weight: bold;
display: inline-block;
overflow: hidden;
-webkit-appearance:button;
}
.card .general .more {
float: right;
top: 88%;
right: 0;
font-size: 15px;
line-height: 20px;
padding: 0;
position: absolute;
display: inline-block;
overflow: hidden;
margin: 0 3% 0.5% 0;
}
</style>
</head> </head>
<body> <body>
<fieldset class="cbi-section"> <fieldset class="cbi-section">

View File

@ -132,10 +132,15 @@
text-align: left; text-align: left;
} }
@media only screen and (max-width: 600px) { :root[data-darkmode="true"] {
.myip { #eye-icon {
min-width: 700px !important; -webkit-filter: invert(1);
flex-direction: column !important; filter: invert(1);
}
#data-refresh-icon {
-webkit-filter: invert(1);
filter: invert(1);
} }
} }
</style> </style>
@ -144,7 +149,7 @@
<fieldset class="cbi-section"> <fieldset class="cbi-section">
<table width="100%"> <table width="100%">
<tr><td> <tr><td>
<div class="myip" style="display: flex; min-width: 820px;"> <div style="display: flex; min-width: 820px;">
<div style="width: 48%"> <div style="width: 48%">
<p style="margin: 20px 0 20px 8%; padding: 0px !important; text-align: left; font-size: 25px; font-weight: bold;"><%:IP Address%> <p style="margin: 20px 0 20px 8%; padding: 0px !important; text-align: left; font-size: 25px; font-weight: bold;"><%:IP Address%>
<span style="float: right;"><img src="/luci-static/resources/openclash/img/eye-light.svg" height="20px" title="<%:Hide IP%>" alt="<%:Hide IP%>" id="eye-icon" onclick="return privacy_my_ip(this)" /></span> <span style="float: right;"><img src="/luci-static/resources/openclash/img/eye-light.svg" height="20px" title="<%:Hide IP%>" alt="<%:Hide IP%>" id="eye-icon" onclick="return privacy_my_ip(this)" /></span>
@ -164,7 +169,7 @@
</div> </div>
<div style="width: 52%"> <div style="width: 52%">
<p style="margin: 20px 0 20px 8%; padding: 0px !important;text-align: left; font-size: 25px; font-weight: bold;"><%:Website Access Check%> <p style="margin: 20px 0 20px 8%; padding: 0px !important;text-align: left; font-size: 25px; font-weight: bold;"><%:Website Access Check%>
<span style="float: right; margin: 0 10% 0 0;"><img src="/luci-static/resources/openclash/img/arrow-clockwise-light.svg" height="20px" title="<%:Refresh%>" alt="<%:Refresh%>" onclick="return refresh_myip(this)" /></span> <span style="float: right; margin: 0 10% 0 0;"><img src="/luci-static/resources/openclash/img/arrow-clockwise-light.svg" height="20px" title="<%:Refresh%>" alt="<%:Refresh%>" id="data-refresh-icon" onclick="return refresh_myip(this)" /></span>
</p> </p>
<p style="margin: 10px 0 0 8%; text-align: left; padding-left: 0px !important; padding-right: 0px !important;"> <p style="margin: 10px 0 0 8%; text-align: left; padding-left: 0px !important; padding-right: 0px !important;">
<span class="ip-state_title"><%:Baidu Search%>:</span><span id="http-baidu"></span><span id="ldtime-baidu"></span> <span class="ip-state_title"><%:Baidu Search%>:</span><span id="http-baidu"></span><span id="ldtime-baidu"></span>

View File

@ -1,5 +1,16 @@
<style type="text/css"> <style type="text/css">
:root[data-darkmode="true"] {
.select-popup {
background-color: #000000;
}
.select-option:hover {
background-color: #444444;
}
}
.select-popup { .select-popup {
position: fixed; position: fixed;
top: 50%; top: 50%;
@ -16,6 +27,10 @@
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5); box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5);
} }
.select-class {
width: auto;
}
.select-popup.hidden { .select-popup.hidden {
display: none; display: none;
} }
@ -52,7 +67,7 @@
<div id="selectPopup" class="select-popup hidden"> <div id="selectPopup" class="select-popup hidden">
<table width="100%"><tr> <table width="100%"><tr>
<td width="25%" align="center"><%:Compiled Version Selected (Auto-save when you click to update or download)%></td> <td width="25%" align="center"><%:Compiled Version Selected (Auto-save when you click to update or download)%></td>
<td width="25%" align="center"><select id="CORE_VERSION_CDN"> <td width="25%" align="center"><select class="select-class" id="CORE_VERSION_CDN">
<option value="linux-386"><%:linux-386%></option> <option value="linux-386"><%:linux-386%></option>
<option value="linux-amd64"><%:linux-amd64(x86-64)%></option> <option value="linux-amd64"><%:linux-amd64(x86-64)%></option>
<option value="linux-amd64-v3"><%:linux-amd64-v3(x86-64)%></option> <option value="linux-amd64-v3"><%:linux-amd64-v3(x86-64)%></option>
@ -73,7 +88,7 @@
<option value="0"><%:Not Set%></option> <option value="0"><%:Not Set%></option>
</select></td> </select></td>
<td width="25%" align="center"><%:Release Branch Selected (Auto-save when you click to update or download)%></td> <td width="25%" align="center"><%:Release Branch Selected (Auto-save when you click to update or download)%></td>
<td width="25%" align="center"><select id="RELEASE_BRANCH_CDN"> <td width="25%" align="center"><select class="select-class" id="RELEASE_BRANCH_CDN">
<option value="master">Master</option> <option value="master">Master</option>
<option value="dev">Developer</option> <option value="dev">Developer</option>
</select></td> </select></td>
@ -97,6 +112,36 @@
var core_version_cdn = document.getElementById('CORE_VERSION_CDN'); var core_version_cdn = document.getElementById('CORE_VERSION_CDN');
var release_branch_cdn = document.getElementById('RELEASE_BRANCH_CDN'); var release_branch_cdn = document.getElementById('RELEASE_BRANCH_CDN');
function isDarkBackground(element) {
var style = window.getComputedStyle(element);
var bgColor = style.backgroundColor;
let r, g, b;
if (/rgb\(/.test(bgColor)) {
var rgb = bgColor.match(/\d+/g);
r = parseInt(rgb);
g = parseInt(rgb);
b = parseInt(rgb);
} else if (/#/.test(bgColor)) {
if (bgColor.length === 4) {
r = parseInt(bgColor + bgColor, 16);
g = parseInt(bgColor + bgColor, 16);
b = parseInt(bgColor + bgColor, 16);
} else {
r = parseInt(bgColor.slice(1, 3), 16);
g = parseInt(bgColor.slice(3, 5), 16);
b = parseInt(bgColor.slice(5, 7), 16);
}
} else {
return false;
}
var luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;
return luminance < 128;
};
if (isDarkBackground(document.body)) {
document.documentElement.setAttribute('data-darkmode', 'true');
};
function get_update_info() { function get_update_info() {
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_info")%>', null, function(x, status) { XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_info")%>', null, function(x, status) {
if ( x && x.status == 200 ) { if ( x && x.status == 200 ) {

View File

@ -85,7 +85,7 @@
<input type="radio" id="direct" name="radios" value="direct" onclick="return switch_rule_mode(this.value)"/> <input type="radio" id="direct" name="radios" value="direct" onclick="return switch_rule_mode(this.value)"/>
<label for="direct"><%:Direct%></label> <label for="direct"><%:Direct%></label>
</span></td><td width="25%"><%:Control Panel Login Secret%></td><td width="25%" align="left" id="_dase"><%:Collecting data...%></td></tr> </span></td><td width="25%"><%:Control Panel Login Secret%></td><td width="25%" align="left" id="_dase"><%:Collecting data...%></td></tr>
<tr><td colspan="4"><div style="margin: 10px 0; text-align: center"><span id="_web" style="width: 33%; display: inline-block;"></span><span id="_webm" style="width: 33%; display: inline-block;"><%:Collecting data...%></span><span id="_webo" style="width: 33%; display: inline-block;"></span></div></td></tr> <tr><td colspan="4"><div style="margin: 10px 0; text-align: center"><span id="_web" style="width: 25%; display: inline-block;"></span><span id="_webm" style="width: 25%; display: inline-block;"><%:Collecting data...%></span><span id="_webz" style="width: 25%; display: inline-block;"><%:Collecting data...%></span><span id="_webo" style="width: 25%; display: inline-block;"></span></div></td></tr>
<tr id="tool_label2"><td colspan="4"> <tr id="tool_label2"><td colspan="4">
<div style="margin: 10px 0; text-align: center"> <div style="margin: 10px 0; text-align: center">
<span> <span>
@ -193,6 +193,7 @@
var web = document.getElementById('_web'); var web = document.getElementById('_web');
var webo = document.getElementById('_webo'); var webo = document.getElementById('_webo');
var webm = document.getElementById('_webm'); var webm = document.getElementById('_webm');
var webz = document.getElementById('_webz');
var watchdog = document.getElementById('_watchdog'); var watchdog = document.getElementById('_watchdog');
var daip = document.getElementById('_daip'); var daip = document.getElementById('_daip');
var dase = document.getElementById('_dase'); var dase = document.getElementById('_dase');
@ -253,6 +254,7 @@
web.innerHTML = status.web ? '<input type="button" class="btn cbi-button cbi-button-reload" value="<%:Yacd Control Panel%>" onclick="return ycad_dashboard(this)"/>' : '<b style=color:red><%:Not Running%></b>'; web.innerHTML = status.web ? '<input type="button" class="btn cbi-button cbi-button-reload" value="<%:Yacd Control Panel%>" onclick="return ycad_dashboard(this)"/>' : '<b style=color:red><%:Not Running%></b>';
webo.innerHTML = status.web ? '<input type="button" class="btn cbi-button cbi-button-reload" value="<%:Dashboard Control Panel%>" onclick="return net_dashboard(this)"/>' : '<b style=color:red><%:Not Running%></b>'; webo.innerHTML = status.web ? '<input type="button" class="btn cbi-button cbi-button-reload" value="<%:Dashboard Control Panel%>" onclick="return net_dashboard(this)"/>' : '<b style=color:red><%:Not Running%></b>';
webm.innerHTML = status.web ? '<input type="button" class="btn cbi-button cbi-button-reload" value="<%:Metacubexd Control Panel%>" onclick="return meta_dashboard(this)"/>' : '<b style=color:red><%:Not Running%></b>'; webm.innerHTML = status.web ? '<input type="button" class="btn cbi-button cbi-button-reload" value="<%:Metacubexd Control Panel%>" onclick="return meta_dashboard(this)"/>' : '<b style=color:red><%:Not Running%></b>';
webz.innerHTML = status.web ? '<input type="button" class="btn cbi-button cbi-button-reload" value="<%:zashboard Control Panel%>" onclick="return net_zashboard(this)"/>' : '<b style=color:red><%:Not Running%></b>';
close_all_connection.innerHTML = status.clash ? '<input type="button" class="btn cbi-button cbi-button-reload" value="<%:Close All Connections%>" onclick="return b_close_all_connection(this)"/>' : '<b style=color:red><%:Not Running%></b>'; close_all_connection.innerHTML = status.clash ? '<input type="button" class="btn cbi-button cbi-button-reload" value="<%:Close All Connections%>" onclick="return b_close_all_connection(this)"/>' : '<b style=color:red><%:Not Running%></b>';
reload_firewall.innerHTML = status.clash ? '<input type="button" class="btn cbi-button cbi-button-reload" value="<%:Reload Firewall Rules%>" onclick="return b_reload_firewall(this)"/>' : '<b style=color:red><%:Not Running%></b>'; reload_firewall.innerHTML = status.clash ? '<input type="button" class="btn cbi-button cbi-button-reload" value="<%:Reload Firewall Rules%>" onclick="return b_reload_firewall(this)"/>' : '<b style=color:red><%:Not Running%></b>';
flush_fakeip_cache.innerHTML = status.clash ? '<input type="button" class="btn cbi-button cbi-button-reload" value="<%:Flush Fake-IP Cache%>" onclick="return b_flush_fakeip_cache(this)"/>' : '<b style=color:red><%:Not Running%></b>'; flush_fakeip_cache.innerHTML = status.clash ? '<input type="button" class="btn cbi-button cbi-button-reload" value="<%:Flush Fake-IP Cache%>" onclick="return b_flush_fakeip_cache(this)"/>' : '<b style=color:red><%:Not Running%></b>';
@ -727,8 +729,8 @@
btn.value = '<%:Checking...%>'; btn.value = '<%:Checking...%>';
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_other_rules")%>', null, function(x, status) { XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_other_rules")%>', null, function(x, status) {
if ( x && x.status == 200 ) { if ( x && x.status == 200 ) {
btn.disabled = false; btn.disabled = false;
btn.value = '<%:Check Third Party Rules Update%>'; btn.value = '<%:Check Third Party Rules Update%>';
} }
else { else {
btn.disabled = false; btn.disabled = false;
@ -744,12 +746,12 @@
btn.value = '<%:Checking...%>'; btn.value = '<%:Checking...%>';
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_geoip")%>', null, function(x, status) { XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_geoip")%>', null, function(x, status) {
if ( x && x.status == 200 ) { if ( x && x.status == 200 ) {
btn.disabled = false; btn.disabled = false;
btn.value = '<%:Check GEOIP Data Update%>'; btn.value = '<%:Check GEOIP Data Update%>';
} }
else { else {
btn.disabled = false; btn.disabled = false;
btn.value = '<%:Check GEOIP Data Update%>'; btn.value = '<%:Check GEOIP Data Update%>';
} }
return false; return false;
}); });
@ -761,12 +763,12 @@
btn.value = '<%:Checking...%>'; btn.value = '<%:Checking...%>';
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_geosite")%>', null, function(x, status) { XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_geosite")%>', null, function(x, status) {
if ( x && x.status == 200 ) { if ( x && x.status == 200 ) {
btn.disabled = false; btn.disabled = false;
btn.value = '<%:Check GeoSite Data Update%>'; btn.value = '<%:Check GeoSite Data Update%>';
} }
else { else {
btn.disabled = false; btn.disabled = false;
btn.value = '<%:Check GeoSite Data Update%>'; btn.value = '<%:Check GeoSite Data Update%>';
} }
return false; return false;
}); });
@ -806,12 +808,12 @@
btn.value = '<%:Checking...%>'; btn.value = '<%:Checking...%>';
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_subscribe")%>', null, function(x, status) { XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_subscribe")%>', null, function(x, status) {
if ( x && x.status == 200 ) { if ( x && x.status == 200 ) {
btn.disabled = false; btn.disabled = false;
btn.value = '<%:Check Config Update%>'; btn.value = '<%:Check Config Update%>';
} }
else { else {
btn.disabled = false; btn.disabled = false;
btn.value = '<%:Check Config Update%>'; btn.value = '<%:Check Config Update%>';
} }
return false; return false;
}); });
@ -823,12 +825,12 @@
btn.value = '<%:Reloading...%>'; btn.value = '<%:Reloading...%>';
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "reload_firewall")%>', null, function(x, status) { XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "reload_firewall")%>', null, function(x, status) {
if ( x && x.status == 200 ) { if ( x && x.status == 200 ) {
btn.disabled = false; btn.disabled = false;
btn.value = '<%:Reload Firewall Rules%>'; btn.value = '<%:Reload Firewall Rules%>';
} }
else { else {
btn.disabled = false; btn.disabled = false;
btn.value = '<%:Firewall Rules Reset Failed%>'; btn.value = '<%:Firewall Rules Reset Failed%>';
} }
return false; return false;
}); });
@ -840,17 +842,38 @@
btn.value = '<%:Reloading...%>'; btn.value = '<%:Reloading...%>';
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "close_all_connection")%>', null, function(x, status) { XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "close_all_connection")%>', null, function(x, status) {
if ( x && x.status == 200 ) { if ( x && x.status == 200 ) {
btn.disabled = false; btn.disabled = false;
btn.value = '<%:Close All Connections%>'; btn.value = '<%:Close All Connections%>';
} }
else { else {
btn.disabled = false; btn.disabled = false;
btn.value = '<%:Close All Connections Failed%>'; btn.value = '<%:Close All Connections Failed%>';
} }
return false; return false;
}); });
}; };
function net_zashboard(btn)
{
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "status")%>', null, function(x, status) {
btn.disabled = true;
btn.value = '<%:zashboard Control Panel%>';
if (status.daip && window.location.hostname == status.daip) {
url9='<%="http://'+window.location.hostname+':'+status.cn_port+'/ui/zashboard/#/setup?hostname='+ window.location.hostname + '&port=' + status.cn_port + '&secret=' + status.dase +'"%>';
}
else if (status.daip && window.location.hostname != status.daip && status.db_foward_domain && status.db_foward_port) {
var ui_proto = status.db_forward_ssl == 0 ? 'http://' : 'https://';
url9='<%="'+ui_proto+status.db_foward_domain+':'+status.db_foward_port+'/ui/zashboard/#/setup?hostname='+ status.db_foward_domain + '&port=' + status.db_foward_port + '&secret=' + status.dase +'"%>';
}
else {
url9='<%="http://'+window.location.hostname+':'+status.cn_port+'/ui/zashboard/#/"%>';
}
winOpen(url9);
return false;
});
};
function meta_dashboard(btn) function meta_dashboard(btn)
{ {
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "status")%>', null, function(x, status) { XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "status")%>', null, function(x, status) {

View File

@ -35,12 +35,22 @@
white-space: nowrap; white-space: nowrap;
} }
.text_show{
color: #000000;
text-shadow:
-0.7px -0.7px 0 #ffffff,
0.7px -0.7px 0 #ffffff,
-0.7px 0.7px 0 #ffffff,
0.7px 0.7px 0 #ffffff;
}
:root[data-darkmode="true"] { :root[data-darkmode="true"] {
#icon_wrench { #icon_wrench {
-webkit-filter: invert(1); -webkit-filter: invert(1);
filter: invert(1); filter: invert(1);
} }
#icon_arrow { #icon_arrow {
-webkit-filter: invert(1); -webkit-filter: invert(1);
filter: invert(1); filter: invert(1);
@ -63,12 +73,42 @@ var retry_<%=idname%> = 0;
var s_<%=idname%>; var s_<%=idname%>;
sub_info_get_<%=idname%>(); sub_info_get_<%=idname%>();
function isDarkBackground(element) {
var style = window.getComputedStyle(element);
var bgColor = style.backgroundColor;
let r, g, b;
if (/rgb\(/.test(bgColor)) {
var rgb = bgColor.match(/\d+/g);
r = parseInt(rgb);
g = parseInt(rgb);
b = parseInt(rgb);
} else if (/#/.test(bgColor)) {
if (bgColor.length === 4) {
r = parseInt(bgColor + bgColor, 16);
g = parseInt(bgColor + bgColor, 16);
b = parseInt(bgColor + bgColor, 16);
} else {
r = parseInt(bgColor.slice(1, 3), 16);
g = parseInt(bgColor.slice(3, 5), 16);
b = parseInt(bgColor.slice(5, 7), 16);
}
} else {
return false;
}
var luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;
return luminance < 128;
};
if (isDarkBackground(document.body)) {
document.documentElement.setAttribute('data-darkmode', 'true');
};
function progressbar_<%=idname%>(v, m, pc, np, f, t, tr) { function progressbar_<%=idname%>(v, m, pc, np, f, t, tr) {
return String.format( return String.format(
'<div style="width:250px; max-width:500px; position:relative; border:1px solid #999999; border-radius: 6px">' + '<div style="width:250px; max-width:500px; position:relative; border:1px solid #999999; border-radius: 6px">' +
(pc >= 50 ? '<div style="background-color:#9edd9e; width:%d%%; height:36px; border-radius: 6px">' : (pc < 50 && pc >= 20 ? '<div style="background-color:#ffc99f; width:%d%%; height:35px">' : '<div style="background-color:#ffb9b9; width:%d%%; height:35px">')) + (pc >= 50 ? '<div style="background-color:#9edd9e; width:%d%%; height:36px; border-radius: 6px">' : (pc < 50 && pc >= 20 ? '<div style="background-color:#ffc99f; width:%d%%; height:35px">' : '<div style="background-color:#ffb9b9; width:%d%%; height:35px">')) +
'<div style="position:absolute; left:0;' + (tr == "null" ? 'top:12px;' : 'top:0;') + 'text-align:center; width:100%%">' + '<div style="position:absolute; left:0;' + (tr == "null" ? 'top:12px;' : 'top:0;') + 'text-align:center; width:100%%">' +
'<small style="color: black">%s '+ (f ? f : '/') +' %s ' + (np ? "" : '(%s%%)') + (tr == "null" ? '<div style="visibility: hidden;">' : '<div style="visibility: visible;">') + '%s (<%:Remaining%> %s <%:days%>)</small>' + '<small class="text_show">%s '+ (f ? f : '/') +' %s ' + (np ? "" : '(%s%%)') + (tr == "null" ? '<div style="visibility: hidden;">' : '<div style="visibility: visible;">') + '%s (<%:Remaining%> %s <%:days%>)</small>' +
'</div>' + '</div>' +
'</div>' + '</div>' +
'</div>', pc, v, m, pc, t, tr '</div>', pc, v, m, pc, t, tr

View File

@ -27,6 +27,9 @@
if ( btn_type_<%=self.option%> == "Metacubexd" ) { if ( btn_type_<%=self.option%> == "Metacubexd" ) {
switch_dashboard_<%=self.option%>.innerHTML = '<input type="button" class="btn cbi-button cbi-button-reset" value="<%:Update Metacubexd Version%>" onclick="return switch_dashboard(this, btn_type_<%=self.option%>, \'Official\')"/>'; switch_dashboard_<%=self.option%>.innerHTML = '<input type="button" class="btn cbi-button cbi-button-reset" value="<%:Update Metacubexd Version%>" onclick="return switch_dashboard(this, btn_type_<%=self.option%>, \'Official\')"/>';
} }
if ( btn_type_<%=self.option%> == "zashboard" ) {
switch_dashboard_<%=self.option%>.innerHTML = '<input type="button" class="btn cbi-button cbi-button-reset" value="<%:Update zashboard Version%>" onclick="return switch_dashboard(this, btn_type_<%=self.option%>, \'Official\')"/>';
}
} }
}); });
@ -54,16 +57,18 @@
{ {
document.getElementById("switch_dashboard_"+name).innerHTML = '<input type="button" class="btn cbi-button cbi-button-reset" value="<%:Switch Successful%> - <%:Switch To Meta Version%>" onclick="return switch_dashboard(this, \'Yacd\', \'Meta\')"/>'; document.getElementById("switch_dashboard_"+name).innerHTML = '<input type="button" class="btn cbi-button cbi-button-reset" value="<%:Switch Successful%> - <%:Switch To Meta Version%>" onclick="return switch_dashboard(this, \'Yacd\', \'Meta\')"/>';
} }
else{ else if ( name == "Metacubexd" ) {
document.getElementById("switch_dashboard_"+name).innerHTML = '<input type="button" class="btn cbi-button cbi-button-reset" value="<%:Update Successful%> - <%:Update Metacubexd Version%>" onclick="return switch_dashboard(this, \'Metacubexd\', \'Official\')"/>'; document.getElementById("switch_dashboard_"+name).innerHTML = '<input type="button" class="btn cbi-button cbi-button-reset" value="<%:Update Successful%> - <%:Update Metacubexd Version%>" onclick="return switch_dashboard(this, \'Metacubexd\', \'Official\')"/>';
} } else {
document.getElementById("switch_dashboard_"+name).innerHTML = '<input type="button" class="btn cbi-button cbi-button-reset" value="<%:Update Successful%> - <%:Update zashboard Version%>" onclick="return switch_dashboard(this, \'zashboard\', \'Official\')"/>';
}
} }
} }
else if ( status.download_state == "2" ) { else if ( status.download_state == "2" ) {
btn.value = '<%:Unzip Error%>'; btn.value = '<%:Unzip Error%>';
} }
else { else {
if ( name == "Metacubexd" ) { if ( name == "Metacubexd" || name == "zashboard" ) {
btn.value = '<%:Update Failed%>'; btn.value = '<%:Update Failed%>';
} }
else { else {

View File

@ -36,7 +36,7 @@
&nbsp;&nbsp;<%:Current Config File%>:&nbsp; &nbsp;&nbsp;<%:Current Config File%>:&nbsp;
<select class="tool_label_select" id="cfg_name"> <select class="tool_label_select" id="cfg_name">
</select>&nbsp;&nbsp; </select>&nbsp;&nbsp;
<input type="button" class="btn cbi-button cbi-button-apply" value="<%:Switch%>" onclick="return switch_config(this)" /> <input type="button" class="btn cbi-button cbi-button-apply" value="<%:SwiTch%>" onclick="return switch_config(this)" />
&nbsp; &nbsp;
</span> </span>
</li> </li>

View File

@ -0,0 +1,27 @@
<%+cbi/valueheader%>
<%
local fs = require "luci.openclash"
local filename = fs.filename(self:cfgvalue(section)) or "config"
local display = self.display or ""
local idname = math.random(1000)..(string.match(filename, "[%w_]+") or "")
%>
<script type="text/javascript">//<![CDATA[
function act_update_config_<%=idname%>(btn)
{
btn.disabled = true;
btn.value = '<%:UpDate%>';
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash","update_config")%>',{filename: "<%=filename%>"}, function(x,status){});
btn.disabled = false;
return false;
};
//]]></script>
<%
if display == "" then
%>
<input type="button" class="btn cbi-button cbi-input-reload" value="<%:UpDate%>" onclick="return act_update_config_<%=idname%>(this)" />
<%
end
%>
<%+cbi/valuefooter%>

View File

@ -215,15 +215,6 @@ msgstr "使用 Dnsmasq 转发"
msgid "Firewall Redirect" msgid "Firewall Redirect"
msgstr "使用防火墙转发" msgstr "使用防火墙转发"
msgid "Disable Dnsmasq's DNS Cache"
msgstr "禁止 Dnsmasq 缓存 DNS"
msgid "Recommended Enabled For Avoiding Some Connection Errors"
msgstr "推荐启用,防止因缓存造成连接错误"
msgid "(Maybe Incompatible For Your Firmware)"
msgstr "(部分固件可能不兼容)"
msgid "Custom DNS Setting" msgid "Custom DNS Setting"
msgstr "*自定义上游 DNS 服务器" msgstr "*自定义上游 DNS 服务器"
@ -789,6 +780,18 @@ msgstr "启用传输协议设置"
msgid "Hysterir QUIC parameters" msgid "Hysterir QUIC parameters"
msgstr "QUIC 参数" msgstr "QUIC 参数"
msgid "QUIC init stream receive window"
msgstr "QUIC 初始流接收窗口大小"
msgid "QUIC max stream receive window"
msgstr "QUIC 最大的流接收窗口大小"
msgid "QUIC init connection receive window"
msgstr "QUIC 初始的连接接收窗口大小"
msgid "QUIC max connection receive window"
msgstr "QUIC 最大的连接接收窗口大小"
msgid "Edit Rule Providers" msgid "Edit Rule Providers"
msgstr "编辑规则集配置" msgstr "编辑规则集配置"
@ -1189,13 +1192,16 @@ msgid "Running Mode"
msgstr "运行模式" msgstr "运行模式"
msgid "Yacd Control Panel" msgid "Yacd Control Panel"
msgstr "Yacd 控制面板" msgstr "Yacd 面板"
msgid "Dashboard Control Panel" msgid "Dashboard Control Panel"
msgstr "Dashboard 控制面板" msgstr "Dashboard 面板"
msgid "Metacubexd Control Panel" msgid "Metacubexd Control Panel"
msgstr "Metacubexd 控制面板" msgstr "Metacubexd 面板"
msgid "zashboard Control Panel"
msgstr "zashboard 面板"
msgid "Control Panel Login IP" msgid "Control Panel Login IP"
msgstr "控制面板登录 IP" msgstr "控制面板登录 IP"
@ -1605,8 +1611,11 @@ msgstr "开始下载"
msgid "Download Successful, Start Pre Update Test..." msgid "Download Successful, Start Pre Update Test..."
msgstr "下载成功,开始进行更新前测试..." msgstr "下载成功,开始进行更新前测试..."
msgid "Pre Update Test Failed, The File is Saved in /tmp/openclash.ipk, Please Try to Update Manually!" msgid "Pre Update Test Failed, The File is Saved in /tmp/openclash.apk, Please Try to Update Manually With"
msgstr "更新前测试失败,文件保存在 /tmp/openclash.ipk请尝试手动更新" msgstr "更新前测试失败,文件保存在 /tmp/openclash.apk请尝试以下命令手动更新"
msgid "Pre Update Test Failed, The File is Saved in /tmp/openclash.ipk, Please Try to Update Manually With"
msgstr "更新前测试失败,文件保存在 /tmp/openclash.ipk请尝试以下命令手动更新"
msgid "Pre Update Test Passed, Ready to Update and Please Do not Refresh The Page and Other Operations..." msgid "Pre Update Test Passed, Ready to Update and Please Do not Refresh The Page and Other Operations..."
msgstr "更新前测试通过,准备开始更新,更新过程请不要刷新页面和进行其他操作..." msgstr "更新前测试通过,准备开始更新,更新过程请不要刷新页面和进行其他操作..."
@ -1620,11 +1629,11 @@ msgstr "正在安装新版本,更新过程请不要刷新页面和进行其他
msgid "OpenClash Update Successful, About To Restart!" msgid "OpenClash Update Successful, About To Restart!"
msgstr "OpenClash 更新成功,即将进行重启!" msgstr "OpenClash 更新成功,即将进行重启!"
msgid "OpenClash Update Failed, The File is Saved in /tmp/openclash.ipk, Please Try to Update Manually!" msgid "OpenClash Update Failed, The File is Saved in /tmp/openclash.ipk, Please Try to Update Manually With"
msgstr "OpenClash 更新失败,文件保存在 /tmp/openclash.ipk请尝试手动更新" msgstr "OpenClash 更新失败,文件保存在 /tmp/openclash.ipk请尝试以下命令手动更新"
msgid "OpenClash Update Failed, The File is Saved in /tmp/openclash.apk, Please Try to Update Manually!" msgid "OpenClash Update Failed, The File is Saved in /tmp/openclash.apk, Please Try to Update Manually With"
msgstr "OpenClash 更新失败,文件保存在 /tmp/openclash.apk请尝试手动更新" msgstr "OpenClash 更新失败,文件保存在 /tmp/openclash.apk请尝试以下命令手动更新"
msgid "Download Failed, Please Check The Network or Try Again Later!" msgid "Download Failed, Please Check The Network or Try Again Later!"
msgstr "下载失败,请检查网络或稍后再试!" msgstr "下载失败,请检查网络或稍后再试!"
@ -1965,12 +1974,6 @@ msgstr "提示:检测到大陆白名单列表不存在,准备开始下载...
msgid "Tip: Detected that the Chnroute Cidr List Format is wrong, Ready to Reformat..." msgid "Tip: Detected that the Chnroute Cidr List Format is wrong, Ready to Reformat..."
msgstr "提示:检测到大陆白名单列表格式错误,准备重新格式化..." msgstr "提示:检测到大陆白名单列表格式错误,准备重新格式化..."
msgid "Error: Could Not Load The Capsh Library, Please Verify The Capsh Shell Library Work Well..."
msgstr "错误Capsh 异常请尝试重新安装依赖【libcap】和相应的Capsh库终止启动..."
msgid "Tip: You Could Download And Re-Install The libcap & libcap-bin Library From The Address Give"
msgstr "提示:你可以尝试从给出的地址中查找、下载并重新安装架构对应的 libcap 和 libcap-bin 依赖"
msgid "Error: OpenClash Can Not Start, Please Check The Error Info And Try Again!" msgid "Error: OpenClash Can Not Start, Please Check The Error Info And Try Again!"
msgstr "错误OpenClash 启动失败,请到日志页面查看详细错误信息!" msgstr "错误OpenClash 启动失败,请到日志页面查看详细错误信息!"
@ -2043,18 +2046,6 @@ msgstr "重置 OpenClash 防火墙规则..."
msgid "Warning: OpenClash Now Disabled, Need Start From Luci Page, Exit..." msgid "Warning: OpenClash Now Disabled, Need Start From Luci Page, Exit..."
msgstr "警告OpenClash 目前处于未启用状态,请从插件页面启动本插件,脚本退出..." msgstr "警告OpenClash 目前处于未启用状态,请从插件页面启动本插件,脚本退出..."
msgid "Warning: Multiple Restart Scripts Running, Exit..."
msgstr "警告:多个 OpenClash 启动脚本运行中,此脚本退出..."
msgid "Watchdog: Multiple Clash Processes, Kill All..."
msgstr "守护程序:检测到多个 Clash 内核运行,清理中..."
msgid "Watchdog: Clash Core Problem, Restart..."
msgstr "守护程序:检测到 Clash 内核崩溃,重启中..."
msgid "Watchdog: Already Restart 3 Times With Clash Core Problem, Auto-Exit..."
msgstr "守护程序:已尝试自动重启三次 Clash 内核为防止频繁重启造成严重后果OpenClash 将停止运行..."
msgid "Watchdog: Log Size Limit, Clean Up All Log Records..." msgid "Watchdog: Log Size Limit, Clean Up All Log Records..."
msgstr "守护程序:因日志大小限制,清理所有日志内容..." msgstr "守护程序:因日志大小限制,清理所有日志内容..."
@ -2721,8 +2712,8 @@ msgstr "未选择上传文件"
msgid "Custom Params" msgid "Custom Params"
msgstr "自定义参数" msgstr "自定义参数"
msgid "eg: \"rename=\\s+([2-9])[xX]@ (HIGH:$1)\"" msgid "eg: \"rename=match@replace\" , \"rename=\\s+([2-9])[xX]@ (HIGH:$1)\""
msgstr "格式示例:\"rename=\\s+([2-9])[xX]@ (高倍率:$1)\"" msgstr "格式示例:\"rename=match@replace\" , \"rename=\\s+([2-9])[xX]@ (高倍率:$1)\""
msgid "Use Rule Provider" msgid "Use Rule Provider"
msgstr "使用规则集" msgstr "使用规则集"
@ -2958,6 +2949,9 @@ msgstr "切换(更新) Yacd 版本"
msgid "Update Metacubexd Version" msgid "Update Metacubexd Version"
msgstr "更新 Metacubexd 版本" msgstr "更新 Metacubexd 版本"
msgid "Update zashboard Version"
msgstr "更新 zashboard 版本"
msgid "Downloading File..." msgid "Downloading File..."
msgstr "文件下载中..." msgstr "文件下载中..."
@ -3051,6 +3045,9 @@ msgstr "警告TUN 接口启动失败,尝试重启内核..."
msgid "Error: Core Start Failed, Please Check The Log Infos!" msgid "Error: Core Start Failed, Please Check The Log Infos!"
msgstr "错误:内核启动失败,请查看《内核日志》排查失败原因!" msgstr "错误:内核启动失败,请查看《内核日志》排查失败原因!"
msgid "Error: Core Status Abnormal, Please Check The Log Infos!"
msgstr "错误:内核状态异常,请查看《内核日志》排查异常原因!"
msgid "Forced Sniff Pure IP Connections" msgid "Forced Sniff Pure IP Connections"
msgstr "强制探测(嗅探)所有纯 IP 的连接" msgstr "强制探测(嗅探)所有纯 IP 的连接"
@ -3102,8 +3099,8 @@ msgstr "测速(连通性)间隔修改"
msgid "Modify The URL-Test Interval In The Config" msgid "Modify The URL-Test Interval In The Config"
msgstr "修改配置文件中的测速(连通性)间隔" msgstr "修改配置文件中的测速(连通性)间隔"
msgid "Whether to Enable Process Rules, If You Are Not Sure, Please Choose off Which Useful in Router Environment" msgid "Whether to Enable Process Rules, Only Works on Routerself, If You Are Not Sure, Please Choose off Which Useful in Router Environment, Depend on kmod-inet-diag"
msgstr "是否启用进程规则,在路由环境下保持关闭可以提升性能" msgstr "是否启用进程规则,仅能匹配路由器自身进程,在路由环境下保持关闭可以提升性能,依赖 kmod-inet-diag"
msgid "Enable Process Rule" msgid "Enable Process Rule"
msgstr "启用进程规则" msgstr "启用进程规则"
@ -3451,4 +3448,25 @@ msgid "Target"
msgstr "对象" msgstr "对象"
msgid "Error: Network Anomaly, Suspend Unlock Detection..." msgid "Error: Network Anomaly, Suspend Unlock Detection..."
msgstr "错误:网络异常,暂停解锁检测..." msgstr "错误:网络异常,暂停解锁检测..."
msgid "(Not Support mrs Format)"
msgstr "(不支持 mrs 格式)"
msgid "UpDate"
msgstr "更新"
msgid "Local Network"
msgstr "内部网络地址"
msgid "Error: LAN IP Address Get Error, Please Check The LAN Interface Setting or Choose the Correct Interface in the Setting!"
msgstr "错误LAN IP 地址获取失败,请检查 LAN 接口设置或在插件设置中选择正确的 LAN 接口名称"
msgid "Warning: Skiped The Custom Rule Because Group & Proxy Not Found:"
msgstr "警告:因未找到对应的策略组或代理,为避免启动失败,已跳过此条自定义规则的添加:"
msgid "Disable quic-go GSO Support"
msgstr "禁用 quic-go GSO 支持"
msgid "Suggestion: If Encountering Issues With QUIC UDP on The Linux Kernel Version Above 6.6, Please Try to Enable."
msgstr "建议: 如果固件 Linux 核心版本在 6.6 以上时遇到 quic-go 的 UDP 连接问题,请尝试启用。"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
#'www.baidu.com': '114.114.114.114' #'www.baidu.com': '114.114.114.114'
#'+.internal.crop.com': '10.0.0.1' #'+.internal.crop.com': '10.0.0.1'
#"_vlmcs._tcp.lan": '127.0.0.1:53'
#"geosite:category-games@cn": [https://doh.pub/dns-query, 114.114.114.114, 223.5.5.5] #"geosite:category-games@cn": [https://doh.pub/dns-query, 114.114.114.114, 223.5.5.5]
#"geosite:google": [tls://8.8.4.4, https://1.0.0.1/dns-query] #"geosite:google": [tls://8.8.4.4, https://1.0.0.1/dns-query]
#"geosite:cn": [https://doh.pub/dns-query, 114.114.114.114, 223.5.5.5] #"geosite:cn": [https://doh.pub/dns-query, 114.114.114.114, 223.5.5.5]

View File

@ -7,7 +7,7 @@ sniffer:
parse-pure-ip: true parse-pure-ip: true
# 是否使用嗅探结果作为实际访问,默认 true # 是否使用嗅探结果作为实际访问,默认 true
# 全局配置,优先级低于 sniffer.sniff 实际配置 # 全局配置,优先级低于 sniffer.sniff 实际配置
override-destination: false override-destination: true
sniff: # TLS 和 QUIC 默认如果不配置 ports 默认嗅探 443 sniff: # TLS 和 QUIC 默认如果不配置 ports 默认嗅探 443
QUIC: QUIC:
ports: [ 443 ] ports: [ 443 ]

View File

@ -21,28 +21,45 @@ mkdir -p /etc/openclash/core
mkdir -p /etc/openclash/history mkdir -p /etc/openclash/history
mkdir -p /usr/share/openclash/backup mkdir -p /usr/share/openclash/backup
#Backup
cp -f "/etc/config/openclash" "/usr/share/openclash/backup/openclash" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_rules.list" "/usr/share/openclash/backup/openclash_custom_rules.list" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_rules_2.list" "/usr/share/openclash/backup/openclash_custom_rules_2.list" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_hosts.list" "/usr/share/openclash/backup/openclash_custom_hosts.list" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_fake_filter.list" "/usr/share/openclash/backup/openclash_custom_fake_filter.list" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_domain_dns.list" "/usr/share/openclash/backup/openclash_custom_domain_dns.list" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_domain_dns_policy.list" "/usr/share/openclash/backup/openclash_custom_domain_dns_policy.list" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_fallback_filter.yaml" "/usr/share/openclash/backup/openclash_custom_fallback_filter.yaml" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_sniffer.yaml" "/usr/share/openclash/backup/openclash_custom_sniffer.yaml" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_localnetwork_ipv4.list" "/usr/share/openclash/backup/openclash_custom_localnetwork_ipv4.list" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_localnetwork_ipv6.list" "/usr/share/openclash/backup/openclash_custom_localnetwork_ipv6.list" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_chnroute_pass.list" "/usr/share/openclash/backup/openclash_custom_chnroute_pass.list" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_chnroute6_pass.list" "/usr/share/openclash/backup/openclash_custom_chnroute6_pass.list" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_firewall_rules.sh" "/usr/share/openclash/backup/openclash_custom_firewall_rules.sh" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_overwrite.sh" "/usr/share/openclash/backup/openclash_custom_overwrite.sh" >/dev/null 2>&1
mkdir -p /lib/upgrade/keep.d mkdir -p /lib/upgrade/keep.d
cat > "/lib/upgrade/keep.d/luci-app-openclash" <<-EOF cat > "/lib/upgrade/keep.d/luci-app-openclash" <<-EOF
/etc/openclash/ /etc/openclash/
EOF EOF
#Set Chnroute Format
FW4=$(command -v fw4)
if [ -n "$FW4" ]; then
#v4
if [ -z "$(cat "/etc/openclash/china_ip_route.ipset" |grep "define china_ip_route")" ]; then
echo "define china_ip_route = {" >/tmp/china_ip_route.list
awk '!/^$/&&!/^#/{printf(" %s,'" "'\n",$0)}' /etc/openclash/china_ip_route.ipset >>/tmp/china_ip_route.list
echo "}" >>/tmp/china_ip_route.list
echo "add set inet fw4 china_ip_route { type ipv4_addr; flags interval; auto-merge; }" >>/tmp/china_ip_route.list
echo 'add element inet fw4 china_ip_route $china_ip_route' >>/tmp/china_ip_route.list
fi
#v6
if [ -z "$(cat "/etc/openclash/china_ip6_route.ipset" |grep "define china_ip6_route")" ]; then
echo "define china_ip6_route = {" >/tmp/china_ip6_route.list
awk '!/^$/&&!/^#/{printf(" %s,'" "'\n",$0)}' /etc/openclash/china_ip6_route.ipset >>/tmp/china_ip6_route.list
echo "}" >>/tmp/china_ip6_route.list
echo "add set inet fw4 china_ip6_route { type ipv6_addr; flags interval; auto-merge; }" >>/tmp/china_ip6_route.list
echo 'add element inet fw4 china_ip6_route $china_ip6_route' >>/tmp/china_ip6_route.list
fi
else
#v4
if [ -z "$(cat "/etc/openclash/china_ip_route.ipset" |grep "create china_ip_route")" ]; then
echo "create china_ip_route hash:net family inet hashsize 1024 maxelem 1000000" >/tmp/china_ip_route.list
awk '!/^$/&&!/^#/{printf("add china_ip_route %s'" "'\n",$0)}' /etc/openclash/china_ip_route.ipset >>/tmp/china_ip_route.list
fi
#v6
if [ -z "$(cat "/etc/openclash/china_ip6_route.ipset" |grep "create china_ip6_route")" ]; then
echo "create china_ip6_route hash:net family inet6 hashsize 1024 maxelem 1000000" >/tmp/china_ip6_route.list
awk '!/^$/&&!/^#/{printf("add china_ip6_route %s'" "'\n",$0)}' /etc/openclash/china_ip6_route.ipset >>/tmp/china_ip6_route.list
fi
fi
mv -f /tmp/china_ip_route.list /etc/openclash/china_ip_route.ipset >/dev/null 2>&1
mv -f /tmp/china_ip6_route.list /etc/openclash/china_ip6_route.ipset >/dev/null 2>&1
#Set Dashboard Secret #Set Dashboard Secret
if [ -z "$(uci -q get openclash.config.dashboard_password)" ]; then if [ -z "$(uci -q get openclash.config.dashboard_password)" ]; then
uci -q set openclash.config.dashboard_password="$(tr -cd 'a-zA-Z0-9' </dev/urandom 2>/dev/null| head -c8 || date +%N| md5sum |head -c8)" uci -q set openclash.config.dashboard_password="$(tr -cd 'a-zA-Z0-9' </dev/urandom 2>/dev/null| head -c8 || date +%N| md5sum |head -c8)"
@ -100,12 +117,44 @@ fi
uci -q commit openclash uci -q commit openclash
#Backup
cp -f "/etc/config/openclash" "/usr/share/openclash/backup/openclash" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_rules.list" "/usr/share/openclash/backup/openclash_custom_rules.list" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_rules_2.list" "/usr/share/openclash/backup/openclash_custom_rules_2.list" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_hosts.list" "/usr/share/openclash/backup/openclash_custom_hosts.list" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_fake_filter.list" "/usr/share/openclash/backup/openclash_custom_fake_filter.list" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_domain_dns.list" "/usr/share/openclash/backup/openclash_custom_domain_dns.list" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_domain_dns_policy.list" "/usr/share/openclash/backup/openclash_custom_domain_dns_policy.list" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_fallback_filter.yaml" "/usr/share/openclash/backup/openclash_custom_fallback_filter.yaml" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_sniffer.yaml" "/usr/share/openclash/backup/openclash_custom_sniffer.yaml" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_localnetwork_ipv4.list" "/usr/share/openclash/backup/openclash_custom_localnetwork_ipv4.list" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_localnetwork_ipv6.list" "/usr/share/openclash/backup/openclash_custom_localnetwork_ipv6.list" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_chnroute_pass.list" "/usr/share/openclash/backup/openclash_custom_chnroute_pass.list" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_chnroute6_pass.list" "/usr/share/openclash/backup/openclash_custom_chnroute6_pass.list" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_firewall_rules.sh" "/usr/share/openclash/backup/openclash_custom_firewall_rules.sh" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_overwrite.sh" "/usr/share/openclash/backup/openclash_custom_overwrite.sh" >/dev/null 2>&1
cp -f "/etc/openclash/custom/openclash_custom_overwrite.sh" "/usr/share/openclash/backup/openclash_custom_overwrite.sh" >/dev/null 2>&1
cp -f "/etc/openclash/china_ip_route.ipset" "/usr/share/openclash/backup/china_ip_route.ipset" >/dev/null 2>&1
cp -f "/etc/openclash/china_ip6_route.ipset" "/usr/share/openclash/backup/china_ip6_route.ipset" >/dev/null 2>&1
#Restore #Restore
if [ -f "/tmp/openclash.bak" ]; then if [ -f "/tmp/openclash.bak" ]; then
#delete old geosite database first #delete old geosite database first
if [ "/etc/openclash/GeoSite.dat" -nt "/tmp/openclash/GeoSite.dat" ]; then if [ "/etc/openclash/GeoSite.dat" -nt "/tmp/openclash/GeoSite.dat" ]; then
rm -rf "/tmp/openclash/GeoSite.dat" >/dev/null 2>&1 rm -rf "/tmp/openclash/GeoSite.dat" >/dev/null 2>&1
fi fi
#delete error china_ip_route first
if [ -n "$FW4" ]; then
if [ -z "$(cat "/tmp/openclash/china_ip_route.ipset" |grep "define china_ip_route")" ]; then
rm -f "/tmp/openclash/china_ip_route.ipset" >/dev/null 2>&1
rm -f "/tmp/openclash/china_ip6_route.ipset" >/dev/null 2>&1
fi
else
if [ -z "$(cat "/tmp/openclash/china_ip_route.ipset" |grep "create china_ip_route")" ]; then
rm -f "/tmp/openclash/china_ip_route.ipset" >/dev/null 2>&1
rm -f "/tmp/openclash/china_ip6_route.ipset" >/dev/null 2>&1
fi
fi
mv -f "/tmp/openclash.bak" "/etc/config/openclash" >/dev/null 2>&1 mv -f "/tmp/openclash.bak" "/etc/config/openclash" >/dev/null 2>&1
cp -rf "/tmp/openclash/." "/etc/openclash/" >/dev/null 2>&1 cp -rf "/tmp/openclash/." "/etc/openclash/" >/dev/null 2>&1
if [ -d "/tmp/openclash_dashboard/" ]; then if [ -d "/tmp/openclash_dashboard/" ]; then

View File

@ -7,9 +7,11 @@ set_lock() {
del_lock() { del_lock() {
flock -u 884 2>/dev/null flock -u 884 2>/dev/null
rm -rf "/tmp/lock/openclash_clash_version.lock" rm -rf "/tmp/lock/openclash_clash_version.lock" 2>/dev/null
} }
set_lock
TIME=$(date "+%Y-%m-%d-%H") TIME=$(date "+%Y-%m-%d-%H")
CHTIME=$(date "+%Y-%m-%d-%H" -r "/tmp/clash_last_version" 2>/dev/null) CHTIME=$(date "+%Y-%m-%d-%H" -r "/tmp/clash_last_version" 2>/dev/null)
LAST_OPVER="/tmp/clash_last_version" LAST_OPVER="/tmp/clash_last_version"
@ -19,7 +21,6 @@ if [ -n "$1" ]; then
github_address_mod="$1" github_address_mod="$1"
fi fi
LOG_FILE="/tmp/openclash.log" LOG_FILE="/tmp/openclash.log"
set_lock
if [ "$TIME" != "$CHTIME" ]; then if [ "$TIME" != "$CHTIME" ]; then
if [ "$github_address_mod" != "0" ]; then if [ "$github_address_mod" != "0" ]; then

View File

@ -3,6 +3,7 @@
. /usr/share/openclash/ruby.sh . /usr/share/openclash/ruby.sh
. /usr/share/openclash/openclash_ps.sh . /usr/share/openclash/openclash_ps.sh
. /usr/share/openclash/log.sh . /usr/share/openclash/log.sh
. /lib/functions/procd.sh
set_lock() { set_lock() {
exec 889>"/tmp/lock/openclash_subs.lock" 2>/dev/null exec 889>"/tmp/lock/openclash_subs.lock" 2>/dev/null
@ -11,9 +12,11 @@ set_lock() {
del_lock() { del_lock() {
flock -u 889 2>/dev/null flock -u 889 2>/dev/null
rm -rf "/tmp/lock/openclash_subs.lock" rm -rf "/tmp/lock/openclash_subs.lock" 2>/dev/null
} }
set_lock
LOGTIME=$(echo $(date "+%Y-%m-%d %H:%M:%S")) LOGTIME=$(echo $(date "+%Y-%m-%d %H:%M:%S"))
LOG_FILE="/tmp/openclash.log" LOG_FILE="/tmp/openclash.log"
CFG_FILE="/tmp/yaml_sub_tmp_config.yaml" CFG_FILE="/tmp/yaml_sub_tmp_config.yaml"
@ -26,7 +29,6 @@ CLASH="/etc/openclash/clash"
CLASH_CONFIG="/etc/openclash" CLASH_CONFIG="/etc/openclash"
restart=0 restart=0
only_download=0 only_download=0
set_lock
urlencode() { urlencode() {
if [ "$#" -eq 1 ]; then if [ "$#" -eq 1 ]; then
@ -34,12 +36,7 @@ urlencode() {
fi fi
} }
kill_watchdog() { kill_streaming_unlock() {
watchdog_pids=$(unify_ps_pids "openclash_watchdog.sh")
for watchdog_pid in $watchdog_pids; do
kill -9 "$watchdog_pid" >/dev/null 2>&1
done
streaming_unlock_pids=$(unify_ps_pids "openclash_streaming_unlock.lua") streaming_unlock_pids=$(unify_ps_pids "openclash_streaming_unlock.lua")
for streaming_unlock_pid in $streaming_unlock_pids; do for streaming_unlock_pid in $streaming_unlock_pids; do
kill -9 "$streaming_unlock_pid" >/dev/null 2>&1 kill -9 "$streaming_unlock_pid" >/dev/null 2>&1
@ -50,7 +47,7 @@ config_test()
{ {
if [ -f "$CLASH" ]; then if [ -f "$CLASH" ]; then
LOG_OUT "Config File Download Successful, Test If There is Any Errors..." LOG_OUT "Config File Download Successful, Test If There is Any Errors..."
test_info=$(nohup $CLASH -t -d $CLASH_CONFIG -f "$CFG_FILE") test_info=$($CLASH -t -d $CLASH_CONFIG -f "$CFG_FILE")
local IFS=$'\n' local IFS=$'\n'
for i in $test_info; do for i in $test_info; do
if [ -n "$(echo "$i" |grep "configuration file")" ]; then if [ -n "$(echo "$i" |grep "configuration file")" ]; then
@ -254,14 +251,15 @@ change_dns()
{ {
if pidof clash >/dev/null; then if pidof clash >/dev/null; then
/etc/init.d/openclash reload "restore" >/dev/null 2>&1 /etc/init.d/openclash reload "restore" >/dev/null 2>&1
[ "$(unify_ps_status "openclash_watchdog.sh")" -eq 0 ] && [ "$(unify_ps_prevent)" -eq 0 ] && nohup /usr/share/openclash/openclash_watchdog.sh & procd_send_signal "openclash" "openclash-watchdog" CONT
fi fi
} }
config_download_direct() config_download_direct()
{ {
if pidof clash >/dev/null && [ "$router_self_proxy" = 1 ]; then if pidof clash >/dev/null && [ "$router_self_proxy" = 1 ]; then
kill_watchdog kill_streaming_unlock
procd_send_signal "openclash" "openclash-watchdog" STOP
/etc/init.d/openclash reload "revert" >/dev/null 2>&1 /etc/init.d/openclash reload "revert" >/dev/null 2>&1
sleep 3 sleep 3
@ -358,7 +356,11 @@ convert_custom_param()
return return
fi fi
local p_name="${1%%=*}" p_value="${1#*=}" local p_name="${1%%=*}" p_value="${1#*=}"
append_custom_params="${append_custom_params}&${p_name}=$(urlencode "$p_value")" if [ -z "$append_custom_params" ]; then
append_custom_params="&${p_name}=$(urlencode "$p_value")"
else
append_custom_params="${append_custom_params}\`$(urlencode "$p_value")"
fi
} }
sub_info_get() sub_info_get()
@ -383,7 +385,13 @@ sub_info_get()
config_get "sub_ua" "$section" "sub_ua" "Clash" config_get "sub_ua" "$section" "sub_ua" "Clash"
if [ "$enabled" -eq 0 ]; then if [ "$enabled" -eq 0 ]; then
return if [ -n "$2" ]; then
if [ "$2" != "$CONFIG_FILE" ] && [ "$2" != "$name" ]; then
return
fi
else
return
fi
fi fi
if [ -z "$address" ]; then if [ -z "$address" ]; then
@ -415,7 +423,7 @@ sub_info_get()
BACKPACK_FILE="/etc/openclash/backup/$name.yaml" BACKPACK_FILE="/etc/openclash/backup/$name.yaml"
fi fi
if [ -n "$2" ] && [ "$2" != "$CONFIG_FILE" ]; then if [ -n "$2" ] && [ "$2" != "$CONFIG_FILE" ] && [ "$2" != "$name" ]; then
return return
fi fi
@ -508,13 +516,13 @@ config_foreach sub_info_get "config_subscribe" "$1"
uci -q delete openclash.config.config_update_path uci -q delete openclash.config.config_update_path
uci commit openclash uci commit openclash
if [ "$restart" -eq 1 ] && [ "$(unify_ps_prevent)" -eq 0 ] && [ "$(find /tmp/lock/ |grep -v "openclash.lock" |grep -c "openclash")" -le 1 ]; then if [ "$restart" -eq 1 ] && [ "$(unify_ps_prevent)" -eq 0 ]; then
/etc/init.d/openclash restart >/dev/null 2>&1 & /etc/init.d/openclash restart >/dev/null 2>&1 &
elif [ "$restart" -eq 0 ] && [ "$(unify_ps_prevent)" -eq 0 ] && [ "$(find /tmp/lock/ |grep -v "openclash.lock" |grep -c "openclash")" -le 1 ] && [ "$(uci -q get openclash.config.restart)" -eq 1 ]; then elif [ "$restart" -eq 0 ] && [ "$(unify_ps_prevent)" -eq 0 ] && [ "$(uci -q get openclash.config.restart)" -eq 1 ]; then
/etc/init.d/openclash restart >/dev/null 2>&1 & /etc/init.d/openclash restart >/dev/null 2>&1 &
uci -q set openclash.config.restart=0 uci -q set openclash.config.restart=0
uci -q commit openclash uci -q commit openclash
elif [ "$restart" -eq 1 ] && [ "$(unify_ps_prevent)" -eq 0 ] && [ "$(find /tmp/lock/ |grep -v "openclash.lock" |grep -c "openclash")" -gt 1 ]; then elif [ "$restart" -eq 1 ] && [ "$(unify_ps_prevent)" -eq 0 ]; then
uci -q set openclash.config.restart=1 uci -q set openclash.config.restart=1
uci -q commit openclash uci -q commit openclash
else else

View File

@ -2,7 +2,6 @@
. /usr/share/openclash/openclash_ps.sh . /usr/share/openclash/openclash_ps.sh
. /usr/share/openclash/log.sh . /usr/share/openclash/log.sh
FW4=$(command -v fw4)
set_lock() { set_lock() {
exec 879>"/tmp/lock/openclash_chn.lock" 2>/dev/null exec 879>"/tmp/lock/openclash_chn.lock" 2>/dev/null
@ -11,9 +10,12 @@
del_lock() { del_lock() {
flock -u 879 2>/dev/null flock -u 879 2>/dev/null
rm -rf "/tmp/lock/openclash_chn.lock" rm -rf "/tmp/lock/openclash_chn.lock" 2>/dev/null
} }
set_lock
FW4=$(command -v fw4)
china_ip_route=$(uci -q get openclash.config.china_ip_route) china_ip_route=$(uci -q get openclash.config.china_ip_route)
china_ip6_route=$(uci -q get openclash.config.china_ip6_route) china_ip6_route=$(uci -q get openclash.config.china_ip6_route)
CHNR_CUSTOM_URL=$(uci -q get openclash.config.chnr_custom_url) CHNR_CUSTOM_URL=$(uci -q get openclash.config.chnr_custom_url)
@ -24,7 +26,7 @@
en_mode=$(uci -q get openclash.config.en_mode) en_mode=$(uci -q get openclash.config.en_mode)
LOG_FILE="/tmp/openclash.log" LOG_FILE="/tmp/openclash.log"
restart=0 restart=0
set_lock
if [ "$small_flash_memory" != "1" ]; then if [ "$small_flash_memory" != "1" ]; then
chnr_path="/etc/openclash/china_ip_route.ipset" chnr_path="/etc/openclash/china_ip_route.ipset"
@ -111,9 +113,9 @@
LOG_OUT "Chnroute6 Cidr List Update Error, Please Try Again Later..." LOG_OUT "Chnroute6 Cidr List Update Error, Please Try Again Later..."
fi fi
if [ "$restart" -eq 1 ] && [ "$(unify_ps_prevent)" -eq 0 ] && [ "$(find /tmp/lock/ |grep -v "openclash.lock" |grep -c "openclash")" -le 1 ]; then if [ "$restart" -eq 1 ] && [ "$(unify_ps_prevent)" -eq 0 ]; then
/etc/init.d/openclash restart >/dev/null 2>&1 & /etc/init.d/openclash restart >/dev/null 2>&1 &
elif [ "$restart" -eq 0 ] && [ "$(unify_ps_prevent)" -eq 0 ] && [ "$(find /tmp/lock/ |grep -v "openclash.lock" |grep -c "openclash")" -le 1 ] && [ "$(uci -q get openclash.config.restart)" -eq 1 ]; then elif [ "$restart" -eq 0 ] && [ "$(unify_ps_prevent)" -eq 0 ] && [ "$(uci -q get openclash.config.restart)" -eq 1 ]; then
/etc/init.d/openclash restart >/dev/null 2>&1 & /etc/init.d/openclash restart >/dev/null 2>&1 &
uci -q set openclash.config.restart=0 uci -q set openclash.config.restart=0
uci -q commit openclash uci -q commit openclash

View File

@ -3,6 +3,18 @@
. /usr/share/openclash/openclash_ps.sh . /usr/share/openclash/openclash_ps.sh
. /usr/share/openclash/log.sh . /usr/share/openclash/log.sh
set_lock() {
exec 872>"/tmp/lock/openclash_core.lock" 2>/dev/null
flock -x 872 2>/dev/null
}
del_lock() {
flock -u 872 2>/dev/null
rm -rf "/tmp/lock/openclash_core.lock" 2>/dev/null
}
set_lock
github_address_mod=$(uci -q get openclash.config.github_address_mod || echo 0) github_address_mod=$(uci -q get openclash.config.github_address_mod || echo 0)
if [ "$github_address_mod" = "0" ] && [ -z "$(echo $2 2>/dev/null |grep -E 'http|one_key_update')" ] && [ -z "$(echo $3 2>/dev/null |grep 'http')" ]; then if [ "$github_address_mod" = "0" ] && [ -z "$(echo $2 2>/dev/null |grep -E 'http|one_key_update')" ] && [ -z "$(echo $3 2>/dev/null |grep 'http')" ]; then
LOG_OUT "Tip: If the download fails, try setting the CDN in Overwrite Settings - General Settings - Github Address Modify Options" LOG_OUT "Tip: If the download fails, try setting the CDN in Overwrite Settings - General Settings - Github Address Modify Options"
@ -29,6 +41,7 @@ fi
if [ ! -f "/tmp/clash_last_version" ]; then if [ ! -f "/tmp/clash_last_version" ]; then
LOG_OUT "Error: 【"$CORE_TYPE"】Core Version Check Error, Please Try Again Later..." LOG_OUT "Error: 【"$CORE_TYPE"】Core Version Check Error, Please Try Again Later..."
SLOG_CLEAN SLOG_CLEAN
del_lock
exit 0 exit 0
fi fi
@ -77,6 +90,7 @@ if [ "$CORE_CV" != "$CORE_LV" ] || [ -z "$CORE_CV" ]; then
LOG_OUT "【"$CORE_TYPE"】Core Update Failed. Please Make Sure Enough Flash Memory Space or Selected Correct Core Platform And Try Again!" LOG_OUT "【"$CORE_TYPE"】Core Update Failed. Please Make Sure Enough Flash Memory Space or Selected Correct Core Platform And Try Again!"
rm -rf /tmp/clash_meta >/dev/null 2>&1 rm -rf /tmp/clash_meta >/dev/null 2>&1
SLOG_CLEAN SLOG_CLEAN
del_lock
exit 0 exit 0
fi fi
@ -85,10 +99,10 @@ if [ "$CORE_CV" != "$CORE_LV" ] || [ -z "$CORE_CV" ]; then
if [ "$?" == "0" ]; then if [ "$?" == "0" ]; then
LOG_OUT "【"$CORE_TYPE"】Core Update Successful!" LOG_OUT "【"$CORE_TYPE"】Core Update Successful!"
if [ "$if_restart" -eq 1 ]; then if [ "$if_restart" -eq 1 ]; then
uci -q set openclash.config.config_reload=1 uci -q set openclash.config.restart=1
uci -q commit openclash uci -q commit openclash
if ([ -z "$2" ] || ([ -n "$2" ] && [ "$2" != "one_key_update" ])) && [ "$(find /tmp/lock/ |grep -v "openclash.lock" |grep -c "openclash")" -le 1 ] && [ "$(unify_ps_prevent)" -eq 0 ]; then if ([ -z "$2" ] || ([ -n "$2" ] && [ "$2" != "one_key_update" ])) && [ "$(unify_ps_prevent)" -eq 0 ]; then
uci -q set openclash.config.config_reload=0 uci -q set openclash.config.restart=0
uci -q commit openclash uci -q commit openclash
/etc/init.d/openclash restart >/dev/null 2>&1 & /etc/init.d/openclash restart >/dev/null 2>&1 &
fi fi
@ -113,4 +127,4 @@ else
fi fi
rm -rf /tmp/clash_meta >/dev/null 2>&1 rm -rf /tmp/clash_meta >/dev/null 2>&1
del_lock

View File

@ -9,7 +9,7 @@ set_lock() {
del_lock() { del_lock() {
flock -u 885 2>/dev/null flock -u 885 2>/dev/null
rm -rf "/tmp/lock/openclash_debug.lock" rm -rf "/tmp/lock/openclash_debug.lock" 2>/dev/null
} }
ipk_v() ipk_v()
@ -21,10 +21,10 @@ ipk_v()
fi fi
} }
DEBUG_LOG="/tmp/openclash_debug.log"
LOGTIME=$(echo $(date "+%Y-%m-%d %H:%M:%S"))
set_lock set_lock
DEBUG_LOG="/tmp/openclash_debug.log"
LOGTIME=$(echo $(date "+%Y-%m-%d %H:%M:%S"))
enable_custom_dns=$(uci -q get openclash.config.enable_custom_dns) enable_custom_dns=$(uci -q get openclash.config.enable_custom_dns)
rule_source=$(uci -q get openclash.config.rule_source) rule_source=$(uci -q get openclash.config.rule_source)
enable_custom_clash_rules=$(uci -q get openclash.config.enable_custom_clash_rules) enable_custom_clash_rules=$(uci -q get openclash.config.enable_custom_clash_rules)
@ -139,15 +139,11 @@ cat >> "$DEBUG_LOG" <<-EOF
dnsmasq-full: $(ts_re "$(ipk_v "dnsmasq-full")") dnsmasq-full: $(ts_re "$(ipk_v "dnsmasq-full")")
dnsmasq-full(ipset): $(ts_re "$(dnsmasq --version |grep -v no-ipset |grep ipset)") dnsmasq-full(ipset): $(ts_re "$(dnsmasq --version |grep -v no-ipset |grep ipset)")
dnsmasq-full(nftset): $(ts_re "$(dnsmasq --version |grep nftset)") dnsmasq-full(nftset): $(ts_re "$(dnsmasq --version |grep nftset)")
coreutils: $(ts_re "$(ipk_v "coreutils")")
coreutils-nohup: $(ts_re "$(ipk_v "coreutils-nohup")")
bash: $(ts_re "$(ipk_v "bash")") bash: $(ts_re "$(ipk_v "bash")")
curl: $(ts_re "$(ipk_v "curl")") curl: $(ts_re "$(ipk_v "curl")")
ca-certificates: $(ts_re "$(ipk_v "ca-certificates")") ca-bundle: $(ts_re "$(ipk_v "ca-bundle")")
ipset: $(ts_re "$(ipk_v "ipset")") ipset: $(ts_re "$(ipk_v "ipset")")
ip-full: $(ts_re "$(ipk_v "ip-full")") ip-full: $(ts_re "$(ipk_v "ip-full")")
libcap: $(ts_re "$(ipk_v "libcap")")
libcap-bin: $(ts_re "$(ipk_v "libcap-bin")")
ruby: $(ts_re "$(ipk_v "ruby")") ruby: $(ts_re "$(ipk_v "ruby")")
ruby-yaml: $(ts_re "$(ipk_v "ruby-yaml")") ruby-yaml: $(ts_re "$(ipk_v "ruby-yaml")")
ruby-psych: $(ts_re "$(ipk_v "ruby-psych")") ruby-psych: $(ts_re "$(ipk_v "ruby-psych")")
@ -182,7 +178,6 @@ cat >> "$DEBUG_LOG" <<-EOF
运行状态: 运行中 运行状态: 运行中
运行内核:$core_type 运行内核:$core_type
进程pid: $(pidof clash) 进程pid: $(pidof clash)
运行权限: `getpcaps $(pidof clash)`
运行用户: $(ps |grep "/etc/openclash/clash" |grep -v grep |awk '{print $2}' 2>/dev/null) 运行用户: $(ps |grep "/etc/openclash/clash" |grep -v grep |awk '{print $2}' 2>/dev/null)
EOF EOF
else else

View File

@ -2,6 +2,18 @@
. /usr/share/openclash/log.sh . /usr/share/openclash/log.sh
. /lib/functions.sh . /lib/functions.sh
set_lock() {
exec 871>"/tmp/lock/openclash_dashboard.lock" 2>/dev/null
flock -x 871 2>/dev/null
}
del_lock() {
flock -u 871 2>/dev/null
rm -rf "/tmp/lock/openclash_dashboard.lock" 2>/dev/null
}
set_lock
DASH_NAME="$1" DASH_NAME="$1"
DASH_TYPE="$2" DASH_TYPE="$2"
DASH_FILE_DIR="/tmp/dash.zip" DASH_FILE_DIR="/tmp/dash.zip"
@ -28,6 +40,11 @@
DOWNLOAD_PATH="https://codeload.github.com/MetaCubeX/Yacd-meta/zip/refs/heads/gh-pages" DOWNLOAD_PATH="https://codeload.github.com/MetaCubeX/Yacd-meta/zip/refs/heads/gh-pages"
FILE_PATH_INCLUDE="Yacd-meta-gh-pages" FILE_PATH_INCLUDE="Yacd-meta-gh-pages"
fi fi
elif [ "$DASH_NAME" == "zashboard" ]; then
UNPACK_FILE_DIR="/usr/share/openclash/ui/zashboard/"
BACKUP_FILE_DIR="/usr/share/openclash/ui/zashboard_backup/"
DOWNLOAD_PATH="https://codeload.github.com/Zephyruso/zashboard/zip/refs/heads/gh-pages"
FILE_PATH_INCLUDE="zashboard-gh-pages"
else else
UNPACK_FILE_DIR="/usr/share/openclash/ui/metacubexd/" UNPACK_FILE_DIR="/usr/share/openclash/ui/metacubexd/"
BACKUP_FILE_DIR="/usr/share/openclash/ui/metacubexd_backup/" BACKUP_FILE_DIR="/usr/share/openclash/ui/metacubexd_backup/"
@ -49,6 +66,7 @@
rm -rf "$BACKUP_FILE_DIR" >/dev/null 2>&1 rm -rf "$BACKUP_FILE_DIR" >/dev/null 2>&1
rm -rf "$DASH_FILE_TMP" >/dev/null 2>&1 rm -rf "$DASH_FILE_TMP" >/dev/null 2>&1
LOG_OUT "Control Panel【$DASH_NAME - $DASH_TYPE】Download Successful!" && SLOG_CLEAN LOG_OUT "Control Panel【$DASH_NAME - $DASH_TYPE】Download Successful!" && SLOG_CLEAN
del_lock
exit 1 exit 1
else else
LOG_OUT "Control Panel【$DASH_NAME - $DASH_TYPE】Unzip Error!" && SLOG_CLEAN LOG_OUT "Control Panel【$DASH_NAME - $DASH_TYPE】Unzip Error!" && SLOG_CLEAN
@ -56,6 +74,7 @@
rm -rf "$DASH_FILE_DIR" >/dev/null 2>&1 rm -rf "$DASH_FILE_DIR" >/dev/null 2>&1
rm -rf "$BACKUP_FILE_DIR" >/dev/null 2>&1 rm -rf "$BACKUP_FILE_DIR" >/dev/null 2>&1
rm -rf "$DASH_FILE_TMP" >/dev/null 2>&1 rm -rf "$DASH_FILE_TMP" >/dev/null 2>&1
del_lock
exit 2 exit 2
fi fi
else else
@ -64,6 +83,7 @@
rm -rf "$DASH_FILE_DIR" >/dev/null 2>&1 rm -rf "$DASH_FILE_DIR" >/dev/null 2>&1
rm -rf "$BACKUP_FILE_DIR" >/dev/null 2>&1 rm -rf "$BACKUP_FILE_DIR" >/dev/null 2>&1
rm -rf "$DASH_FILE_TMP" >/dev/null 2>&1 rm -rf "$DASH_FILE_TMP" >/dev/null 2>&1
del_lock
exit 2 exit 2
fi fi
else else
@ -72,5 +92,8 @@
rm -rf "$DASH_FILE_DIR" >/dev/null 2>&1 rm -rf "$DASH_FILE_DIR" >/dev/null 2>&1
rm -rf "$DASH_FILE_TMP" >/dev/null 2>&1 rm -rf "$DASH_FILE_TMP" >/dev/null 2>&1
LOG_OUT "Control Panel【$DASH_NAME - $DASH_TYPE】Download Error!" && SLOG_CLEAN LOG_OUT "Control Panel【$DASH_NAME - $DASH_TYPE】Download Error!" && SLOG_CLEAN
del_lock
exit 0 exit 0
fi fi
del_lock

View File

@ -2,11 +2,23 @@
. /usr/share/openclash/log.sh . /usr/share/openclash/log.sh
. /lib/functions.sh . /lib/functions.sh
urlencode() { urlencode() {
if [ "$#" -eq 1 ]; then if [ "$#" -eq 1 ]; then
echo "$(/usr/share/openclash/openclash_urlencode.lua "$1")" echo "$(/usr/share/openclash/openclash_urlencode.lua "$1")"
fi fi
} }
set_lock() {
exec 870>"/tmp/lock/openclash_rulelist.lock" 2>/dev/null
flock -x 870 2>/dev/null
}
del_lock() {
flock -u 870 2>/dev/null
rm -rf "/tmp/lock/openclash_rulelist.lock" 2>/dev/null
}
set_lock
RULE_FILE_NAME="$1" RULE_FILE_NAME="$1"
LOG_FILE="/tmp/openclash.log" LOG_FILE="/tmp/openclash.log"
@ -25,6 +37,7 @@ urlencode() {
if [ -z "$DOWNLOAD_PATH" ]; then if [ -z "$DOWNLOAD_PATH" ]; then
LOG_OUT "Rule File【$RULE_FILE_NAME】Download Error!" && SLOG_CLEAN LOG_OUT "Rule File【$RULE_FILE_NAME】Download Error!" && SLOG_CLEAN
del_lock
exit 0 exit 0
fi fi
@ -70,15 +83,20 @@ urlencode() {
fi fi
rm -rf "$TMP_RULE_DIR" >/dev/null 2>&1 rm -rf "$TMP_RULE_DIR" >/dev/null 2>&1
LOG_OUT "Rule File【$RULE_FILE_NAME】Download Successful!" && SLOG_CLEAN LOG_OUT "Rule File【$RULE_FILE_NAME】Download Successful!" && SLOG_CLEAN
del_lock
exit 1 exit 1
else else
LOG_OUT "Rule File【$RULE_FILE_NAME】No Change, Do Nothing!" && SLOG_CLEAN LOG_OUT "Rule File【$RULE_FILE_NAME】No Change, Do Nothing!" && SLOG_CLEAN
rm -rf "$TMP_RULE_DIR" >/dev/null 2>&1 rm -rf "$TMP_RULE_DIR" >/dev/null 2>&1
rm -rf "$TMP_RULE_DIR_TMP" >/dev/null 2>&1 rm -rf "$TMP_RULE_DIR_TMP" >/dev/null 2>&1
del_lock
exit 2 exit 2
fi fi
else else
rm -rf "$TMP_RULE_DIR" >/dev/null 2>&1 rm -rf "$TMP_RULE_DIR" >/dev/null 2>&1
LOG_OUT "Rule File【$RULE_FILE_NAME】Download Error!" && SLOG_CLEAN LOG_OUT "Rule File【$RULE_FILE_NAME】Download Error!" && SLOG_CLEAN
del_lock
exit 0 exit 0
fi fi
del_lock

View File

@ -9,16 +9,17 @@
del_lock() { del_lock() {
flock -u 873 2>/dev/null flock -u 873 2>/dev/null
rm -rf "/tmp/lock/openclash_geoip.lock" rm -rf "/tmp/lock/openclash_geoip.lock" 2>/dev/null
} }
set_lock
small_flash_memory=$(uci get openclash.config.small_flash_memory 2>/dev/null) small_flash_memory=$(uci get openclash.config.small_flash_memory 2>/dev/null)
GEOIP_CUSTOM_URL=$(uci get openclash.config.geoip_custom_url 2>/dev/null) GEOIP_CUSTOM_URL=$(uci get openclash.config.geoip_custom_url 2>/dev/null)
github_address_mod=$(uci -q get openclash.config.github_address_mod || echo 0) github_address_mod=$(uci -q get openclash.config.github_address_mod || echo 0)
LOG_FILE="/tmp/openclash.log" LOG_FILE="/tmp/openclash.log"
restart=0 restart=0
set_lock
if [ "$small_flash_memory" != "1" ]; then if [ "$small_flash_memory" != "1" ]; then
geoip_path="/etc/openclash/GeoIP.dat" geoip_path="/etc/openclash/GeoIP.dat"
mkdir -p /etc/openclash mkdir -p /etc/openclash
@ -56,9 +57,9 @@
LOG_OUT "GeoIP Dat Update Error, Please Try Again Later..." LOG_OUT "GeoIP Dat Update Error, Please Try Again Later..."
fi fi
if [ "$restart" -eq 1 ] && [ "$(unify_ps_prevent)" -eq 0 ] && [ "$(find /tmp/lock/ |grep -v "openclash.lock" |grep -c "openclash")" -le 1 ]; then if [ "$restart" -eq 1 ] && [ "$(unify_ps_prevent)" -eq 0 ]; then
/etc/init.d/openclash restart >/dev/null 2>&1 & /etc/init.d/openclash restart >/dev/null 2>&1 &
elif [ "$restart" -eq 0 ] && [ "$(unify_ps_prevent)" -eq 0 ] && [ "$(find /tmp/lock/ |grep -v "openclash.lock" |grep -c "openclash")" -le 1 ] && [ "$(uci -q get openclash.config.restart)" -eq 1 ]; then elif [ "$restart" -eq 0 ] && [ "$(unify_ps_prevent)" -eq 0 ] && [ "$(uci -q get openclash.config.restart)" -eq 1 ]; then
/etc/init.d/openclash restart >/dev/null 2>&1 & /etc/init.d/openclash restart >/dev/null 2>&1 &
uci -q set openclash.config.restart=0 uci -q set openclash.config.restart=0
uci -q commit openclash uci -q commit openclash

View File

@ -9,15 +9,16 @@
del_lock() { del_lock() {
flock -u 874 2>/dev/null flock -u 874 2>/dev/null
rm -rf "/tmp/lock/openclash_geosite.lock" rm -rf "/tmp/lock/openclash_geosite.lock" 2>/dev/null
} }
set_lock
small_flash_memory=$(uci get openclash.config.small_flash_memory 2>/dev/null) small_flash_memory=$(uci get openclash.config.small_flash_memory 2>/dev/null)
GEOSITE_CUSTOM_URL=$(uci get openclash.config.geosite_custom_url 2>/dev/null) GEOSITE_CUSTOM_URL=$(uci get openclash.config.geosite_custom_url 2>/dev/null)
github_address_mod=$(uci -q get openclash.config.github_address_mod || echo 0) github_address_mod=$(uci -q get openclash.config.github_address_mod || echo 0)
LOG_FILE="/tmp/openclash.log" LOG_FILE="/tmp/openclash.log"
restart=0 restart=0
set_lock
if [ "$small_flash_memory" != "1" ]; then if [ "$small_flash_memory" != "1" ]; then
geosite_path="/etc/openclash/GeoSite.dat" geosite_path="/etc/openclash/GeoSite.dat"
@ -56,9 +57,9 @@
LOG_OUT "GeoSite Database Update Error, Please Try Again Later..." LOG_OUT "GeoSite Database Update Error, Please Try Again Later..."
fi fi
if [ "$restart" -eq 1 ] && [ "$(unify_ps_prevent)" -eq 0 ] && [ "$(find /tmp/lock/ |grep -v "openclash.lock" |grep -c "openclash")" -le 1 ]; then if [ "$restart" -eq 1 ] && [ "$(unify_ps_prevent)" -eq 0 ]; then
/etc/init.d/openclash restart >/dev/null 2>&1 & /etc/init.d/openclash restart >/dev/null 2>&1 &
elif [ "$restart" -eq 0 ] && [ "$(unify_ps_prevent)" -eq 0 ] && [ "$(find /tmp/lock/ |grep -v "openclash.lock" |grep -c "openclash")" -le 1 ] && [ "$(uci -q get openclash.config.restart)" -eq 1 ]; then elif [ "$restart" -eq 0 ] && [ "$(unify_ps_prevent)" -eq 0 ] && [ "$(uci -q get openclash.config.restart)" -eq 1 ]; then
/etc/init.d/openclash restart >/dev/null 2>&1 & /etc/init.d/openclash restart >/dev/null 2>&1 &
uci -q set openclash.config.restart=0 uci -q set openclash.config.restart=0
uci -q commit openclash uci -q commit openclash

View File

@ -4,6 +4,8 @@ require "nixio"
require "luci.util" require "luci.util"
require "luci.sys" require "luci.sys"
local ntm = require "luci.model.network".init() local ntm = require "luci.model.network".init()
local cidr = require "luci.ip"
local fs = require "luci.openclash"
local type = arg[1] local type = arg[1]
local rv = {} local rv = {}
local wan, wan6 local wan, wan6
@ -30,6 +32,7 @@ if wan then
for i = 1, #wan do for i = 1, #wan do
rv.wan[i] = { rv.wan[i] = {
ipaddr = wan[i]:ipaddr(), ipaddr = wan[i]:ipaddr(),
ip6addr = wan[i]:ip6addr(),
gwaddr = wan[i]:gwaddr(), gwaddr = wan[i]:gwaddr(),
netmask = wan[i]:netmask(), netmask = wan[i]:netmask(),
dns = wan[i]:dnsaddrs(), dns = wan[i]:dnsaddrs(),
@ -150,4 +153,33 @@ if type == "wanip6" then
end end
end end
if type == "lan_cidr" then
if wan then
for o = 1, #(rv.wan) do
if rv.wan[o].proto ~= "pppoe" then
if rv.wan[o].ipaddr and rv.wan[o].netmask then
local network = cidr.IPv4(rv.wan[o].ipaddr, rv.wan[o].netmask):network():string()
local prefix = cidr.IPv4(rv.wan[o].ipaddr, rv.wan[o].netmask):prefix()
print(network.."/"..prefix)
end
end
end
end
end
if type == "lan_cidr6" then
if wan then
for o = 1, #(rv.wan) do
if rv.wan[o].proto ~= "pppoe" then
if rv.wan[o].ip6addr then
local ip6, prefix = rv.wan[o].ip6addr:match("([^/]+)/(%d+)")
local network = cidr.IPv6(ip6, tonumber(prefix)):network():string()
local prefix = cidr.IPv6(ip6, tonumber(prefix)):prefix()
print(network.."/"..prefix)
end
end
end
end
end
os.exit(0) os.exit(0)

View File

@ -9,7 +9,7 @@ set_lock() {
del_lock() { del_lock() {
flock -u 881 2>/dev/null flock -u 881 2>/dev/null
rm -rf "/tmp/lock/openclash_history_get.lock" rm -rf "/tmp/lock/openclash_history_get.lock" 2>/dev/null
} }
close_all_conection() { close_all_conection() {
@ -24,8 +24,11 @@ close_all_conection() {
curl -m 2 -H "Authorization: Bearer ${SECRET}" -H "Content-Type:application/json" -X DELETE http://"$LAN_IP":"$PORT"/connections >/dev/null 2>&1 curl -m 2 -H "Authorization: Bearer ${SECRET}" -H "Content-Type:application/json" -X DELETE http://"$LAN_IP":"$PORT"/connections >/dev/null 2>&1
} }
set_lock
if [ "$1" = "close_all_conection" ]; then if [ "$1" = "close_all_conection" ]; then
close_all_conection close_all_conection
del_lock
exit 0 exit 0
fi fi
@ -38,8 +41,6 @@ core_version=$(uci -q get openclash.config.core_version || echo 0)
CACHE_PATH_OLD="/etc/openclash/.cache" CACHE_PATH_OLD="/etc/openclash/.cache"
source "/etc/openwrt_release" source "/etc/openwrt_release"
set_lock
if [ -z "$CONFIG_FILE" ] || [ ! -f "$CONFIG_FILE" ]; then if [ -z "$CONFIG_FILE" ] || [ ! -f "$CONFIG_FILE" ]; then
CONFIG_FILE=$(uci get openclash.config.config_path 2>/dev/null) CONFIG_FILE=$(uci get openclash.config.config_path 2>/dev/null)
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null) CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)

View File

@ -9,15 +9,16 @@
del_lock() { del_lock() {
flock -u 880 2>/dev/null flock -u 880 2>/dev/null
rm -rf "/tmp/lock/openclash_ipdb.lock" rm -rf "/tmp/lock/openclash_ipdb.lock" 2>/dev/null
} }
set_lock
small_flash_memory=$(uci get openclash.config.small_flash_memory 2>/dev/null) small_flash_memory=$(uci get openclash.config.small_flash_memory 2>/dev/null)
GEOIP_CUSTOM_URL=$(uci get openclash.config.geo_custom_url 2>/dev/null) GEOIP_CUSTOM_URL=$(uci get openclash.config.geo_custom_url 2>/dev/null)
github_address_mod=$(uci -q get openclash.config.github_address_mod || echo 0) github_address_mod=$(uci -q get openclash.config.github_address_mod || echo 0)
LOG_FILE="/tmp/openclash.log" LOG_FILE="/tmp/openclash.log"
restart=0 restart=0
set_lock
if [ "$small_flash_memory" != "1" ]; then if [ "$small_flash_memory" != "1" ]; then
geoip_path="/etc/openclash/Country.mmdb" geoip_path="/etc/openclash/Country.mmdb"
@ -55,9 +56,9 @@
LOG_OUT "Geoip Database Update Error, Please Try Again Later..." LOG_OUT "Geoip Database Update Error, Please Try Again Later..."
fi fi
if [ "$restart" -eq 1 ] && [ "$(unify_ps_prevent)" -eq 0 ] && [ "$(find /tmp/lock/ |grep -v "openclash.lock" |grep -c "openclash")" -le 1 ]; then if [ "$restart" -eq 1 ] && [ "$(unify_ps_prevent)" -eq 0 ]; then
/etc/init.d/openclash restart >/dev/null 2>&1 & /etc/init.d/openclash restart >/dev/null 2>&1 &
elif [ "$restart" -eq 0 ] && [ "$(unify_ps_prevent)" -eq 0 ] && [ "$(find /tmp/lock/ |grep -v "openclash.lock" |grep -c "openclash")" -le 1 ] && [ "$(uci -q get openclash.config.restart)" -eq 1 ]; then elif [ "$restart" -eq 0 ] && [ "$(unify_ps_prevent)" -eq 0 ] && [ "$(uci -q get openclash.config.restart)" -eq 1 ]; then
/etc/init.d/openclash restart >/dev/null 2>&1 & /etc/init.d/openclash restart >/dev/null 2>&1 &
uci -q set openclash.config.restart=0 uci -q set openclash.config.restart=0
uci -q commit openclash uci -q commit openclash

View File

@ -11,116 +11,117 @@
del_lock() { del_lock() {
flock -u 877 2>/dev/null flock -u 877 2>/dev/null
rm -rf "/tmp/lock/openclash_rule.lock" rm -rf "/tmp/lock/openclash_rule.lock" 2>/dev/null
} }
yml_other_rules_dl() yml_other_rules_dl()
{ {
local section="$1" local section="$1"
local enabled config local enabled config
config_get_bool "enabled" "$section" "enabled" "1" config_get_bool "enabled" "$section" "enabled" "1"
config_get "config" "$section" "config" "" config_get "config" "$section" "config" ""
if [ "$enabled" = "0" ] || [ "$config" != "$2" ]; then if [ "$enabled" = "0" ] || [ "$config" != "$2" ]; then
return return
fi
if [ -n "$rule_name" ]; then
LOG_OUT "Warrning: Multiple Other-Rules-Configurations Enabled, Ignore..."
return
fi
config_get "rule_name" "$section" "rule_name" ""
LOG_OUT "Start Downloading Third Party Rules in Use..."
if [ "$rule_name" = "lhie1" ]; then
if [ "$github_address_mod" != "0" ]; then
if [ "$github_address_mod" == "https://cdn.jsdelivr.net/" ] || [ "$github_address_mod" == "https://fastly.jsdelivr.net/" ] || [ "$github_address_mod" == "https://testingcf.jsdelivr.net/" ]; then
curl -SsL --connect-timeout 30 -m 60 --speed-time 30 --speed-limit 1 --retry 2 "$github_address_mod"gh/dler-io/Rules@master/Clash/Rule.yaml -o /tmp/rules.yaml 2>&1 |sed ':a;N;$!ba; s/\n/ /g' | awk -v time="$(date "+%Y-%m-%d %H:%M:%S")" -v file="/tmp/rules.yaml" '{print time "【" file "】Download Failed:【"$0"】"}' >> "$LOG_FILE"
else
curl -SsL --connect-timeout 30 -m 60 --speed-time 30 --speed-limit 1 --retry 2 "$github_address_mod"https://raw.githubusercontent.com/dler-io/Rules/master/Clash/Rule.yaml -o /tmp/rules.yaml 2>&1 |sed ':a;N;$!ba; s/\n/ /g' | awk -v time="$(date "+%Y-%m-%d %H:%M:%S")" -v file="/tmp/rules.yaml" '{print time "【" file "】Download Failed:【"$0"】"}' >> "$LOG_FILE"
fi
else
curl -SsL --connect-timeout 30 -m 60 --speed-time 30 --speed-limit 1 --retry 2 https://raw.githubusercontent.com/dler-io/Rules/master/Clash/Rule.yaml -o /tmp/rules.yaml 2>&1 |sed ':a;N;$!ba; s/\n/ /g' | awk -v time="$(date "+%Y-%m-%d %H:%M:%S")" -v file="/tmp/rules.yaml" '{print time "【" file "】Download Failed:【"$0"】"}' >> "$LOG_FILE"
fi fi
sed -i '1i rules:' /tmp/rules.yaml
fi if [ -n "$rule_name" ]; then
if [ -s "/tmp/rules.yaml" ]; then LOG_OUT "Warrning: Multiple Other-Rules-Configurations Enabled, Ignore..."
LOG_OUT "Download Successful, Start Preprocessing Rule File..." return
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e " fi
begin
YAML.load_file('/tmp/rules.yaml'); config_get "rule_name" "$section" "rule_name" ""
rescue Exception => e
YAML.LOG('Error: Unable To Parse Updated Rules File,【${rule_name}:' + e.message + '】'); LOG_OUT "Start Downloading Third Party Rules in Use..."
system 'rm -rf /tmp/rules.yaml 2>/dev/null'; if [ "$rule_name" = "lhie1" ]; then
end if [ "$github_address_mod" != "0" ]; then
" 2>/dev/null >> $LOG_FILE if [ "$github_address_mod" == "https://cdn.jsdelivr.net/" ] || [ "$github_address_mod" == "https://fastly.jsdelivr.net/" ] || [ "$github_address_mod" == "https://testingcf.jsdelivr.net/" ]; then
if [ $? -ne 0 ]; then curl -SsL --connect-timeout 30 -m 60 --speed-time 30 --speed-limit 1 --retry 2 "$github_address_mod"gh/dler-io/Rules@master/Clash/Rule.yaml -o /tmp/rules.yaml 2>&1 |sed ':a;N;$!ba; s/\n/ /g' | awk -v time="$(date "+%Y-%m-%d %H:%M:%S")" -v file="/tmp/rules.yaml" '{print time "【" file "】Download Failed:【"$0"】"}' >> "$LOG_FILE"
LOG_OUT "Error: Ruby Works Abnormally, Please Check The Ruby Library Depends!" else
rm -rf /tmp/rules.yaml >/dev/null 2>&1 curl -SsL --connect-timeout 30 -m 60 --speed-time 30 --speed-limit 1 --retry 2 "$github_address_mod"https://raw.githubusercontent.com/dler-io/Rules/master/Clash/Rule.yaml -o /tmp/rules.yaml 2>&1 |sed ':a;N;$!ba; s/\n/ /g' | awk -v time="$(date "+%Y-%m-%d %H:%M:%S")" -v file="/tmp/rules.yaml" '{print time "【" file "】Download Failed:【"$0"】"}' >> "$LOG_FILE"
SLOG_CLEAN fi
del_lock else
exit 0 curl -SsL --connect-timeout 30 -m 60 --speed-time 30 --speed-limit 1 --retry 2 https://raw.githubusercontent.com/dler-io/Rules/master/Clash/Rule.yaml -o /tmp/rules.yaml 2>&1 |sed ':a;N;$!ba; s/\n/ /g' | awk -v time="$(date "+%Y-%m-%d %H:%M:%S")" -v file="/tmp/rules.yaml" '{print time "【" file "】Download Failed:【"$0"】"}' >> "$LOG_FILE"
elif [ ! -f "/tmp/rules.yaml" ]; then fi
LOG_OUT "Error:【$rule_name】Rule File Format Validation Failed, Please Try Again Later..." sed -i '1i rules:' /tmp/rules.yaml
rm -rf /tmp/rules.yaml >/dev/null 2>&1 fi
SLOG_CLEAN if [ -s "/tmp/rules.yaml" ]; then
del_lock LOG_OUT "Download Successful, Start Preprocessing Rule File..."
exit 0 ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
elif ! "$(ruby_read "/tmp/rules.yaml" ".key?('rules')")" ; then begin
LOG_OUT "Error: Updated Others Rules【$rule_name】Has No Rules Field, Update Exit..." YAML.load_file('/tmp/rules.yaml');
rm -rf /tmp/rules.yaml >/dev/null 2>&1 rescue Exception => e
SLOG_CLEAN YAML.LOG('Error: Unable To Parse Updated Rules File,【${rule_name}:' + e.message + '】');
del_lock system 'rm -rf /tmp/rules.yaml 2>/dev/null';
exit 0 end
#校验是否含有新策略组 " 2>/dev/null >> $LOG_FILE
elif ! "$(ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e " if [ $? -ne 0 ]; then
Value = YAML.load_file('/usr/share/openclash/res/${rule_name}.yaml'); LOG_OUT "Error: Ruby Works Abnormally, Please Check The Ruby Library Depends!"
Value_1 = YAML.load_file('/tmp/rules.yaml'); rm -rf /tmp/rules.yaml >/dev/null 2>&1
OLD_GROUP = Value['rules'].collect{|x| x.split(',')[2] or x.split(',')[1]}.uniq.map(&:strip); SLOG_CLEAN
NEW_GROUP = Value_1['rules'].collect{|x| x.split(',')[2] or x.split(',')[1]}.uniq.map(&:strip); del_lock
if (OLD_GROUP | NEW_GROUP).eql?(OLD_GROUP) then exit 0
if (OLD_GROUP | NEW_GROUP).eql?(NEW_GROUP) then elif [ ! -f "/tmp/rules.yaml" ]; then
puts true LOG_OUT "Error:【$rule_name】Rule File Format Validation Failed, Please Try Again Later..."
rm -rf /tmp/rules.yaml >/dev/null 2>&1
SLOG_CLEAN
del_lock
exit 0
elif ! "$(ruby_read "/tmp/rules.yaml" ".key?('rules')")" ; then
LOG_OUT "Error: Updated Others Rules【$rule_name】Has No Rules Field, Update Exit..."
rm -rf /tmp/rules.yaml >/dev/null 2>&1
SLOG_CLEAN
del_lock
exit 0
#校验是否含有新策略组
elif ! "$(ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
Value = YAML.load_file('/usr/share/openclash/res/${rule_name}.yaml');
Value_1 = YAML.load_file('/tmp/rules.yaml');
OLD_GROUP = Value['rules'].collect{|x| x.split(',')[2] or x.split(',')[1]}.uniq.map(&:strip);
NEW_GROUP = Value_1['rules'].collect{|x| x.split(',')[2] or x.split(',')[1]}.uniq.map(&:strip);
if (OLD_GROUP | NEW_GROUP).eql?(OLD_GROUP) then
if (OLD_GROUP | NEW_GROUP).eql?(NEW_GROUP) then
puts true
else
puts false
end
else else
puts false puts false
end end
")" && [ -f "/usr/share/openclash/res/${rule_name}.yaml" ]; then
LOG_OUT "Error: Updated Others Rules【$rule_name】Has Incompatible Proxy-Group, Update Exit, Please Wait For OpenClash Update To Adapt..."
rm -rf /tmp/rules.yaml >/dev/null 2>&1
SLOG_CLEAN
del_lock
exit 0
fi
#取出规则部分
ruby_read "/tmp/rules.yaml" ".select {|x| 'rule-providers' == x or 'rules' == x }.to_yaml" > "$OTHER_RULE_FILE"
#合并
cat "$OTHER_RULE_FILE" > "/tmp/rules.yaml" 2>/dev/null
rm -rf /tmp/other_rule* 2>/dev/null
LOG_OUT "Check The Downloaded Rule File For Updates..."
cmp -s /usr/share/openclash/res/"$rule_name".yaml /tmp/rules.yaml
if [ "$?" -ne "0" ]; then
LOG_OUT "Detected that The Downloaded Rule File Has Been Updated, Starting To Replace..."
mv /tmp/rules.yaml /usr/share/openclash/res/"$rule_name".yaml >/dev/null 2>&1
LOG_OUT "Other Rules【$rule_name】Update Successful!"
restart=1
else else
puts false LOG_OUT "Updated Other Rules【$rule_name】No Change, Do Nothing!"
end fi
")" && [ -f "/usr/share/openclash/res/${rule_name}.yaml" ]; then
LOG_OUT "Error: Updated Others Rules【$rule_name】Has Incompatible Proxy-Group, Update Exit, Please Wait For OpenClash Update To Adapt..."
rm -rf /tmp/rules.yaml >/dev/null 2>&1
SLOG_CLEAN
del_lock
exit 0
fi
#取出规则部分
ruby_read "/tmp/rules.yaml" ".select {|x| 'rule-providers' == x or 'rules' == x }.to_yaml" > "$OTHER_RULE_FILE"
#合并
cat "$OTHER_RULE_FILE" > "/tmp/rules.yaml" 2>/dev/null
rm -rf /tmp/other_rule* 2>/dev/null
LOG_OUT "Check The Downloaded Rule File For Updates..."
cmp -s /usr/share/openclash/res/"$rule_name".yaml /tmp/rules.yaml
if [ "$?" -ne "0" ]; then
LOG_OUT "Detected that The Downloaded Rule File Has Been Updated, Starting To Replace..."
mv /tmp/rules.yaml /usr/share/openclash/res/"$rule_name".yaml >/dev/null 2>&1
LOG_OUT "Other Rules【$rule_name】Update Successful!"
restart=1
else else
LOG_OUT "Updated Other Rules【$rule_name】No Change, Do Nothing!" LOG_OUT "Other Rules【$rule_name】Update Error, Please Try Again Later..."
fi fi
else
LOG_OUT "Other Rules【$rule_name】Update Error, Please Try Again Later..."
fi
} }
set_lock
LOG_FILE="/tmp/openclash.log" LOG_FILE="/tmp/openclash.log"
RUlE_SOURCE=$(uci get openclash.config.rule_source 2>/dev/null) RUlE_SOURCE=$(uci get openclash.config.rule_source 2>/dev/null)
github_address_mod=$(uci -q get openclash.config.github_address_mod || echo 0) github_address_mod=$(uci -q get openclash.config.github_address_mod || echo 0)
set_lock
if [ "$RUlE_SOURCE" = "0" ]; then if [ "$RUlE_SOURCE" = "0" ]; then
LOG_OUT "Other Rules Not Enable, Update Stop!" LOG_OUT "Other Rules Not Enable, Update Stop!"
@ -151,9 +152,9 @@
if [ -z "$rule_name" ]; then if [ -z "$rule_name" ]; then
LOG_OUT "Get Other Rules Settings Faild, Update Stop!" LOG_OUT "Get Other Rules Settings Faild, Update Stop!"
fi fi
if [ "$restart" -eq 1 ] && [ "$(unify_ps_prevent)" -eq 0 ] && [ "$(find /tmp/lock/ |grep -v "openclash.lock" |grep -c "openclash")" -le 1 ]; then if [ "$restart" -eq 1 ] && [ "$(unify_ps_prevent)" -eq 0 ]; then
/etc/init.d/openclash restart >/dev/null 2>&1 & /etc/init.d/openclash restart >/dev/null 2>&1 &
elif [ "$restart" -eq 0 ] && [ "$(unify_ps_prevent)" -eq 0 ] && [ "$(find /tmp/lock/ |grep -v "openclash.lock" |grep -c "openclash")" -le 1 ] && [ "$(uci -q get openclash.config.restart)" -eq 1 ]; then elif [ "$restart" -eq 0 ] && [ "$(unify_ps_prevent)" -eq 0 ] && [ "$(uci -q get openclash.config.restart)" -eq 1 ]; then
/etc/init.d/openclash restart >/dev/null 2>&1 & /etc/init.d/openclash restart >/dev/null 2>&1 &
uci -q set openclash.config.restart=0 uci -q set openclash.config.restart=0
uci -q commit openclash uci -q commit openclash

View File

@ -1111,7 +1111,7 @@ function netflix_unlock_test()
local filmId = 70143836 local filmId = 70143836
local url = "https://www.netflix.com/title/"..filmId local url = "https://www.netflix.com/title/"..filmId
local headers = "User-Agent: "..UA local headers = "User-Agent: "..UA
local info = SYS.exec(string.format('curl -sLI --connect-timeout 5 -m 5 --speed-time 5 --speed-limit 1 --retry 2 -o /dev/null -w %%{json} -H "Content-Type: application/json" -H "%s" -XGET %s', headers, url)) local info = SYS.exec(string.format('curl -sLI --connect-timeout 5 -m 5 --speed-time 5 --speed-limit 1 --retry 2 -o /dev/null -w %%{json} -H "Content-Type: application/json" -H "host: www.netflix.com" -H "accept-language: en-US,en;q=0.9" -H "sec-ch-ua: Google Chrome;v=125, Chromium;v=125, Not.A/Brand;v=24" -H "sec-ch-ua-mobile: ?0" -H "sec-ch-ua-platform: Windows" -H "sec-fetch-site: none" -H "sec-fetch-mode: navigate" -H "sec-fetch-user: ?1" -H "sec-fetch-dest: document" -H "%s" -XGET %s', headers, url))
local result = {} local result = {}
local region local region
local old_region = get_old_region() local old_region = get_old_region()

View File

@ -8,9 +8,11 @@ set_lock() {
del_lock() { del_lock() {
flock -u 878 2>/dev/null flock -u 878 2>/dev/null
rm -rf "/tmp/lock/openclash_update.lock" rm -rf "/tmp/lock/openclash_update.lock" 2>/dev/null
} }
set_lock
if [ -n "$1" ] && [ "$1" != "one_key_update" ]; then if [ -n "$1" ] && [ "$1" != "one_key_update" ]; then
[ ! -f "/tmp/openclash_last_version" ] && /usr/share/openclash/openclash_version.sh "$1" 2>/dev/null [ ! -f "/tmp/openclash_last_version" ] && /usr/share/openclash/openclash_version.sh "$1" 2>/dev/null
elif [ -n "$2" ]; then elif [ -n "$2" ]; then
@ -22,6 +24,7 @@ fi
if [ ! -f "/tmp/openclash_last_version" ]; then if [ ! -f "/tmp/openclash_last_version" ]; then
LOG_OUT "Error: Failed to Get Version Information, Please Try Again Later..." LOG_OUT "Error: Failed to Get Version Information, Please Try Again Later..."
SLOG_CLEAN SLOG_CLEAN
del_lock
exit 0 exit 0
fi fi
@ -30,7 +33,7 @@ LAST_VER=$(sed -n 1p "$LAST_OPVER" 2>/dev/null |sed "s/^v//g" |tr -d "\n")
if [ -x "/bin/opkg" ]; then if [ -x "/bin/opkg" ]; then
OP_CV=$(rm -f /var/lock/opkg.lock && opkg status luci-app-openclash 2>/dev/null |grep 'Version' |awk -F 'Version: ' '{print $2}' |awk -F '.' '{print $2$3}' 2>/dev/null) OP_CV=$(rm -f /var/lock/opkg.lock && opkg status luci-app-openclash 2>/dev/null |grep 'Version' |awk -F 'Version: ' '{print $2}' |awk -F '.' '{print $2$3}' 2>/dev/null)
elif [ -x "/usr/bin/apk" ]; then elif [ -x "/usr/bin/apk" ]; then
OP_CV=$(apk list luci-app-openclash 2>/dev/null |grep 'installed' | grep -oE '\d+(\.\d+)*' | head -1 |awk -F '.' '{print $2$3}' 2>/dev/null) OP_CV=$(apk list luci-app-openclash 2>/dev/null|grep 'installed' | grep -oE '[0-9]+(\.[0-9]+)*' | head -1 |awk -F '.' '{print $2$3}' 2>/dev/null)
fi fi
OP_LV=$(sed -n 1p "$LAST_OPVER" 2>/dev/null |awk -F 'v' '{print $2}' |awk -F '.' '{print $2$3}' 2>/dev/null) OP_LV=$(sed -n 1p "$LAST_OPVER" 2>/dev/null |awk -F 'v' '{print $2}' |awk -F '.' '{print $2$3}' 2>/dev/null)
RELEASE_BRANCH=$(uci -q get openclash.config.release_branch || echo "master") RELEASE_BRANCH=$(uci -q get openclash.config.release_branch || echo "master")
@ -58,8 +61,6 @@ else
fi fi
fi fi
set_lock
if [ -n "$OP_CV" ] && [ -n "$OP_LV" ] && [ "$(expr "$OP_LV" \> "$OP_CV")" -eq 1 ] && [ -f "$LAST_OPVER" ]; then if [ -n "$OP_CV" ] && [ -n "$OP_LV" ] && [ "$(expr "$OP_LV" \> "$OP_CV")" -eq 1 ] && [ -f "$LAST_OPVER" ]; then
LOG_OUT "Start Downloading【OpenClash - v$LAST_VER】..." LOG_OUT "Start Downloading【OpenClash - v$LAST_VER】..."
if [ "$github_address_mod" != "0" ]; then if [ "$github_address_mod" != "0" ]; then
@ -89,9 +90,9 @@ if [ -n "$OP_CV" ] && [ -n "$OP_LV" ] && [ "$(expr "$OP_LV" \> "$OP_CV")" -eq 1
if [ -x "/bin/opkg" ]; then if [ -x "/bin/opkg" ]; then
if [ -s "/tmp/openclash.ipk" ]; then if [ -s "/tmp/openclash.ipk" ]; then
if [ -z "$(opkg install /tmp/openclash.ipk --noaction 2>/dev/null |grep 'Upgrading luci-app-openclash on root' 2>/dev/null)" ]; then if [ -z "$(opkg install /tmp/openclash.ipk --noaction 2>/dev/null |grep 'Upgrading luci-app-openclash on root' 2>/dev/null)" ]; then
LOG_OUT "【OpenClash - v$LAST_VER】Pre Update Test Failed, The File is Saved in /tmp/openclash.ipk, Please Try to Update Manually!" LOG_OUT "【OpenClash - v$LAST_VER】Pre Update Test Failed, The File is Saved in /tmp/openclash.ipk, Please Try to Update Manually With【opkg install /tmp/openclash.ipk】"
if [ "$(uci -q get openclash.config.config_reload)" -eq 1 ]; then if [ "$(uci -q get openclash.config.restart)" -eq 1 ]; then
uci -q set openclash.config.config_reload=0 uci -q set openclash.config.restart=0
uci -q commit openclash uci -q commit openclash
/etc/init.d/openclash restart >/dev/null 2>&1 & /etc/init.d/openclash restart >/dev/null 2>&1 &
else else
@ -103,11 +104,12 @@ if [ -n "$OP_CV" ] && [ -n "$OP_LV" ] && [ "$(expr "$OP_LV" \> "$OP_CV")" -eq 1
fi fi
elif [ -x "/usr/bin/apk" ]; then elif [ -x "/usr/bin/apk" ]; then
if [ -s "/tmp/openclash.apk" ]; then if [ -s "/tmp/openclash.apk" ]; then
apk add -s -q --clean-protected --allow-untrusted /tmp/openclash.apk >/dev/null 2>&1 apk update >/dev/null 2>&1
apk add -s -q --force-overwrite --clean-protected --allow-untrusted /tmp/openclash.apk >/dev/null 2>&1
if [ "$?" != "0" ]; then if [ "$?" != "0" ]; then
LOG_OUT "【OpenClash - v$LAST_VER】Pre Update Test Failed, The File is Saved in /tmp/openclash.apk, Please Try to Update Manually!" LOG_OUT "【OpenClash - v$LAST_VER】Pre Update Test Failed, The File is Saved in /tmp/openclash.apk, Please Try to Update Manually With【apk add -q --force-overwrite --clean-protected --allow-untrusted /tmp/openclash.apk】"
if [ "$(uci -q get openclash.config.config_reload)" -eq 1 ]; then if [ "$(uci -q get openclash.config.restart)" -eq 1 ]; then
uci -q set openclash.config.config_reload=0 uci -q set openclash.config.restart=0
uci -q commit openclash uci -q commit openclash
/etc/init.d/openclash restart >/dev/null 2>&1 & /etc/init.d/openclash restart >/dev/null 2>&1 &
else else
@ -148,7 +150,7 @@ LOG_OUT "Installing The New Version, Please Do Not Refresh The Page or Do Other
if [ -x "/bin/opkg" ]; then if [ -x "/bin/opkg" ]; then
opkg install /tmp/openclash.ipk opkg install /tmp/openclash.ipk
elif [ -x "/usr/bin/apk" ]; then elif [ -x "/usr/bin/apk" ]; then
apk add -q --clean-protected --allow-untrusted /tmp/openclash.apk apk add -q --force-overwrite --clean-protected --allow-untrusted /tmp/openclash.apk
fi fi
if [ -x "/bin/opkg" ]; then if [ -x "/bin/opkg" ]; then
if [ "$?" != "0" ] || [ -z "$(opkg info *openclash |grep Installed-Time)" ]; then if [ "$?" != "0" ] || [ -z "$(opkg info *openclash |grep Installed-Time)" ]; then
@ -161,35 +163,35 @@ if [ -x "/bin/opkg" ]; then
uci -q commit openclash uci -q commit openclash
/etc/init.d/openclash restart 2>/dev/null /etc/init.d/openclash restart 2>/dev/null
else else
LOG_OUT "OpenClash Update Failed, The File is Saved in /tmp/openclash.ipk, Please Try to Update Manually!" LOG_OUT "OpenClash Update Failed, The File is Saved in /tmp/openclash.ipk, Please Try to Update Manually With【opkg install /tmp/openclash.ipk】"
SLOG_CLEAN SLOG_CLEAN
fi fi
elif [ -x "/usr/bin/apk" ]; then elif [ -x "/usr/bin/apk" ]; then
if [ "$?" != "0" ] || [ -z "$(apk list luci-app-openclash 2>/dev/null |grep 'installed')" ]; then if [ "$?" != "0" ] || [ -z "$(apk list luci-app-openclash 2>/dev/null |grep 'installed')" ]; then
apk add -q --clean-protected --allow-untrusted /tmp/openclash.apk apk add -q --force-overwrite --clean-protected --allow-untrusted /tmp/openclash.apk
fi fi
if [ "$?" != "0" ] || [ -z "$(apk list luci-app-openclash 2>/dev/null |grep 'installed')" ]; then if [ "$?" == "0" ] || [ -n "$(apk list luci-app-openclash 2>/dev/null |grep 'installed')" ]; then
rm -rf /tmp/openclash.apk >/dev/null 2>&1 rm -rf /tmp/openclash.apk >/dev/null 2>&1
LOG_OUT "OpenClash Update Successful, About To Restart!" LOG_OUT "OpenClash Update Successful, About To Restart!"
uci -q set openclash.config.enable=1 uci -q set openclash.config.enable=1
uci -q commit openclash uci -q commit openclash
/etc/init.d/openclash restart 2>/dev/null /etc/init.d/openclash restart 2>/dev/null
else else
LOG_OUT "OpenClash Update Failed, The File is Saved in /tmp/openclash.apk, Please Try to Update Manually!" LOG_OUT "OpenClash Update Failed, The File is Saved in /tmp/openclash.apk, Please Try to Update Manually With【apk add -q --force-overwrite --clean-protected --allow-untrusted /tmp/openclash.apk】"
SLOG_CLEAN SLOG_CLEAN
fi fi
fi fi
EOF EOF
chmod 4755 /tmp/openclash_update.sh chmod 4755 /tmp/openclash_update.sh
nohup /tmp/openclash_update.sh & /tmp/openclash_update.sh &
wait wait
rm -rf /tmp/openclash_update.sh rm -rf /tmp/openclash_update.sh
else else
LOG_OUT "【OpenClash - v$LAST_VER】Download Failed, Please Check The Network or Try Again Later!" LOG_OUT "【OpenClash - v$LAST_VER】Download Failed, Please Check The Network or Try Again Later!"
rm -rf /tmp/openclash.ipk >/dev/null 2>&1 rm -rf /tmp/openclash.ipk >/dev/null 2>&1
rm -rf /tmp/openclash.apk >/dev/null 2>&1 rm -rf /tmp/openclash.apk >/dev/null 2>&1
if [ "$(uci -q get openclash.config.config_reload)" -eq 1 ]; then if [ "$(uci -q get openclash.config.restart)" -eq 1 ]; then
uci -q set openclash.config.config_reload=0 uci -q set openclash.config.restart=0
uci -q commit openclash uci -q commit openclash
/etc/init.d/openclash restart >/dev/null 2>&1 & /etc/init.d/openclash restart >/dev/null 2>&1 &
else else
@ -202,8 +204,8 @@ else
else else
LOG_OUT "OpenClash Has not Been Updated, Stop Continuing!" LOG_OUT "OpenClash Has not Been Updated, Stop Continuing!"
fi fi
if [ "$(uci -q get openclash.config.config_reload)" -eq 1 ]; then if [ "$(uci -q get openclash.config.restart)" -eq 1 ]; then
uci -q set openclash.config.config_reload=0 uci -q set openclash.config.restart=0
uci -q commit openclash uci -q commit openclash
/etc/init.d/openclash restart >/dev/null 2>&1 & /etc/init.d/openclash restart >/dev/null 2>&1 &
else else

View File

@ -1,4 +1,15 @@
#!/bin/bash #!/bin/bash
set_lock() {
exec 869>"/tmp/lock/openclash_version.lock" 2>/dev/null
flock -x 869 2>/dev/null
}
del_lock() {
flock -u 869 2>/dev/null
rm -rf "/tmp/lock/openclash_version.lock" 2>/dev/null
}
set_lock
TIME=$(date "+%Y-%m-%d-%H") TIME=$(date "+%Y-%m-%d-%H")
CHTIME=$(date "+%Y-%m-%d-%H" -r "/tmp/openclash_last_version" 2>/dev/null) CHTIME=$(date "+%Y-%m-%d-%H" -r "/tmp/openclash_last_version" 2>/dev/null)
@ -7,7 +18,7 @@ RELEASE_BRANCH=$(uci -q get openclash.config.release_branch || echo "master")
if [ -x "/bin/opkg" ]; then if [ -x "/bin/opkg" ]; then
OP_CV=$(rm -f /var/lock/opkg.lock && opkg status luci-app-openclash 2>/dev/null |grep 'Version' |awk -F 'Version: ' '{print $2}' |awk -F '.' '{print $2$3}' 2>/dev/null) OP_CV=$(rm -f /var/lock/opkg.lock && opkg status luci-app-openclash 2>/dev/null |grep 'Version' |awk -F 'Version: ' '{print $2}' |awk -F '.' '{print $2$3}' 2>/dev/null)
elif [ -x "/usr/bin/apk" ]; then elif [ -x "/usr/bin/apk" ]; then
OP_CV=$(apk list luci-app-openclash 2>/dev/null|grep 'installed' | grep -oE '\d+(\.\d+)*' | head -1 |awk -F '.' '{print $2$3}' 2>/dev/null) OP_CV=$(apk list luci-app-openclash 2>/dev/null|grep 'installed' | grep -oE '[0-9]+(\.[0-9]+)*' | head -1 |awk -F '.' '{print $2$3}' 2>/dev/null)
fi fi
OP_LV=$(sed -n 1p $LAST_OPVER 2>/dev/null |awk -F 'v' '{print $2}' |awk -F '.' '{print $2$3}' 2>/dev/null) OP_LV=$(sed -n 1p $LAST_OPVER 2>/dev/null |awk -F 'v' '{print $2}' |awk -F '.' '{print $2$3}' 2>/dev/null)
github_address_mod=$(uci -q get openclash.config.github_address_mod || echo 0) github_address_mod=$(uci -q get openclash.config.github_address_mod || echo 0)
@ -32,15 +43,20 @@ if [ "$TIME" != "$CHTIME" ]; then
if [ "$(expr "$OP_CV" \>= "$OP_LV")" = "1" ]; then if [ "$(expr "$OP_CV" \>= "$OP_LV")" = "1" ]; then
sed -i '/^https:/,$d' $LAST_OPVER sed -i '/^https:/,$d' $LAST_OPVER
elif [ "$(expr "$OP_LV" \> "$OP_CV")" = "1" ] && [ -n "$OP_LV" ]; then elif [ "$(expr "$OP_LV" \> "$OP_CV")" = "1" ] && [ -n "$OP_LV" ]; then
del_lock
exit 2 exit 2
else else
del_lock
exit 0 exit 0
fi fi
else else
rm -rf "$LAST_OPVER" rm -rf "$LAST_OPVER"
fi fi
elif [ "$(expr "$OP_LV" \> "$OP_CV")" = "1" ] && [ -n "$OP_LV" ]; then elif [ "$(expr "$OP_LV" \> "$OP_CV")" = "1" ] && [ -n "$OP_LV" ]; then
del_lock
exit 2 exit 2
else else
del_lock
exit 0 exit 0
fi 2>/dev/null fi 2>/dev/null
del_lock

View File

@ -16,7 +16,6 @@ log_size=$(uci -q get openclash.config.log_size || echo 1024)
router_self_proxy=$(uci -q get openclash.config.router_self_proxy || echo 1) router_self_proxy=$(uci -q get openclash.config.router_self_proxy || echo 1)
stream_auto_select_interval=$(uci -q get openclash.config.stream_auto_select_interval || echo 30) stream_auto_select_interval=$(uci -q get openclash.config.stream_auto_select_interval || echo 30)
skip_proxy_address=$(uci -q get openclash.config.skip_proxy_address || echo 0) skip_proxy_address=$(uci -q get openclash.config.skip_proxy_address || echo 0)
CRASH_NUM=0
CFG_UPDATE_INT=1 CFG_UPDATE_INT=1
SKIP_PROXY_ADDRESS=1 SKIP_PROXY_ADDRESS=1
SKIP_PROXY_ADDRESS_INTERVAL=30 SKIP_PROXY_ADDRESS_INTERVAL=30
@ -56,7 +55,7 @@ begin
if servers.include?(i['server']) then if servers.include?(i['server']) then
next; next;
end; end;
if i['server'] =~ reg and not servers.include?(i['server']) then if i['server'] =~ reg then
servers = servers.push(i['server']).uniq servers = servers.push(i['server']).uniq
syscall = '/usr/share/openclash/openclash_debug_dns.lua 2>/dev/null \"' + i['server'] + '\" \"true\"' syscall = '/usr/share/openclash/openclash_debug_dns.lua 2>/dev/null \"' + i['server'] + '\" \"true\"'
result = IO.popen(syscall).read.split(/\n+/) result = IO.popen(syscall).read.split(/\n+/)
@ -93,7 +92,7 @@ begin
if servers.include?(j['server']) then if servers.include?(j['server']) then
next; next;
end; end;
if j['server'] =~ reg and not servers.include?(j['server']) then if j['server'] =~ reg then
servers = servers.push(j['server']).uniq servers = servers.push(j['server']).uniq
syscall = '/usr/share/openclash/openclash_debug_dns.lua 2>/dev/null \"' + j['server'] + '\" \"true\"' syscall = '/usr/share/openclash/openclash_debug_dns.lua 2>/dev/null \"' + j['server'] + '\" \"true\"'
result = IO.popen(syscall).read.split(/\n+/) result = IO.popen(syscall).read.split(/\n+/)
@ -109,6 +108,28 @@ begin
end; end;
end; end;
end; end;
if not i['path'] and i['type'] == 'inline' and i['payload'] and not i['payload'].empty? then
Value['payload'].each do
|k|
threadsp << Thread.new {
if k['server'] then
if servers.include?(k['server']) then
next;
end;
if k['server'] =~ reg then
servers = servers.push(k['server']).uniq
syscall = '/usr/share/openclash/openclash_debug_dns.lua 2>/dev/null \"' + k['server'] + '\" \"true\"'
result = IO.popen(syscall).read.split(/\n+/)
if result then
ips = ips | result
end;
else
ips = ips.push(k['server']).uniq
end;
end;
};
end;
end;
threadsp.each(&:join); threadsp.each(&:join);
}; };
end; end;
@ -144,12 +165,6 @@ rescue Exception => e
end" 2>/dev/null >> $LOG_FILE end" 2>/dev/null >> $LOG_FILE
} }
#wait for core start complete
while ( [ -n "$(unify_ps_pids "/etc/init.d/openclash")" ] )
do
sleep 1
done >/dev/null 2>&1
while :; while :;
do do
cfg_update=$(uci -q get openclash.config.auto_update) cfg_update=$(uci -q get openclash.config.auto_update)
@ -170,34 +185,12 @@ do
stream_auto_select_google_not_cn=$(uci -q get openclash.config.stream_auto_select_google_not_cn || echo 0) stream_auto_select_google_not_cn=$(uci -q get openclash.config.stream_auto_select_google_not_cn || echo 0)
stream_auto_select_openai=$(uci -q get openclash.config.stream_auto_select_openai || echo 0) stream_auto_select_openai=$(uci -q get openclash.config.stream_auto_select_openai || echo 0)
upnp_lease_file=$(uci -q get upnpd.config.upnp_lease_file) upnp_lease_file=$(uci -q get upnpd.config.upnp_lease_file)
enable=$(uci -q get openclash.config.enable)
if [ "$enable" -eq 1 ]; then #wait for core start complete
clash_pids=$(pidof clash |sed 's/$//g' |wc -l) while ( [ -n "$(unify_ps_pids "/etc/init.d/openclash")" ] )
if [ "$clash_pids" -gt 1 ]; then do
LOG_OUT "Watchdog: Multiple Clash Processes, Kill All..." sleep 1
clash_pids=$(pidof clash |sed 's/$//g') done >/dev/null 2>&1
for clash_pid in $clash_pids; do
kill -9 "$clash_pid" 2>/dev/null
done >/dev/null 2>&1
sleep 1
fi 2>/dev/null
if ! pidof clash >/dev/null; then
CRASH_NUM=$(expr "$CRASH_NUM" + 1)
if [ "$CRASH_NUM" -le 3 ]; then
LOG_OUT "Watchdog: Clash Core Problem, Restart..."
/etc/init.d/openclash reload "core"
sleep 10
continue
else
LOG_OUT "Watchdog: Already Restart 3 Times With Clash Core Problem, Auto-Exit..."
/etc/init.d/openclash stop
exit 0
fi
else
CRASH_NUM=0
fi
fi
## Porxy history ## Porxy history
/usr/share/openclash/openclash_history_get.sh /usr/share/openclash/openclash_history_get.sh
@ -234,12 +227,19 @@ fi
## Localnetwork 刷新 ## Localnetwork 刷新
wan_ip4s=$(/usr/share/openclash/openclash_get_network.lua "wanip" 2>/dev/null) wan_ip4s=$(/usr/share/openclash/openclash_get_network.lua "wanip" 2>/dev/null)
wan_ip6s=$(ifconfig | grep 'inet6 addr' | awk '{print $3}' 2>/dev/null) wan_ip6s=$(ifconfig | grep 'inet6 addr' | awk '{print $3}' 2>/dev/null)
lan_ip4s=$(/usr/share/openclash/openclash_get_network.lua "lan_cidr" 2>/dev/null)
lan_ip6s=$(/usr/share/openclash/openclash_get_network.lua "lan_cidr6" 2>/dev/null)
if [ -n "$FW4" ]; then if [ -n "$FW4" ]; then
if [ -n "$wan_ip4s" ]; then if [ -n "$wan_ip4s" ]; then
for wan_ip4 in $wan_ip4s; do for wan_ip4 in $wan_ip4s; do
nft add element inet fw4 localnetwork { "$wan_ip4" } 2>/dev/null nft add element inet fw4 localnetwork { "$wan_ip4" } 2>/dev/null
done done
fi fi
if [ -n "$lan_ip4s" ]; then
for lan_ip4 in $lan_ip4s; do
nft add element inet fw4 localnetwork { "$lan_ip4" } 2>/dev/null
done
fi
if [ "$ipv6_enable" -eq 1 ]; then if [ "$ipv6_enable" -eq 1 ]; then
if [ -n "$wan_ip6s" ]; then if [ -n "$wan_ip6s" ]; then
@ -247,6 +247,11 @@ fi
nft add element inet fw4 localnetwork6 { "$wan_ip6" } 2>/dev/null nft add element inet fw4 localnetwork6 { "$wan_ip6" } 2>/dev/null
done done
fi fi
if [ -n "$lan_ip6s" ]; then
for lan_ip6 in $lan_ip6s; do
nft add element inet fw4 localnetwork6 { "$lan_ip6" } 2>/dev/null
done
fi
fi fi
else else
if [ -n "$wan_ip4s" ]; then if [ -n "$wan_ip4s" ]; then
@ -254,12 +259,22 @@ fi
ipset add localnetwork "$wan_ip4" 2>/dev/null ipset add localnetwork "$wan_ip4" 2>/dev/null
done done
fi fi
if [ -n "$lan_ip4s" ]; then
for lan_ip4 in $lan_ip4s; do
ipset add localnetwork "$lan_ip4" 2>/dev/null
done
fi
if [ "$ipv6_enable" -eq 1 ]; then if [ "$ipv6_enable" -eq 1 ]; then
if [ -n "$wan_ip6s" ]; then if [ -n "$wan_ip6s" ]; then
for wan_ip6 in $wan_ip6s; do for wan_ip6 in $wan_ip6s; do
ipset add localnetwork6 "$wan_ip6" 2>/dev/null ipset add localnetwork6 "$wan_ip6" 2>/dev/null
done done
fi fi
if [ -n "$lan_ip6s" ]; then
for lan_ip6 in $lan_ip6s; do
ipset add localnetwork6 "$lan_ip6" 2>/dev/null
done
fi
fi fi
fi fi

View File

@ -0,0 +1 @@
board.zash.run.place

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="size-6" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M11.622 1.602a.75.75 0 0 1 .756 0l2.25 1.313a.75.75 0 0 1-.756 1.295L12 3.118 10.128 4.21a.75.75 0 1 1-.756-1.295l2.25-1.313ZM5.898 5.81a.75.75 0 0 1-.27 1.025l-1.14.665 1.14.665a.75.75 0 1 1-.756 1.295L3.75 8.806v.944a.75.75 0 0 1-1.5 0V7.5a.75.75 0 0 1 .372-.648l2.25-1.312a.75.75 0 0 1 1.026.27Zm12.204 0a.75.75 0 0 1 1.026-.27l2.25 1.312a.75.75 0 0 1 .372.648v2.25a.75.75 0 0 1-1.5 0v-.944l-1.122.654a.75.75 0 1 1-.756-1.295l1.14-.665-1.14-.665a.75.75 0 0 1-.27-1.025Zm-9 5.25a.75.75 0 0 1 1.026-.27L12 11.882l1.872-1.092a.75.75 0 1 1 .756 1.295l-1.878 1.096V15a.75.75 0 0 1-1.5 0v-1.82l-1.878-1.095a.75.75 0 0 1-.27-1.025ZM3 13.5a.75.75 0 0 1 .75.75v1.82l1.878 1.095a.75.75 0 1 1-.756 1.295l-2.25-1.312a.75.75 0 0 1-.372-.648v-2.25A.75.75 0 0 1 3 13.5Zm18 0a.75.75 0 0 1 .75.75v2.25a.75.75 0 0 1-.372.648l-2.25 1.312a.75.75 0 1 1-.756-1.295l1.878-1.096V14.25a.75.75 0 0 1 .75-.75Zm-9 5.25a.75.75 0 0 1 .75.75v.944l1.122-.654a.75.75 0 1 1 .756 1.295l-2.25 1.313a.75.75 0 0 1-.756 0l-2.25-1.313a.75.75 0 1 1 .756-1.295l1.122.654V19.5a.75.75 0 0 1 .75-.75Z" clip-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-6">
<path fill-rule="evenodd" d="M11.622 1.602a.75.75 0 0 1 .756 0l2.25 1.313a.75.75 0 0 1-.756 1.295L12 3.118 10.128 4.21a.75.75 0 1 1-.756-1.295l2.25-1.313ZM5.898 5.81a.75.75 0 0 1-.27 1.025l-1.14.665 1.14.665a.75.75 0 1 1-.756 1.295L3.75 8.806v.944a.75.75 0 0 1-1.5 0V7.5a.75.75 0 0 1 .372-.648l2.25-1.312a.75.75 0 0 1 1.026.27Zm12.204 0a.75.75 0 0 1 1.026-.27l2.25 1.312a.75.75 0 0 1 .372.648v2.25a.75.75 0 0 1-1.5 0v-.944l-1.122.654a.75.75 0 1 1-.756-1.295l1.14-.665-1.14-.665a.75.75 0 0 1-.27-1.025Zm-9 5.25a.75.75 0 0 1 1.026-.27L12 11.882l1.872-1.092a.75.75 0 1 1 .756 1.295l-1.878 1.096V15a.75.75 0 0 1-1.5 0v-1.82l-1.878-1.095a.75.75 0 0 1-.27-1.025ZM3 13.5a.75.75 0 0 1 .75.75v1.82l1.878 1.095a.75.75 0 1 1-.756 1.295l-2.25-1.312a.75.75 0 0 1-.372-.648v-2.25A.75.75 0 0 1 3 13.5Zm18 0a.75.75 0 0 1 .75.75v2.25a.75.75 0 0 1-.372.648l-2.25 1.312a.75.75 0 1 1-.756-1.295l1.878-1.096V14.25a.75.75 0 0 1 .75-.75Zm-9 5.25a.75.75 0 0 1 .75.75v.944l1.122-.654a.75.75 0 1 1 .756 1.295l-2.25 1.313a.75.75 0 0 1-.756 0l-2.25-1.313a.75.75 0 1 1 .756-1.295l1.122.654V19.5a.75.75 0 0 1 .75-.75Z" clip-rule="evenodd" />
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,39 @@
<!doctype html>
<html lang="">
<head>
<meta charset="UTF-8" />
<title>zashboard</title>
<meta
name="viewport"
content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover"
/>
<meta
name="description"
content="A dashboard using clash api"
/>
<link
rel="apple-touch-icon"
href="./apple-touch-icon.png"
/>
<link
rel="icon"
href="./favicon.ico"
sizes="48x48"
/>
<link
rel="icon"
href="./favicon.svg"
sizes="any"
type="image/svg+xml"
/>
<meta
name="theme-color"
content="#FFFFFF"
/>
<script type="module" crossorigin src="./assets/index-DnsHUhFc.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-DrFVUP5k.css">
<link rel="manifest" href="./manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="./registerSW.js"></script></head>
<body>
<div id="app"></div>
</body>
</html>

View File

@ -0,0 +1 @@
{"name":"zashboard","short_name":"zashboard","start_url":"./","display":"standalone","background_color":"#ffffff","lang":"en","scope":"./","description":"a dashboard using clash api","theme_color":"#000000","icons":[{"src":"./pwa-192x192.png","sizes":"192x192","type":"image/png","purpose":"any"},{"src":"./pwa-512x512.png","sizes":"512x512","type":"image/png","purpose":"any"},{"src":"./pwa-maskable-192x192.png","sizes":"192x192","type":"image/png","purpose":"maskable"},{"src":"./pwa-maskable-512x512.png","sizes":"512x512","type":"image/png","purpose":"maskable"}]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -0,0 +1 @@
if('serviceWorker' in navigator) {window.addEventListener('load', () => {navigator.serviceWorker.register('./sw.js', { scope: './' })})}

View File

@ -0,0 +1 @@
if(!self.define){let e,i={};const s=(s,n)=>(s=new URL(s+".js",n).href,i[s]||new Promise((i=>{if("document"in self){const e=document.createElement("script");e.src=s,e.onload=i,document.head.appendChild(e)}else e=s,importScripts(s),i()})).then((()=>{let e=i[s];if(!e)throw new Error(`Module ${s} didnt register its module`);return e})));self.define=(n,r)=>{const d=e||("document"in self?document.currentScript.src:"")||location.href;if(i[d])return;let f={};const c=e=>s(e,d),o={module:{uri:d},exports:f,require:c};i[d]=Promise.all(n.map((e=>o[e]||c(e)))).then((e=>(r(...e),f)))}}define(["./workbox-3e8df8c8"],(function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"assets/index-DnsHUhFc.js",revision:null},{url:"assets/index-DrFVUP5k.css",revision:null},{url:"index.html",revision:"b9c89c6ddeb9522dd6cfbb2001a09b88"},{url:"registerSW.js",revision:"402b66900e731ca748771b6fc5e7a068"},{url:"favicon.svg",revision:"7f1c4521acc10694fefef8f72dd2ea5f"},{url:"pwa-192x192.png",revision:"021df52501f4357c03eebd808f40dc6a"},{url:"pwa-512x512.png",revision:"d2f759aaabcb2c44ff52b27fde3de6e0"},{url:"pwa-maskable-192x192.png",revision:"7cd11dc5f0490b349d23eef5591d10e5"},{url:"pwa-maskable-512x512.png",revision:"8c97dc367a85a5a1eba523b24f79d03b"},{url:"manifest.webmanifest",revision:"c452912633990899ffe790f985ad0db9"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html")))}));

File diff suppressed because one or more lines are too long

View File

@ -374,6 +374,13 @@ threads << Thread.new {
if '${29}' != '0' then if '${29}' != '0' then
Value['global-client-fingerprint']='${29}'; Value['global-client-fingerprint']='${29}';
end; end;
if ${36} == 1 then
if Value.key?('experimental') then
Value['experimental']['quic-go-disable-gso']=true;
else
Value['experimental']={'quic-go-disable-gso'=>true};
end;
end;
if ${16} == 1 then if ${16} == 1 then
Value['dns']['ipv6']=true; Value['dns']['ipv6']=true;
@ -398,7 +405,7 @@ threads << Thread.new {
end; end;
if ${18} == 1 then if ${18} == 1 then
Value_sniffer={'sniffer'=>{'enable'=>true}}; Value_sniffer={'sniffer'=>{'enable'=>true, 'override-destination'=>true, 'sniff'=>{'QUIC'=>{'ports'=>[443]}, 'TLS'=>{'ports'=>[443, 8443]}, 'HTTP'=>{'ports'=>[80, '8080-8880'], 'override-destination'=>true}}, 'force-domain'=>['+.netflix.com', '+.nflxvideo.net', '+.amazonaws.com', '+.media.dssott.com'], 'skip-domain'=>['+.apple.com', 'Mijia Cloud', 'dlg.io.mi.com', '+.oray.com', '+.sunlogin.net', '+.push.apple.com']}};
Value['sniffer']=Value_sniffer['sniffer']; Value['sniffer']=Value_sniffer['sniffer'];
if '$1' == 'redir-host' then if '$1' == 'redir-host' then
Value['sniffer']['force-dns-mapping']=true; Value['sniffer']['force-dns-mapping']=true;
@ -420,7 +427,7 @@ threads << Thread.new {
Value['tun']=Value_2['tun']; Value['tun']=Value_2['tun'];
Value['tun']['stack']='$stack_type'; Value['tun']['stack']='$stack_type';
Value['tun']['device']='utun'; Value['tun']['device']='utun';
Value_2={'dns-hijack'=>['tcp://any:53']}; Value_2={'dns-hijack'=>['127.0.0.1:53']};
Value['tun'].merge!(Value_2); Value['tun'].merge!(Value_2);
Value['tun']['endpoint-independent-nat']=true; Value['tun']['endpoint-independent-nat']=true;
Value['tun']['auto-route']=false; Value['tun']['auto-route']=false;

View File

@ -221,20 +221,6 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
uci_commands << uci_set + 'policy_filter=\"' + x['filter'].to_s + '\"' uci_commands << uci_set + 'policy_filter=\"' + x['filter'].to_s + '\"'
end end
}; };
threads_g << Thread.new {
#interface-name
if x.key?('interface-name') then
uci_commands << uci_set + 'interface_name=\"' + x['interface-name'].to_s + '\"'
end
};
threads_g << Thread.new {
#routing-mark
if x.key?('routing-mark') then
uci_commands << uci_set + 'routing_mark=\"' + x['routing-mark'].to_s + '\"'
end
};
threads_g << Thread.new { threads_g << Thread.new {
#other_group #other_group

View File

@ -217,7 +217,7 @@ yml_groups_set()
{ {
local section="$1" local section="$1"
local enabled config type name disable_udp strategy old_name test_url test_interval tolerance interface_name routing_mark policy_filter local enabled config type name disable_udp strategy old_name test_url test_interval tolerance policy_filter
config_get_bool "enabled" "$section" "enabled" "1" config_get_bool "enabled" "$section" "enabled" "1"
config_get "config" "$section" "config" "" config_get "config" "$section" "config" ""
config_get "type" "$section" "type" "" config_get "type" "$section" "type" ""
@ -228,8 +228,6 @@ yml_groups_set()
config_get "test_url" "$section" "test_url" "" config_get "test_url" "$section" "test_url" ""
config_get "test_interval" "$section" "test_interval" "" config_get "test_interval" "$section" "test_interval" ""
config_get "tolerance" "$section" "tolerance" "" config_get "tolerance" "$section" "tolerance" ""
config_get "interface_name" "$section" "interface_name" ""
config_get "routing_mark" "$section" "routing_mark" ""
config_get "policy_filter" "$section" "policy_filter" "" config_get "policy_filter" "$section" "policy_filter" ""
if [ "$enabled" = "0" ]; then if [ "$enabled" = "0" ]; then
@ -334,12 +332,6 @@ yml_groups_set()
[ -n "$policy_filter" ] && { [ -n "$policy_filter" ] && {
echo " filter: \"$policy_filter\"" >>$GROUP_FILE echo " filter: \"$policy_filter\"" >>$GROUP_FILE
} }
[ -n "$interface_name" ] && {
echo " interface-name: \"$interface_name\"" >>$GROUP_FILE
}
[ -n "$routing_mark" ] && {
echo " routing-mark: \"$routing_mark\"" >>$GROUP_FILE
}
} }
create_config=$(uci -q get openclash.config.create_config) create_config=$(uci -q get openclash.config.create_config)

View File

@ -392,43 +392,6 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
uci_commands << uci_set + 'tfo=\"' + x['tfo'].to_s + '\"' uci_commands << uci_set + 'tfo=\"' + x['tfo'].to_s + '\"'
end end
}; };
threads << Thread.new{
#Multiplex
if x.key?('smux') then
if x['smux'].key?('enabled') then
uci_commands << uci_set + 'multiplex=\"' + x['smux']['enabled'].to_s + '\"'
end;
#multiplex_protocol
if x['smux'].key?('protocol') then
uci_commands << uci_set + 'multiplex_protocol=\"' + x['smux']['protocol'].to_s + '\"'
end;
#multiplex_max_connections
if x['smux'].key?('max-connections') then
uci_commands << uci_set + 'multiplex_max_connections=\"' + x['smux']['max-connections'].to_s + '\"'
end;
#multiplex_min_streams
if x['smux'].key?('min-streams') then
uci_commands << uci_set + 'multiplex_min_streams=\"' + x['smux']['min-streams'].to_s + '\"'
end;
#multiplex_max_streams
if x['smux'].key?('max-streams') then
uci_commands << uci_set + 'multiplex_max_streams=\"' + x['smux']['max-streams'].to_s + '\"'
end;
#multiplex_padding
if x['smux'].key?('padding') then
uci_commands << uci_set + 'multiplex_padding=\"' + x['smux']['padding'].to_s + '\"'
end;
#multiplex_statistic
if x['smux'].key?('statistic') then
uci_commands << uci_set + 'multiplex_statistic=\"' + x['smux']['statistic'].to_s + '\"'
end;
#multiplex_only_tcp
if x['smux'].key?('only-tcp') then
uci_commands << uci_set + 'multiplex_only_tcp=\"' + x['smux']['only-tcp'].to_s + '\"'
end;
end;
};
if x['type'] == 'ss' then if x['type'] == 'ss' then
threads << Thread.new{ threads << Thread.new{
@ -445,6 +408,43 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
end end
}; };
threads << Thread.new{
#Multiplex
if x.key?('smux') then
if x['smux'].key?('enabled') then
uci_commands << uci_set + 'multiplex=\"' + x['smux']['enabled'].to_s + '\"'
end;
#multiplex_protocol
if x['smux'].key?('protocol') then
uci_commands << uci_set + 'multiplex_protocol=\"' + x['smux']['protocol'].to_s + '\"'
end;
#multiplex_max_connections
if x['smux'].key?('max-connections') then
uci_commands << uci_set + 'multiplex_max_connections=\"' + x['smux']['max-connections'].to_s + '\"'
end;
#multiplex_min_streams
if x['smux'].key?('min-streams') then
uci_commands << uci_set + 'multiplex_min_streams=\"' + x['smux']['min-streams'].to_s + '\"'
end;
#multiplex_max_streams
if x['smux'].key?('max-streams') then
uci_commands << uci_set + 'multiplex_max_streams=\"' + x['smux']['max-streams'].to_s + '\"'
end;
#multiplex_padding
if x['smux'].key?('padding') then
uci_commands << uci_set + 'multiplex_padding=\"' + x['smux']['padding'].to_s + '\"'
end;
#multiplex_statistic
if x['smux'].key?('statistic') then
uci_commands << uci_set + 'multiplex_statistic=\"' + x['smux']['statistic'].to_s + '\"'
end;
#multiplex_only_tcp
if x['smux'].key?('only-tcp') then
uci_commands << uci_set + 'multiplex_only_tcp=\"' + x['smux']['only-tcp'].to_s + '\"'
end;
end;
};
threads << Thread.new{ threads << Thread.new{
#plugin-opts #plugin-opts
if x.key?('plugin-opts') then if x.key?('plugin-opts') then
@ -552,6 +552,7 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
end end
}; };
end; end;
if x['type'] == 'vmess' then if x['type'] == 'vmess' then
threads << Thread.new{ threads << Thread.new{
#uuid #uuid
@ -729,6 +730,37 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
}; };
end; end;
#Mieru
if x['type'] == 'mieru' then
threads << Thread.new{
#port-range
if x.key?('port-range') then
uci_commands << uci_set + 'port_range=\"' + x['port-range'].to_s + '\"'
end
};
threads << Thread.new{
#username
if x.key?('username') then
uci_commands << uci_set + 'username=\"' + x['username'].to_s + '\"'
end
};
threads << Thread.new{
#transport
if x.key?('transport') then
uci_commands << uci_set + 'transport=\"' + x['transport'].to_s + '\"'
end
};
threads << Thread.new{
#multiplexing
if x.key?('multiplexing') then
uci_commands << uci_set + 'multiplexing=\"' + x['multiplexing'].to_s + '\"'
end
};
end;
#Tuic #Tuic
if x['type'] == 'tuic' then if x['type'] == 'tuic' then
threads << Thread.new{ threads << Thread.new{
@ -964,6 +996,38 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
end end
}; };
#hysteria2
threads << Thread.new{
#initial_stream_receive_window
if x.key?('initial-stream-receive-window') then
uci_commands << uci_set + 'initial_stream_receive_window=\"' + x['initial-stream-receive-window'].to_s + '\"'
end
};
#hysteria2
threads << Thread.new{
#max_stream_receive_window
if x.key?('max-stream-receive-window') then
uci_commands << uci_set + 'max_stream_receive_window=\"' + x['max-stream-receive-window'].to_s + '\"'
end
};
#hysteria2
threads << Thread.new{
#initial_connection_receive_window
if x.key?('initial-connection-receive-window') then
uci_commands << uci_set + 'initial_connection_receive_window=\"' + x['initial-connection-receive-window'].to_s + '\"'
end
};
#hysteria2
threads << Thread.new{
#max_connection_receive_window
if x.key?('max-connection-receive-window') then
uci_commands << uci_set + 'max_connection_receive_window=\"' + x['max-connection-receive-window'].to_s + '\"'
end
};
#hysteria hysteria2 #hysteria hysteria2
threads << Thread.new{ threads << Thread.new{
#hysteria_obfs #hysteria_obfs
@ -1254,6 +1318,7 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
end end
}; };
end; end;
if x['type'] == 'http' or x['type'] == 'trojan' then if x['type'] == 'http' or x['type'] == 'trojan' then
threads << Thread.new{ threads << Thread.new{
if x.key?('sni') then if x.key?('sni') then
@ -1261,6 +1326,7 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
end end
}; };
end; end;
if x['type'] == 'trojan' then if x['type'] == 'trojan' then
threads << Thread.new{ threads << Thread.new{
#alpn #alpn

View File

@ -263,6 +263,10 @@ yml_servers_set()
config_get "recv_window_conn" "$section" "recv_window_conn" "" config_get "recv_window_conn" "$section" "recv_window_conn" ""
config_get "recv_window" "$section" "recv_window" "" config_get "recv_window" "$section" "recv_window" ""
config_get "disable_mtu_discovery" "$section" "disable_mtu_discovery" "" config_get "disable_mtu_discovery" "$section" "disable_mtu_discovery" ""
config_get "initial_stream_receive_window" "$section" "initial_stream_receive_window" ""
config_get "max_stream_receive_window" "$section" "max_stream_receive_window" ""
config_get "initial_connection_receive_window" "$section" "initial_connection_receive_window" ""
config_get "max_connection_receive_window" "$section" "max_connection_receive_window" ""
config_get "xudp" "$section" "xudp" "" config_get "xudp" "$section" "xudp" ""
config_get "packet_encoding" "$section" "packet_encoding" "" config_get "packet_encoding" "$section" "packet_encoding" ""
config_get "global_padding" "$section" "global_padding" "" config_get "global_padding" "$section" "global_padding" ""
@ -311,6 +315,10 @@ yml_servers_set()
config_get "multiplex_only_tcp" "$section" "multiplex_only_tcp" "" config_get "multiplex_only_tcp" "$section" "multiplex_only_tcp" ""
config_get "other_parameters" "$section" "other_parameters" "" config_get "other_parameters" "$section" "other_parameters" ""
config_get "hysteria_obfs_password" "$section" "hysteria_obfs_password" "" config_get "hysteria_obfs_password" "$section" "hysteria_obfs_password" ""
config_get "port_range" "$section" "port_range" ""
config_get "username" "$section" "username" ""
config_get "transport" "$section" "transport" "TCP"
config_get "multiplexing" "$section" "multiplexing" "MULTIPLEXING_LOW"
if [ "$enabled" = "0" ]; then if [ "$enabled" = "0" ]; then
return return
@ -418,6 +426,14 @@ yml_servers_set()
fi fi
fi fi
if [ "$client_fingerprint" = "none" ]; then
client_fingerprint=""
fi
if [ "$multiplex" = "false" ]; then
multiplex=""
fi
#ss #ss
if [ "$type" = "ss" ]; then if [ "$type" = "ss" ]; then
cat >> "$SERVER_FILE" <<-EOF cat >> "$SERVER_FILE" <<-EOF
@ -692,6 +708,36 @@ EOF
fi fi
fi fi
#Mieru
if [ "$type" = "mieru" ]; then
cat >> "$SERVER_FILE" <<-EOF
- name: "$name"
type: $type
server: "$server"
port: $port
EOF
if [ -n "$port_range" ]; then
cat >> "$SERVER_FILE" <<-EOF
port-range: "$port_range"
EOF
fi
if [ -n "$username" ]; then
cat >> "$SERVER_FILE" <<-EOF
username: "$username"
EOF
fi
if [ -n "$transport" ]; then
cat >> "$SERVER_FILE" <<-EOF
transport: "$transport"
EOF
fi
if [ -n "$multiplexing" ]; then
cat >> "$SERVER_FILE" <<-EOF
multiplexing: "$multiplexing"
EOF
fi
fi
#Tuic #Tuic
if [ "$type" = "tuic" ]; then if [ "$type" = "tuic" ]; then
cat >> "$SERVER_FILE" <<-EOF cat >> "$SERVER_FILE" <<-EOF
@ -978,6 +1024,26 @@ EOF
if [ -n "$hysteria_ca_str" ]; then if [ -n "$hysteria_ca_str" ]; then
cat >> "$SERVER_FILE" <<-EOF cat >> "$SERVER_FILE" <<-EOF
ca-str: "$hysteria_ca_str" ca-str: "$hysteria_ca_str"
EOF
fi
if [ -n "$initial_stream_receive_window" ]; then
cat >> "$SERVER_FILE" <<-EOF
initial-stream-receive-window: "$initial_stream_receive_window"
EOF
fi
if [ -n "$max_stream_receive_window" ]; then
cat >> "$SERVER_FILE" <<-EOF
max_stream_receive_window: "$max_stream_receive_window"
EOF
fi
if [ -n "$initial_connection_receive_window" ]; then
cat >> "$SERVER_FILE" <<-EOF
initial-connection-receive-window: "$initial_connection_receive_window"
EOF
fi
if [ -n "$max_connection_receive_window" ]; then
cat >> "$SERVER_FILE" <<-EOF
max-connection-receive-window: "$max_connection_receive_window"
EOF EOF
fi fi
if [ -n "$fingerprint" ]; then if [ -n "$fingerprint" ]; then
@ -1318,37 +1384,37 @@ cat >> "$SERVER_FILE" <<-EOF
EOF EOF
if [ -n "$multiplex_protocol" ]; then if [ -n "$multiplex_protocol" ]; then
cat >> "$SERVER_FILE" <<-EOF cat >> "$SERVER_FILE" <<-EOF
protocol: $multiplex_protocol protocol: $multiplex_protocol
EOF EOF
fi fi
if [ -n "$multiplex_max_connections" ]; then if [ -n "$multiplex_max_connections" ]; then
cat >> "$SERVER_FILE" <<-EOF cat >> "$SERVER_FILE" <<-EOF
max-connections: $multiplex_max_connections max-connections: $multiplex_max_connections
EOF EOF
fi fi
if [ -n "$multiplex_min_streams" ]; then if [ -n "$multiplex_min_streams" ]; then
cat >> "$SERVER_FILE" <<-EOF cat >> "$SERVER_FILE" <<-EOF
min-streams: $multiplex_min_streams min-streams: $multiplex_min_streams
EOF EOF
fi fi
if [ -n "$multiplex_max_streams" ]; then if [ -n "$multiplex_max_streams" ]; then
cat >> "$SERVER_FILE" <<-EOF cat >> "$SERVER_FILE" <<-EOF
max-streams: $multiplex_max_streams max-streams: $multiplex_max_streams
EOF EOF
fi fi
if [ -n "$multiplex_padding" ]; then if [ -n "$multiplex_padding" ]; then
cat >> "$SERVER_FILE" <<-EOF cat >> "$SERVER_FILE" <<-EOF
padding: $multiplex_padding padding: $multiplex_padding
EOF EOF
fi fi
if [ -n "$multiplex_statistic" ]; then if [ -n "$multiplex_statistic" ]; then
cat >> "$SERVER_FILE" <<-EOF cat >> "$SERVER_FILE" <<-EOF
statistic: $multiplex_statistic statistic: $multiplex_statistic
EOF EOF
fi fi
if [ -n "$multiplex_only_tcp" ]; then if [ -n "$multiplex_only_tcp" ]; then
cat >> "$SERVER_FILE" <<-EOF cat >> "$SERVER_FILE" <<-EOF
only-tcp: $multiplex_only_tcp only-tcp: $multiplex_only_tcp
EOF EOF
fi fi
fi fi

View File

@ -18,7 +18,7 @@ SKIP_CUSTOM_OTHER_RULES=0
yml_set_custom_rule_provider() yml_set_custom_rule_provider()
{ {
local section="$1" local section="$1"
local enabled name config type behavior path url interval group position local enabled name config type behavior path url interval group position other_parameters
config_get_bool "enabled" "$section" "enabled" "1" config_get_bool "enabled" "$section" "enabled" "1"
config_get "name" "$section" "name" "" config_get "name" "$section" "name" ""
config_get "config" "$section" "config" "" config_get "config" "$section" "config" ""
@ -30,6 +30,7 @@ yml_set_custom_rule_provider()
config_get "group" "$section" "group" "" config_get "group" "$section" "group" ""
config_get "position" "$section" "position" "" config_get "position" "$section" "position" ""
config_get "format" "$section" "format" "" config_get "format" "$section" "format" ""
config_get "other_parameters" "$section" "other_parameters" ""
if [ "$enabled" = "0" ]; then if [ "$enabled" = "0" ]; then
return return
@ -63,7 +64,7 @@ yml_set_custom_rule_provider()
else else
path="./rule_provider/$name.yaml" path="./rule_provider/$name.yaml"
fi fi
elif [ -z "$path" ]; then elif [ -z "$path" ] && [ "$type" != "inline" ]; then
return return
fi fi
@ -79,8 +80,12 @@ cat >> "$RULE_PROVIDER_FILE" <<-EOF
$name: $name:
type: $type type: $type
behavior: $behavior behavior: $behavior
EOF
if [ -n "$path" ]; then
cat >> "$RULE_PROVIDER_FILE" <<-EOF
path: $path path: $path
EOF EOF
fi
if [ -n "$format" ]; then if [ -n "$format" ]; then
cat >> "$RULE_PROVIDER_FILE" <<-EOF cat >> "$RULE_PROVIDER_FILE" <<-EOF
format: $format format: $format
@ -93,6 +98,11 @@ cat >> "$RULE_PROVIDER_FILE" <<-EOF
EOF EOF
fi fi
#other_parameters
if [ -n "$other_parameters" ]; then
echo -e "$other_parameters" >> "$RULE_PROVIDER_FILE"
fi
yml_rule_set_add "$name" "$group" "$position" yml_rule_set_add "$name" "$group" "$position"
} }
@ -136,7 +146,6 @@ yml_gen_rule_provider_file()
else else
RULE_PROVIDER_FILE_URL="${github_address_mod}https://raw.githubusercontent.com/${RULE_PROVIDER_FILE_URL_PATH}" RULE_PROVIDER_FILE_URL="${github_address_mod}https://raw.githubusercontent.com/${RULE_PROVIDER_FILE_URL_PATH}"
fi fi
fi fi
if [ -n "$(grep "$RULE_PROVIDER_FILE_URL" $RULE_PROVIDER_FILE 2>/dev/null)" ]; then if [ -n "$(grep "$RULE_PROVIDER_FILE_URL" $RULE_PROVIDER_FILE 2>/dev/null)" ]; then
return return
@ -358,7 +367,7 @@ yml_other_set()
); );
match_group=Value['rules'].grep(/(MATCH|FINAL)/)[0]; match_group=Value['rules'].grep(/(MATCH|FINAL)/)[0];
if not match_group.nil? then if not match_group.nil? then
common_port_group=match_group.split(',')[2] or common_port_group=match_group.split(',')[1]; common_port_group = (match_group.split(',')[-1] =~ /^no-resolve$|^src$/) ? match_group.split(',')[-2] : match_group.split(',')[-1];
if not common_port_group.nil? then if not common_port_group.nil? then
ruby_add_index = Value['rules'].index(Value['rules'].grep(/(MATCH|FINAL)/).first); ruby_add_index = Value['rules'].index(Value['rules'].grep(/(MATCH|FINAL)/).first);
ruby_add_index ||= -1; ruby_add_index ||= -1;
@ -399,23 +408,66 @@ yml_other_set()
YAML.LOG('Error: Set BT/P2P DIRECT Rules Failed,【' + e.message + '】'); YAML.LOG('Error: Set BT/P2P DIRECT Rules Failed,【' + e.message + '】');
end; end;
#Router Self Proxy Rule #Custom Rule Provider
begin begin
if $6 == 0 and $8 != 2 and '$9' == 'fake-ip' then if File::exist?('$RULE_PROVIDER_FILE') then
if Value.has_key?('rules') and not Value['rules'].to_a.empty? then Value_1 = YAML.load_file('$RULE_PROVIDER_FILE');
if Value['rules'].to_a.grep(/(?=.*SRC-IP-CIDR,'$7')/).empty? and not '$7'.empty? then if Value.has_key?('rule-providers') and not Value['rule-providers'].to_a.empty? then
Value['rules']=Value['rules'].to_a.insert(0,'SRC-IP-CIDR,$7/32,DIRECT'); Value['rule-providers'].merge!(Value_1);
end;
else else
Value['rules']=['SRC-IP-CIDR,$7/32,DIRECT']; Value['rule-providers']=Value_1;
end; end;
elsif Value.has_key?('rules') and not Value['rules'].to_a.empty? then
Value['rules'].delete('SRC-IP-CIDR,$7/32,DIRECT');
end; end;
rescue Exception => e rescue Exception => e
YAML.LOG('Error: Set Router Self Proxy Rule Failed,【' + e.message + '】'); YAML.LOG('Error: Custom Rule Provider Merge Failed,【' + e.message + '】');
end; end;
#Game Proxy
begin
if File::exist?('/tmp/yaml_groups.yaml') or File::exist?('/tmp/yaml_servers.yaml') or File::exist?('/tmp/yaml_provider.yaml') then
if File::exist?('/tmp/yaml_groups.yaml') then
Value_1 = YAML.load_file('/tmp/yaml_groups.yaml');
if Value.has_key?('proxy-groups') and not Value['proxy-groups'].to_a.empty? then
Value['proxy-groups'] = Value['proxy-groups'] + Value_1;
Value['proxy-groups'].uniq;
else
Value['proxy-groups'] = Value_1;
end;
end;
if File::exist?('/tmp/yaml_servers.yaml') then
Value_2 = YAML.load_file('/tmp/yaml_servers.yaml');
if Value.has_key?('proxies') and not Value['proxies'].to_a.empty? then
Value['proxies'] = Value['proxies'] + Value_2['proxies'];
Value['proxies'].uniq;
else
Value['proxies']=Value_2['proxies'];
end
end;
if File::exist?('/tmp/yaml_provider.yaml') then
Value_3 = YAML.load_file('/tmp/yaml_provider.yaml');
if Value.has_key?('proxy-providers') and not Value['proxy-providers'].to_a.empty? then
Value['proxy-providers'].merge!(Value_3['proxy-providers']);
Value['proxy-providers'].uniq;
else
Value['proxy-providers']=Value_3['proxy-providers'];
end;
end;
end;
rescue Exception => e
YAML.LOG('Error: Game Proxy Merge Failed,【' + e.message + '】');
end;
#CONFIG_GROUP
CUSTOM_RULE = YAML.load_file('/etc/openclash/custom/openclash_custom_rules.list')
CUSTOM_RULE_2 = YAML.load_file('/etc/openclash/custom/openclash_custom_rules_2.list')
CONFIG_GROUP = (Value['proxy-groups'].map { |x| x['name'] }\
+ ['DIRECT', 'REJECT']\
+ (if Value['proxies'] != nil and not Value['proxies'].empty? then Value['proxies'].map { |x| x['name'] } else [] end)\
+ (if Value['sub-rules'] != nil and not Value['sub-rules'].empty? then Value['sub-rules'].keys else [] end)\
+ (if CUSTOM_RULE['sub-rules'] != nil and not CUSTOM_RULE['sub-rules'].empty? then CUSTOM_RULE['sub-rules'].keys else [] end)\
+ (if CUSTOM_RULE_2['sub-rules'] != nil and not CUSTOM_RULE_2['sub-rules'].empty? then CUSTOM_RULE_2['sub-rules'].keys else [] end)\
).uniq;
#Custom Rule Set #Custom Rule Set
begin begin
if Value.has_key?('rules') and not Value['rules'].to_a.empty? then if Value.has_key?('rules') and not Value['rules'].to_a.empty? then
@ -433,25 +485,61 @@ yml_other_set()
ruby_add_index ||= -1; ruby_add_index ||= -1;
Value_1 = YAML.load_file('/tmp/yaml_rule_set_bottom_custom.yaml'); Value_1 = YAML.load_file('/tmp/yaml_rule_set_bottom_custom.yaml');
if ruby_add_index != -1 then if ruby_add_index != -1 then
Value_1['rules'].uniq.reverse.each{|x| Value['rules'].insert(ruby_add_index,x)}; Value_1['rules'].uniq.reverse.each{|x|
RULE_GROUP = (x.split(',')[-1] =~ /^no-resolve$|^src$/) ? x.split(',')[-2] : x.split(',')[-1];
if CONFIG_GROUP.include?(RULE_GROUP) then
Value['rules'].insert(ruby_add_index,x);
else
YAML.LOG('Warning: Skiped The Custom Rule Because Group & Proxy Not Found:【' + x + '】');
end;
};
else else
Value_1['rules'].uniq.each{|x| Value['rules'].insert(ruby_add_index,x)}; Value_1['rules'].uniq.each{|x|
RULE_GROUP = (x.split(',')[-1] =~ /^no-resolve$|^src$/) ? x.split(',')[-2] : x.split(',')[-1];
if CONFIG_GROUP.include?(RULE_GROUP) then
Value['rules'].insert(ruby_add_index,x);
else
YAML.LOG('Warning: Skiped The Custom Rule Because Group & Proxy Not Found:【' + x + '】');
end;
};
end; end;
end; end;
if File::exist?('/tmp/yaml_rule_set_top_custom.yaml') then if File::exist?('/tmp/yaml_rule_set_top_custom.yaml') then
Value_1 = YAML.load_file('/tmp/yaml_rule_set_top_custom.yaml'); Value_1 = YAML.load_file('/tmp/yaml_rule_set_top_custom.yaml');
Value_1['rules'].uniq.reverse.each{|x| Value['rules'].insert(0,x)}; Value_1['rules'].uniq.reverse.each{|x|
RULE_GROUP = (x.split(',')[-1] =~ /^no-resolve$|^src$/) ? x.split(',')[-2] : x.split(',')[-1];
if CONFIG_GROUP.include?(RULE_GROUP) then
Value['rules'].insert(0,x);
else
YAML.LOG('Warning: Skiped The Custom Rule Because Group & Proxy Not Found:【' + x + '】');
end;
};
end; end;
else else
if File::exist?('/tmp/yaml_rule_set_top_custom.yaml') then if File::exist?('/tmp/yaml_rule_set_top_custom.yaml') then
Value['rules'] = YAML.load_file('/tmp/yaml_rule_set_top_custom.yaml')['rules'].uniq; Value_1 = YAML.load_file('/tmp/yaml_rule_set_top_custom.yaml')['rules'].uniq;
Value_1.each{|x|
RULE_GROUP = (x.split(',')[-1] =~ /^no-resolve$|^src$/) ? x.split(',')[-2] : x.split(',')[-1];
if not CONFIG_GROUP.include?(RULE_GROUP) then
Value_1.delete(x);
YAML.LOG('Warning: Skiped The Custom Rule Because Group & Proxy Not Found:【' + x + '】');
end;
};
Value['rules'] = Value_1;
end; end;
if File::exist?('/tmp/yaml_rule_set_bottom_custom.yaml') then if File::exist?('/tmp/yaml_rule_set_bottom_custom.yaml') then
Value_1 = YAML.load_file('/tmp/yaml_rule_set_bottom_custom.yaml'); Value_1 = YAML.load_file('/tmp/yaml_rule_set_bottom_custom.yaml')['rules'].uniq;
Value_1.each{|x|
RULE_GROUP = (x.split(',')[-1] =~ /^no-resolve$|^src$/) ? x.split(',')[-2] : x.split(',')[-1];
if not CONFIG_GROUP.include?(RULE_GROUP) then
Value_1.delete(x);
YAML.LOG('Warning: Skiped The Custom Rule Because Group & Proxy Not Found:【' + x + '】');
end;
};
if File::exist?('/tmp/yaml_rule_set_top_custom.yaml') then if File::exist?('/tmp/yaml_rule_set_top_custom.yaml') then
Value['rules'] = Value['rules'] | Value_1['rules'].uniq; Value['rules'] = Value['rules'] | Value_1;
else else
Value['rules'] = Value_1['rules'].uniq; Value['rules'] = Value_1;
end; end;
end; end;
end; end;
@ -476,7 +564,12 @@ yml_other_set()
end; end;
if defined? Value_2 then if defined? Value_2 then
Value_2.each{|x| Value_2.each{|x|
Value['rules'].insert(0,x); RULE_GROUP = (x.split(',')[-1] =~ /^no-resolve$|^src$/) ? x.split(',')[-2] : x.split(',')[-1];
if CONFIG_GROUP.include?(RULE_GROUP) then
Value['rules'].insert(0,x);
else
YAML.LOG('Warning: Skiped The Custom Rule Because Group & Proxy Not Found:【' + x + '】');
end;
}; };
Value['rules'] = Value['rules'].uniq; Value['rules'] = Value['rules'].uniq;
end; end;
@ -504,7 +597,12 @@ yml_other_set()
Value_4 = Value_4.reverse!; Value_4 = Value_4.reverse!;
end; end;
Value_4.each{|x| Value_4.each{|x|
Value['rules'].insert(ruby_add_index,x); RULE_GROUP = (x.split(',')[-1] =~ /^no-resolve$|^src$/) ? x.split(',')[-2] : x.split(',')[-1];
if CONFIG_GROUP.include?(RULE_GROUP) then
Value['rules'].insert(ruby_add_index,x);
else
YAML.LOG('Warning: Skiped The Custom Rule Because Group & Proxy Not Found:【' + x + '】');
end;
}; };
Value['rules'] = Value['rules'].uniq; Value['rules'] = Value['rules'].uniq;
end; end;
@ -516,10 +614,24 @@ yml_other_set()
if Value_1 != false then if Value_1 != false then
if Value_1.class.to_s == 'Hash' then if Value_1.class.to_s == 'Hash' then
if not Value_1['rules'].to_a.empty? and Value_1['rules'].class.to_s == 'Array' then if not Value_1['rules'].to_a.empty? and Value_1['rules'].class.to_s == 'Array' then
Value_1['rules'].to_a.each{|x|
RULE_GROUP = (x.split(',')[-1] =~ /^no-resolve$|^src$/) ? x.split(',')[-2] : x.split(',')[-1];
if not CONFIG_GROUP.include?(RULE_GROUP) then
Value_1['rules'].delete(x);
YAML.LOG('Warning: Skiped The Custom Rule Because Group & Proxy Not Found:【' + x + '】');
end;
};
Value['rules'] = Value_1['rules']; Value['rules'] = Value_1['rules'];
Value['rules'] = Value['rules'].uniq; Value['rules'] = Value['rules'].uniq;
end; end;
elsif Value_1.class.to_s == 'Array' then elsif Value_1.class.to_s == 'Array' then
Value_1.each{|x|
RULE_GROUP = (x.split(',')[-1] =~ /^no-resolve$|^src$/) ? x.split(',')[-2] : x.split(',')[-1];
if not CONFIG_GROUP.include?(RULE_GROUP) then
Value_1.delete(x);
YAML.LOG('Warning: Skiped The Custom Rule Because Group & Proxy Not Found:【' + x + '】');
end;
};
Value['rules'] = Value_1; Value['rules'] = Value_1;
Value['rules'] = Value['rules'].uniq; Value['rules'] = Value['rules'].uniq;
end; end;
@ -531,10 +643,24 @@ yml_other_set()
if Value['rules'].to_a.empty? then if Value['rules'].to_a.empty? then
if Value_2.class.to_s == 'Hash' then if Value_2.class.to_s == 'Hash' then
if not Value_2['rules'].to_a.empty? and Value_2['rules'].class.to_s == 'Array' then if not Value_2['rules'].to_a.empty? and Value_2['rules'].class.to_s == 'Array' then
Value_2['rules'].to_a.each{|x|
RULE_GROUP = (x.split(',')[-1] =~ /^no-resolve$|^src$/) ? x.split(',')[-2] : x.split(',')[-1];
if not CONFIG_GROUP.include?(RULE_GROUP) then
Value_2['rules'].delete(x);
YAML.LOG('Warning: Skiped The Custom Rule Because Group & Proxy Not Found:【' + x + '】');
end;
};
Value['rules'] = Value_2['rules']; Value['rules'] = Value_2['rules'];
Value['rules'] = Value['rules'].uniq; Value['rules'] = Value['rules'].uniq;
end; end;
elsif Value_2.class.to_s == 'Array' then elsif Value_2.class.to_s == 'Array' then
Value_2.each{|x|
RULE_GROUP = (x.split(',')[-1] =~ /^no-resolve$|^src$/) ? x.split(',')[-2] : x.split(',')[-1];
if not CONFIG_GROUP.include?(RULE_GROUP) then
Value_2.delete(x);
YAML.LOG('Warning: Skiped The Custom Rule Because Group & Proxy Not Found:【' + x + '】');
end;
};
Value['rules'] = Value_2; Value['rules'] = Value_2;
Value['rules'] = Value['rules'].uniq; Value['rules'] = Value['rules'].uniq;
end; end;
@ -558,7 +684,12 @@ yml_other_set()
Value_3 = Value_3.reverse!; Value_3 = Value_3.reverse!;
end end
Value_3.each{|x| Value_3.each{|x|
Value['rules'].insert(ruby_add_index,x); RULE_GROUP = (x.split(',')[-1] =~ /^no-resolve$|^src$/) ? x.split(',')[-2] : x.split(',')[-1];
if CONFIG_GROUP.include?(RULE_GROUP) then
Value['rules'].insert(ruby_add_index,x);
else
YAML.LOG('Warning: Skiped The Custom Rule Because Group & Proxy Not Found:【' + x + '】');
end;
}; };
Value['rules'] = Value['rules'].uniq; Value['rules'] = Value['rules'].uniq;
end; end;
@ -614,60 +745,28 @@ yml_other_set()
rescue Exception => e rescue Exception => e
YAML.LOG('Error: Set Custom Rules Failed,【' + e.message + '】'); YAML.LOG('Error: Set Custom Rules Failed,【' + e.message + '】');
end; end;
#Router Self Proxy Rule
begin
if $6 == 0 and $8 != 2 and '$9' == 'fake-ip' then
if Value.has_key?('rules') and not Value['rules'].to_a.empty? then
if Value['rules'].to_a.grep(/(?=.*SRC-IP-CIDR,'$7')/).empty? and not '$7'.empty? then
Value['rules']=Value['rules'].to_a.insert(0,'SRC-IP-CIDR,$7/32,DIRECT');
end;
else
Value['rules']=['SRC-IP-CIDR,$7/32,DIRECT'];
end;
elsif Value.has_key?('rules') and not Value['rules'].to_a.empty? then
Value['rules'].delete('SRC-IP-CIDR,$7/32,DIRECT');
end;
rescue Exception => e
YAML.LOG('Error: Set Router Self Proxy Rule Failed,【' + e.message + '】');
end;
}; };
t2=Thread.new{ t2=Thread.new{
#Create threads #Create threads
threads = []; threads = [];
#Custom Rule Provider
begin
if File::exist?('$RULE_PROVIDER_FILE') then
Value_1 = YAML.load_file('$RULE_PROVIDER_FILE');
if Value.has_key?('rule-providers') and not Value['rule-providers'].to_a.empty? then
Value['rule-providers'].merge!(Value_1);
else
Value['rule-providers']=Value_1;
end;
end;
rescue Exception => e
YAML.LOG('Error: Custom Rule Provider Merge Failed,【' + e.message + '】');
end;
#Game Proxy
begin
if File::exist?('/tmp/yaml_groups.yaml') or File::exist?('/tmp/yaml_servers.yaml') or File::exist?('/tmp/yaml_provider.yaml') then
if File::exist?('/tmp/yaml_groups.yaml') then
Value_1 = YAML.load_file('/tmp/yaml_groups.yaml');
if Value.has_key?('proxy-groups') and not Value['proxy-groups'].to_a.empty? then
Value['proxy-groups'] = Value['proxy-groups'] + Value_1;
Value['proxy-groups'].uniq;
else
Value['proxy-groups'] = Value_1;
end;
end;
if File::exist?('/tmp/yaml_servers.yaml') then
Value_2 = YAML.load_file('/tmp/yaml_servers.yaml');
if Value.has_key?('proxies') and not Value['proxies'].to_a.empty? then
Value['proxies'] = Value['proxies'] + Value_2['proxies'];
Value['proxies'].uniq;
else
Value['proxies']=Value_2['proxies'];
end
end;
if File::exist?('/tmp/yaml_provider.yaml') then
Value_3 = YAML.load_file('/tmp/yaml_provider.yaml');
if Value.has_key?('proxy-providers') and not Value['proxy-providers'].to_a.empty? then
Value['proxy-providers'].merge!(Value_3['proxy-providers']);
Value['proxy-providers'].uniq;
else
Value['proxy-providers']=Value_3['proxy-providers'];
end;
end;
end;
rescue Exception => e
YAML.LOG('Error: Game Proxy Merge Failed,【' + e.message + '】');
end;
#provider path #provider path
begin begin
@ -681,6 +780,9 @@ yml_other_set()
v=File.basename(x['path']); v=File.basename(x['path']);
x['path']='./'+p+'/'+v; x['path']='./'+p+'/'+v;
end; end;
if not x['path'] and x['type'] == 'http' then
x['path']='./'+p+'/'+x['name'];
end;
#CDN Replace #CDN Replace
if '$github_address_mod' != '0' then if '$github_address_mod' != '0' then
if '$github_address_mod' == 'https://cdn.jsdelivr.net/' or '$github_address_mod' == 'https://fastly.jsdelivr.net/' or '$github_address_mod' == 'https://testingcf.jsdelivr.net/'then if '$github_address_mod' == 'https://cdn.jsdelivr.net/' or '$github_address_mod' == 'https://fastly.jsdelivr.net/' or '$github_address_mod' == 'https://testingcf.jsdelivr.net/'then

View File

@ -0,0 +1,153 @@
/*
Name: material
Author: Mattia Astorino (http://github.com/equinusocio)
Website: https://material-theme.site/
*/
.cm-s-material-log.CodeMirror {
background-color: #263238;
color: #EEFFFF;
}
.cm-s-material-log .CodeMirror-gutters {
background: #263238;
color: #546E7A;
border: none;
}
.cm-s-material-log .CodeMirror-guttermarker,
.cm-s-material-log .CodeMirror-guttermarker-subtle,
.cm-s-material-log .CodeMirror-linenumber {
color: #546E7A;
}
.cm-s-material-log .CodeMirror-cursor {
border-left: 1px solid #FFCC00;
}
.cm-s-material-log.cm-fat-cursor .CodeMirror-cursor {
background-color: #5d6d5c80 !important;
}
.cm-s-material-log .cm-animate-fat-cursor {
background-color: #5d6d5c80 !important;
}
.cm-s-material-log div.CodeMirror-selected {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material-log.CodeMirror-focused div.CodeMirror-selected {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material-log .CodeMirror-line::selection,
.cm-s-material-log .CodeMirror-line>span::selection,
.cm-s-material-log .CodeMirror-line>span>span::selection {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material-log .CodeMirror-line::-moz-selection,
.cm-s-material-log .CodeMirror-line>span::-moz-selection,
.cm-s-material-log .CodeMirror-line>span>span::-moz-selection {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material-log .CodeMirror-activeline-background {
background: rgba(0, 0, 0, 0.5);
}
.cm-s-material-log .cm-keyword {
color: #C792EA;
}
.cm-s-material-log .cm-operator {
color: #89DDFF;
}
.cm-s-material-log .cm-variable-2 {
color: #EEFFFF;
}
.cm-s-material-log .cm-variable-3 {
color: #EEFFFF;
}
.cm-s-material-log .cm-type {
color: #f07178;
}
.cm-s-material-log .cm-builtin {
color: #FFCB6B;
}
.cm-s-material-log .cm-atom {
color: #F78C6C;
}
.cm-s-material-log .cm-number {
color: #FF5370;
}
.cm-s-material-log .cm-def {
color: #82AAFF;
}
.cm-s-material-log .cm-string {
color: #C3E88D;
}
.cm-s-material-log .cm-string-2 {
color: #C3E88D;
}
.cm-s-material-log .cm-comment {
color: #546E7A;
}
.cm-s-material-log .cm-variable {
color: #EEFFFF;
}
.cm-s-material-log .cm-tag {
color: #FF5370;
}
.cm-s-material-log .cm-tip {
color: #ff6f00;
}
.cm-s-material-log .cm-watchdog {
color: #b300ff;
}
.cm-s-material-log .cm-warn {
line-height: 1em;
font-weight: bold;
color: #ff00bb;
}
.cm-s-material-log .cm-meta {
color: #FFCB6B;
}
.cm-s-material-log .cm-attribute {
color: #C792EA;
}
.cm-s-material-log .cm-property {
color: #C792EA;
}
.cm-s-material-log .cm-qualifier {
color: #DECB6B;
}
.cm-s-material-log .cm-error {
line-height: 1em;
font-weight: bold;
color: #FF0000;
}
.cm-s-material-log .CodeMirror-matchingbracket {
text-decoration: underline;
color: white !important;
}