@ -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
|
||||
|
@ -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
|
||||
@ -347,14 +348,19 @@ function action_flush_fakeip_cache()
|
||||
local dase = dase() or ""
|
||||
local cn_port = cn_port()
|
||||
if not daip or not cn_port then return end
|
||||
state = luci.sys.exec(string.format('curl -sL -m 3 -H "Content-Type: application/json" -H "Authorization: Bearer %s" -XPOST http://"%s":"%s"/cache/fakeip/flush', dase, daip, cn_port))
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
state = luci.sys.exec(string.format('curl -sL -m 3 -H "Content-Type: application/json" -H "Authorization: Bearer %s" -XPOST http://"%s":"%s"/cache/fakeip/flush', dase, daip, cn_port))
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json({
|
||||
flush_status = state;
|
||||
})
|
||||
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
|
||||
|
||||
|
@ -79,11 +79,11 @@ if a then
|
||||
btnis.template="openclash/other_button"
|
||||
btnis.render=function(o,t,a)
|
||||
if not e[t] then return false end
|
||||
if IsYamlFile(e[t].name) or IsYmlFile(e[t].name) then
|
||||
a.display=""
|
||||
else
|
||||
a.display="none"
|
||||
end
|
||||
if IsYamlFile(e[t].name) or IsYmlFile(e[t].name) then
|
||||
a.display=""
|
||||
else
|
||||
a.display="none"
|
||||
end
|
||||
o.inputstyle="apply"
|
||||
Button.render(o,t,a)
|
||||
end
|
||||
@ -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
|
||||
|
||||
|
@ -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 "))
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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}
|
||||
}
|
||||
|
@ -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"))
|
||||
|
@ -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"))
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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');
|
||||
|
@ -4,207 +4,245 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no,minimal-ui">
|
||||
<style>
|
||||
<style>
|
||||
|
||||
.center {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
min-width: 800px;
|
||||
}
|
||||
:root[data-darkmode="true"] {
|
||||
.card {
|
||||
background: linear-gradient(rgb(0, 0, 0), rgb(70, 70, 70));
|
||||
}
|
||||
|
||||
.card {
|
||||
width: 100%;
|
||||
height: 250px;
|
||||
background-color: #fff;
|
||||
background: linear-gradient(#f8f8f8, #fff);
|
||||
box-shadow: 0 8px 16px -8px rgba(0,0,0,0.4);
|
||||
border-radius: 6px;
|
||||
position: relative;
|
||||
}
|
||||
.card .additional {
|
||||
background: linear-gradient(#337ab7, rgb(70, 70, 70));
|
||||
}
|
||||
|
||||
.card h1 {
|
||||
text-align: center;
|
||||
}
|
||||
.card .general .dler-title{
|
||||
color: #bbbbbb;
|
||||
}
|
||||
|
||||
.card .additional {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(#337ab7, #fefefe);
|
||||
transition: width 0.5s;
|
||||
overflow: hidden;
|
||||
z-index: 2;
|
||||
}
|
||||
.card .general .dler-result{
|
||||
color: #bbbbbb;
|
||||
}
|
||||
|
||||
.card .additional .user-card {
|
||||
width: 150px;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
float: left;
|
||||
}
|
||||
.card .general .dler-result2{
|
||||
color: #bbbbbb;
|
||||
}
|
||||
|
||||
.card .additional .user-card::after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 10%;
|
||||
right: -2px;
|
||||
height: 80%;
|
||||
border-left: 2px solid rgba(0,0,0,0.025);*/
|
||||
}
|
||||
.card .general h1 {
|
||||
color: #bbbbbb;
|
||||
}
|
||||
|
||||
.card .additional .user-card img {
|
||||
.card .additional .user-card::after {
|
||||
border-left: 2px solid #bbbbbb;
|
||||
}
|
||||
|
||||
left: 20%;
|
||||
bottom: 30%;
|
||||
width: 60%;
|
||||
border-radius: 60%;
|
||||
position: absolute;
|
||||
.card .additional .more-info h1 {
|
||||
color: #bbbbbb;
|
||||
}
|
||||
|
||||
}
|
||||
.card .additional .coords {
|
||||
color: #bbbbbb;
|
||||
}
|
||||
}
|
||||
|
||||
.card .additional .more-info {
|
||||
position: relative;
|
||||
top: 28%;
|
||||
height: 50%;
|
||||
margin: 0 auto;
|
||||
width: 50%;
|
||||
padding-left: 150px;
|
||||
padding-top: 1%;
|
||||
}
|
||||
.center {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
min-width: 800px;
|
||||
}
|
||||
|
||||
.card .additional .more-info h1 {
|
||||
color: #fff;
|
||||
margin-bottom: 0;
|
||||
margin: 0 1rem;
|
||||
font-size: 2rem;
|
||||
position: relative;
|
||||
}
|
||||
.card {
|
||||
width: 100%;
|
||||
height: 250px;
|
||||
background-color: #fff;
|
||||
background: linear-gradient(#f8f8f8, #fff);
|
||||
box-shadow: 0 8px 16px -8px rgba(0,0,0,0.4);
|
||||
border-radius: 6px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.card .additional .coords {
|
||||
margin: 0 1rem;
|
||||
color: #fff;
|
||||
font-size: 1rem;
|
||||
position: relative;
|
||||
top: 10%;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
line-height: 20px;
|
||||
}
|
||||
.card h1 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.card .general {
|
||||
width: auto;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
margin-left: 150px;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
padding-top: 0;
|
||||
}
|
||||
.card .additional {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(#337ab7, #fefefe);
|
||||
transition: width 0.5s;
|
||||
overflow: hidden;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.card .general h1 {
|
||||
font-size: 30px;
|
||||
text-align: center;
|
||||
padding-top: 5px;
|
||||
margin: 0 0 0 -12%;
|
||||
line-height: 35px;
|
||||
color: black;
|
||||
}
|
||||
.card .additional .user-card {
|
||||
width: 150px;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.card .general .dler-info {
|
||||
top: 22%;
|
||||
width: 90%;
|
||||
height: 70%;
|
||||
display: flex;
|
||||
position: absolute;
|
||||
margin: 0 0 0 8%;
|
||||
}
|
||||
.card .additional .user-card::after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 10%;
|
||||
right: -2px;
|
||||
height: 80%;
|
||||
border-left: 2px solid rgba(0,0,0,0.025);
|
||||
}
|
||||
|
||||
.card .general .dler-info p {
|
||||
padding: 8px !important;
|
||||
text-align: center;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.card .additional .user-card img {
|
||||
|
||||
.card .general .dler-info div {
|
||||
position: relative;
|
||||
}
|
||||
left: 20%;
|
||||
bottom: 30%;
|
||||
width: 60%;
|
||||
border-radius: 60%;
|
||||
position: absolute;
|
||||
|
||||
.card .general .dler-title {
|
||||
font-weight: bold;
|
||||
color: #444;
|
||||
font-size: 15px;
|
||||
display: inline-block;
|
||||
width: 45%;
|
||||
overflow: hidden;
|
||||
vertical-align:bottom;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
line-height: 25px;
|
||||
height: 25px;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
.card .general .dler-result {
|
||||
color: #444;
|
||||
font-size:16px;
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
width: 55%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align:bottom;
|
||||
text-align: right;
|
||||
line-height: 25px;
|
||||
height: 25px;
|
||||
}
|
||||
.card .additional .more-info {
|
||||
position: relative;
|
||||
top: 28%;
|
||||
height: 50%;
|
||||
margin: 0 auto;
|
||||
width: 50%;
|
||||
padding-left: 150px;
|
||||
padding-top: 1%;
|
||||
}
|
||||
|
||||
.card .general .dler-result2 {
|
||||
color: #444;
|
||||
font-size:16px;
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
width: 55%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align:bottom;
|
||||
text-align: right;
|
||||
line-height: 25px;
|
||||
height: 25px;
|
||||
}
|
||||
.card .additional .more-info h1 {
|
||||
color: #fff;
|
||||
margin-bottom: 0;
|
||||
margin: 0 1rem;
|
||||
font-size: 2rem;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.card .general .btn {
|
||||
color: #fff;
|
||||
border-color: #337ab7 !important;
|
||||
background: #1473e6;
|
||||
background-color: #1473e6 !important;
|
||||
box-shadow: 0 8px 16px -8px rgba(0,0,0,0.4);
|
||||
border-radius: 6px;
|
||||
width: 90px;
|
||||
height: 90px !important;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
-webkit-appearance:button;
|
||||
}
|
||||
.card .additional .coords {
|
||||
margin: 0 1rem;
|
||||
color: #fff;
|
||||
font-size: 1rem;
|
||||
position: relative;
|
||||
top: 10%;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.card .general .more {
|
||||
float: right;
|
||||
top: 88%;
|
||||
right: 0;
|
||||
font-size: 15px;
|
||||
line-height: 20px;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
margin: 0 3% 0.5% 0;
|
||||
}
|
||||
</style>
|
||||
.card .general {
|
||||
width: auto;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
margin-left: 150px;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.card .general h1 {
|
||||
font-size: 30px;
|
||||
text-align: center;
|
||||
padding-top: 5px;
|
||||
margin: 0 0 0 -12%;
|
||||
line-height: 35px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.card .general .dler-info {
|
||||
top: 22%;
|
||||
width: 90%;
|
||||
height: 70%;
|
||||
display: flex;
|
||||
position: absolute;
|
||||
margin: 0 0 0 8%;
|
||||
}
|
||||
|
||||
.card .general .dler-info p {
|
||||
padding: 8px !important;
|
||||
text-align: center;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.card .general .dler-info div {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.card .general .dler-title {
|
||||
font-weight: bold;
|
||||
color: #444;
|
||||
font-size: 15px;
|
||||
display: inline-block;
|
||||
width: 45%;
|
||||
overflow: hidden;
|
||||
vertical-align:bottom;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
line-height: 25px;
|
||||
height: 25px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.card .general .dler-result {
|
||||
color: #444;
|
||||
font-size:16px;
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
width: 55%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align:bottom;
|
||||
text-align: right;
|
||||
line-height: 25px;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
.card .general .dler-result2 {
|
||||
color: #444;
|
||||
font-size:16px;
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
width: 55%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align:bottom;
|
||||
text-align: right;
|
||||
line-height: 25px;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
.card .general .btn {
|
||||
color: #fff;
|
||||
border-color: #337ab7 !important;
|
||||
background: #1473e6;
|
||||
background-color: #1473e6 !important;
|
||||
box-shadow: 0 8px 16px -8px rgba(0,0,0,0.4);
|
||||
border-radius: 6px;
|
||||
width: 90px;
|
||||
height: 90px !important;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
-webkit-appearance:button;
|
||||
}
|
||||
|
||||
.card .general .more {
|
||||
float: right;
|
||||
top: 88%;
|
||||
right: 0;
|
||||
font-size: 15px;
|
||||
line-height: 20px;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
margin: 0 3% 0.5% 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<fieldset class="cbi-section">
|
||||
|
@ -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>
|
||||
|
@ -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 ) {
|
||||
|
@ -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>';
|
||||
@ -727,8 +729,8 @@
|
||||
btn.value = '<%:Checking...%>';
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_other_rules")%>', null, function(x, status) {
|
||||
if ( x && x.status == 200 ) {
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Check Third Party Rules Update%>';
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Check Third Party Rules Update%>';
|
||||
}
|
||||
else {
|
||||
btn.disabled = false;
|
||||
@ -744,12 +746,12 @@
|
||||
btn.value = '<%:Checking...%>';
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_geoip")%>', null, function(x, status) {
|
||||
if ( x && x.status == 200 ) {
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Check GEOIP Data Update%>';
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Check GEOIP Data Update%>';
|
||||
}
|
||||
else {
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Check GEOIP Data Update%>';
|
||||
btn.value = '<%:Check GEOIP Data Update%>';
|
||||
}
|
||||
return false;
|
||||
});
|
||||
@ -761,12 +763,12 @@
|
||||
btn.value = '<%:Checking...%>';
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_geosite")%>', null, function(x, status) {
|
||||
if ( x && x.status == 200 ) {
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Check GeoSite Data Update%>';
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Check GeoSite Data Update%>';
|
||||
}
|
||||
else {
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Check GeoSite Data Update%>';
|
||||
btn.value = '<%:Check GeoSite Data Update%>';
|
||||
}
|
||||
return false;
|
||||
});
|
||||
@ -806,12 +808,12 @@
|
||||
btn.value = '<%:Checking...%>';
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_subscribe")%>', null, function(x, status) {
|
||||
if ( x && x.status == 200 ) {
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Check Config Update%>';
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Check Config Update%>';
|
||||
}
|
||||
else {
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Check Config Update%>';
|
||||
btn.value = '<%:Check Config Update%>';
|
||||
}
|
||||
return false;
|
||||
});
|
||||
@ -823,12 +825,12 @@
|
||||
btn.value = '<%:Reloading...%>';
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "reload_firewall")%>', null, function(x, status) {
|
||||
if ( x && x.status == 200 ) {
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Reload Firewall Rules%>';
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Reload Firewall Rules%>';
|
||||
}
|
||||
else {
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Firewall Rules Reset Failed%>';
|
||||
btn.value = '<%:Firewall Rules Reset Failed%>';
|
||||
}
|
||||
return false;
|
||||
});
|
||||
@ -840,17 +842,38 @@
|
||||
btn.value = '<%:Reloading...%>';
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "close_all_connection")%>', null, function(x, status) {
|
||||
if ( x && x.status == 200 ) {
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Close All Connections%>';
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Close All Connections%>';
|
||||
}
|
||||
else {
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Close All Connections Failed%>';
|
||||
btn.value = '<%:Close All Connections Failed%>';
|
||||
}
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
function net_zashboard(btn)
|
||||
{
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "status")%>', null, function(x, status) {
|
||||
btn.disabled = true;
|
||||
btn.value = '<%:zashboard Control Panel%>';
|
||||
if (status.daip && window.location.hostname == status.daip) {
|
||||
url9='<%="http://'+window.location.hostname+':'+status.cn_port+'/ui/zashboard/#/setup?hostname='+ window.location.hostname + '&port=' + status.cn_port + '&secret=' + status.dase +'"%>';
|
||||
}
|
||||
else if (status.daip && window.location.hostname != status.daip && status.db_foward_domain && status.db_foward_port) {
|
||||
var ui_proto = status.db_forward_ssl == 0 ? 'http://' : 'https://';
|
||||
url9='<%="'+ui_proto+status.db_foward_domain+':'+status.db_foward_port+'/ui/zashboard/#/setup?hostname='+ status.db_foward_domain + '&port=' + status.db_foward_port + '&secret=' + status.dase +'"%>';
|
||||
}
|
||||
else {
|
||||
url9='<%="http://'+window.location.hostname+':'+status.cn_port+'/ui/zashboard/#/"%>';
|
||||
}
|
||||
winOpen(url9);
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
function meta_dashboard(btn)
|
||||
{
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "status")%>', null, function(x, status) {
|
||||
|
@ -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
|
||||
|
@ -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,16 +57,18 @@
|
||||
{
|
||||
document.getElementById("switch_dashboard_"+name).innerHTML = '<input type="button" class="btn cbi-button cbi-button-reset" value="<%:Switch Successful%> - <%:Switch To Meta Version%>" onclick="return switch_dashboard(this, \'Yacd\', \'Meta\')"/>';
|
||||
}
|
||||
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\')"/>';
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( status.download_state == "2" ) {
|
||||
btn.value = '<%:Unzip Error%>';
|
||||
}
|
||||
else {
|
||||
if ( name == "Metacubexd" ) {
|
||||
if ( name == "Metacubexd" || name == "zashboard" ) {
|
||||
btn.value = '<%:Update Failed%>';
|
||||
}
|
||||
else {
|
||||
|
@ -36,7 +36,7 @@
|
||||
<%:Current Config File%>:
|
||||
<select class="tool_label_select" id="cfg_name">
|
||||
</select>
|
||||
<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)" />
|
||||
|
||||
</span>
|
||||
</li>
|
||||
|
27
luci-app-openclash/luasrc/view/openclash/update_config.htm
Normal 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%>
|
@ -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 连接问题,请尝试启用。"
|
@ -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]
|
@ -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 ]
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,7 +385,13 @@ sub_info_get()
|
||||
config_get "sub_ua" "$section" "sub_ua" "Clash"
|
||||
|
||||
if [ "$enabled" -eq 0 ]; then
|
||||
return
|
||||
if [ -n "$2" ]; then
|
||||
if [ "$2" != "$CONFIG_FILE" ] && [ "$2" != "$name" ]; then
|
||||
return
|
||||
fi
|
||||
else
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$address" ]; then
|
||||
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -2,11 +2,23 @@
|
||||
. /usr/share/openclash/log.sh
|
||||
. /lib/functions.sh
|
||||
|
||||
urlencode() {
|
||||
if [ "$#" -eq 1 ]; then
|
||||
echo "$(/usr/share/openclash/openclash_urlencode.lua "$1")"
|
||||
fi
|
||||
}
|
||||
urlencode() {
|
||||
if [ "$#" -eq 1 ]; then
|
||||
echo "$(/usr/share/openclash/openclash_urlencode.lua "$1")"
|
||||
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"
|
||||
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -11,116 +11,117 @@
|
||||
|
||||
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()
|
||||
{
|
||||
local section="$1"
|
||||
local enabled config
|
||||
config_get_bool "enabled" "$section" "enabled" "1"
|
||||
config_get "config" "$section" "config" ""
|
||||
local section="$1"
|
||||
local enabled config
|
||||
config_get_bool "enabled" "$section" "enabled" "1"
|
||||
config_get "config" "$section" "config" ""
|
||||
|
||||
if [ "$enabled" = "0" ] || [ "$config" != "$2" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -n "$rule_name" ]; then
|
||||
LOG_OUT "Warrning: Multiple Other-Rules-Configurations Enabled, Ignore..."
|
||||
return
|
||||
fi
|
||||
|
||||
config_get "rule_name" "$section" "rule_name" ""
|
||||
|
||||
LOG_OUT "Start Downloading Third Party Rules in Use..."
|
||||
if [ "$rule_name" = "lhie1" ]; then
|
||||
if [ "$github_address_mod" != "0" ]; then
|
||||
if [ "$github_address_mod" == "https://cdn.jsdelivr.net/" ] || [ "$github_address_mod" == "https://fastly.jsdelivr.net/" ] || [ "$github_address_mod" == "https://testingcf.jsdelivr.net/" ]; then
|
||||
curl -SsL --connect-timeout 30 -m 60 --speed-time 30 --speed-limit 1 --retry 2 "$github_address_mod"gh/dler-io/Rules@master/Clash/Rule.yaml -o /tmp/rules.yaml 2>&1 |sed ':a;N;$!ba; s/\n/ /g' | awk -v time="$(date "+%Y-%m-%d %H:%M:%S")" -v file="/tmp/rules.yaml" '{print time "【" file "】Download Failed:【"$0"】"}' >> "$LOG_FILE"
|
||||
else
|
||||
curl -SsL --connect-timeout 30 -m 60 --speed-time 30 --speed-limit 1 --retry 2 "$github_address_mod"https://raw.githubusercontent.com/dler-io/Rules/master/Clash/Rule.yaml -o /tmp/rules.yaml 2>&1 |sed ':a;N;$!ba; s/\n/ /g' | awk -v time="$(date "+%Y-%m-%d %H:%M:%S")" -v file="/tmp/rules.yaml" '{print time "【" file "】Download Failed:【"$0"】"}' >> "$LOG_FILE"
|
||||
fi
|
||||
else
|
||||
curl -SsL --connect-timeout 30 -m 60 --speed-time 30 --speed-limit 1 --retry 2 https://raw.githubusercontent.com/dler-io/Rules/master/Clash/Rule.yaml -o /tmp/rules.yaml 2>&1 |sed ':a;N;$!ba; s/\n/ /g' | awk -v time="$(date "+%Y-%m-%d %H:%M:%S")" -v file="/tmp/rules.yaml" '{print time "【" file "】Download Failed:【"$0"】"}' >> "$LOG_FILE"
|
||||
if [ "$enabled" = "0" ] || [ "$config" != "$2" ]; then
|
||||
return
|
||||
fi
|
||||
sed -i '1i rules:' /tmp/rules.yaml
|
||||
fi
|
||||
if [ -s "/tmp/rules.yaml" ]; then
|
||||
LOG_OUT "Download Successful, Start Preprocessing Rule File..."
|
||||
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
|
||||
begin
|
||||
YAML.load_file('/tmp/rules.yaml');
|
||||
rescue Exception => e
|
||||
YAML.LOG('Error: Unable To Parse Updated Rules File,【${rule_name}:' + e.message + '】');
|
||||
system 'rm -rf /tmp/rules.yaml 2>/dev/null';
|
||||
end
|
||||
" 2>/dev/null >> $LOG_FILE
|
||||
if [ $? -ne 0 ]; then
|
||||
LOG_OUT "Error: Ruby Works Abnormally, Please Check The Ruby Library Depends!"
|
||||
rm -rf /tmp/rules.yaml >/dev/null 2>&1
|
||||
SLOG_CLEAN
|
||||
del_lock
|
||||
exit 0
|
||||
elif [ ! -f "/tmp/rules.yaml" ]; then
|
||||
LOG_OUT "Error:【$rule_name】Rule File Format Validation Failed, Please Try Again Later..."
|
||||
rm -rf /tmp/rules.yaml >/dev/null 2>&1
|
||||
SLOG_CLEAN
|
||||
del_lock
|
||||
exit 0
|
||||
elif ! "$(ruby_read "/tmp/rules.yaml" ".key?('rules')")" ; then
|
||||
LOG_OUT "Error: Updated Others Rules【$rule_name】Has No Rules Field, Update Exit..."
|
||||
rm -rf /tmp/rules.yaml >/dev/null 2>&1
|
||||
SLOG_CLEAN
|
||||
del_lock
|
||||
exit 0
|
||||
#校验是否含有新策略组
|
||||
elif ! "$(ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
|
||||
Value = YAML.load_file('/usr/share/openclash/res/${rule_name}.yaml');
|
||||
Value_1 = YAML.load_file('/tmp/rules.yaml');
|
||||
OLD_GROUP = Value['rules'].collect{|x| x.split(',')[2] or x.split(',')[1]}.uniq.map(&:strip);
|
||||
NEW_GROUP = Value_1['rules'].collect{|x| x.split(',')[2] or x.split(',')[1]}.uniq.map(&:strip);
|
||||
if (OLD_GROUP | NEW_GROUP).eql?(OLD_GROUP) then
|
||||
if (OLD_GROUP | NEW_GROUP).eql?(NEW_GROUP) then
|
||||
puts true
|
||||
|
||||
if [ -n "$rule_name" ]; then
|
||||
LOG_OUT "Warrning: Multiple Other-Rules-Configurations Enabled, Ignore..."
|
||||
return
|
||||
fi
|
||||
|
||||
config_get "rule_name" "$section" "rule_name" ""
|
||||
|
||||
LOG_OUT "Start Downloading Third Party Rules in Use..."
|
||||
if [ "$rule_name" = "lhie1" ]; then
|
||||
if [ "$github_address_mod" != "0" ]; then
|
||||
if [ "$github_address_mod" == "https://cdn.jsdelivr.net/" ] || [ "$github_address_mod" == "https://fastly.jsdelivr.net/" ] || [ "$github_address_mod" == "https://testingcf.jsdelivr.net/" ]; then
|
||||
curl -SsL --connect-timeout 30 -m 60 --speed-time 30 --speed-limit 1 --retry 2 "$github_address_mod"gh/dler-io/Rules@master/Clash/Rule.yaml -o /tmp/rules.yaml 2>&1 |sed ':a;N;$!ba; s/\n/ /g' | awk -v time="$(date "+%Y-%m-%d %H:%M:%S")" -v file="/tmp/rules.yaml" '{print time "【" file "】Download Failed:【"$0"】"}' >> "$LOG_FILE"
|
||||
else
|
||||
curl -SsL --connect-timeout 30 -m 60 --speed-time 30 --speed-limit 1 --retry 2 "$github_address_mod"https://raw.githubusercontent.com/dler-io/Rules/master/Clash/Rule.yaml -o /tmp/rules.yaml 2>&1 |sed ':a;N;$!ba; s/\n/ /g' | awk -v time="$(date "+%Y-%m-%d %H:%M:%S")" -v file="/tmp/rules.yaml" '{print time "【" file "】Download Failed:【"$0"】"}' >> "$LOG_FILE"
|
||||
fi
|
||||
else
|
||||
curl -SsL --connect-timeout 30 -m 60 --speed-time 30 --speed-limit 1 --retry 2 https://raw.githubusercontent.com/dler-io/Rules/master/Clash/Rule.yaml -o /tmp/rules.yaml 2>&1 |sed ':a;N;$!ba; s/\n/ /g' | awk -v time="$(date "+%Y-%m-%d %H:%M:%S")" -v file="/tmp/rules.yaml" '{print time "【" file "】Download Failed:【"$0"】"}' >> "$LOG_FILE"
|
||||
fi
|
||||
sed -i '1i rules:' /tmp/rules.yaml
|
||||
fi
|
||||
if [ -s "/tmp/rules.yaml" ]; then
|
||||
LOG_OUT "Download Successful, Start Preprocessing Rule File..."
|
||||
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
|
||||
begin
|
||||
YAML.load_file('/tmp/rules.yaml');
|
||||
rescue Exception => e
|
||||
YAML.LOG('Error: Unable To Parse Updated Rules File,【${rule_name}:' + e.message + '】');
|
||||
system 'rm -rf /tmp/rules.yaml 2>/dev/null';
|
||||
end
|
||||
" 2>/dev/null >> $LOG_FILE
|
||||
if [ $? -ne 0 ]; then
|
||||
LOG_OUT "Error: Ruby Works Abnormally, Please Check The Ruby Library Depends!"
|
||||
rm -rf /tmp/rules.yaml >/dev/null 2>&1
|
||||
SLOG_CLEAN
|
||||
del_lock
|
||||
exit 0
|
||||
elif [ ! -f "/tmp/rules.yaml" ]; then
|
||||
LOG_OUT "Error:【$rule_name】Rule File Format Validation Failed, Please Try Again Later..."
|
||||
rm -rf /tmp/rules.yaml >/dev/null 2>&1
|
||||
SLOG_CLEAN
|
||||
del_lock
|
||||
exit 0
|
||||
elif ! "$(ruby_read "/tmp/rules.yaml" ".key?('rules')")" ; then
|
||||
LOG_OUT "Error: Updated Others Rules【$rule_name】Has No Rules Field, Update Exit..."
|
||||
rm -rf /tmp/rules.yaml >/dev/null 2>&1
|
||||
SLOG_CLEAN
|
||||
del_lock
|
||||
exit 0
|
||||
#校验是否含有新策略组
|
||||
elif ! "$(ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
|
||||
Value = YAML.load_file('/usr/share/openclash/res/${rule_name}.yaml');
|
||||
Value_1 = YAML.load_file('/tmp/rules.yaml');
|
||||
OLD_GROUP = Value['rules'].collect{|x| x.split(',')[2] or x.split(',')[1]}.uniq.map(&:strip);
|
||||
NEW_GROUP = Value_1['rules'].collect{|x| x.split(',')[2] or x.split(',')[1]}.uniq.map(&:strip);
|
||||
if (OLD_GROUP | NEW_GROUP).eql?(OLD_GROUP) then
|
||||
if (OLD_GROUP | NEW_GROUP).eql?(NEW_GROUP) then
|
||||
puts true
|
||||
else
|
||||
puts false
|
||||
end
|
||||
else
|
||||
puts false
|
||||
end
|
||||
")" && [ -f "/usr/share/openclash/res/${rule_name}.yaml" ]; then
|
||||
LOG_OUT "Error: Updated Others Rules【$rule_name】Has Incompatible Proxy-Group, Update Exit, Please Wait For OpenClash Update To Adapt..."
|
||||
rm -rf /tmp/rules.yaml >/dev/null 2>&1
|
||||
SLOG_CLEAN
|
||||
del_lock
|
||||
exit 0
|
||||
fi
|
||||
|
||||
#取出规则部分
|
||||
ruby_read "/tmp/rules.yaml" ".select {|x| 'rule-providers' == x or 'rules' == x }.to_yaml" > "$OTHER_RULE_FILE"
|
||||
#合并
|
||||
cat "$OTHER_RULE_FILE" > "/tmp/rules.yaml" 2>/dev/null
|
||||
rm -rf /tmp/other_rule* 2>/dev/null
|
||||
|
||||
LOG_OUT "Check The Downloaded Rule File For Updates..."
|
||||
cmp -s /usr/share/openclash/res/"$rule_name".yaml /tmp/rules.yaml
|
||||
if [ "$?" -ne "0" ]; then
|
||||
LOG_OUT "Detected that The Downloaded Rule File Has Been Updated, Starting To Replace..."
|
||||
mv /tmp/rules.yaml /usr/share/openclash/res/"$rule_name".yaml >/dev/null 2>&1
|
||||
LOG_OUT "Other Rules【$rule_name】Update Successful!"
|
||||
restart=1
|
||||
else
|
||||
puts false
|
||||
end
|
||||
")" && [ -f "/usr/share/openclash/res/${rule_name}.yaml" ]; then
|
||||
LOG_OUT "Error: Updated Others Rules【$rule_name】Has Incompatible Proxy-Group, Update Exit, Please Wait For OpenClash Update To Adapt..."
|
||||
rm -rf /tmp/rules.yaml >/dev/null 2>&1
|
||||
SLOG_CLEAN
|
||||
del_lock
|
||||
exit 0
|
||||
fi
|
||||
|
||||
#取出规则部分
|
||||
ruby_read "/tmp/rules.yaml" ".select {|x| 'rule-providers' == x or 'rules' == x }.to_yaml" > "$OTHER_RULE_FILE"
|
||||
#合并
|
||||
cat "$OTHER_RULE_FILE" > "/tmp/rules.yaml" 2>/dev/null
|
||||
rm -rf /tmp/other_rule* 2>/dev/null
|
||||
|
||||
LOG_OUT "Check The Downloaded Rule File For Updates..."
|
||||
cmp -s /usr/share/openclash/res/"$rule_name".yaml /tmp/rules.yaml
|
||||
if [ "$?" -ne "0" ]; then
|
||||
LOG_OUT "Detected that The Downloaded Rule File Has Been Updated, Starting To Replace..."
|
||||
mv /tmp/rules.yaml /usr/share/openclash/res/"$rule_name".yaml >/dev/null 2>&1
|
||||
LOG_OUT "Other Rules【$rule_name】Update Successful!"
|
||||
restart=1
|
||||
LOG_OUT "Updated Other Rules【$rule_name】No Change, Do Nothing!"
|
||||
fi
|
||||
else
|
||||
LOG_OUT "Updated Other Rules【$rule_name】No Change, Do Nothing!"
|
||||
LOG_OUT "Other Rules【$rule_name】Update Error, Please Try Again Later..."
|
||||
fi
|
||||
else
|
||||
LOG_OUT "Other Rules【$rule_name】Update Error, Please Try Again Later..."
|
||||
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
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
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
|
||||
#wait for core start complete
|
||||
while ( [ -n "$(unify_ps_pids "/etc/init.d/openclash")" ] )
|
||||
do
|
||||
sleep 1
|
||||
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
|
||||
|
||||
|
@ -0,0 +1 @@
|
||||
board.zash.run.place
|
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 1.8 KiB |
@ -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 |
@ -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 |
@ -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>
|
@ -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"}]}
|
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 7.2 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 4.6 KiB |
@ -0,0 +1 @@
|
||||
if('serviceWorker' in navigator) {window.addEventListener('load', () => {navigator.serviceWorker.register('./sw.js', { scope: './' })})}
|
@ -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} didn’t 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")))}));
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -393,43 +393,6 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
|
||||
end
|
||||
};
|
||||
|
||||
threads << Thread.new{
|
||||
#Multiplex
|
||||
if x.key?('smux') then
|
||||
if x['smux'].key?('enabled') then
|
||||
uci_commands << uci_set + 'multiplex=\"' + x['smux']['enabled'].to_s + '\"'
|
||||
end;
|
||||
#multiplex_protocol
|
||||
if x['smux'].key?('protocol') then
|
||||
uci_commands << uci_set + 'multiplex_protocol=\"' + x['smux']['protocol'].to_s + '\"'
|
||||
end;
|
||||
#multiplex_max_connections
|
||||
if x['smux'].key?('max-connections') then
|
||||
uci_commands << uci_set + 'multiplex_max_connections=\"' + x['smux']['max-connections'].to_s + '\"'
|
||||
end;
|
||||
#multiplex_min_streams
|
||||
if x['smux'].key?('min-streams') then
|
||||
uci_commands << uci_set + 'multiplex_min_streams=\"' + x['smux']['min-streams'].to_s + '\"'
|
||||
end;
|
||||
#multiplex_max_streams
|
||||
if x['smux'].key?('max-streams') then
|
||||
uci_commands << uci_set + 'multiplex_max_streams=\"' + x['smux']['max-streams'].to_s + '\"'
|
||||
end;
|
||||
#multiplex_padding
|
||||
if x['smux'].key?('padding') then
|
||||
uci_commands << uci_set + 'multiplex_padding=\"' + x['smux']['padding'].to_s + '\"'
|
||||
end;
|
||||
#multiplex_statistic
|
||||
if x['smux'].key?('statistic') then
|
||||
uci_commands << uci_set + 'multiplex_statistic=\"' + x['smux']['statistic'].to_s + '\"'
|
||||
end;
|
||||
#multiplex_only_tcp
|
||||
if x['smux'].key?('only-tcp') then
|
||||
uci_commands << uci_set + 'multiplex_only_tcp=\"' + x['smux']['only-tcp'].to_s + '\"'
|
||||
end;
|
||||
end;
|
||||
};
|
||||
|
||||
if x['type'] == 'ss' then
|
||||
threads << Thread.new{
|
||||
#cipher
|
||||
@ -445,6 +408,43 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
|
||||
end
|
||||
};
|
||||
|
||||
threads << Thread.new{
|
||||
#Multiplex
|
||||
if x.key?('smux') then
|
||||
if x['smux'].key?('enabled') then
|
||||
uci_commands << uci_set + 'multiplex=\"' + x['smux']['enabled'].to_s + '\"'
|
||||
end;
|
||||
#multiplex_protocol
|
||||
if x['smux'].key?('protocol') then
|
||||
uci_commands << uci_set + 'multiplex_protocol=\"' + x['smux']['protocol'].to_s + '\"'
|
||||
end;
|
||||
#multiplex_max_connections
|
||||
if x['smux'].key?('max-connections') then
|
||||
uci_commands << uci_set + 'multiplex_max_connections=\"' + x['smux']['max-connections'].to_s + '\"'
|
||||
end;
|
||||
#multiplex_min_streams
|
||||
if x['smux'].key?('min-streams') then
|
||||
uci_commands << uci_set + 'multiplex_min_streams=\"' + x['smux']['min-streams'].to_s + '\"'
|
||||
end;
|
||||
#multiplex_max_streams
|
||||
if x['smux'].key?('max-streams') then
|
||||
uci_commands << uci_set + 'multiplex_max_streams=\"' + x['smux']['max-streams'].to_s + '\"'
|
||||
end;
|
||||
#multiplex_padding
|
||||
if x['smux'].key?('padding') then
|
||||
uci_commands << uci_set + 'multiplex_padding=\"' + x['smux']['padding'].to_s + '\"'
|
||||
end;
|
||||
#multiplex_statistic
|
||||
if x['smux'].key?('statistic') then
|
||||
uci_commands << uci_set + 'multiplex_statistic=\"' + x['smux']['statistic'].to_s + '\"'
|
||||
end;
|
||||
#multiplex_only_tcp
|
||||
if x['smux'].key?('only-tcp') then
|
||||
uci_commands << uci_set + 'multiplex_only_tcp=\"' + x['smux']['only-tcp'].to_s + '\"'
|
||||
end;
|
||||
end;
|
||||
};
|
||||
|
||||
threads << Thread.new{
|
||||
#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
|
||||
|
@ -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
|
||||
@ -1318,37 +1384,37 @@ cat >> "$SERVER_FILE" <<-EOF
|
||||
EOF
|
||||
if [ -n "$multiplex_protocol" ]; then
|
||||
cat >> "$SERVER_FILE" <<-EOF
|
||||
protocol: $multiplex_protocol
|
||||
protocol: $multiplex_protocol
|
||||
EOF
|
||||
fi
|
||||
if [ -n "$multiplex_max_connections" ]; then
|
||||
cat >> "$SERVER_FILE" <<-EOF
|
||||
max-connections: $multiplex_max_connections
|
||||
max-connections: $multiplex_max_connections
|
||||
EOF
|
||||
fi
|
||||
if [ -n "$multiplex_min_streams" ]; then
|
||||
cat >> "$SERVER_FILE" <<-EOF
|
||||
min-streams: $multiplex_min_streams
|
||||
min-streams: $multiplex_min_streams
|
||||
EOF
|
||||
fi
|
||||
if [ -n "$multiplex_max_streams" ]; then
|
||||
cat >> "$SERVER_FILE" <<-EOF
|
||||
max-streams: $multiplex_max_streams
|
||||
max-streams: $multiplex_max_streams
|
||||
EOF
|
||||
fi
|
||||
if [ -n "$multiplex_padding" ]; then
|
||||
cat >> "$SERVER_FILE" <<-EOF
|
||||
padding: $multiplex_padding
|
||||
padding: $multiplex_padding
|
||||
EOF
|
||||
fi
|
||||
if [ -n "$multiplex_statistic" ]; then
|
||||
cat >> "$SERVER_FILE" <<-EOF
|
||||
statistic: $multiplex_statistic
|
||||
statistic: $multiplex_statistic
|
||||
EOF
|
||||
fi
|
||||
if [ -n "$multiplex_only_tcp" ]; then
|
||||
cat >> "$SERVER_FILE" <<-EOF
|
||||
only-tcp: $multiplex_only_tcp
|
||||
only-tcp: $multiplex_only_tcp
|
||||
EOF
|
||||
fi
|
||||
fi
|
||||
|
@ -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
|
||||
YAML.LOG('Warning: Skiped The Custom Rule Because Group & Proxy Not Found:【' + x + '】');
|
||||
end;
|
||||
};
|
||||
else
|
||||
Value_1['rules'].uniq.each{|x| Value['rules'].insert(ruby_add_index,x)};
|
||||
Value_1['rules'].uniq.each{|x|
|
||||
RULE_GROUP = (x.split(',')[-1] =~ /^no-resolve$|^src$/) ? x.split(',')[-2] : x.split(',')[-1];
|
||||
if CONFIG_GROUP.include?(RULE_GROUP) then
|
||||
Value['rules'].insert(ruby_add_index,x);
|
||||
else
|
||||
YAML.LOG('Warning: Skiped The Custom Rule Because Group & Proxy Not Found:【' + x + '】');
|
||||
end;
|
||||
};
|
||||
end;
|
||||
end;
|
||||
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|
|
||||
Value['rules'].insert(0,x);
|
||||
RULE_GROUP = (x.split(',')[-1] =~ /^no-resolve$|^src$/) ? x.split(',')[-2] : x.split(',')[-1];
|
||||
if CONFIG_GROUP.include?(RULE_GROUP) then
|
||||
Value['rules'].insert(0,x);
|
||||
else
|
||||
YAML.LOG('Warning: Skiped The Custom Rule Because Group & Proxy Not Found:【' + x + '】');
|
||||
end;
|
||||
};
|
||||
Value['rules'] = Value['rules'].uniq;
|
||||
end;
|
||||
@ -504,7 +597,12 @@ yml_other_set()
|
||||
Value_4 = Value_4.reverse!;
|
||||
end;
|
||||
Value_4.each{|x|
|
||||
Value['rules'].insert(ruby_add_index,x);
|
||||
RULE_GROUP = (x.split(',')[-1] =~ /^no-resolve$|^src$/) ? x.split(',')[-2] : x.split(',')[-1];
|
||||
if CONFIG_GROUP.include?(RULE_GROUP) then
|
||||
Value['rules'].insert(ruby_add_index,x);
|
||||
else
|
||||
YAML.LOG('Warning: Skiped The Custom Rule Because Group & Proxy Not Found:【' + x + '】');
|
||||
end;
|
||||
};
|
||||
Value['rules'] = Value['rules'].uniq;
|
||||
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|
|
||||
Value['rules'].insert(ruby_add_index,x);
|
||||
RULE_GROUP = (x.split(',')[-1] =~ /^no-resolve$|^src$/) ? x.split(',')[-2] : x.split(',')[-1];
|
||||
if CONFIG_GROUP.include?(RULE_GROUP) then
|
||||
Value['rules'].insert(ruby_add_index,x);
|
||||
else
|
||||
YAML.LOG('Warning: Skiped The Custom Rule Because Group & Proxy Not Found:【' + x + '】');
|
||||
end;
|
||||
};
|
||||
Value['rules'] = Value['rules'].uniq;
|
||||
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
|
||||
|
@ -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;
|
||||
}
|