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
PKG_NAME:=luci-app-openclash
PKG_VERSION:=0.46.064
PKG_VERSION:=0.46.075
PKG_MAINTAINER:=vernesong <https://github.com/vernesong/OpenClash>
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
@ -42,8 +42,8 @@ define Package/$(PKG_NAME)
SUBMENU:=3. Applications
TITLE:=LuCI support for clash
PKGARCH:=all
DEPENDS:=+dnsmasq-full +coreutils +coreutils-nohup +bash +curl +ca-certificates +ip-full \
+libcap +libcap-bin +ruby +ruby-yaml +kmod-tun +unzip
DEPENDS:=+dnsmasq-full +bash +curl +ca-bundle +ip-full \
+ruby +ruby-yaml +kmod-tun +unzip
MAINTAINER:=vernesong
endef
@ -122,9 +122,9 @@ endef
define Package/$(PKG_NAME)/postrm
#!/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
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
DNSMASQ_CONF_DIR="/tmp/dnsmasq.d"
fi

View File

@ -31,6 +31,7 @@ function index()
entry({"admin", "services", "openclash", "opupdate"},call("action_opupdate"))
entry({"admin", "services", "openclash", "coreupdate"},call("action_coreupdate"))
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", "restore"}, call("action_restore_config"))
entry({"admin", "services", "openclash", "backup"}, call("action_backup"))
@ -252,7 +253,7 @@ local function opcv()
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}'")
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
@ -355,6 +356,11 @@ function action_flush_fakeip_cache()
})
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()
uci:set("openclash", "config", "enable", "0")
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_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/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 &")
end

View File

@ -95,6 +95,20 @@ if a then
SYS.call("/etc/init.d/openclash restart >/dev/null 2>&1 &")
HTTP.redirect(luci.dispatcher.build_url("admin", "services", "openclash", "client"))
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
if not a then
@ -152,6 +166,7 @@ o.inputstyle = "reset"
o.write = function()
uci:set("openclash", "config", "enable", 0)
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 &")
end

View File

@ -280,7 +280,7 @@ o.description = font_red..bold_on..translate("Change The Delay Calculation Metho
o.default = "0"
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("off", translate("OFF "))
o:value("always", translate("Always "))

View File

@ -180,7 +180,7 @@ o:depends("sub_convert", "1")
---- 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:depends("sub_convert", "1")

View File

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

View File

@ -259,7 +259,7 @@ btnrn.template="openclash/input_rename"
btnrn.rawhtml = true
btnrn.render=function(c,t,a)
c.value = e[t].name
Button.render(c,t,a)
DummyValue.render(c,t,a)
end
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.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.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"))

View File

@ -59,6 +59,7 @@ o.rmempty = true
o.description = translate("Choose The Provider Type")
o:value("http")
o:value("file")
o:value("inline")
o = s:option(Value, "name", translate("Provider Name"))
o.rmempty = false
@ -134,7 +135,16 @@ function o.cfgvalue(self, section)
"# proxy-name:\n"..
"# - pattern: \"IPLC-(.*?)倍\"\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
return Value.cfgvalue(self, section)
end

View File

@ -57,22 +57,25 @@ o.default = "Rule-provider - "..sid
o = s:option(ListValue, "type", translate("Rule Providers Type"))
o.rmempty = true
o.description = translate("Choose The Rule Providers Type")
o:value("http", translate("http"))
o:value("file", translate("file"))
o:value("http")
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.rmempty = true
o.description = translate("Choose The Rule Behavior")
o:value("domain")
o:value("ipcidr")
o:value("classical")
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:value("classical", translate("classical").." "..translate("(Not Support mrs Format)"))
o = s:option(ListValue, "path", translate("Rule Providers Path"))
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("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 = {
{Commit, Back}
}
@ -159,4 +192,5 @@ o.write = function()
end
m:append(Template("openclash/toolbar_show"))
m:append(Template("openclash/config_editor"))
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("tuic", translate("Tuic")..translate("(Only Meta Core)"))
o:value("snell", translate("Snell"))
o:value("mieru", translate("Mieru"))
o:value("socks5", translate("Socks5"))
o:value("http", translate("HTTP(S)"))
@ -182,6 +183,35 @@ o:depends("type", "ss")
o:depends("type", "ssr")
o:depends("type", "trojan")
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 ]]--
o = s:option(Value, "tc_ip", translate("Server IP"))
@ -706,6 +736,7 @@ o:depends("type", "hysteria2")
-- [[ recv_window_conn ]]--
o = s:option(Flag, "flag_quicparam", translate("Hysterir QUIC parameters"))
o:depends("type", "hysteria")
o:depends("type", "hysteria2")
o.rmempty = true
o.default = "0"
@ -722,6 +753,34 @@ o.placeholder = translate("QUIC connection receive window")
o.datatype = "uinteger"
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 ]]--
o = s:option(Value, "hop_interval", translate("Hop Interval (Unit:second)"))
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.rmempty = true
o:value("none")
o:value("random")
o:value("chrome")
o:value("firefox")
o:value("safari")
@ -836,6 +896,7 @@ o.rmempty = false
o:value("true")
o:value("false")
o.default = "false"
o:depends({type = "ss", obfs = "none"})
o = s:option(ListValue, "multiplex_protocol", translate("Protocol"))
o.rmempty = true

View File

@ -14,7 +14,7 @@ font_off = [[</b>]]
bold_on = [[<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
local lan_ip = fs.lanip()
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.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.description = translate("Move Core And GEOIP Data File To /tmp/etc/openclash For Small Flash Memory Device")
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"
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.default = 0
o:depends("enable_redirect_dns", "1")
@ -216,9 +214,10 @@ o.cfgvalue = function(...)
end
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.rmempty = false
ip_ac.rmempty = true
ip_ac:value("localnetwork", translate("Local Network"))
o = s2:option(Value, "src_port", translate("Internal ports"))
o.datatype = "or(port, portrange)"
@ -240,8 +239,9 @@ o.default = "tcp"
o.rmempty = false
o = s2:option(ListValue, "target", translate("Target"))
o:value("return", translate("Return"))
o:value("accept", translate("Accept"))
o:value("return", translate("RETURN"))
o:value("accept", translate("ACCEPT"))
o:value("drop", translate("DROP"))
o.rmempty = false
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.datatype = "uinteger"
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.default = "urltest"
@ -398,27 +399,21 @@ o.default = 0
o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_netflix", translate("Group Filter"))
o.default = "Netflix|奈飞"
o.placeholder = "Netflix|奈飞"
o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
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.default = ""
o.placeholder = "HK|SG|TW"
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_netflix", "1")
function o.validate(self, value)
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.rmempty = true
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:depends("stream_auto_select_netflix", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "Netflix", translate("Manual Test"))
o.rawhtml = true
@ -432,27 +427,21 @@ o.default = 0
o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_disney", translate("Group Filter"))
o.default = "Disney|迪士尼"
o.placeholder = "Disney|迪士尼"
o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
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.default = ""
o.placeholder = "HK|SG|TW"
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_disney", "1")
function o.validate(self, value)
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.rmempty = true
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:depends("stream_auto_select_disney", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "Disney Plus", translate("Manual Test"))
o.rawhtml = true
@ -466,27 +455,21 @@ o.default = 0
o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_ytb", translate("Group Filter"))
o.default = "YouTube|油管"
o.placeholder = "YouTube|油管"
o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
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.default = ""
o.placeholder = "HK|US"
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_ytb", "1")
function o.validate(self, value)
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.rmempty = true
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:depends("stream_auto_select_ytb", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "YouTube Premium", translate("Manual Test"))
o.rawhtml = true
@ -500,27 +483,21 @@ o.default = 0
o:depends("stream_auto_select", "1")
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.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
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.default = ""
o.placeholder = "HK|US|SG"
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_prime_video", "1")
function o.validate(self, value)
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.rmempty = true
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:depends("stream_auto_select_prime_video", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "Amazon Prime Video", translate("Manual Test"))
o.rawhtml = true
@ -534,27 +511,21 @@ o.default = 0
o:depends("stream_auto_select", "1")
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.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
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.default = ""
o.placeholder = "US"
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_hbo_max", "1")
function o.validate(self, value)
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.rmempty = true
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:depends("stream_auto_select_hbo_max", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "HBO Max", translate("Manual Test"))
o.rawhtml = true
@ -568,27 +539,21 @@ o.default = 0
o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_tvb_anywhere", translate("Group Filter"))
o.default = "TVB"
o.placeholder = "TVB"
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.rmempty = true
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.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_tvb_anywhere", "1")
function o.validate(self, value)
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.rmempty = true
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:depends("stream_auto_select_tvb_anywhere", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "TVB Anywhere+", translate("Manual Test"))
o.rawhtml = true
@ -602,27 +567,21 @@ o.default = 0
o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_dazn", translate("Group Filter"))
o.default = "DAZN"
o.placeholder = "DAZN"
o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
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.default = ""
o.placeholder = "DE"
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_dazn", "1")
function o.validate(self, value)
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.rmempty = true
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:depends("stream_auto_select_dazn", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "DAZN", translate("Manual Test"))
o.rawhtml = true
@ -636,27 +595,21 @@ o.default = 0
o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_paramount_plus", translate("Group Filter"))
o.default = "Paramount"
o.placeholder = "Paramount"
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.rmempty = true
o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_paramount_plus", translate("Unlock Region Filter"))
o.default = ""
o.placeholder = "US"
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_paramount_plus", "1")
function o.validate(self, value)
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.rmempty = true
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:depends("stream_auto_select_paramount_plus", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "Paramount Plus", translate("Manual Test"))
o.rawhtml = true
@ -670,27 +623,21 @@ o.default = 0
o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_discovery_plus", translate("Group Filter"))
o.default = "Discovery"
o.placeholder = "Discovery"
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.rmempty = true
o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_discovery_plus", translate("Unlock Region Filter"))
o.default = ""
o.placeholder = "US"
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_discovery_plus", "1")
function o.validate(self, value)
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.rmempty = true
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:depends("stream_auto_select_discovery_plus", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "Discovery Plus", translate("Manual Test"))
o.rawhtml = true
@ -704,10 +651,10 @@ o.default = 0
o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_bilibili", translate("Group Filter"))
o.default = "Bilibili"
o.placeholder = "Bilibili"
o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
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.default = "CN"
@ -716,17 +663,12 @@ o:value("HK/MO/TW", translate("Hongkong/Macau/Taiwan"))
o:value("TW", translate("Taiwan Only"))
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_bilibili", "1")
function o.validate(self, value)
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.rmempty = false
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:depends("stream_auto_select_bilibili", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "Bilibili", translate("Manual Test"))
o.rawhtml = true
@ -740,15 +682,15 @@ o.default = 0
o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_google_not_cn", translate("Group Filter"))
o.default = "Google"
o.placeholder = "Google"
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.rmempty = true
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:depends("stream_auto_select_google_not_cn", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "Google", translate("Manual Test"))
o.rawhtml = true
@ -762,27 +704,21 @@ o.default = 0
o:depends("stream_auto_select", "1")
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.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
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.default = ""
o.placeholder = "US"
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_openai", "1")
function o.validate(self, value)
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.rmempty = true
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:depends("stream_auto_select_openai", "1")
o.rmempty = true
o = s:taboption("stream_enhance", DummyValue, "OpenAI", translate("Manual Test"))
o.rawhtml = true
@ -1068,6 +1004,10 @@ o = s:taboption("dashboard", DummyValue, "Metacubexd", translate("Update Metacub
o.template="openclash/switch_dashboard"
o.rawhtml = true
o = s:taboption("dashboard", DummyValue, "zashboard", translate("Update zashboard Version"))
o.template="openclash/switch_dashboard"
o.rawhtml = true
---- ipv6
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

View File

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

View File

@ -28,6 +28,7 @@
</style>
<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-log.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/lint/lint.css">
@ -87,6 +88,33 @@ local sconf = "/etc/openclash/"..conf_name
</table>
<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)
{
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");
oc_editor.setSize("100%", "540px");
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');

View File

@ -6,6 +6,44 @@
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no,minimal-ui">
<style>
:root[data-darkmode="true"] {
.card {
background: linear-gradient(rgb(0, 0, 0), rgb(70, 70, 70));
}
.card .additional {
background: linear-gradient(#337ab7, rgb(70, 70, 70));
}
.card .general .dler-title{
color: #bbbbbb;
}
.card .general .dler-result{
color: #bbbbbb;
}
.card .general .dler-result2{
color: #bbbbbb;
}
.card .general h1 {
color: #bbbbbb;
}
.card .additional .user-card::after {
border-left: 2px solid #bbbbbb;
}
.card .additional .more-info h1 {
color: #bbbbbb;
}
.card .additional .coords {
color: #bbbbbb;
}
}
.center {
top: 50%;
left: 50%;
@ -50,7 +88,7 @@
top: 10%;
right: -2px;
height: 80%;
border-left: 2px solid rgba(0,0,0,0.025);*/
border-left: 2px solid rgba(0,0,0,0.025);
}
.card .additional .user-card img {

View File

@ -132,10 +132,15 @@
text-align: left;
}
@media only screen and (max-width: 600px) {
.myip {
min-width: 700px !important;
flex-direction: column !important;
:root[data-darkmode="true"] {
#eye-icon {
-webkit-filter: invert(1);
filter: invert(1);
}
#data-refresh-icon {
-webkit-filter: invert(1);
filter: invert(1);
}
}
</style>
@ -144,7 +149,7 @@
<fieldset class="cbi-section">
<table width="100%">
<tr><td>
<div class="myip" style="display: flex; min-width: 820px;">
<div style="display: flex; min-width: 820px;">
<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%>
<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 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%>
<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 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>

View File

@ -1,5 +1,16 @@
<style type="text/css">
:root[data-darkmode="true"] {
.select-popup {
background-color: #000000;
}
.select-option:hover {
background-color: #444444;
}
}
.select-popup {
position: fixed;
top: 50%;
@ -16,6 +27,10 @@
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5);
}
.select-class {
width: auto;
}
.select-popup.hidden {
display: none;
}
@ -52,7 +67,7 @@
<div id="selectPopup" class="select-popup hidden">
<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"><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-amd64"><%:linux-amd64(x86-64)%></option>
<option value="linux-amd64-v3"><%:linux-amd64-v3(x86-64)%></option>
@ -73,7 +88,7 @@
<option value="0"><%:Not Set%></option>
</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"><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="dev">Developer</option>
</select></td>
@ -97,6 +112,36 @@
var core_version_cdn = document.getElementById('CORE_VERSION_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() {
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_info")%>', null, function(x, status) {
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)"/>
<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>
<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">
<div style="margin: 10px 0; text-align: center">
<span>
@ -193,6 +193,7 @@
var web = document.getElementById('_web');
var webo = document.getElementById('_webo');
var webm = document.getElementById('_webm');
var webz = document.getElementById('_webz');
var watchdog = document.getElementById('_watchdog');
var daip = document.getElementById('_daip');
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>';
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>';
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>';
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>';
@ -851,6 +853,27 @@
});
};
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)
{
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "status")%>', null, function(x, status) {

View File

@ -35,12 +35,22 @@
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"] {
#icon_wrench {
-webkit-filter: invert(1);
filter: invert(1);
}
#icon_arrow {
-webkit-filter: invert(1);
filter: invert(1);
@ -63,12 +73,42 @@ var retry_<%=idname%> = 0;
var s_<%=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) {
return String.format(
'<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">')) +
'<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>', pc, v, m, pc, t, tr

View File

@ -27,6 +27,9 @@
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\')"/>';
}
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,8 +57,10 @@
{
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\')"/>';
} 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\')"/>';
}
}
}
@ -63,7 +68,7 @@
btn.value = '<%:Unzip Error%>';
}
else {
if ( name == "Metacubexd" ) {
if ( name == "Metacubexd" || name == "zashboard" ) {
btn.value = '<%:Update Failed%>';
}
else {

View File

@ -36,7 +36,7 @@
&nbsp;&nbsp;<%:Current Config File%>:&nbsp;
<select class="tool_label_select" id="cfg_name">
</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;
</span>
</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"
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"
msgstr "*自定义上游 DNS 服务器"
@ -789,6 +780,18 @@ msgstr "启用传输协议设置"
msgid "Hysterir QUIC parameters"
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"
msgstr "编辑规则集配置"
@ -1189,13 +1192,16 @@ msgid "Running Mode"
msgstr "运行模式"
msgid "Yacd Control Panel"
msgstr "Yacd 控制面板"
msgstr "Yacd 面板"
msgid "Dashboard Control Panel"
msgstr "Dashboard 控制面板"
msgstr "Dashboard 面板"
msgid "Metacubexd Control Panel"
msgstr "Metacubexd 控制面板"
msgstr "Metacubexd 面板"
msgid "zashboard Control Panel"
msgstr "zashboard 面板"
msgid "Control Panel Login IP"
msgstr "控制面板登录 IP"
@ -1605,8 +1611,11 @@ msgstr "开始下载"
msgid "Download Successful, Start Pre Update Test..."
msgstr "下载成功,开始进行更新前测试..."
msgid "Pre Update Test Failed, The File is Saved in /tmp/openclash.ipk, Please Try to Update Manually!"
msgstr "更新前测试失败,文件保存在 /tmp/openclash.ipk请尝试手动更新"
msgid "Pre Update Test Failed, The File is Saved in /tmp/openclash.apk, Please Try to Update Manually With"
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..."
msgstr "更新前测试通过,准备开始更新,更新过程请不要刷新页面和进行其他操作..."
@ -1620,11 +1629,11 @@ msgstr "正在安装新版本,更新过程请不要刷新页面和进行其他
msgid "OpenClash Update Successful, About To Restart!"
msgstr "OpenClash 更新成功,即将进行重启!"
msgid "OpenClash Update Failed, The File is Saved in /tmp/openclash.ipk, Please Try to Update Manually!"
msgstr "OpenClash 更新失败,文件保存在 /tmp/openclash.ipk请尝试手动更新"
msgid "OpenClash Update Failed, The File is Saved in /tmp/openclash.ipk, Please Try to Update Manually With"
msgstr "OpenClash 更新失败,文件保存在 /tmp/openclash.ipk请尝试以下命令手动更新"
msgid "OpenClash Update Failed, The File is Saved in /tmp/openclash.apk, Please Try to Update Manually!"
msgstr "OpenClash 更新失败,文件保存在 /tmp/openclash.apk请尝试手动更新"
msgid "OpenClash Update Failed, The File is Saved in /tmp/openclash.apk, Please Try to Update Manually With"
msgstr "OpenClash 更新失败,文件保存在 /tmp/openclash.apk请尝试以下命令手动更新"
msgid "Download Failed, Please Check The Network or Try Again Later!"
msgstr "下载失败,请检查网络或稍后再试!"
@ -1965,12 +1974,6 @@ msgstr "提示:检测到大陆白名单列表不存在,准备开始下载...
msgid "Tip: Detected that the Chnroute Cidr List Format is wrong, Ready to Reformat..."
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!"
msgstr "错误OpenClash 启动失败,请到日志页面查看详细错误信息!"
@ -2043,18 +2046,6 @@ msgstr "重置 OpenClash 防火墙规则..."
msgid "Warning: OpenClash Now Disabled, Need Start From Luci Page, Exit..."
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..."
msgstr "守护程序:因日志大小限制,清理所有日志内容..."
@ -2721,8 +2712,8 @@ msgstr "未选择上传文件"
msgid "Custom Params"
msgstr "自定义参数"
msgid "eg: \"rename=\\s+([2-9])[xX]@ (HIGH:$1)\""
msgstr "格式示例:\"rename=\\s+([2-9])[xX]@ (高倍率:$1)\""
msgid "eg: \"rename=match@replace\" , \"rename=\\s+([2-9])[xX]@ (HIGH:$1)\""
msgstr "格式示例:\"rename=match@replace\" , \"rename=\\s+([2-9])[xX]@ (高倍率:$1)\""
msgid "Use Rule Provider"
msgstr "使用规则集"
@ -2958,6 +2949,9 @@ msgstr "切换(更新) Yacd 版本"
msgid "Update Metacubexd Version"
msgstr "更新 Metacubexd 版本"
msgid "Update zashboard Version"
msgstr "更新 zashboard 版本"
msgid "Downloading File..."
msgstr "文件下载中..."
@ -3051,6 +3045,9 @@ msgstr "警告TUN 接口启动失败,尝试重启内核..."
msgid "Error: Core Start Failed, Please Check The Log Infos!"
msgstr "错误:内核启动失败,请查看《内核日志》排查失败原因!"
msgid "Error: Core Status Abnormal, Please Check The Log Infos!"
msgstr "错误:内核状态异常,请查看《内核日志》排查异常原因!"
msgid "Forced Sniff Pure IP Connections"
msgstr "强制探测(嗅探)所有纯 IP 的连接"
@ -3102,8 +3099,8 @@ msgstr "测速(连通性)间隔修改"
msgid "Modify The URL-Test Interval In The Config"
msgstr "修改配置文件中的测速(连通性)间隔"
msgid "Whether to Enable Process Rules, If You Are Not Sure, Please Choose off Which Useful in Router Environment"
msgstr "是否启用进程规则,在路由环境下保持关闭可以提升性能"
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 "是否启用进程规则,仅能匹配路由器自身进程,在路由环境下保持关闭可以提升性能,依赖 kmod-inet-diag"
msgid "Enable Process Rule"
msgstr "启用进程规则"
@ -3452,3 +3449,24 @@ msgstr "对象"
msgid "Error: Network Anomaly, Suspend Unlock Detection..."
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'
#'+.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: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]

View File

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

View File

@ -21,28 +21,45 @@ mkdir -p /etc/openclash/core
mkdir -p /etc/openclash/history
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
cat > "/lib/upgrade/keep.d/luci-app-openclash" <<-EOF
/etc/openclash/
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
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)"
@ -100,12 +117,44 @@ fi
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
if [ -f "/tmp/openclash.bak" ]; then
#delete old geosite database first
if [ "/etc/openclash/GeoSite.dat" -nt "/tmp/openclash/GeoSite.dat" ]; then
rm -rf "/tmp/openclash/GeoSite.dat" >/dev/null 2>&1
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
cp -rf "/tmp/openclash/." "/etc/openclash/" >/dev/null 2>&1
if [ -d "/tmp/openclash_dashboard/" ]; then

View File

@ -7,9 +7,11 @@ set_lock() {
del_lock() {
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")
CHTIME=$(date "+%Y-%m-%d-%H" -r "/tmp/clash_last_version" 2>/dev/null)
LAST_OPVER="/tmp/clash_last_version"
@ -19,7 +21,6 @@ if [ -n "$1" ]; then
github_address_mod="$1"
fi
LOG_FILE="/tmp/openclash.log"
set_lock
if [ "$TIME" != "$CHTIME" ]; then
if [ "$github_address_mod" != "0" ]; then

View File

@ -3,6 +3,7 @@
. /usr/share/openclash/ruby.sh
. /usr/share/openclash/openclash_ps.sh
. /usr/share/openclash/log.sh
. /lib/functions/procd.sh
set_lock() {
exec 889>"/tmp/lock/openclash_subs.lock" 2>/dev/null
@ -11,9 +12,11 @@ set_lock() {
del_lock() {
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"))
LOG_FILE="/tmp/openclash.log"
CFG_FILE="/tmp/yaml_sub_tmp_config.yaml"
@ -26,7 +29,6 @@ CLASH="/etc/openclash/clash"
CLASH_CONFIG="/etc/openclash"
restart=0
only_download=0
set_lock
urlencode() {
if [ "$#" -eq 1 ]; then
@ -34,12 +36,7 @@ urlencode() {
fi
}
kill_watchdog() {
watchdog_pids=$(unify_ps_pids "openclash_watchdog.sh")
for watchdog_pid in $watchdog_pids; do
kill -9 "$watchdog_pid" >/dev/null 2>&1
done
kill_streaming_unlock() {
streaming_unlock_pids=$(unify_ps_pids "openclash_streaming_unlock.lua")
for streaming_unlock_pid in $streaming_unlock_pids; do
kill -9 "$streaming_unlock_pid" >/dev/null 2>&1
@ -50,7 +47,7 @@ config_test()
{
if [ -f "$CLASH" ]; then
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'
for i in $test_info; do
if [ -n "$(echo "$i" |grep "configuration file")" ]; then
@ -254,14 +251,15 @@ change_dns()
{
if pidof clash >/dev/null; then
/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
}
config_download_direct()
{
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
sleep 3
@ -358,7 +356,11 @@ convert_custom_param()
return
fi
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()
@ -383,8 +385,14 @@ sub_info_get()
config_get "sub_ua" "$section" "sub_ua" "Clash"
if [ "$enabled" -eq 0 ]; then
if [ -n "$2" ]; then
if [ "$2" != "$CONFIG_FILE" ] && [ "$2" != "$name" ]; then
return
fi
else
return
fi
fi
if [ -z "$address" ]; then
return
@ -415,7 +423,7 @@ sub_info_get()
BACKPACK_FILE="/etc/openclash/backup/$name.yaml"
fi
if [ -n "$2" ] && [ "$2" != "$CONFIG_FILE" ]; then
if [ -n "$2" ] && [ "$2" != "$CONFIG_FILE" ] && [ "$2" != "$name" ]; then
return
fi
@ -508,13 +516,13 @@ config_foreach sub_info_get "config_subscribe" "$1"
uci -q delete openclash.config.config_update_path
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 &
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 &
uci -q set openclash.config.restart=0
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 commit openclash
else

View File

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

View File

@ -3,6 +3,18 @@
. /usr/share/openclash/openclash_ps.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)
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"
@ -29,6 +41,7 @@ fi
if [ ! -f "/tmp/clash_last_version" ]; then
LOG_OUT "Error: 【"$CORE_TYPE"】Core Version Check Error, Please Try Again Later..."
SLOG_CLEAN
del_lock
exit 0
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!"
rm -rf /tmp/clash_meta >/dev/null 2>&1
SLOG_CLEAN
del_lock
exit 0
fi
@ -85,10 +99,10 @@ if [ "$CORE_CV" != "$CORE_LV" ] || [ -z "$CORE_CV" ]; then
if [ "$?" == "0" ]; then
LOG_OUT "【"$CORE_TYPE"】Core Update Successful!"
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
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
uci -q set openclash.config.config_reload=0
if ([ -z "$2" ] || ([ -n "$2" ] && [ "$2" != "one_key_update" ])) && [ "$(unify_ps_prevent)" -eq 0 ]; then
uci -q set openclash.config.restart=0
uci -q commit openclash
/etc/init.d/openclash restart >/dev/null 2>&1 &
fi
@ -113,4 +127,4 @@ else
fi
rm -rf /tmp/clash_meta >/dev/null 2>&1
del_lock

View File

@ -9,7 +9,7 @@ set_lock() {
del_lock() {
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()
@ -21,10 +21,10 @@ ipk_v()
fi
}
DEBUG_LOG="/tmp/openclash_debug.log"
LOGTIME=$(echo $(date "+%Y-%m-%d %H:%M:%S"))
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)
rule_source=$(uci -q get openclash.config.rule_source)
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(ipset): $(ts_re "$(dnsmasq --version |grep -v no-ipset |grep ipset)")
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")")
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")")
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-yaml: $(ts_re "$(ipk_v "ruby-yaml")")
ruby-psych: $(ts_re "$(ipk_v "ruby-psych")")
@ -182,7 +178,6 @@ cat >> "$DEBUG_LOG" <<-EOF
运行状态: 运行中
运行内核:$core_type
进程pid: $(pidof clash)
运行权限: `getpcaps $(pidof clash)`
运行用户: $(ps |grep "/etc/openclash/clash" |grep -v grep |awk '{print $2}' 2>/dev/null)
EOF
else

View File

@ -2,6 +2,18 @@
. /usr/share/openclash/log.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_TYPE="$2"
DASH_FILE_DIR="/tmp/dash.zip"
@ -28,6 +40,11 @@
DOWNLOAD_PATH="https://codeload.github.com/MetaCubeX/Yacd-meta/zip/refs/heads/gh-pages"
FILE_PATH_INCLUDE="Yacd-meta-gh-pages"
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
UNPACK_FILE_DIR="/usr/share/openclash/ui/metacubexd/"
BACKUP_FILE_DIR="/usr/share/openclash/ui/metacubexd_backup/"
@ -49,6 +66,7 @@
rm -rf "$BACKUP_FILE_DIR" >/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
del_lock
exit 1
else
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 "$BACKUP_FILE_DIR" >/dev/null 2>&1
rm -rf "$DASH_FILE_TMP" >/dev/null 2>&1
del_lock
exit 2
fi
else
@ -64,6 +83,7 @@
rm -rf "$DASH_FILE_DIR" >/dev/null 2>&1
rm -rf "$BACKUP_FILE_DIR" >/dev/null 2>&1
rm -rf "$DASH_FILE_TMP" >/dev/null 2>&1
del_lock
exit 2
fi
else
@ -72,5 +92,8 @@
rm -rf "$DASH_FILE_DIR" >/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
del_lock
exit 0
fi
del_lock

View File

@ -8,6 +8,18 @@ urlencode() {
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"
LOG_FILE="/tmp/openclash.log"
RELEASE_BRANCH=$(uci -q get openclash.config.release_branch || echo "master")
@ -25,6 +37,7 @@ urlencode() {
if [ -z "$DOWNLOAD_PATH" ]; then
LOG_OUT "Rule File【$RULE_FILE_NAME】Download Error!" && SLOG_CLEAN
del_lock
exit 0
fi
@ -70,15 +83,20 @@ urlencode() {
fi
rm -rf "$TMP_RULE_DIR" >/dev/null 2>&1
LOG_OUT "Rule File【$RULE_FILE_NAME】Download Successful!" && SLOG_CLEAN
del_lock
exit 1
else
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_TMP" >/dev/null 2>&1
del_lock
exit 2
fi
else
rm -rf "$TMP_RULE_DIR" >/dev/null 2>&1
LOG_OUT "Rule File【$RULE_FILE_NAME】Download Error!" && SLOG_CLEAN
del_lock
exit 0
fi
del_lock

View File

@ -9,15 +9,16 @@
del_lock() {
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)
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)
LOG_FILE="/tmp/openclash.log"
restart=0
set_lock
if [ "$small_flash_memory" != "1" ]; then
geoip_path="/etc/openclash/GeoIP.dat"
@ -56,9 +57,9 @@
LOG_OUT "GeoIP Dat Update Error, Please Try Again Later..."
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 &
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 &
uci -q set openclash.config.restart=0
uci -q commit openclash

View File

@ -9,15 +9,16 @@
del_lock() {
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)
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)
LOG_FILE="/tmp/openclash.log"
restart=0
set_lock
if [ "$small_flash_memory" != "1" ]; then
geosite_path="/etc/openclash/GeoSite.dat"
@ -56,9 +57,9 @@
LOG_OUT "GeoSite Database Update Error, Please Try Again Later..."
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 &
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 &
uci -q set openclash.config.restart=0
uci -q commit openclash

View File

@ -4,6 +4,8 @@ require "nixio"
require "luci.util"
require "luci.sys"
local ntm = require "luci.model.network".init()
local cidr = require "luci.ip"
local fs = require "luci.openclash"
local type = arg[1]
local rv = {}
local wan, wan6
@ -30,6 +32,7 @@ if wan then
for i = 1, #wan do
rv.wan[i] = {
ipaddr = wan[i]:ipaddr(),
ip6addr = wan[i]:ip6addr(),
gwaddr = wan[i]:gwaddr(),
netmask = wan[i]:netmask(),
dns = wan[i]:dnsaddrs(),
@ -150,4 +153,33 @@ if type == "wanip6" then
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)

View File

@ -9,7 +9,7 @@ set_lock() {
del_lock() {
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() {
@ -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
}
set_lock
if [ "$1" = "close_all_conection" ]; then
close_all_conection
del_lock
exit 0
fi
@ -38,8 +41,6 @@ core_version=$(uci -q get openclash.config.core_version || echo 0)
CACHE_PATH_OLD="/etc/openclash/.cache"
source "/etc/openwrt_release"
set_lock
if [ -z "$CONFIG_FILE" ] || [ ! -f "$CONFIG_FILE" ]; then
CONFIG_FILE=$(uci get openclash.config.config_path 2>/dev/null)
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)

View File

@ -9,15 +9,16 @@
del_lock() {
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)
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)
LOG_FILE="/tmp/openclash.log"
restart=0
set_lock
if [ "$small_flash_memory" != "1" ]; then
geoip_path="/etc/openclash/Country.mmdb"
@ -55,9 +56,9 @@
LOG_OUT "Geoip Database Update Error, Please Try Again Later..."
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 &
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 &
uci -q set openclash.config.restart=0
uci -q commit openclash

View File

@ -11,7 +11,7 @@
del_lock() {
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()
@ -117,10 +117,11 @@
fi
}
set_lock
LOG_FILE="/tmp/openclash.log"
RUlE_SOURCE=$(uci get openclash.config.rule_source 2>/dev/null)
github_address_mod=$(uci -q get openclash.config.github_address_mod || echo 0)
set_lock
if [ "$RUlE_SOURCE" = "0" ]; then
LOG_OUT "Other Rules Not Enable, Update Stop!"
@ -151,9 +152,9 @@
if [ -z "$rule_name" ]; then
LOG_OUT "Get Other Rules Settings Faild, Update Stop!"
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 &
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 &
uci -q set openclash.config.restart=0
uci -q commit openclash

View File

@ -1111,7 +1111,7 @@ function netflix_unlock_test()
local filmId = 70143836
local url = "https://www.netflix.com/title/"..filmId
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 region
local old_region = get_old_region()

View File

@ -8,9 +8,11 @@ set_lock() {
del_lock() {
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
[ ! -f "/tmp/openclash_last_version" ] && /usr/share/openclash/openclash_version.sh "$1" 2>/dev/null
elif [ -n "$2" ]; then
@ -22,6 +24,7 @@ fi
if [ ! -f "/tmp/openclash_last_version" ]; then
LOG_OUT "Error: Failed to Get Version Information, Please Try Again Later..."
SLOG_CLEAN
del_lock
exit 0
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
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
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
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")
@ -58,8 +61,6 @@ else
fi
fi
set_lock
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】..."
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 [ -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
LOG_OUT "【OpenClash - v$LAST_VER】Pre Update Test Failed, The File is Saved in /tmp/openclash.ipk, Please Try to Update Manually!"
if [ "$(uci -q get openclash.config.config_reload)" -eq 1 ]; then
uci -q set openclash.config.config_reload=0
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.restart)" -eq 1 ]; then
uci -q set openclash.config.restart=0
uci -q commit openclash
/etc/init.d/openclash restart >/dev/null 2>&1 &
else
@ -103,11 +104,12 @@ if [ -n "$OP_CV" ] && [ -n "$OP_LV" ] && [ "$(expr "$OP_LV" \> "$OP_CV")" -eq 1
fi
elif [ -x "/usr/bin/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
LOG_OUT "【OpenClash - v$LAST_VER】Pre Update Test Failed, The File is Saved in /tmp/openclash.apk, Please Try to Update Manually!"
if [ "$(uci -q get openclash.config.config_reload)" -eq 1 ]; then
uci -q set openclash.config.config_reload=0
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.restart)" -eq 1 ]; then
uci -q set openclash.config.restart=0
uci -q commit openclash
/etc/init.d/openclash restart >/dev/null 2>&1 &
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
opkg install /tmp/openclash.ipk
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
if [ -x "/bin/opkg" ]; then
if [ "$?" != "0" ] || [ -z "$(opkg info *openclash |grep Installed-Time)" ]; then
@ -161,35 +163,35 @@ if [ -x "/bin/opkg" ]; then
uci -q commit openclash
/etc/init.d/openclash restart 2>/dev/null
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
fi
elif [ -x "/usr/bin/apk" ]; 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
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
LOG_OUT "OpenClash Update Successful, About To Restart!"
uci -q set openclash.config.enable=1
uci -q commit openclash
/etc/init.d/openclash restart 2>/dev/null
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
fi
fi
EOF
chmod 4755 /tmp/openclash_update.sh
nohup /tmp/openclash_update.sh &
/tmp/openclash_update.sh &
wait
rm -rf /tmp/openclash_update.sh
else
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.apk >/dev/null 2>&1
if [ "$(uci -q get openclash.config.config_reload)" -eq 1 ]; then
uci -q set openclash.config.config_reload=0
if [ "$(uci -q get openclash.config.restart)" -eq 1 ]; then
uci -q set openclash.config.restart=0
uci -q commit openclash
/etc/init.d/openclash restart >/dev/null 2>&1 &
else
@ -202,8 +204,8 @@ else
else
LOG_OUT "OpenClash Has not Been Updated, Stop Continuing!"
fi
if [ "$(uci -q get openclash.config.config_reload)" -eq 1 ]; then
uci -q set openclash.config.config_reload=0
if [ "$(uci -q get openclash.config.restart)" -eq 1 ]; then
uci -q set openclash.config.restart=0
uci -q commit openclash
/etc/init.d/openclash restart >/dev/null 2>&1 &
else

View File

@ -1,4 +1,15 @@
#!/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")
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
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
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
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)
@ -32,15 +43,20 @@ if [ "$TIME" != "$CHTIME" ]; then
if [ "$(expr "$OP_CV" \>= "$OP_LV")" = "1" ]; then
sed -i '/^https:/,$d' $LAST_OPVER
elif [ "$(expr "$OP_LV" \> "$OP_CV")" = "1" ] && [ -n "$OP_LV" ]; then
del_lock
exit 2
else
del_lock
exit 0
fi
else
rm -rf "$LAST_OPVER"
fi
elif [ "$(expr "$OP_LV" \> "$OP_CV")" = "1" ] && [ -n "$OP_LV" ]; then
del_lock
exit 2
else
del_lock
exit 0
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)
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)
CRASH_NUM=0
CFG_UPDATE_INT=1
SKIP_PROXY_ADDRESS=1
SKIP_PROXY_ADDRESS_INTERVAL=30
@ -56,7 +55,7 @@ begin
if servers.include?(i['server']) then
next;
end;
if i['server'] =~ reg and not servers.include?(i['server']) then
if i['server'] =~ reg then
servers = servers.push(i['server']).uniq
syscall = '/usr/share/openclash/openclash_debug_dns.lua 2>/dev/null \"' + i['server'] + '\" \"true\"'
result = IO.popen(syscall).read.split(/\n+/)
@ -93,7 +92,7 @@ begin
if servers.include?(j['server']) then
next;
end;
if j['server'] =~ reg and not servers.include?(j['server']) then
if j['server'] =~ reg then
servers = servers.push(j['server']).uniq
syscall = '/usr/share/openclash/openclash_debug_dns.lua 2>/dev/null \"' + j['server'] + '\" \"true\"'
result = IO.popen(syscall).read.split(/\n+/)
@ -109,6 +108,28 @@ begin
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);
};
end;
@ -144,12 +165,6 @@ rescue Exception => e
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 :;
do
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_openai=$(uci -q get openclash.config.stream_auto_select_openai || echo 0)
upnp_lease_file=$(uci -q get upnpd.config.upnp_lease_file)
enable=$(uci -q get openclash.config.enable)
if [ "$enable" -eq 1 ]; then
clash_pids=$(pidof clash |sed 's/$//g' |wc -l)
if [ "$clash_pids" -gt 1 ]; then
LOG_OUT "Watchdog: Multiple Clash Processes, Kill All..."
clash_pids=$(pidof clash |sed 's/$//g')
for clash_pid in $clash_pids; do
kill -9 "$clash_pid" 2>/dev/null
done >/dev/null 2>&1
#wait for core start complete
while ( [ -n "$(unify_ps_pids "/etc/init.d/openclash")" ] )
do
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
done >/dev/null 2>&1
## Porxy history
/usr/share/openclash/openclash_history_get.sh
@ -234,12 +227,19 @@ fi
## Localnetwork 刷新
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)
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 "$wan_ip4s" ]; then
for wan_ip4 in $wan_ip4s; do
nft add element inet fw4 localnetwork { "$wan_ip4" } 2>/dev/null
done
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 [ -n "$wan_ip6s" ]; then
@ -247,6 +247,11 @@ fi
nft add element inet fw4 localnetwork6 { "$wan_ip6" } 2>/dev/null
done
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
else
if [ -n "$wan_ip4s" ]; then
@ -254,12 +259,22 @@ fi
ipset add localnetwork "$wan_ip4" 2>/dev/null
done
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 [ -n "$wan_ip6s" ]; then
for wan_ip6 in $wan_ip6s; do
ipset add localnetwork6 "$wan_ip6" 2>/dev/null
done
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

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
Value['global-client-fingerprint']='${29}';
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
Value['dns']['ipv6']=true;
@ -398,7 +405,7 @@ threads << Thread.new {
end;
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'];
if '$1' == 'redir-host' then
Value['sniffer']['force-dns-mapping']=true;
@ -420,7 +427,7 @@ threads << Thread.new {
Value['tun']=Value_2['tun'];
Value['tun']['stack']='$stack_type';
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']['endpoint-independent-nat']=true;
Value['tun']['auto-route']=false;

View File

@ -222,20 +222,6 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
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 {
#other_group
if x.key?('proxies') then

View File

@ -217,7 +217,7 @@ yml_groups_set()
{
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 "config" "$section" "config" ""
config_get "type" "$section" "type" ""
@ -228,8 +228,6 @@ yml_groups_set()
config_get "test_url" "$section" "test_url" ""
config_get "test_interval" "$section" "test_interval" ""
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" ""
if [ "$enabled" = "0" ]; then
@ -334,12 +332,6 @@ yml_groups_set()
[ -n "$policy_filter" ] && {
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)

View File

@ -393,6 +393,21 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
end
};
if x['type'] == 'ss' then
threads << Thread.new{
#cipher
if x.key?('cipher') then
uci_commands << uci_set + 'cipher=\"' + x['cipher'].to_s + '\"'
end
};
threads << Thread.new{
#udp-over-tcp
if x.key?('udp-over-tcp') then
uci_commands << uci_set + 'udp_over_tcp=\"' + x['udp-over-tcp'].to_s + '\"'
end
};
threads << Thread.new{
#Multiplex
if x.key?('smux') then
@ -430,21 +445,6 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
end;
};
if x['type'] == 'ss' then
threads << Thread.new{
#cipher
if x.key?('cipher') then
uci_commands << uci_set + 'cipher=\"' + x['cipher'].to_s + '\"'
end
};
threads << Thread.new{
#udp-over-tcp
if x.key?('udp-over-tcp') then
uci_commands << uci_set + 'udp_over_tcp=\"' + x['udp-over-tcp'].to_s + '\"'
end
};
threads << Thread.new{
#plugin-opts
if x.key?('plugin-opts') then
@ -552,6 +552,7 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
end
};
end;
if x['type'] == 'vmess' then
threads << Thread.new{
#uuid
@ -729,6 +730,37 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
};
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
if x['type'] == 'tuic' then
threads << Thread.new{
@ -964,6 +996,38 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
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
threads << Thread.new{
#hysteria_obfs
@ -1254,6 +1318,7 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
end
};
end;
if x['type'] == 'http' or x['type'] == 'trojan' then
threads << Thread.new{
if x.key?('sni') then
@ -1261,6 +1326,7 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
end
};
end;
if x['type'] == 'trojan' then
threads << Thread.new{
#alpn

View File

@ -263,6 +263,10 @@ yml_servers_set()
config_get "recv_window_conn" "$section" "recv_window_conn" ""
config_get "recv_window" "$section" "recv_window" ""
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 "packet_encoding" "$section" "packet_encoding" ""
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 "other_parameters" "$section" "other_parameters" ""
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
return
@ -418,6 +426,14 @@ yml_servers_set()
fi
fi
if [ "$client_fingerprint" = "none" ]; then
client_fingerprint=""
fi
if [ "$multiplex" = "false" ]; then
multiplex=""
fi
#ss
if [ "$type" = "ss" ]; then
cat >> "$SERVER_FILE" <<-EOF
@ -692,6 +708,36 @@ EOF
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
if [ "$type" = "tuic" ]; then
cat >> "$SERVER_FILE" <<-EOF
@ -978,6 +1024,26 @@ EOF
if [ -n "$hysteria_ca_str" ]; then
cat >> "$SERVER_FILE" <<-EOF
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
fi
if [ -n "$fingerprint" ]; then

View File

@ -18,7 +18,7 @@ SKIP_CUSTOM_OTHER_RULES=0
yml_set_custom_rule_provider()
{
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 "name" "$section" "name" ""
config_get "config" "$section" "config" ""
@ -30,6 +30,7 @@ yml_set_custom_rule_provider()
config_get "group" "$section" "group" ""
config_get "position" "$section" "position" ""
config_get "format" "$section" "format" ""
config_get "other_parameters" "$section" "other_parameters" ""
if [ "$enabled" = "0" ]; then
return
@ -63,7 +64,7 @@ yml_set_custom_rule_provider()
else
path="./rule_provider/$name.yaml"
fi
elif [ -z "$path" ]; then
elif [ -z "$path" ] && [ "$type" != "inline" ]; then
return
fi
@ -79,8 +80,12 @@ cat >> "$RULE_PROVIDER_FILE" <<-EOF
$name:
type: $type
behavior: $behavior
EOF
if [ -n "$path" ]; then
cat >> "$RULE_PROVIDER_FILE" <<-EOF
path: $path
EOF
fi
if [ -n "$format" ]; then
cat >> "$RULE_PROVIDER_FILE" <<-EOF
format: $format
@ -93,6 +98,11 @@ cat >> "$RULE_PROVIDER_FILE" <<-EOF
EOF
fi
#other_parameters
if [ -n "$other_parameters" ]; then
echo -e "$other_parameters" >> "$RULE_PROVIDER_FILE"
fi
yml_rule_set_add "$name" "$group" "$position"
}
@ -136,7 +146,6 @@ yml_gen_rule_provider_file()
else
RULE_PROVIDER_FILE_URL="${github_address_mod}https://raw.githubusercontent.com/${RULE_PROVIDER_FILE_URL_PATH}"
fi
fi
if [ -n "$(grep "$RULE_PROVIDER_FILE_URL" $RULE_PROVIDER_FILE 2>/dev/null)" ]; then
return
@ -358,7 +367,7 @@ yml_other_set()
);
match_group=Value['rules'].grep(/(MATCH|FINAL)/)[0];
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
ruby_add_index = Value['rules'].index(Value['rules'].grep(/(MATCH|FINAL)/).first);
ruby_add_index ||= -1;
@ -399,23 +408,66 @@ yml_other_set()
YAML.LOG('Error: Set BT/P2P DIRECT Rules Failed,【' + e.message + '】');
end;
#Router Self Proxy Rule
#Custom Rule Provider
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;
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['rules']=['SRC-IP-CIDR,$7/32,DIRECT'];
Value['rule-providers']=Value_1;
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 + '】');
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;
#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
begin
if Value.has_key?('rules') and not Value['rules'].to_a.empty? then
@ -433,25 +485,61 @@ yml_other_set()
ruby_add_index ||= -1;
Value_1 = YAML.load_file('/tmp/yaml_rule_set_bottom_custom.yaml');
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
Value_1['rules'].uniq.each{|x| Value['rules'].insert(ruby_add_index,x)};
YAML.LOG('Warning: Skiped The Custom Rule Because Group & Proxy Not Found:【' + x + '】');
end;
};
else
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;
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['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;
else
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;
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
Value['rules'] = Value['rules'] | Value_1['rules'].uniq;
Value['rules'] = Value['rules'] | Value_1;
else
Value['rules'] = Value_1['rules'].uniq;
Value['rules'] = Value_1;
end;
end;
end;
@ -476,7 +564,12 @@ yml_other_set()
end;
if defined? Value_2 then
Value_2.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;
};
Value['rules'] = Value['rules'].uniq;
end;
@ -504,7 +597,12 @@ yml_other_set()
Value_4 = Value_4.reverse!;
end;
Value_4.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;
};
Value['rules'] = Value['rules'].uniq;
end;
@ -516,10 +614,24 @@ yml_other_set()
if Value_1 != false 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
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['rules'].uniq;
end;
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['rules'].uniq;
end;
@ -531,10 +643,24 @@ yml_other_set()
if Value['rules'].to_a.empty? 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
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['rules'].uniq;
end;
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['rules'].uniq;
end;
@ -558,7 +684,12 @@ yml_other_set()
Value_3 = Value_3.reverse!;
end
Value_3.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;
};
Value['rules'] = Value['rules'].uniq;
end;
@ -614,61 +745,29 @@ yml_other_set()
rescue Exception => e
YAML.LOG('Error: Set Custom Rules Failed,【' + e.message + '】');
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{
#Create 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
begin
provider = {'proxy-providers' => 'proxy_provider', 'rule-providers' => 'rule_provider'}
@ -681,6 +780,9 @@ yml_other_set()
v=File.basename(x['path']);
x['path']='./'+p+'/'+v;
end;
if not x['path'] and x['type'] == 'http' then
x['path']='./'+p+'/'+x['name'];
end;
#CDN Replace
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

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;
}