Merge Mainline

This commit is contained in:
CN_SZTL 2020-12-05 19:05:37 +08:00
commit 353a4cba23
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
179 changed files with 35853 additions and 13975 deletions

View File

@ -18,8 +18,28 @@ else
cmake_tool=$(shell which $(1))
endif
CMAKE_C_COMPILER:=$(call cmake_tool,$(TARGET_CC_NOCACHE))
CMAKE_CXX_COMPILER:=$(call cmake_tool,$(TARGET_CXX_NOCACHE))
ifeq ($(CONFIG_CCACHE),)
CMAKE_C_COMPILER:=$(call cmake_tool,$(TARGET_CC))
CMAKE_CXX_COMPILER:=$(call cmake_tool,$(TARGET_CXX))
CMAKE_C_COMPILER_ARG1:=
CMAKE_CXX_COMPILER_ARG1:=
CMAKE_HOST_C_COMPILER:=$(HOSTCC)
CMAKE_HOST_CXX_COMPILER:=$(HOSTCXX)
CMAKE_HOST_C_COMPILER_ARG1:=
CMAKE_HOST_CXX_COMPILER_ARG1:=
else
CCACHE:=$(STAGING_DIR_HOST)/bin/ccache
CMAKE_C_COMPILER:=$(CCACHE)
CMAKE_C_COMPILER_ARG1:=$(TARGET_CC_NOCACHE)
CMAKE_CXX_COMPILER:=$(CCACHE)
CMAKE_CXX_COMPILER_ARG1:=$(TARGET_CXX_NOCACHE)
CMAKE_HOST_C_COMPILER:=$(CCACHE)
CMAKE_HOST_C_COMPILER_ARG1:=$(HOSTCC_NOCACHE)
CMAKE_HOST_CXX_COMPILER:=$(CCACHE)
CMAKE_HOST_CXX_COMPILER_ARG1:=$(HOSTCXX_NOCACHE)
endif
CMAKE_AR:=$(call cmake_tool,$(TARGET_AR))
CMAKE_NM:=$(call cmake_tool,$(TARGET_NM))
CMAKE_RANLIB:=$(call cmake_tool,$(TARGET_RANLIB))
@ -41,11 +61,12 @@ define Build/Configure/Default
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_FLAGS_RELEASE="-DNDEBUG" \
-DCMAKE_CXX_FLAGS_RELEASE="-DNDEBUG" \
$(if $(CONFIG_CCACHE),-DCMAKE_CXX_COMPILER_LAUNCHER="$(STAGING_DIR_HOST)/bin/ccache") \
$(if $(CONFIG_CCACHE),-DCMAKE_C_COMPILER_LAUNCHER="$(STAGING_DIR_HOST)/bin/ccache") \
-DCMAKE_C_COMPILER="$(CMAKE_C_COMPILER)" \
-DCMAKE_C_COMPILER_ARG1="$(CMAKE_C_COMPILER_ARG1)" \
-DCMAKE_CXX_COMPILER="$(CMAKE_CXX_COMPILER)" \
-DCMAKE_CXX_COMPILER_ARG1="$(CMAKE_CXX_COMPILER_ARG1)" \
-DCMAKE_ASM_COMPILER="$(CMAKE_C_COMPILER)" \
-DCMAKE_ASM_COMPILER_ARG1="$(CMAKE_C_COMPILER_ARG1)" \
-DCMAKE_EXE_LINKER_FLAGS:STRING="$(TARGET_LDFLAGS)" \
-DCMAKE_MODULE_LINKER_FLAGS:STRING="$(TARGET_LDFLAGS) $(CMAKE_SHARED_LDFLAGS)" \
-DCMAKE_SHARED_LINKER_FLAGS:STRING="$(TARGET_LDFLAGS) $(CMAKE_SHARED_LDFLAGS)" \
@ -86,6 +107,12 @@ define Host/Configure/Default
LDFLAGS="$(HOST_LDFLAGS)" \
cmake \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER="$(CMAKE_HOST_C_COMPILER)" \
-DCMAKE_C_COMPILER_ARG1="$(CMAKE_HOST_C_COMPILER_ARG1)" \
-DCMAKE_CXX_COMPILER="$(CMAKE_HOST_CXX_COMPILER)" \
-DCMAKE_CXX_COMPILER_ARG1="$(CMAKE_HOST_CXX_COMPILER_ARG1)" \
-DCMAKE_ASM_COMPILER="$(CMAKE_HOST_C_COMPILER)" \
-DCMAKE_ASM_COMPILER_ARG1="$(CMAKE_HOST_C_COMPILER_ARG1)" \
-DCMAKE_C_FLAGS_RELEASE="-DNDEBUG" \
-DCMAKE_CXX_FLAGS_RELEASE="-DNDEBUG" \
-DCMAKE_EXE_LINKER_FLAGS:STRING="$(HOST_LDFLAGS)" \

View File

@ -12,7 +12,7 @@ include $(INCLUDE_DIR)/version.mk
include $(INCLUDE_DIR)/feeds.mk
PKG_NAME:=base-files
PKG_RELEASE:=215
PKG_RELEASE:=216
PKG_FLAGS:=nonshared
PKG_FILE_DEPENDS:=$(PLATFORM_DIR)/ $(GENERIC_PLATFORM_DIR)/base-files/

View File

@ -1,4 +1,4 @@
[ -x /bin/more ] || alias more=less
[ -x /bin/more ] || [ -x /usr/bin/more ] || alias more=less
[ -x /usr/bin/vim ] && alias vi=vim || alias vim=vi
alias ll='ls -alF --color=auto'
@ -9,12 +9,24 @@ alias ll='ls -alF --color=auto'
[ -x /usr/bin/ldd ] || ldd() { LD_TRACE_LOADED_OBJECTS=1 $*; }
service() {
[ -f "/etc/init.d/$1" ] || {
echo "service "'"'"$1"'"'" not found, the following services are available:"
ls "/etc/init.d"
if [ -f "/etc/init.d/$1" ]; then
/etc/init.d/$@
else
echo "Usage: service <service> [command]"
if [ -n "$1" ]; then
echo "Service "'"'"$1"'"'" not found, the following services are available:"
else
echo "The following services are available:"
fi
for F in /etc/init.d/* ; do
printf "%-30s\t%10s\t%10s\n" "$F" \
$( $($F enabled) && echo "enabled" || echo "disabled" ) \
$( [ "$(ubus call service list "{ 'verbose': true, 'name': '$(basename $F)' }" \
| jsonfilter -q -e "@.$(basename $F).instances[*].running")" = "true" ] \
&& echo "running" || echo "stopped" )
done;
return 1
}
/etc/init.d/$@
fi
}
[ -n "$KSH_VERSION" -o \! -s "$HOME/.shinit" ] || . "$HOME/.shinit"

View File

@ -19,7 +19,7 @@ define Package/luci-app-autoipsetadder
SUBMENU:=3. Applications
TITLE:=LuCI Support for autoipsetadder
PKGARCH:=all
DEPENDS:= +httping +curl
DEPENDS:= +httping +curl +coreutils-stdbuf
endef
define Package/luci-app-autoipsetadder/description

View File

@ -12,8 +12,8 @@ LUCI_DEPENDS:=+node +node-request +coreutils +coreutils-nohup +wget
LUCI_PKGARCH:=all
PKG_NAME:=luci-app-jd-dailybonus
PKG_VERSION:=0.8.7
PKG_RELEASE:=20201031
PKG_VERSION:=0.8.8
PKG_RELEASE:=20201204
include $(TOPDIR)/feeds/luci/luci.mk

View File

@ -5,7 +5,7 @@ function index()
if not nixio.fs.access("/etc/config/jd-dailybonus") then
return
end
entry({"admin", "services", "jd-dailybonus"}, alias("admin", "services", "jd-dailybonus", "client"), _("JD-DailyBonus"), 10).dependent = true -- 首页
entry({"admin", "services", "jd-dailybonus", "client"}, cbi("jd-dailybonus/client"),_("Client"), 10).leaf = true -- 基本设置
entry({"admin", "services", "jd-dailybonus", "log"},form("jd-dailybonus/log"),_("Log"), 30).leaf = true -- 日志页面
@ -32,7 +32,7 @@ function run()
local failed = luci.http.formvalue("failed")
local name = ""
uci:foreach("vssr", "global", function(s) name = s[".name"] end)
if cookie ~= " " then
uci:set("jd-dailybonus", '@global[0]', 'auto_update', auto_update)
uci:set("jd-dailybonus", '@global[0]', 'auto_update_time', auto_update_time)
@ -43,8 +43,8 @@ function run()
uci:set("jd-dailybonus", '@global[0]', 'cookie2', cookie2)
uci:set("jd-dailybonus", '@global[0]', 'serverchan', serverchan)
uci:set("jd-dailybonus", '@global[0]', 'failed', failed)
uci:save("jd-dailybonus")
uci:commit("jd-dailybonus")
uci:save("jd-dailybonus")
uci:commit("jd-dailybonus")
luci.sys.call("/usr/share/jd-dailybonus/newapp.sh -r")
luci.sys.call("/usr/share/jd-dailybonus/newapp.sh -a")
e.error = 0

View File

@ -1,9 +1,9 @@
config global
option version '1.79'
option version '1.87'
option auto_run_time '1'
option auto_run '1'
option auto_update_time '1'
option auto_update '1'
option stop '0'
option failed '0'
option remote_url 'https://raw.githubusercontent.com/NobyDa/Script/master/JD-DailyBonus/JD_DailyBonus.js'
option remote_url 'https://cdn.jsdelivr.net/gh/NobyDa/Script/JD-DailyBonus/JD_DailyBonus.js'

View File

@ -49,8 +49,6 @@ cancel() {
exit 1
}
REMOTE_SCRIPT=$(uci_get_by_type global remote_url)
fill_cookie() {
cookie1=$(uci_get_by_type global cookie)
if [ ! "$cookie1" = "" ]; then
@ -77,13 +75,6 @@ fill_cookie() {
fi
}
if [ -e $TEMP_SCRIPT ]; then
remote_ver=$(cat $TEMP_SCRIPT | sed -n '/更新时间/p' | awk '{for (i=1;i<=NF;i++){if ($i ~/v/) {print $i}}}' | sed 's/v//')
else
remote_ver=$(cat $JD_SCRIPT | sed -n '/更新时间/p' | awk '{for (i=1;i<=NF;i++){if ($i ~/v/) {print $i}}}' | sed 's/v//')
fi
local_ver=$(uci_get_by_type global version)
add_cron() {
sed -i '/jd-dailybonus/d' $CRON_FILE
[ $(uci_get_by_type global auto_run 0) -eq 1 ] && echo '5 '$(uci_get_by_type global auto_run_time)' * * * sleep '$(expr $(head -n 128 /dev/urandom | tr -dc "0123456789" | head -c4) % 180)'s; /usr/share/jd-dailybonus/newapp.sh -w' >>$CRON_FILE
@ -96,7 +87,7 @@ add_cron() {
serverchan() {
sckey=$(uci_get_by_type global serverchan)
failed=$(uci_get_by_type global failed)
desc=$(cat /www/JD_DailyBonus.htm | grep -E '签到号|签到概览|签到总计|账号总计|其他总计' | sed 's/$/&\n/g')
desc=$(cat /www/JD_DailyBonus.htm | grep -E '签到号|签到概览|签到奖励|其他奖励|账号总计|其他总计' | sed 's/$/&\n/g')
serverurlflag=$(uci_get_by_type global serverurl)
serverurl=https://sc.ftqq.com/
if [ "$serverurlflag" = "sct" ]; then
@ -118,15 +109,13 @@ serverchan() {
run() {
fill_cookie
echo -e $(date '+%Y-%m-%d %H:%M:%S %A') >$LOG_HTM 2>/dev/null
[ ! -f "/usr/bin/node" ] && echo "未安装node,请安装后再试!">>$LOG_HTM && exit 1
node $JD_SCRIPT >>$LOG_HTM 2>&1 &
[ ! -f "/usr/bin/node" ] && echo -e "未安装node.js,请安装后再试!\nNode.js is not installed, please try again after installation!">>$LOG_HTM && exit 1
node $JD_SCRIPT >>$LOG_HTM 2>/dev/null
}
back_run() {
fill_cookie
echo -e $(date '+%Y-%m-%d %H:%M:%S %A') >$LOG_HTM 2>/dev/null
[ ! -f "/usr/bin/node" ] && echo "未安装node,请安装后再试!">>$LOG_HTM && exit 1
node $JD_SCRIPT >>$LOG_HTM 2>/dev/null
run
sleep 1s
serverchan
}
@ -136,22 +125,37 @@ save() {
}
# Update Script From Server
download() {
REMOTE_SCRIPT=$(uci_get_by_type global remote_url)
wget-ssl --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" --no-check-certificate -t 3 -T 10 -q $REMOTE_SCRIPT -O $TEMP_SCRIPT
return $?
}
get_ver() {
echo $(cat $1 | sed -n '/更新时间/p' | awk '{for (i=1;i<=NF;i++){if ($i ~/v/) {print $i}}}' | sed 's/v//')
}
check_ver() {
wget-ssl --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" --no-check-certificate -t 3 -T 10 -q $REMOTE_SCRIPT -O $TEMP_SCRIPT
download
if [ $? -ne 0 ]; then
cancel "501"
else
echo $remote_ver
echo $(get_ver $TEMP_SCRIPT)
fi
}
update() {
wget-ssl --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" --no-check-certificate -t 3 -T 10 -q $REMOTE_SCRIPT -O $TEMP_SCRIPT
download
if [ $? -ne 0 ]; then
cancel "501"
fi
if [ $(expr $local_ver \< $remote_ver) -eq 1 ]; then
if [ -e $JD_SCRIPT ]; then
local_ver=$(get_ver $JD_SCRIPT)
else
local_ver=0
fi
remote_ver=$(get_ver $TEMP_SCRIPT)
if [ $(expr "$local_ver" \< "$remote_ver") -eq 1 ]; then
cp -r $TEMP_SCRIPT $JD_SCRIPT
fill_cookie
uci set jd-dailybonus.@global[0].version=$remote_ver

View File

@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-openclash
PKG_VERSION:=0.40.14
PKG_VERSION:=0.41.06
PKG_RELEASE:=beta
PKG_MAINTAINER:=vernesong <https://github.com/vernesong/OpenClash>
@ -18,7 +18,7 @@ define Package/$(PKG_NAME)
SUBMENU:=3. Applications
TITLE:=LuCI support for clash
PKGARCH:=all
DEPENDS:=+iptables +dnsmasq-full +coreutils +coreutils-nohup +bash +curl +jsonfilter +ca-certificates +ipset +ip-full +iptables-mod-tproxy +iptables-mod-extra +libcap
DEPENDS:=+iptables +dnsmasq-full +coreutils +coreutils-nohup +bash +curl +jsonfilter +ca-certificates +ipset +ip-full +iptables-mod-tproxy +iptables-mod-extra +libcap +ruby +ruby-yaml
MAINTAINER:=vernesong
endef
@ -85,6 +85,8 @@ define Package/$(PKG_NAME)/postrm
rm -rf /tmp/rule_providers_name >/dev/null 2>&1
rm -rf /tmp/clash_last_version >/dev/null 2>&1
rm -rf /usr/share/openclash/backup >/dev/null 2>&1
rm -rf /tmp/openclash_fake_filter.list >/dev/null 2>&1
rm -rf /tmp/openclash_servers_fake_filter.conf >/dev/null 2>&1
uci delete firewall.openclash >/dev/null 2>&1
uci commit firewall >/dev/null 2>&1
uci delete ucitrack.@openclash[-1] >/dev/null 2>&1

View File

@ -14,6 +14,8 @@ function index()
entry({"admin", "services", "openclash", "status"},call("action_status")).leaf=true
entry({"admin", "services", "openclash", "state"},call("action_state")).leaf=true
entry({"admin", "services", "openclash", "startlog"},call("action_start")).leaf=true
entry({"admin", "services", "openclash", "refresh_log"},call("action_refresh_log"))
entry({"admin", "services", "openclash", "del_log"},call("action_del_log"))
entry({"admin", "services", "openclash", "close_all_connection"},call("action_close_all_connection"))
entry({"admin", "services", "openclash", "restore_history"},call("action_restore_history"))
entry({"admin", "services", "openclash", "get_history"},call("action_get_history"))
@ -442,4 +444,23 @@ function action_download_rule()
luci.http.write_json({
rule_download_status = download_rule();
})
end
function action_refresh_log()
local logfile="/tmp/openclash.log"
if not fs.access(logfile) then
luci.http.write("")
return
end
luci.http.prepare_content("text/plain; charset=utf-8")
local f=io.open(logfile, "r+")
f:seek("set")
local a=f:read(2048000) or ""
f:close()
luci.http.write(a)
end
function action_del_log()
luci.sys.exec("echo '' > /tmp/openclash.log")
return
end

View File

@ -27,55 +27,15 @@ end
function config_check(CONFIG_FILE)
local yaml = fs.isfile(CONFIG_FILE)
local proxy,group,rule
if yaml then
proxy_provier = luci.sys.call(string.format('egrep "^ {0,}proxy-provider:" "%s" >/dev/null 2>&1',CONFIG_FILE))
if (proxy_provier ~= 0) then
proxy_provier = luci.sys.call(string.format('egrep "^ {0,}proxy-providers:" "%s" >/dev/null 2>&1',CONFIG_FILE))
end
proxy = luci.sys.call(string.format('egrep "^ {0,}Proxy:" "%s" >/dev/null 2>&1',CONFIG_FILE))
if (proxy ~= 0) then
proxy = luci.sys.call(string.format('egrep "^proxies:" "%s" >/dev/null 2>&1',CONFIG_FILE))
end
group = luci.sys.call(string.format('egrep " {0,}Proxy Group" "%s" >/dev/null 2>&1',CONFIG_FILE))
if (group ~= 0) then
group = luci.sys.call(string.format('egrep "^ {0,}proxy-groups:" "%s" >/dev/null 2>&1',CONFIG_FILE))
end
rule = luci.sys.call(string.format('egrep "^ {0,}Rule:" "%s" >/dev/null 2>&1',CONFIG_FILE))
if (rule ~= 0) then
rule = luci.sys.call(string.format('egrep "^ {0,}rules:" "%s" >/dev/null 2>&1',CONFIG_FILE))
if (rule ~= 0) then
rule = luci.sys.call(string.format('egrep "^ {0,}script:" "%s" >/dev/null 2>&1',CONFIG_FILE))
end
end
end
if yaml then
if (proxy == 0) then
proxy = ""
else
if (proxy_provier == 0) then
proxy = ""
else
proxy = " - 代理服务器"
end
end
if (group == 0) then
group = ""
else
group = " - 策略组"
end
if (rule == 0) then
rule = ""
else
rule = " - 规则"
end
if (proxy=="") and (group=="") and (rule=="") then
yaml = SYS.exec(string.format('ruby -ryaml -E UTF-8 -e "puts YAML.load_file(\'%s\')" 2>/dev/null',CONFIG_FILE))
if yaml ~= "false\n" and yaml ~= "" then
return "Config Normal"
else
return proxy..group..rule.." - 部分异常"
end
return "Config Abnormal"
end
elseif (yaml ~= 0) then
return "配置文件不存在"
return "File Not Exist"
end
end
@ -93,7 +53,7 @@ if fs.mtime(BACKUP_FILE) then
else
e[t].mtime=os.date("%Y-%m-%d %H:%M:%S",a.mtime)
end
if string.sub(luci.sys.exec("uci get openclash.config.config_path 2>/dev/null"), 23, -2) == e[t].name then
if string.sub(SYS.exec("uci get openclash.config.config_path 2>/dev/null"), 23, -2) == e[t].name then
e[t].state=translate("Enable")
else
e[t].state=translate("Disable")
@ -109,7 +69,7 @@ st=tb:option(DummyValue,"state",translate("State"))
st.template="openclash/cfg_check"
nm=tb:option(DummyValue,"name",translate("Config Alias"))
mt=tb:option(DummyValue,"mtime",translate("Update Time"))
ck=tb:option(DummyValue,"check",translate("启动参数检查"))
ck=tb:option(DummyValue,"check",translate("Grammar Check"))
ck.template="openclash/cfg_check"
btnis=tb:option(Button,"switch",translate("Switch Config"))
@ -126,7 +86,7 @@ Button.render(o,t,a)
end
btnis.write=function(a,t)
fs.unlink("/tmp/Proxy_Group")
luci.sys.exec(string.format('uci set openclash.config.config_path="/etc/openclash/config/%s"',e[t].name))
SYS.exec(string.format('uci set openclash.config.config_path="/etc/openclash/config/%s"',e[t].name))
uci:set("openclash", "config", "enable", 1)
uci:commit("openclash")
SYS.call("/etc/init.d/openclash restart >/dev/null 2>&1 &")

View File

@ -12,6 +12,8 @@ font_green = [[<font color="green">]]
font_off = [[</font>]]
bold_on = [[<strong>]]
bold_off = [[</strong>]]
align_mid = [[<p align="center">]]
align_mid_off = [[</p>]]
function IsYamlFile(e)
e=e or""
@ -25,7 +27,7 @@ function IsYmlFile(e)
end
function default_config_set(f)
local cf=string.sub(luci.sys.exec("uci get openclash.config.config_path 2>/dev/null"), 1, -2)
local cf=string.sub(SYS.exec("uci get openclash.config.config_path 2>/dev/null"), 1, -2)
if cf == "/etc/openclash/config/"..f or not cf or cf == "" or not fs.isfile(cf) then
if CHIF == "1" and cf == "/etc/openclash/config/"..f then
return
@ -34,11 +36,11 @@ function default_config_set(f)
if fis ~= nil then
fcf = fs.basename(fis)
if fcf then
luci.sys.exec(string.format('uci set openclash.config.config_path="/etc/openclash/config/%s"',fcf))
SYS.exec(string.format('uci set openclash.config.config_path="/etc/openclash/config/%s"',fcf))
uci:commit("openclash")
end
else
luci.sys.exec("uci set openclash.config.config_path=/etc/openclash/config/config.yaml")
SYS.exec("uci set openclash.config.config_path=/etc/openclash/config/config.yaml")
uci:commit("openclash")
end
end
@ -46,55 +48,15 @@ end
function config_check(CONFIG_FILE)
local yaml = fs.isfile(CONFIG_FILE)
local proxy,group,rule
if yaml then
proxy_provier = luci.sys.call(string.format('egrep "^ {0,}proxy-provider:" "%s" >/dev/null 2>&1',CONFIG_FILE))
if (proxy_provier ~= 0) then
proxy_provier = luci.sys.call(string.format('egrep "^ {0,}proxy-providers:" "%s" >/dev/null 2>&1',CONFIG_FILE))
end
proxy = luci.sys.call(string.format('egrep "^ {0,}Proxy:" "%s" >/dev/null 2>&1',CONFIG_FILE))
if (proxy ~= 0) then
proxy = luci.sys.call(string.format('egrep "^proxies:" "%s" >/dev/null 2>&1',CONFIG_FILE))
end
group = luci.sys.call(string.format('egrep " {0,}Proxy Group" "%s" >/dev/null 2>&1',CONFIG_FILE))
if (group ~= 0) then
group = luci.sys.call(string.format('egrep "^ {0,}proxy-groups:" "%s" >/dev/null 2>&1',CONFIG_FILE))
end
rule = luci.sys.call(string.format('egrep "^ {0,}Rule:" "%s" >/dev/null 2>&1',CONFIG_FILE))
if (rule ~= 0) then
rule = luci.sys.call(string.format('egrep "^ {0,}rules:" "%s" >/dev/null 2>&1',CONFIG_FILE))
if (rule ~= 0) then
rule = luci.sys.call(string.format('egrep "^ {0,}script:" "%s" >/dev/null 2>&1',CONFIG_FILE))
end
end
end
if yaml then
if (proxy == 0) then
proxy = ""
else
if (proxy_provier == 0) then
proxy = ""
else
proxy = " - 代理服务器"
end
end
if (group == 0) then
group = ""
else
group = " - 策略组"
end
if (rule == 0) then
rule = ""
else
rule = " - 规则"
end
if (proxy=="") and (group=="") and (rule=="") then
yaml = SYS.exec(string.format('ruby -ryaml -E UTF-8 -e "puts YAML.load_file(\'%s\')" 2>/dev/null',CONFIG_FILE))
if yaml ~= "false\n" and yaml ~= "" then
return "Config Normal"
else
return proxy..group..rule.." - 部分异常"
end
return "Config Abnormal"
end
elseif (yaml ~= 0) then
return "配置文件不存在"
return "File Not Exist"
end
end
@ -200,7 +162,7 @@ if fs.mtime(BACKUP_FILE) then
else
e[t].mtime=os.date("%Y-%m-%d %H:%M:%S",a.mtime)
end
if string.sub(luci.sys.exec("uci get openclash.config.config_path 2>/dev/null"), 23, -2) == e[t].name then
if string.sub(SYS.exec("uci get openclash.config.config_path 2>/dev/null"), 23, -2) == e[t].name then
e[t].state=translate("Enable")
else
e[t].state=translate("Disable")
@ -220,7 +182,7 @@ st.template="openclash/cfg_check"
nm=tb:option(DummyValue,"name",translate("Config Alias"))
mt=tb:option(DummyValue,"mtime",translate("Update Time"))
sz=tb:option(DummyValue,"size",translate("Size"))
ck=tb:option(DummyValue,"check",translate("启动参数检查"))
ck=tb:option(DummyValue,"check",translate("Grammar Check"))
ck.template="openclash/cfg_check"
btnis=tb:option(Button,"switch",translate("Switch Config"))
@ -237,7 +199,7 @@ Button.render(o,t,a)
end
btnis.write=function(a,t)
fs.unlink("/tmp/Proxy_Group")
luci.sys.exec(string.format('uci set openclash.config.config_path="/etc/openclash/config/%s"',e[t].name))
SYS.exec(string.format('uci set openclash.config.config_path="/etc/openclash/config/%s"',e[t].name))
uci:commit("openclash")
HTTP.redirect(luci.dispatcher.build_url("admin", "services", "openclash", "config"))
end
@ -284,6 +246,7 @@ btnrm.write=function(a,t)
fs.unlink("/tmp/Proxy_Group")
fs.unlink("/etc/openclash/backup/"..fs.basename(e[t].name))
fs.unlink("/etc/openclash/history/"..fs.basename(e[t].name))
fs.unlink("/etc/openclash/"..fs.basename(e[t].name))
local a=fs.unlink("/etc/openclash/config/"..fs.basename(e[t].name))
default_config_set(fs.basename(e[t].name))
if a then table.remove(e,t)end
@ -314,7 +277,7 @@ o.write = function()
HTTP.redirect(DISP.build_url("admin", "services", "openclash", "rule-providers-file-manage"))
end
m = SimpleForm("config_file_edit",translate("Config File Edit"))
m = SimpleForm("openclash",translate("Config File Edit"))
m.reset = false
m.submit = false
@ -323,14 +286,17 @@ local tab = {
}
s = m:section(Table, tab)
s.description = align_mid..translate("Support syntax check, press").." "..font_green..bold_on.."F11"..bold_off..font_off.." "..translate("to enter full screen editing mode")..align_mid_off
s.anonymous = true
s.addremove = false
local conf = string.sub(luci.sys.exec("uci get openclash.config.config_path 2>/dev/null"), 1, -2)
local conf = string.sub(SYS.exec("uci get openclash.config.config_path 2>/dev/null"), 1, -2)
local dconf = "/usr/share/openclash/res/default.yaml"
local conf_name = fs.basename(conf)
if not conf_name or conf == "" then conf_name = "config.yaml" end
if not conf_name or conf == "" then conf_name = "config.yaml" conf = "/etc/openclash/config/config.yaml" end
local sconf = "/etc/openclash/"..conf_name
sev = s:option(Value, "user")
sev.template = "cbi/tvalue"
sev = s:option(TextValue, "user")
sev.description = translate("Modify Your Config file:").." "..font_green..bold_on..conf_name..bold_off..font_off.." "..translate("Here, Except The Settings That Were Taken Over")
sev.rows = 40
sev.wrap = "off"
@ -340,22 +306,31 @@ end
sev.write = function(self, section, value)
if (CHIF == "0") then
value = value:gsub("\r\n?", "\n")
NXFS.writefile(conf, value)
local old_value = NXFS.readfile(conf)
if value ~= old_value then
NXFS.writefile(conf, value)
end
end
end
def = s:option(Value, "default")
def.template = "cbi/tvalue"
def.description = translate("Default Config File With Correct General-Settings")
def = s:option(TextValue, "default")
if fs.isfile(sconf) then
def.description = translate("Config File Edited By OpenClash For Running")
else
def.description = translate("Default Config File With Correct Template")
end
def.rows = 40
def.wrap = "off"
def.readonly = true
def.cfgvalue = function(self, section)
return NXFS.readfile(dconf) or ""
return NXFS.readfile(sconf) or NXFS.readfile(dconf) or ""
end
def.write = function(self, section, value)
end
o = s:option(DummyValue, "")
o.anonymous=true
o.template = "openclash/config_editor"
local t = {
{Commit, Apply}

View File

@ -58,9 +58,22 @@ o:value("fallback", translate("Fallback"))
o:value("load-balance", translate("Load-Balance"))
o:value("relay", translate("Relay Traffic"))
o = s:option(ListValue, "strategy", translate("Strategy Type"))
o.rmempty = true
o.description = translate("Choose The Load-Balance's Strategy Type")
o:value("consistent-hashing", translate("Consistent-hashing"))
o:value("round-robin", translate("Round-robin"))
o:depends("type", "load-balance")
o = s:option(Value, "name", translate("Group Name"))
o.rmempty = false
o = s:option(ListValue, "disable_udp", translate("Disable UDP"))
o:value("false", translate("Disable"))
o:value("true", translate("Enable"))
o.default = "false"
o.rmempty = false
o = s:option(Value, "test_url", translate("Test URL"))
o:value("http://www.gstatic.com/generate_204")
o:value("https://cp.cloudflare.com/generate_204")

View File

@ -9,36 +9,11 @@ m.pageaction = false
s.anonymous = true
s.addremove=false
local clog = "/tmp/openclash.log"
log = s:option(TextValue, "clog")
log.readonly=true
log.pollcheck=true
log.template="openclash/log"
log.description = translate("")
log.rows = 29
log.wrap = "off"
log.cfgvalue = function(self, section)
return NXFS.readfile(clog) or ""
end
log.write = function(self, section, value)
end
local t = {
{refresh, clean}
}
a = m:section(Table, t)
o = a:option(Button, "refresh")
o.inputtitle = translate("Refresh Log")
o.inputstyle = "apply"
o.write = function()
HTTP.redirect(luci.dispatcher.build_url("admin", "services", "openclash", "log"))
end
o = a:option(Button, "clean")
o.inputtitle = translate("Clean Log")
o.inputstyle = "apply"
o.write = function()
SYS.call("echo '' >/tmp/openclash.log")
end
return m

View File

@ -67,7 +67,7 @@ o:depends("en_mode", "redir-host-tun")
o:depends("en_mode", "fake-ip-tun")
o:depends("en_mode", "redir-host-mix")
o:depends("en_mode", "fake-ip-mix")
o:value("system", translate("System "))
o:value("system", translate("System"))
o:value("gvisor", translate("Gvisor"))
o.default = "system"
@ -124,6 +124,16 @@ o:value("0", translate("Disable"))
o:value("1", translate("Enable"))
o.default=0
o = s:taboption("settings", ListValue, "interface_name", font_red..bold_on..translate("Bind Network Interface")..bold_off..font_off)
local de_int = SYS.exec("ip route |grep 'default' |awk '{print $5}' 2>/dev/null")
o.description = translate("Default Interface Name:").." "..font_green..bold_on..de_int..bold_off..font_off..translate(",Try Enable If Network Loopback")
local interfaces = SYS.exec("ls -l /sys/class/net/ 2>/dev/null |awk '{print $9}' 2>/dev/null")
for interface in string.gmatch(interfaces, "%S+") do
o:value(interface)
end
o:value("0", translate("Disable"))
o.default=0
o = s:taboption("settings", ListValue, "log_level", translate("Log Level"))
o.description = translate("Select Core's Log Level")
o:value("info", translate("Info Mode"))
@ -164,6 +174,13 @@ o.datatype = "port"
o.rmempty = false
o.description = translate("Please Make Sure Ports Available")
o = s:taboption("settings", Value, "mixed_port")
o.title = translate("Mixed Port")
o.default = 7893
o.datatype = "port"
o.rmempty = false
o.description = translate("Please Make Sure Ports Available")
---- DNS Settings
o = s:taboption("dns", ListValue, "enable_redirect_dns", font_red..bold_on..translate("Redirect Local DNS Setting")..bold_off..font_off)
o.description = translate("Set Local DNS Redirect")
@ -204,7 +221,7 @@ o.inputstyle = "reload"
o.write = function()
m.uci:set("openclash", "config", "enable", 1)
m.uci:commit("openclash")
SYS.call("rm -rf /etc/openclash/fake_filter.list >/dev/null 2>&1 && /etc/init.d/openclash restart >/dev/null 2>&1 &")
SYS.call("rm -rf /tmp/openclash_fake_filter.list >/dev/null 2>&1 && /etc/init.d/openclash restart >/dev/null 2>&1 &")
HTTP.redirect(DISP.build_url("admin", "services", "openclash"))
end
@ -222,7 +239,10 @@ function custom_fake_black.write(self, section, value)
if value then
value = value:gsub("\r\n?", "\n")
NXFS.writefile("/etc/openclash/custom/openclash_custom_fake_filter.list", value)
local old_value = NXFS.readfile("/etc/openclash/custom/openclash_custom_fake_filter.list")
if value ~= old_value then
NXFS.writefile("/etc/openclash/custom/openclash_custom_fake_filter.list", value)
end
end
end
end
@ -247,7 +267,10 @@ function custom_domain_dns.write(self, section, value)
if value then
value = value:gsub("\r\n?", "\n")
NXFS.writefile("/etc/openclash/custom/openclash_custom_domain_dns.list", value)
local old_value = NXFS.readfile("/etc/openclash/custom/openclash_custom_domain_dns.list")
if value ~= old_value then
NXFS.writefile("/etc/openclash/custom/openclash_custom_domain_dns.list", value)
end
end
end
@ -643,7 +666,10 @@ end
function custom_rules.write(self, section, value)
if value then
value = value:gsub("\r\n?", "\n")
NXFS.writefile("/etc/openclash/custom/openclash_custom_rules.list", value)
local old_value = NXFS.readfile("/etc/openclash/custom/openclash_custom_rules.list")
if value ~= old_value then
NXFS.writefile("/etc/openclash/custom/openclash_custom_rules.list", value)
end
end
end
@ -659,7 +685,10 @@ end
function custom_rules_2.write(self, section, value)
if value then
value = value:gsub("\r\n?", "\n")
NXFS.writefile("/etc/openclash/custom/openclash_custom_rules_2.list", value)
local old_value = NXFS.readfile("/etc/openclash/custom/openclash_custom_rules_2.list")
if value ~= old_value then
NXFS.writefile("/etc/openclash/custom/openclash_custom_rules_2.list", value)
end
end
end
@ -679,7 +708,10 @@ end
function custom_hosts.write(self, section, value)
if value then
value = value:gsub("\r\n?", "\n")
NXFS.writefile("/etc/openclash/custom/openclash_custom_hosts.list", value)
local old_value = NXFS.readfile("/etc/openclash/custom/openclash_custom_hosts.list")
if value ~= old_value then
NXFS.writefile("/etc/openclash/custom/openclash_custom_hosts.list", value)
end
end
end
end

View File

@ -0,0 +1,67 @@
<%+cbi/valueheader%>
<style>
.CodeMirror {
text-align: left !important;
font-size: 15px;
line-height: 150%;
resize: both !important;
}
</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/addon/fold/foldgutter.css"/>
<link rel="stylesheet" href="/luci-static/resources/openclash/addon/lint/lint.css">
<link rel="stylesheet" href="/luci-static/resources/openclash/addon/display/fullscreen.css">
<script src="/luci-static/resources/openclash/lib/codemirror.js"></script>
<script src="/luci-static/resources/openclash/mode/yaml/yaml.js"></script>
<script src="/luci-static/resources/openclash/addon/fold/foldcode.js"></script>
<script src="/luci-static/resources/openclash/addon/fold/foldgutter.js"></script>
<script src="/luci-static/resources/openclash/addon/fold/indent-fold.js"></script>
<script src="/luci-static/resources/openclash/addon/edit/matchbrackets.js"></script>
<script src="/luci-static/resources/openclash/addon/selection/active-line.js"></script>
<script src="/luci-static/resources/openclash/addon/lint/lint.js"></script>
<script src="/luci-static/resources/openclash/addon/lint/yaml-lint.js"></script>
<script src="/luci-static/resources/openclash/addon/lint/js-yaml.min.js"></script>
<script src="/luci-static/resources/openclash/addon/display/fullscreen.js"></script>
<script type="text/javascript">//<![CDATA[
function editor(id,wid,readOnly)
{
var editor = CodeMirror.fromTextArea(id, {
mode: "text/yaml",
styleActiveLine: true,
lineNumbers: true,
theme: "material",
lineWrapping: true,
matchBrackets: true,
foldGutter: true,
lint: true,
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter", "CodeMirror-lint-markers"],
extraKeys: {
"F11": function(cm) {
cm.setOption("fullScreen", !cm.getOption("fullScreen"));
},
"Esc": function(cm) {
if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
}
}
});
if (readOnly == "true") {
editor.setOption("readOnly","true");
}
editor.setSize(wid,'700px');
}
var myEditor_use = document.getElementById("cbid.table.1.user");
var myEditor_use_wid = document.getElementById("cbi-table-1-user").offsetWidth;
var myEditor_def = document.getElementById("cbid.table.1.default");
var myEditor_def_wid = document.getElementById("cbi-table-1-default").offsetWidth;
editor(myEditor_use, myEditor_use_wid, 'false');
editor(myEditor_def, myEditor_def_wid, 'true');
//]]>
</script>
<%+cbi/valuefooter%>

View File

@ -0,0 +1,101 @@
<%+cbi/valueheader%>
<textarea id="cbid.openclash.config.clog" class="cbi-input-textarea" style="width: 100%;display:inline" data-update="change" rows="32" cols="60" readonly="readonly" > </textarea>
<fieldset class="cbi-section">
<table width="100%">
<tr>
<td width="33%" align="center">
<input type="button" class="cbi-button cbi-button-apply" id="stop_refresh_button" value="<%:Stop Refresh Log%>" onclick=" return stop_refresh() "/>
</td>
<td width="33%" align="center">
<input type="button" class="cbi-button cbi-button-apply" id="start_refresh_button" value="<%:Start Refresh Log%>" onclick=" return start_refresh() "/>
</td>
<td width="33%" align="center">
<input type="button" class="cbi-button cbi-button-apply" id="del_log_button" value="<%:Clean Log%>" style=" display:inline;" onclick=" return del_log()" />
</td>
</tr>
</table>
</fieldset>
<script type="text/javascript">//<![CDATA[
var r
function stop_refresh() {
clearTimeout(r);
return
}
function start_refresh() {
clearTimeout(r);
r=setTimeout("poll_log()",1000*2);
return
}
function del_log() {
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "del_log")%>',null,function(x, data){
var lv = document.getElementById('cbid.openclash.config.clog');
lv.innerHTML="";
}
);
return
}
function p(s) {
return s < 10 ? '0' + s: s;
}
function line_tolocal(str){
var strt=new Array();
str.trim().split('\n').forEach(function(v, i) {
var dt = new Date(v.substring(6,26));
if (dt != "Invalid Date"){
strt[i]=dt.getFullYear()+"-"+p(dt.getMonth()+1)+"-"+p(dt.getDate())+" "+p(dt.getHours())+":"+p(dt.getMinutes())+":"+p(dt.getSeconds())+v.substring(27);
}else{
strt[i]=v;}})
var old_log_line = sessionStorage.log_line;
if ( old_log_line != null) {
if (old_log_line - strt.length < 0) {
sessionStorage.log_line = strt.length;
return strt.slice('-'+(strt.length-old_log_line))
}
else if (old_log_line == strt.length) {
sessionStorage.log_line = strt.length;
return
}
else if (old_log_line - strt.length > 0) {
sessionStorage.log_line = strt.length;
var lv = document.getElementById('cbid.openclash.config.clog');
lv.innerHTML = "";
return strt
}
}
else {
sessionStorage.log_line = strt.length;
return strt
}
}
function poll_log(){
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "refresh_log")%>', null,
function(x, data) {
if ( x && x.status == 200 ) {
var lv = document.getElementById('cbid.openclash.config.clog');
if (x.responseText && lv) {
var lines=line_tolocal(x.responseText);
if (lines != null) {
lv.innerHTML = lines.reverse().join('\n')+'\n'+lv.innerHTML;
//lv.innerHTML = x.responseText.split('\n').reverse().join('\n')+lv.innerHTML;
}
}
}
}
);
r=setTimeout("poll_log()",1000*2);
}
sessionStorage.removeItem("log_line");
poll_log();
//]]>
</script>
<%+cbi/valuefooter%>

View File

@ -131,27 +131,27 @@
<body>
<div style="display: flex;">
<div style="width: 51%">
<h3>IP 地址</h3>
<h3><%:IP Address%></h3>
<p>
<span class="ip-title">IPIP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;国内:</span><span class="ip-result" id="ip-ipipnet"></span> <span class="ip-geo" id="ip-ipipnet-geo"></span>
<span class="ip-title">IPIP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<%:Mainland%>:</span><span class="ip-result" id="ip-ipipnet"></span> <span class="ip-geo" id="ip-ipipnet-geo"></span>
</p>
<p>
<span class="ip-title">IP.PC&nbsp;&nbsp;&nbsp;&nbsp;国内:</span><span class="ip-result" id="ip-pcol"></span> <span class="ip-geo" id="ip-pcol-ipip"></span>
<span class="ip-title">IP.PC&nbsp;&nbsp;&nbsp;&nbsp;<%:Mainland%>:</span><span class="ip-result" id="ip-pcol"></span> <span class="ip-geo" id="ip-pcol-ipip"></span>
</p>
<p>
<span class="ip-title">IP.SB&nbsp;&nbsp;&nbsp;&nbsp;海外:</span><span class="ip-result" id="ip-ipsb"></span> <span class="ip-geo" id="ip-ipsb-geo"></span>
<span class="ip-title">IP.SB&nbsp;&nbsp;&nbsp;&nbsp;<%:Abroad%>:</span><span class="ip-result" id="ip-ipsb"></span> <span class="ip-geo" id="ip-ipsb-geo"></span>
</p>
<p>
<span class="ip-title">IPIFY&nbsp;&nbsp;&nbsp;&nbsp;海外:</span><span class="ip-result" id="ip-ipify"></span> <span class="ip-geo" id="ip-ipify-ipip"></span>
<span class="ip-title">IPIFY&nbsp;&nbsp;&nbsp;&nbsp;<%:Abroad%>:</span><span class="ip-result" id="ip-ipify"></span> <span class="ip-geo" id="ip-ipify-ipip"></span>
</p>
</div>
<div style="width: 49%">
<h3>网站访问检查</h3>
<h3><%:Website Access Check%></h3>
<p>
<span class="ip-state_title">百度搜索:</span><span id="http-baidu"></span>
<span class="ip-state_title"><%:Baidu Search%>:</span><span id="http-baidu"></span>
</p>
<p>
<span class="ip-state_title">网易云音乐:</span><span id="http-163"></span>
<span class="ip-state_title"><%:NetEase Music%>:</span><span id="http-163"></span>
</p>
<p>
<span class="ip-state_title">GitHub:</span><span id="http-github"></span>
@ -174,10 +174,10 @@
window.open(url2);
}
const $$ = document;
$$.getElementById('ip-pcol').innerHTML = '查询中...';
$$.getElementById('ip-ipify').innerHTML = '查询中...';
$$.getElementById('ip-ipipnet').innerHTML = '查询中...';
$$.getElementById('ip-ipsb').innerHTML = '查询中...';
$$.getElementById('ip-pcol').innerHTML = '<%:Querying...%>';
$$.getElementById('ip-ipify').innerHTML = '<%:Querying...%>';
$$.getElementById('ip-ipipnet').innerHTML = '<%:Querying...%>';
$$.getElementById('ip-ipsb').innerHTML = '<%:Querying...%>';
let random = parseInt(Math.random() * 100000000);
let IP = {
get: (url, type) =>
@ -246,26 +246,26 @@
}
};
$$.getElementById('http-baidu').innerHTML = '<span class="ip-checking">检测中...</span>';
$$.getElementById('http-163').innerHTML = '<span class="ip-checking">检测中...</span>';
$$.getElementById('http-github').innerHTML = '<span class="ip-checking">检测中...</span>';
$$.getElementById('http-youtube').innerHTML = '<span class="ip-checking">检测中...</span>';
$$.getElementById('http-baidu').innerHTML = '<span class="ip-checking"><%:Testing...%></span>';
$$.getElementById('http-163').innerHTML = '<span class="ip-checking"><%:Testing...%></span>';
$$.getElementById('http-github').innerHTML = '<span class="ip-checking"><%:Testing...%></span>';
$$.getElementById('http-youtube').innerHTML = '<span class="ip-checking"><%:Testing...%></span>';
let HTTP = {
checker: (domain, cbElID) => {
let img = new Image;
let timeout = setTimeout(() => {
img.onerror = img.onload = null;
$$.getElementById(cbElID).innerHTML = '<span class="sk-text-error">连接超时</span>'
$$.getElementById(cbElID).innerHTML = '<span class="sk-text-error"><%:Access Timed Out%></span>'
}, 5000);
img.onerror = () => {
clearTimeout(timeout);
$$.getElementById(cbElID).innerHTML = '<span class="sk-text-error">无法访问</span>'
$$.getElementById(cbElID).innerHTML = '<span class="sk-text-error"><%:Access Denied%></span>'
}
img.onload = () => {
clearTimeout(timeout);
$$.getElementById(cbElID).innerHTML = '<span class="sk-text-success">连接正常</span>'
$$.getElementById(cbElID).innerHTML = '<span class="sk-text-success"><%:Access Normal%></span>'
}
img.src = `https://${domain}/favicon.ico?${+(new Date)}`

View File

@ -56,24 +56,22 @@
&nbsp;&nbsp;&nbsp;
<img id="star" src="https://img.shields.io/badge/Star--lightgrey?logo=github&style=social" loading="lazy" alt="star" width="50px" height="20px" onerror="return imgerrorfuns(this,this.src)" onclick="return homepage()" />
&nbsp;&nbsp;&nbsp;
<!--
<img id="telegram" src="https://img.shields.io/badge/Telegram--lightgrey?logo=Telegram&style=social" loading="lazy" alt="Telegram" onerror="return imgerrorfuns(this,this.src)" onclick="return telegrampage()" />
&nbsp;&nbsp;&nbsp;
-->
<img id="sponsor" src="https://img.shields.io/badge/Sponsor--lightgrey?logo=ko-fi&style=social" loading="lazy" alt="Sponsor" width="73px" height="20px" onerror="return imgerrorfuns(this,this.src)" onclick="return sponsorpage()" />
</p>
</td></tr>
<tr><td width="100%" colspan="4">
<p align="center" id="_clashstart">
<b> Tip: OpenClash 成功启动后请耐心等待下方网站访问检查连接正常后再使用 </b>
<b><%:Tip: after started, please wait patiently until the connection is normal%></b>
</p>
</td></tr>
<tr><td width="25%"> OpenClash 主程序 </td><td width="25%" align="left" id="_clash"><%:Collecting data...%></td><td width="25%"> 控制面板登录IP </td><td width="25%" align="left" id="_daip"><%:Collecting data...%></td></tr>
<tr><td width="25%"> OpenClash 守护程序 </td><td width="25%" align="left" id="_watchdog"><%:Collecting data...%></td><td width="25%"> 控制面板登录端口 </td><td width="25%" align="left" id="_dapo"><%:Collecting data...%></td></tr>
<tr><td width="25%"> OpenClash 运行模式 </td><td width="25%" align="left" id="_mode"><%:Collecting data...%></td><td width="25%"> 控制面板登录密钥 </td><td width="25%" align="left" id="_dase"><%:Collecting data...%></td></tr>
<tr><td width="25%"> Yacd 控制面板 </td><td width="25%" align="left" id="_web"><%:Collecting data...%></td><td width="25%"> Dashboard 控制面板 </td><td width="25%" align="left" id="_webo"><%:Collecting data...%></td></tr>
<tr><td width="25%"><%:Main Program%></td><td width="25%" align="left" id="_clash"><%:Collecting data...%></td><td width="25%"><%:Control Panel Login IP%></td><td width="25%" align="left" id="_daip"><%:Collecting data...%></td></tr>
<tr><td width="25%"><%:Core Daemons%></td><td width="25%" align="left" id="_watchdog"><%:Collecting data...%></td><td width="25%"><%:Control Panel Login Port%></td><td width="25%" align="left" id="_dapo"><%:Collecting data...%></td></tr>
<tr><td width="25%"><%:Core Running Mode%></td><td width="25%" align="left" id="_mode"><%:Collecting data...%></td><td width="25%"><%:Control Panel Login Secret%></td><td width="25%" align="left" id="_dase"><%:Collecting data...%></td></tr>
<tr><td width="25%"><%:Yacd Control Panel%></td><td width="25%" align="left" id="_web"><%:Collecting data...%></td><td width="25%"><%:Dashboard Control Panel%></td><td width="25%" align="left" id="_webo"><%:Collecting data...%></td></tr>
<tr><td width="100%" colspan="4"><p align="center"><img id="hid_btn" alt="Show More" height="20px" onclick="return hid_btn_action()"/></p></td></tr>
<tr id="hid_1"><td width="100%" colspan="4"><p align="center"><b> 常用操作快捷按钮 </b></p></td></tr>
<tr id="hid_1"><td width="100%" colspan="4"><p align="center"><b><%:Quick Operation%></b></p></td></tr>
<tr id="hid_2"><td width="25%" align="center" id="_get_history"><%:Collecting data...%></td>
<td width="25%" align="center" id="_restore_history"><%:Collecting data...%></td>
<td width="25%" align="center" id="_close_all_connection"><%:Collecting data...%></td>
@ -89,12 +87,12 @@
<table>
<tr><td width="100%" colspan="4">
<p align="center">
<b> 组件的状态显示,运行前请确保各项目显示正常,需要更新请到全局设置页面操作 </b>
<b><%:Please ensure that all items are displayed normally before running. If you need to update, please go to the global settings page%></b>
</p>
</td></tr>
<tr><td width="25%"> 策略组节点选择 备份日期 </td><td width="25%" align="left" id="_historychecktime"><%:Collecting data...%></td><td width="25%"> lhie1 规则更新日期 </td><td width="25%" align="left" id="_lhie1"><%:Collecting data...%></td></tr>
<tr><td width="25%"> ConnersHua 规则更新日期 </td><td width="25%" align="left" id="_ConnersHua"><%:Collecting data...%></td><td width="25%"> ConnersHua 回国规则更新日期 </td><td width="25%" align="left" id="_ConnersHua_return"><%:Collecting data...%></td></tr>
<tr><td width="25%"> 大陆IP白名单 更新日期 </td><td width="25%" align="left" id="_chnroute"><%:Collecting data...%></td><td width="25%"> GEOIPBy MaxMind数据库日期 </td><td width="25%" align="left" id="_ipdb"><%:Collecting data...%></td></tr>
<tr><td width="25%"><%:Node Select Backup%></td><td width="25%" align="left" id="_historychecktime"><%:Collecting data...%></td><td width="25%"><%:lhie1 Rule Update%></td><td width="25%" align="left" id="_lhie1"><%:Collecting data...%></td></tr>
<tr><td width="25%"><%:ConnersHua Rule Update%></td><td width="25%" align="left" id="_ConnersHua"><%:Collecting data...%></td><td width="25%"><%:ConnersHua Return Rule Update%></td><td width="25%" align="left" id="_ConnersHua_return"><%:Collecting data...%></td></tr>
<tr><td width="25%"><%:Mainland IP Update%></td><td width="25%" align="left" id="_chnroute"><%:Collecting data...%></td><td width="25%"><%:GEOIPBy MaxMindData Update%></td><td width="25%" align="left" id="_ipdb"><%:Collecting data...%></td></tr>
</table>
</fieldset>
<script type="text/javascript">//<![CDATA[
@ -167,7 +165,7 @@
historychecktime.innerHTML = "<b><font color=green>"+status.historychecktime+"</font></b>";
}
else {
historychecktime.innerHTML = "<b><font color=green>"+"<%:暂未备份%>"+"</font></b>";
historychecktime.innerHTML = "<b><font color=green>"+"<%:No Backup%>"+"</font></b>";
}
}
});
@ -175,58 +173,58 @@
if ( x && x.status == 200 ) {
if ( status.restricted_mode != "1" )
{
clash.innerHTML = status.clash ? '<b><font color=green><%:RUNNING%></font></b>' : '<b><font color=red><%:NOT RUNNING%></font></b>';
clash.innerHTML = status.clash ? '<b><font color=green><%:Running%></font></b>' : '<b><font color=red><%:Not Running%></font></b>';
}
else
{
clash.innerHTML = status.clash ? '<b><font color=green><%:RUNNING%><%: <功能受限状态> %></font></b>' : '<b><font color=red><%:NOT RUNNING%></font></b>';
clash.innerHTML = status.clash ? '<b><font color=green><%:Running%> <%:<Limited State>%></font></b>' : '<b><font color=red><%:Not Running%></font></b>';
}
if ( status.mode == "fake-ip\n" )
{
mode.innerHTML = status.clash ? "<b><font color=green><%: Fake-IP(增强)模式 %></font></b>" : '<b><font color=red><%:NOT RUNNING%></font></b>';
mode.innerHTML = status.clash ? "<b><font color=green><%:Fake-IP (Enhance)%></font></b>" : '<b><font color=red><%:Not Running%></font></b>';
}
else if ( status.mode == "redir-host\n" )
{
mode.innerHTML = status.clash ? "<b><font color=green><%: Redir-Host(兼容)模式 %></font></b>" : '<b><font color=red><%:NOT RUNNING%></font></b>';
mode.innerHTML = status.clash ? "<b><font color=green><%:Redir-Host (Compatible)%></font></b>" : '<b><font color=red><%:Not Running%></font></b>';
}
else if ( status.mode == "redir-host-tun\n" )
{
mode.innerHTML = status.clash ? "<b><font color=green><%: Redir-HostTUN模式 %></font></b>" : '<b><font color=red><%:NOT RUNNING%></font></b>';
mode.innerHTML = status.clash ? "<b><font color=green><%:Redir-Host (TUN)%></font></b>" : '<b><font color=red><%:Not Running%></font></b>';
}
else if ( status.mode == "fake-ip-tun\n" )
{
mode.innerHTML = status.clash ? "<b><font color=green><%: Fake-IPTUN模式 %></font></b>" : '<b><font color=red><%:NOT RUNNING%></font></b>';
mode.innerHTML = status.clash ? "<b><font color=green><%:Fake-IP (TUN)%></font></b>" : '<b><font color=red><%:Not Running%></font></b>';
}
else if ( status.mode == "redir-host-vpn\n" )
{
mode.innerHTML = status.clash ? "<b><font color=green><%: Redir-Host(游戏)模式 %></font></b>" : '<b><font color=red><%:NOT RUNNING%></font></b>';
mode.innerHTML = status.clash ? "<b><font color=green><%:Redir-Host (Game)%></font></b>" : '<b><font color=red><%:Not Running%></font></b>';
}
else if ( status.mode == "fake-ip-vpn\n" )
{
mode.innerHTML = status.clash ? "<b><font color=green><%: Fake-IP(游戏)模式 %></font></b>" : '<b><font color=red><%:NOT RUNNING%></font></b>';
mode.innerHTML = status.clash ? "<b><font color=green><%:Fake-IP (Game)%></font></b>" : '<b><font color=red><%:Not Running%></font></b>';
}
else if ( status.mode == "fake-ip-mix\n" )
{
mode.innerHTML = status.clash ? "<b><font color=green><%: Fake-IPTUN-混合)模式 %></font></b>" : '<b><font color=red><%:NOT RUNNING%></font></b>';
mode.innerHTML = status.clash ? "<b><font color=green><%:Fake-IP (TUN-Mix)%></font></b>" : '<b><font color=red><%:Not Running%></font></b>';
}
else if ( status.mode == "redir-host-mix\n" )
{
mode.innerHTML = status.clash ? "<b><font color=green><%: Redir-HostTUN-混合)模式 %></font></b>" : '<b><font color=red><%:NOT RUNNING%></font></b>';
mode.innerHTML = status.clash ? "<b><font color=green><%:Redir-Host (TUN-Mix)%></font></b>" : '<b><font color=red><%:Not Running%></font></b>';
}
watchdog.innerHTML = status.watchdog ? '<b><font color=green><%:RUNNING%></font> </b>' : '<b><font color=red><%:NOT RUNNING%></font></b>';
watchdog.innerHTML = status.watchdog ? '<b><font color=green><%:Running%></font> </b>' : '<b><font color=red><%:Not Running%></font></b>';
daip.innerHTML = status.daip ? "<b><font color=green>"+status.daip+"</font></b>" : "<b><font color=red>"+"<%:Not Set%>"+"</font></b>";
dase.innerHTML = status.dase ? "<b><font color=green>"+status.dase+"</font></b>" : "<b><font color=red>"+"<%:Not Set%>"+"</font></b>";
dapo.innerHTML = status.cn_port ? "<b><font color=green>"+status.cn_port+"</font></b>" : "<b><font color=red>"+"<%:Not Set%>"+"</font></b>";
web.innerHTML = status.web ? '<input type="button" class="cbi-button cbi-button-reload" value="<%:打开控制面板%>" onclick="return ycad_dashboard(this)"/>' : '<b><font color=red><%:NOT RUNNING%></font></b>';
webo.innerHTML = status.web ? '<input type="button" class="cbi-button cbi-button-reload" value="<%:打开控制面板%>" onclick="return net_dashboard(this)"/>' : '<b><font color=red><%:NOT RUNNING%></font></b>';
close_all_connection.innerHTML = status.clash ? '<input type="button" class="cbi-button cbi-button-reload" value="<%:重置所有链接%>" onclick="return b_close_all_connection(this)"/>' : '<b><font color=red><%:NOT RUNNING%></font></b>';
restore_history.innerHTML = status.clash ? '<input type="button" class="cbi-button cbi-button-reload" value="<%:还原策略组节点选择%>" onclick="return b_restore_history(this)"/>' : '<b><font color=red><%:NOT RUNNING%></font></b>';
get_history.innerHTML = status.clash ? '<input type="button" class="cbi-button cbi-button-reload" value="<%:保存策略组节点选择%>" onclick="return b_get_history(this)"/>' : '<b><font color=red><%:NOT RUNNING%></font></b>';
reload_firewall.innerHTML = status.clash ? '<input type="button" class="cbi-button cbi-button-reload" value="<%:重置防火墙规则%>" onclick="return b_reload_firewall(this)"/>' : '<b><font color=red><%:NOT RUNNING%></font></b>';
one_key_update.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:插件和内核检查更新%>" onclick="return all_one_key_update(this)"/>';
update_subscribe.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:配置文件检查更新%>" onclick="return b_update_subscribe(this)"/>';
update_other_rules.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:第三方规则检查更新%>" onclick="return b_update_other_rules(this)"/>';
update_geoip.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:GEOIP数据库检查更新%>" onclick="return b_update_geoip(this)"/>';
web.innerHTML = status.web ? '<input type="button" class="cbi-button cbi-button-reload" value="<%:Open Panel%>" onclick="return ycad_dashboard(this)"/>' : '<b><font color=red><%:Not Running%></font></b>';
webo.innerHTML = status.web ? '<input type="button" class="cbi-button cbi-button-reload" value="<%:Open Panel%>" onclick="return net_dashboard(this)"/>' : '<b><font color=red><%:Not Running%></font></b>';
close_all_connection.innerHTML = status.clash ? '<input type="button" class="cbi-button cbi-button-reload" value="<%:Close All Connections%>" onclick="return b_close_all_connection(this)"/>' : '<b><font color=red><%:Not Running%></font></b>';
restore_history.innerHTML = status.clash ? '<input type="button" class="cbi-button cbi-button-reload" value="<%:Restore Nodes Selection%>" onclick="return b_restore_history(this)"/>' : '<b><font color=red><%:Not Running%></font></b>';
get_history.innerHTML = status.clash ? '<input type="button" class="cbi-button cbi-button-reload" value="<%:Save Nodes Selection%>" onclick="return b_get_history(this)"/>' : '<b><font color=red><%:Not Running%></font></b>';
reload_firewall.innerHTML = status.clash ? '<input type="button" class="cbi-button cbi-button-reload" value="<%:Reload Firewall Rules%>" onclick="return b_reload_firewall(this)"/>' : '<b><font color=red><%:Not Running%></font></b>';
one_key_update.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:Check All Components Update%>" onclick="return all_one_key_update(this)"/>';
update_subscribe.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:Check Config Update%>" onclick="return b_update_subscribe(this)"/>';
update_other_rules.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:Check Third Party Rules Update%>" onclick="return b_update_other_rules(this)"/>';
update_geoip.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:Check GEOIP Data Update%>" onclick="return b_update_geoip(this)"/>';
}
});
XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "services", "openclash", "state")%>', null, function(x, status) {
@ -240,7 +238,7 @@
historychecktime.innerHTML = "<b><font color=green>"+status.historychecktime+"</font></b>";
}
else {
historychecktime.innerHTML = "<b><font color=green>"+"<%:暂未备份%>"+"</font></b>";
historychecktime.innerHTML = "<b><font color=green>"+"<%:No Backup%>"+"</font></b>";
}
}
});
@ -254,28 +252,25 @@
function all_one_key_update(btn)
{
btn.value = '<%:插件和内核检查更新%>';
btn.value = '<%:Check All Components Update%>';
btn.disabled = true;
var r = confirm("确定要一键检查并更新所有内核及插件吗?")
var r = confirm("<%:Check and update all Cores and plug-ins?%>")
if (r == true) {
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "one_key_update_check")%>', null, function(x, status) {
if ( x && x.status == 200 ) {
if ( status.corever != "0\n" ) {
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "one_key_update")%>', null, function(x, status) {
if ( x && x.status == 200 ) {
alert('一键检查更新正在进行...')
}
else {
alert('一键检查更新失败,请稍后再试!')
if ( x && x.status != 200 ) {
alert('<%:Check failed, Please try again later!%>')
}
});
}
else {
alert('未选择编译版本,请到常规设置标签中配置!')
alert('<%:No compiled version is selected. Please configure it in the General Settings tab!%>')
}
}
else {
alert('一键检查更新失败,请稍后再试!')
alert('<%:Check failed, Please try again later!%>')
}
});
}
@ -287,15 +282,15 @@
function b_update_other_rules(btn)
{
btn.disabled = true;
btn.value = '<%:正在检查更新...%>';
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 = '<%:第三方规则检查更新%>';
btn.value = '<%:Check Third Party Rules Update%>';
}
else {
btn.disabled = false;
btn.value = '<%:第三方规则检查更新%>';
btn.value = '<%:Check Third Party Rules Update%>';
}
return false;
});
@ -303,15 +298,15 @@
function b_update_geoip(btn)
{
btn.disabled = true;
btn.value = '<%:正在检查更新...%>';
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 = '<%:GEOIP数据库检查更新%>';
btn.value = '<%:Check GEOIP Data Update%>';
}
else {
btn.disabled = false;
btn.value = '<%:GEOIP数据库检查更新%>';
btn.value = '<%:Check GEOIP Data Update%>';
}
return false;
});
@ -319,15 +314,15 @@
function b_update_subscribe(btn)
{
btn.disabled = true;
btn.value = '<%:正在检查更新...%>';
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 = '<%:配置文件检查更新%>';
btn.value = '<%:Check Config Update%>';
}
else {
btn.disabled = false;
btn.value = '<%:配置文件检查更新%>';
btn.value = '<%:Check Config Update%>';
}
return false;
});
@ -335,15 +330,15 @@
function b_reload_firewall(btn)
{
btn.disabled = true;
btn.value = '<%:正在重置...%>';
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 = '<%:重置防火墙规则%>';
btn.value = '<%:Reload Firewall Rules%>';
}
else {
btn.disabled = false;
btn.value = '<%:防火墙规则重置失败%>';
btn.value = '<%:Firewall Rules Reset Failed%>';
}
return false;
});
@ -351,15 +346,15 @@
function b_close_all_connection(btn)
{
btn.disabled = true;
btn.value = '<%:正在重置...%>';
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 = '<%:重置所有链接%>';
btn.value = '<%:Close All Connections%>';
}
else {
btn.disabled = false;
btn.value = '<%:重置链接失败%>';
btn.value = '<%:Close All Connections Failed%>';
}
return false;
});
@ -367,15 +362,15 @@
function b_restore_history(btn)
{
btn.disabled = true;
btn.value = '<%:正在还原...%>';
btn.value = '<%:Restoring...%>';
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "restore_history")%>', null, function(x, status) {
if ( x && x.status == 200 ) {
btn.disabled = false;
btn.value = '<%:还原策略组节点选择%>';
btn.value = '<%:Restore Nodes Selection%>';
}
else {
btn.disabled = false;
btn.value = '<%:还原失败%>';
btn.value = '<%:Restore Nodes Selection Failed%>';
}
return false;
});
@ -383,15 +378,15 @@
function b_get_history(btn)
{
btn.disabled = true;
btn.value = '<%:正在保存...%>';
btn.value = '<%:Saving...%>';
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "get_history")%>', null, function(x, status) {
if ( x && x.status == 200 ) {
btn.disabled = false;
btn.value = '<%:保存策略组节点选择%>';
btn.value = '<%:Save Nodes Selection%>';
}
else {
btn.disabled = false;
btn.value = '<%:保存失败%>';
btn.value = '<%:Save Nodes Selection Failed%>';
}
return false;
});
@ -401,7 +396,7 @@
{
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "status")%>', status.cn_port, function(x, status) {
btn.disabled = true;
btn.value = '<%:打开控制面板%>';
btn.value = '<%:Open Panel%>';
url1='<%="http://'+window.location.hostname+status.uh_port+'/luci-static/openclash?hostname='+ status.daip + '&port=' + status.cn_port + '&secret=' + status.dase +'"%>';
winOpen(url1);
return false;
@ -411,7 +406,7 @@
{
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "status")%>', status.cn_port, function(x, status) {
btn.disabled = true;
btn.value = '<%:打开控制面板%>';
btn.value = '<%:Open Panel%>';
url2='http://'+window.location.hostname+':'+status.cn_port+'/ui';
winOpen(url2);
return false;
@ -432,7 +427,7 @@
function telegrampage()
{
url6='https://t.me/joinchat/D4mVX0n-n5mOK6YO_W3_Og';
url6='https://t.me/ctcgfw_openwrt_discuss';
winOpen(url6);
}
@ -445,7 +440,7 @@
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "currentversion")%>', status.currentversion, function(x, status) {
if ( x && x.status == 200 ) {
clashversion.innerHTML = '<img id="currenntver" src="'+status.currentversion+'" alt="currentversion" width="200px" onload="return clashversion_check()" onclick="return go_update()">';
clashversion.innerHTML = '<img id="currenntver" src="'+status.currentversion+'" alt="currentversion" height="21px" onload="return clashversion_check()" onclick="return go_update()">';
}
});
@ -465,7 +460,7 @@
{
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "currentversion")%>', status.currentversion, function(x, status) {
if ( x && x.status == 200 ) {
clashversion.innerHTML = '<img id="currenntver" src="'+status.currentversion+'" alt="currentversion" width="200px" onclick="return go_update()">';
clashversion.innerHTML = '<img id="currenntver" src="'+status.currentversion+'" alt="currentversion" height="21px" onclick="return go_update()">';
}
});
}
@ -489,51 +484,51 @@
var rdmdl=Math.floor(Math.random()*12)+1;
if(rdmdl==1)
{
startlog.innerHTML = '<b><font><%: Tip: 您可以在配置文件页面直接修改配置文件(适用于没被接管的内容) %></font></b>';
startlog.innerHTML = '<b><font><%:Tip: You can modify the profile on the profile page (for content that is not taken over)%></font></b>';
}
if(rdmdl==2)
{
startlog.innerHTML = '<b><font><%: Tip: 点击上方版本图标可跳转到客户端发布页面 %></font></b>';
startlog.innerHTML = '<b><font><%:Tip: click the version icon above to jump to the client publishing page%></font></b>';
}
if(rdmdl==3)
{
startlog.innerHTML = '<b><font><%: Tip: 不会编写配置文件?试试在【服务器与策略组管理】页面一键创建 %></font></b>';
startlog.innerHTML = '<b><font><%:Tip: do not write configuration files? Try to create one click on the server page%></font></b>';
}
if(rdmdl==4)
{
startlog.innerHTML = '<b><font><%: Tip: 某些网站链接出现异常? 试试切换模式或者使用第三方规则 %></font></b>';
startlog.innerHTML = '<b><font><%:Tip: some website are abnormal? Try switching modes or using third-party rules%></font></b>';
}
if(rdmdl==5)
{
startlog.innerHTML = '<b><font><%: Tip: 使用 Fake-IP 模式可以获得更加快速的访问体验 %></font></b>';
startlog.innerHTML = '<b><font><%:Tip: using the fake IP mode can get a faster access experience%></font></b>';
}
if(rdmdl==6)
{
startlog.innerHTML = '<b><font><%: Tip: 使用 TLS & TCP & HTTPS 方式查询DNS可以获得更好的抗污染效果 %></font></b>';
startlog.innerHTML = '<b><font><%:Tip: query DNS by TLS & TCP & HTTPS can get better anti pollution effect%></font></b>';
}
if(rdmdl==7)
{
startlog.innerHTML = '<b><font><%: Tip: OpenClash 启动时会检查配置文件参数【服务器策略组、规则、DNS设置】以确保能够正常工作 %></font></b>';
startlog.innerHTML = '<b><font><%:Tip: openlash will check the configuration file parameters to ensure that it works properly%></font></b>';
}
if(rdmdl==8)
{
startlog.innerHTML = '<b><font><%: Tip: 使用自定义DNS上游服务器时NameServer组必须设置至少一个服务器 %></font></b>';
startlog.innerHTML = '<b><font><%:Tip: the nameserver group must have at least one server set when using custom DNS%></font></b>';
}
if(rdmdl==9)
{
startlog.innerHTML = '<b><font><%: Tip: 网站访问检查展示的是当前登录LUCI页面设备的连接情况 %></font></b>';
startlog.innerHTML = '<b><font><%:Tip: the website access check shows the connection of the device currently logged in to the Luci page%></font></b>';
}
if(rdmdl==10)
{
startlog.innerHTML = '<b><font><%: Tip: OpenClash 成功启动后请耐心等待下方网站访问检查连接正常后再使用 %></font></b>';
startlog.innerHTML = '<b><font><%:Tip: after started, please wait patiently until the connection is normal%></font></b>';
}
if(rdmdl==11)
{
startlog.innerHTML = '<b><font><%: Tip: 如果不使用IPV6请关闭IPV6的DHCP服务否则会造成连接异常 %></font></b>';
startlog.innerHTML = '<b><font><%:Tip: if you don not use IPv6, please turn off the DHCP service of IPv6, otherwise the connection will be abnormal%></font></b>';
}
if(rdmdl==12)
{
startlog.innerHTML = '<b><font><%: Tip: 您可以在全局设置页面进行版本更新操作 %></font></b>';
startlog.innerHTML = '<b><font><%:Tip: you can update the version in the global settings page%></font></b>';
}
}
}

View File

@ -14,10 +14,10 @@
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "op_mode")%>', null, function(x, status) {
if ( x && x.status == 200 ) {
if ( status.op_mode == "redir-host" ) {
switch_mode.innerHTML = '<input type="button" class="cbi-button cbi-button-reset" value="<%:切换页面到 Fake-IP 模式%>" onclick="return switch_modes(this)"/>';
switch_mode.innerHTML = '<input type="button" class="cbi-button cbi-button-reset" value="<%:Switch page to Fake-IP mode%>" onclick="return switch_modes(this)"/>';
}
else {
switch_mode.innerHTML = '<input type="button" class="cbi-button cbi-button-reset" value="<%:切换页面到 Redir-Host 模式%>" onclick="return switch_modes(this)"/>';
switch_mode.innerHTML = '<input type="button" class="cbi-button cbi-button-reset" value="<%:Switch page to Redir-Host mode%>" onclick="return switch_modes(this)"/>';
}
}
});
@ -28,11 +28,11 @@
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "switch_mode")%>', null, function(x, status) {
if ( x && x.status == 200 ) {
if ( status.switch_mode == "redir-host" ) {
alert('页面已切换为Fake-IP模式')
alert('<%:Page has been switched to Fake-IP mode!%>')
window.location.href='<%="settings"%>';
}
else {
alert('页面已切换为Redir-Host模式')
alert('<%:Page has been switched to Redir-Host mode!%>')
window.location.href='<%="settings"%>';
}
}

View File

@ -3,43 +3,43 @@
<table>
<tr><td width="100%" colspan="4">
<p align="center" id="update_tip">
<b> 注意:如更新失败可手动下载并上传 </b>
<b><%:Note: if the update fails, you can manually download and upload%></b>
</p>
</td></tr>
<tr><td width="25%"> 已选择编译版本 </td><td width="25%" align="left" id="CORE_VERSION"><%:Collecting data...%></td><td width="25%"> 上次检查更新时间 </td><td width="25%" align="left" id="CHECKTIME"><%:Collecting data...%></td></tr>
<tr><td width="25%"> 处理器架构OS </td><td width="25%" align="left" id="CPU_MODEL"><%:Collecting data...%></td><td width="25%"> 处理器架构OPKG </td><td width="25%" align="left" id="CPU_MODEL2"><%:Collecting data...%></td></tr>
<tr><td width="25%"><%:Compiled Version Selected%></td><td width="25%" align="left" id="CORE_VERSION"><%:Collecting data...%></td><td width="25%"><%:Last Check Update%></td><td width="25%" align="left" id="CHECKTIME"><%:Collecting data...%></td></tr>
<tr><td width="25%"><%:CPU Architecture (OS)%></td><td width="25%" align="left" id="CPU_MODEL"><%:Collecting data...%></td><td width="25%"><%:CPU Architecture (OPKG)%></td><td width="25%" align="left" id="CPU_MODEL2"><%:Collecting data...%></td></tr>
<tr><td width="100%" colspan="4">
<p align="center">
<b> 内核路径:/etc/openclash/core/clash </b>
<b><%:Core path:%> /etc/openclash/core/clash</b>
</p>
</td></tr>
<tr><td width="25%"> 当前【Dev分支】内核版本 </td><td width="25%" align="left" id="CORE_CV"><%:Collecting data...%></td><td width="25%"> 最新【Dev分支】内核版本 </td><td width="25%" align="left" id="CORE_LV"><%:Collecting data...%></td></tr>
<tr><td width="25%"> 更新内核</td><td width="25%" align="left" id="core_up"><%:Collecting data...%></td><td width="25%"> 下载最新版本内核</td><td width="25%" align="left" id="ma_core_up"><%:Collecting data...%></td></tr>
<tr><td width="25%">[dev] <%:Current Core%></td><td width="25%" align="left" id="CORE_CV"><%:Collecting data...%></td><td width="25%">[dev] <%:Latest Core%></td><td width="25%" align="left" id="CORE_LV"><%:Collecting data...%></td></tr>
<tr><td width="25%"><%:Update Core%></td><td width="25%" align="left" id="core_up"><%:Collecting data...%></td><td width="25%"><%:Download Latest Core%></td><td width="25%" align="left" id="ma_core_up"><%:Collecting data...%></td></tr>
<tr><td width="100%" colspan="4">
<p align="center">
<b> 内核路径:/etc/openclash/core/clash_tun </b>
<b><%:Core path:%>/etc/openclash/core/clash_tun </b>
</p>
</td></tr>
<tr><td width="25%"> 当前【TUN模式】内核版本 </td><td width="25%" align="left" id="CORE_TUN_CV"><%:Collecting data...%></td><td width="25%"> 最新【TUN模式】内核版本 </td><td width="25%" align="left" id="CORE_TUN_LV"><%:Collecting data...%></td></tr>
<tr><td width="25%"> 更新内核</td><td width="25%" align="left" id="core_tun_up"><%:Collecting data...%></td><td width="25%"> 下载最新版本内核</td><td width="25%" align="left" id="ma_core_tun_up"><%:Collecting data...%></td></tr>
<tr><td width="25%">[TUN] <%:Current Core%></td><td width="25%" align="left" id="CORE_TUN_CV"><%:Collecting data...%></td><td width="25%">[TUN] <%:Latest Core%></td><td width="25%" align="left" id="CORE_TUN_LV"><%:Collecting data...%></td></tr>
<tr><td width="25%"><%:Update Core%></td><td width="25%" align="left" id="core_tun_up"><%:Collecting data...%></td><td width="25%"><%:Download Latest Core%></td><td width="25%" align="left" id="ma_core_tun_up"><%:Collecting data...%></td></tr>
<tr><td width="100%" colspan="4">
<p align="center">
<b> 内核路径:/etc/openclash/core/clash_game </b>
<b><%:Core path:%>/etc/openclash/core/clash_game </b>
</p>
</td></tr>
<tr><td width="25%"> 当前【游戏模式】内核版本 </td><td width="25%" align="left" id="CORE_GAME_CV"><%:Collecting data...%></td><td width="25%"> 最新【游戏模式】内核版本 </td><td width="25%" align="left" id="CORE_GAME_LV"><%:Collecting data...%></td></tr>
<tr><td width="25%"> 更新内核</td><td width="25%" align="left" id="core_game_up"><%:Collecting data...%></td><td width="25%"> 下载最新版本内核</td><td width="25%" align="left" id="ma_core_game_up"><%:Collecting data...%></td></tr>
<tr><td width="25%">[Game] <%:Current Core%> </td><td width="25%" align="left" id="CORE_GAME_CV"><%:Collecting data...%></td><td width="25%">[Game] <%:Latest Core%></td><td width="25%" align="left" id="CORE_GAME_LV"><%:Collecting data...%></td></tr>
<tr><td width="25%"><%:Update Core%></td><td width="25%" align="left" id="core_game_up"><%:Collecting data...%></td><td width="25%"><%:Download Latest Core%></td><td width="25%" align="left" id="ma_core_game_up"><%:Collecting data...%></td></tr>
</table>
</fieldset>
<fieldset class="cbi-section">
<table>
<tr><td width="100%" colspan="4">
<p align="center">
<b> 客户端版本更新 </b>
<b><%:Client Update%></b>
</p>
</td></tr>
<tr><td width="25%"> 当前客户端版本 </td><td width="25%" align="left" id="OP_CV"><%:Collecting data...%></td><td width="25%"> 最新客户端版本 </td><td width="25%" align="left" id="OP_LV"><%:Collecting data...%></td></tr>
<tr><td width="25%"> 更新客户端 </td><td width="25%" align="left" id="op_up"><%:Collecting data...%></td><td width="25%"> 下载最新版本客户端 </td><td width="25%" align="left" id="ma_op_up"><%:Collecting data...%></td></tr>
<tr><td width="25%"><%:Current Client%></td><td width="25%" align="left" id="OP_CV"><%:Collecting data...%></td><td width="25%"><%:Latest Client%></td><td width="25%" align="left" id="OP_LV"><%:Collecting data...%></td></tr>
<tr><td width="25%"><%:Update Client%></td><td width="25%" align="left" id="op_up"><%:Collecting data...%></td><td width="25%"><%:Download Latest Client%></td><td width="25%" align="left" id="ma_op_up"><%:Collecting data...%></td></tr>
</table>
</fieldset>
<fieldset class="cbi-section">
@ -94,13 +94,13 @@
core_version.innerHTML = "<b><font color=green>"+status.corever+"</font></b>";
}
else {
core_version.innerHTML = "<b><font color=red><%:未选择编译版本,请到常规设置标签中配置%></font></b>";
core_version.innerHTML = "<b><font color=red><%:No compiled version is selected. Please configure it in the General Settings tab!%></font></b>";
}
if ( status.upchecktime != "1" ) {
checktime.innerHTML = "<b><font color=green>"+status.upchecktime+"</font></b>";
}
else {
checktime.innerHTML = "<b><font color=red><%:查询更新失败%></font></b>";
checktime.innerHTML = "<b><font color=red><%:Check Failed%></font></b>";
}
if ( status.corecv == "0" ) {
core_cv.innerHTML = "<b><font color=red><%:File Not Exist%></font></b>";
@ -178,16 +178,16 @@
}
});
core_up.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:检查并更新%>" onclick="return core_update(this)"/>';
core_tun_up.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:检查并更新%>" onclick="return core_tun_update(this)"/>';
core_game_up.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:检查并更新%>" onclick="return core_game_update(this)"/>';
op_up.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:检查并更新%>" onclick="return op_update(this)"/>';
ma_core_up.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:下载到本地%>" onclick="return ma_core_update(this)"/>';
ma_core_tun_up.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:下载到本地%>" onclick="return ma_core_tun_update(this)"/>';
ma_core_game_up.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:下载到本地%>" onclick="return ma_core_game_update(this)"/>';
ma_op_up.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:下载到本地%>" onclick="return ma_op_update(this)"/>';
restore.innerHTML = '<input type="button" class="cbi-button cbi-button-reset" value="<%:还原默认配置%>" onclick="return restore_config(this)"/>';
one_key_update.innerHTML = '<input type="button" class="cbi-button cbi-button-reset" value="<%:一键检查更新%>" onclick="return all_one_key_update(this)"/>';
core_up.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:Check And Update%>" onclick="return core_update(this)"/>';
core_tun_up.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:Check And Update%>" onclick="return core_tun_update(this)"/>';
core_game_up.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:Check And Update%>" onclick="return core_game_update(this)"/>';
op_up.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:Check And Update%>" onclick="return op_update(this)"/>';
ma_core_up.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:Download%>" onclick="return ma_core_update(this)"/>';
ma_core_tun_up.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:Download%>" onclick="return ma_core_tun_update(this)"/>';
ma_core_game_up.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:Download%>" onclick="return ma_core_game_update(this)"/>';
ma_op_up.innerHTML = '<input type="button" class="cbi-button cbi-button-reload" value="<%:Download%>" onclick="return ma_op_update(this)"/>';
restore.innerHTML = '<input type="button" class="cbi-button cbi-button-reset" value="<%:Restore Default Configuration%>" onclick="return restore_config(this)"/>';
one_key_update.innerHTML = '<input type="button" class="cbi-button cbi-button-reset" value="<%:One Click Check Update%>" onclick="return all_one_key_update(this)"/>';
function winOpen(url)
{
@ -200,7 +200,7 @@
function core_update(btn)
{
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "coreupdate")%>', null, function(x, status) {
btn.value = '<%:检查并更新%>';
btn.value = '<%:Check And Update%>';
btn.disabled = false;
return false;
});
@ -209,7 +209,7 @@
function core_tun_update(btn)
{
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "coretunupdate")%>', null, function(x, status) {
btn.value = '<%:检查并更新%>';
btn.value = '<%:Check And Update%>';
btn.disabled = false;
return false;
});
@ -218,7 +218,7 @@
function core_game_update(btn)
{
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "coregameupdate")%>', null, function(x, status) {
btn.value = '<%:检查并更新%>';
btn.value = '<%:Check And Update%>';
btn.disabled = false;
return false;
});
@ -228,7 +228,7 @@
{
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "opupdate")%>', null, function(x, status) {
btn.value = '<%:检查并更新%>';
btn.value = '<%:Check And Update%>';
btn.disabled = false;
return false;
});
@ -236,7 +236,7 @@
function ma_core_update(btn)
{
btn.value = '<%:下载到本地%>';
btn.value = '<%:Download%>';
btn.disabled = false;
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_ma")%>', status.corever, function(x, status) {
if ( x && x.status == 200 ) {
@ -245,7 +245,7 @@
winOpen(url1);
}
else {
alert('未选择编译版本,请到常规设置标签中配置!')
alert('<%:No compiled version is selected. Please configure it in the General Settings tab!%>')
}
}
});
@ -254,7 +254,7 @@
function ma_core_tun_update(btn)
{
btn.value = '<%:下载到本地%>';
btn.value = '<%:Download%>';
btn.disabled = false;
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_ma")%>', null, function(x, status) {
if ( x && x.status == 200 ) {
@ -266,10 +266,10 @@
winOpen(url3);
}
else if ( status.corever == "0\n" ) {
alert('未选择编译版本,请到常规设置标签中配置!')
alert('<%:No compiled version is selected. Please configure it in the General Settings tab!%>')
}
else if ( coretunlvis == "\n" || coretunlvis == "" ) {
alert('最新版本获取失败,请稍后再试!')
alert('<%:Failed to get the latest version. Please try again later!%>')
}
}
});
@ -278,7 +278,7 @@
function ma_core_game_update(btn)
{
btn.value = '<%:下载到本地%>';
btn.value = '<%:Download%>';
btn.disabled = false;
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_ma")%>', status.corever, function(x, status) {
if ( x && x.status == 200 ) {
@ -287,7 +287,7 @@
winOpen(url4);
}
else {
alert('未选择编译版本,请到常规设置标签中配置!')
alert('<%:No compiled version is selected. Please configure it in the General Settings tab!%>')
}
}
});
@ -296,7 +296,7 @@
function ma_op_update(btn)
{
btn.value = '<%:下载到本地%>';
btn.value = '<%:Download%>';
btn.disabled = false;
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_ma")%>', status.oplv, function(x, status) {
if ( x && x.status == 200 ) {
@ -307,7 +307,7 @@
winOpen(url2);
}
else {
alert('最新版本获取失败,请稍后再试!')
alert('<%:Failed to get the latest version. Please try again later!%>')
}
}
});
@ -316,17 +316,17 @@
function restore_config(btn)
{
btn.value = '<%:还原默认配置%>';
btn.value = '<%:Restore Default Configuration%>';
btn.disabled = true;
var r = confirm("确定要还原默认配置吗?")
var r = confirm("<%:Are you sure want to restore the default configuration?%>")
if (r == true) {
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "restore")%>', null, function(x, status) {
if ( x && x.status == 200 ) {
alert('还原默认配置成功!')
alert('<%:Restore succeeded!%>')
window.location.href='<%="settings"%>';
}
else {
alert('还原默认配置失败!')
alert('<%:Restore failed!%>')
window.location.href='<%="settings"%>';
}
});
@ -338,28 +338,25 @@
function all_one_key_update(btn)
{
btn.value = '<%:一键检查更新%>';
btn.value = '<%:One Click Check Update%>';
btn.disabled = true;
var r = confirm("确定要一键检查并更新所有内核及插件吗?")
var r = confirm("<%:Check and update all Cores and plug-ins?%>")
if (r == true) {
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "one_key_update_check")%>', null, function(x, status) {
if ( x && x.status == 200 ) {
if ( status.corever != "0\n" ) {
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "one_key_update")%>', null, function(x, status) {
if ( x && x.status == 200 ) {
alert('一键检查更新正在进行...')
}
else {
alert('一键检查更新失败,请稍后再试!')
if ( x && x.status != 200 ) {
alert('<%:Check failed, Please try again later!%>')
}
});
}
else {
alert('未选择编译版本,请到常规设置标签中配置!')
alert('<%:No compiled version is selected. Please configure it in the General Settings tab!%>')
}
}
else {
alert('一键检查更新失败,请稍后再试!')
alert('<%:Check failed, Please try again later!%>')
}
});
}
@ -375,11 +372,11 @@
var rdmdl=Math.floor(Math.random()*2)+1;
if(rdmdl==1)
{
update_tip.innerHTML = '<b><font><%: 注意:如更新失败可手动下载并上传 %></font></b>';
update_tip.innerHTML = '<b><font><%:Note: if the update fails, you can manually download and upload%></font></b>';
}
if(rdmdl==2)
{
update_tip.innerHTML = '<b><font><%: 注意客户端只支持通过IPK安装的版本进行更新因为随系统编译的版本更新后不会释放旧版本的闪存空间 %></font></b>';
update_tip.innerHTML = '<b><font><%:Note: the client may not support update, because the firmware with squashfs format will not release flash space after updating%></font></b>';
}
}
}

View File

@ -59,10 +59,10 @@ msgstr "启用"
msgid "Disable"
msgstr "停用"
msgid "RUNNING"
msgid "Running"
msgstr "运行中"
msgid "NOT RUNNING"
msgid "Not Running"
msgstr "未运行"
msgid "(Enable or Disable)"
@ -71,6 +71,9 @@ msgstr "(仅添加选中的设置)"
msgid "Config Normal"
msgstr "检查通过"
msgid "Config Abnormal"
msgstr "检查失败"
msgid "File Not Exist"
msgstr "文件不存在"
@ -355,6 +358,9 @@ msgstr "SOCKS5 代理端口"
msgid "HTTP(S) Port"
msgstr "HTTP(S) 代理端口"
msgid "Mixed Port"
msgstr "HTTP(S)&SOCKS5 混合代理端口"
msgid "Set Authentication of SOCKS5/HTTP(S)"
msgstr "设置SOCKS5/HTTP(S)认证信息"
@ -373,9 +379,12 @@ msgstr "您可以在下方直接修改配置文件:"
msgid "Here, Except The Settings That Were Taken Over"
msgstr ",仅支持未被接管的设置"
msgid "Default Config File With Correct General-Settings"
msgid "Default Config File With Correct Template"
msgstr "参考配置文件,方便您查询各项参数注释和正确的设置、顺序"
msgid "Config File Edited By OpenClash For Running"
msgstr "OpenClash修改后用于启动的配置文件"
msgid "Dashboard Secret"
msgstr "管理页面登录密钥"
@ -553,6 +562,9 @@ msgstr "最新内核版本"
msgid "Unknown"
msgstr "查询失败"
msgid "Check Failed"
msgstr "查询更新失败"
msgid "<New>"
msgstr "<可更新>"
@ -762,6 +774,9 @@ msgstr "设置策略组挑选服务器节点的工作方式"
msgid "Group Name"
msgstr "别名(请勿重名)"
msgid "Disable UDP"
msgstr "禁用UDP连接"
msgid "Test URL"
msgstr "检测地址URL"
@ -807,8 +822,11 @@ msgstr "注意:使用一键生成配置文件功能时无需设置此项,修
msgid "Clean Log"
msgstr "清理日志"
msgid "Refresh Log"
msgstr "刷新日志"
msgid "Stop Refresh Log"
msgstr "停止刷新"
msgid "Start Refresh Log"
msgstr "开始刷新"
msgid "Config File"
msgstr "配置文件"
@ -822,6 +840,9 @@ msgstr "更新时间"
msgid "File Name"
msgstr "文件名"
msgid "Grammar Check"
msgstr "语法检查"
msgid "Switch Config"
msgstr "切换"
@ -1045,4 +1066,322 @@ msgid "Small Flash Memory"
msgstr "小闪存模式"
msgid "Move Core And GEOIP Data File To /tmp/etc/openclash For Small Flash Memory Device"
msgstr "针对闪存空间不够的设备移动内核和GEOIP数据库文件到 /tmp/etc/openclash 文件夹"
msgstr "针对闪存空间不够的设备移动内核和GEOIP数据库文件到 /tmp/etc/openclash 文件夹"
msgid "Round-robin"
msgstr "轮询(轮流使用全部代理)"
msgid "Consistent-hashing"
msgstr "哈希匹配(访问相同网站时使用同一个代理)"
msgid "Strategy Type"
msgstr "策略类型"
msgid "Choose The Load-Balance's Strategy Type"
msgstr "选择负载均衡的策略类型"
msgid "Main Program"
msgstr "OpenClash 主程序"
msgid "Core Daemons"
msgstr "OpenClash 守护程序"
msgid "Core Running Mode"
msgstr "OpenClash 运行模式"
msgid "Yacd Control Panel"
msgstr "Yacd 控制面板"
msgid "Dashboard Control Panel"
msgstr "Dashboard 控制面板"
msgid "Control Panel Login IP"
msgstr "控制面板登录IP"
msgid "Control Panel Login Port"
msgstr "控制面板登录端口"
msgid "Control Panel Login Secret"
msgstr "控制面板登录密钥"
msgid "Dashboard Control Panel"
msgstr "Dashboard 控制面板"
msgid "Quick Operation"
msgstr "常用操作快捷按钮"
msgid "Please ensure that all items are displayed normally before running. If you need to update, please go to the global settings page"
msgstr "组件的状态显示,运行前请确保各项目显示正常,需要更新请到全局设置页面操作"
msgid "Node Select Backup"
msgstr "策略组节点选择 备份日期"
msgid "ConnersHua Rule Update"
msgstr "ConnersHua 规则更新日期"
msgid "Mainland IP Update"
msgstr "大陆IP白名单 更新日期"
msgid "lhie1 Rule Update"
msgstr "lhie1 规则更新日期"
msgid "ConnersHua Return Rule Update"
msgstr "ConnersHua 回国规则更新日期"
msgid "GEOIPBy MaxMindData Update"
msgstr "GEOIPBy MaxMind数据库日期"
msgid "No Backup"
msgstr "暂未备份"
msgid "<Limited State>"
msgstr "<功能受限状态>"
msgid "Fake-IP (Enhance)"
msgstr "Fake-IP增强模式"
msgid "Redir-Host (Compatible)"
msgstr "Redir-Host兼容模式"
msgid "Redir-Host (TUN)"
msgstr "Redir-HostTUN模式"
msgid "Fake-IP (TUN)"
msgstr "Fake-IPTUN模式"
msgid "Redir-Host (Game)"
msgstr "Redir-Host游戏模式"
msgid "Fake-IP (Game)"
msgstr "Fake-IP游戏模式"
msgid "Fake-IP (TUN-Mix)"
msgstr "Fake-IPTUN-混合)模式"
msgid "Redir-Host (TUN-Mix)"
msgstr "Redir-HostTUN-混合)模式"
msgid "Open Panel"
msgstr "打开控制面板"
msgid "Close All Connections"
msgstr "重置所有链接"
msgid "Restore Nodes Selection"
msgstr "还原策略组节点选择"
msgid "Save Nodes Selection"
msgstr "保存策略组节点选择"
msgid "Reload Firewall Rules"
msgstr "重置防火墙规则"
msgid "Check All Components Update"
msgstr "插件和内核检查更新"
msgid "Check Config Update"
msgstr "配置文件检查更新"
msgid "Check Third Party Rules Update"
msgstr "第三方规则检查更新"
msgid "Check GEOIP Data Update"
msgstr "GEOIP数据库检查更新"
msgid "Check and update all Cores and plug-ins?"
msgstr "确定要一键检查并更新所有内核及插件吗?"
msgid "Check failed, Please try again later!"
msgstr "一键检查更新失败,请稍后再试!"
msgid "No compiled version is selected. Please configure it in the General Settings tab!"
msgstr "未选择编译版本,请到常规设置标签中配置!"
msgid "Checking..."
msgstr "正在检查更新..."
msgid "Reloading..."
msgstr "正在重置..."
msgid "Restoring..."
msgstr "正在还原..."
msgid "Saving..."
msgstr "正在保存..."
msgid "Firewall Rules Reset Failed"
msgstr "防火墙规则重置失败"
msgid "Close All Connections Railed"
msgstr "重置所有链接失败"
msgid "Restore Nodes Selection Railed"
msgstr "还原失败"
msgid "Save Nodes Selection Failed"
msgstr "备份失败"
msgid "Tip: after started, please wait patiently until the connection is normal"
msgstr "Tip: OpenClash 成功启动后请耐心等待下方网站访问检查连接正常后再使用"
msgid "Tip: You can modify the profile on the profile page (for content that is not taken over)"
msgstr "Tip: 您可以在配置文件页面直接修改配置文件(适用于没被接管的内容)"
msgid "Tip: click the version icon above to jump to the client publishing page"
msgstr "Tip: 点击上方版本图标可跳转到客户端发布页面"
msgid "Tip: do not write configuration files? Try to create one click on the server page"
msgstr "Tip: 不会编写配置文件?试试在【服务器与策略组管理】页面一键创建"
msgid "Tip: some website are abnormal? Try switching modes or using third-party rules"
msgstr "Tip: 某些网站链接出现异常? 试试切换模式或者使用第三方规则"
msgid "Tip: using the fake IP mode can get a faster access experience"
msgstr "Tip: 使用 Fake-IP 模式可以获得更加快速的访问体验"
msgid "Tip: query DNS by TLS & TCP & HTTPS can get better anti pollution effect"
msgstr "Tip: 使用 TLS & TCP & HTTPS 方式查询DNS可以获得更好的抗污染效果"
msgid "Tip: openlash will check the configuration file parameters to ensure that it works properly"
msgstr "Tip: OpenClash 启动时会检查配置文件参数【服务器策略组、规则、DNS设置】以确保能够正常工作"
msgid "Tip: the nameserver group must have at least one server set when using custom DNS"
msgstr "Tip: 使用自定义DNS上游服务器时NameServer组必须设置至少一个服务器"
msgid "Tip: the website access check shows the connection of the device currently logged in to the Luci page"
msgstr "Tip: 网站访问检查展示的是当前登录LUCI页面设备的连接情况"
msgid "Tip: if you don not use IPv6, please turn off the DHCP service of IPv6, otherwise the connection will be abnormal"
msgstr "Tip: 如果不使用IPV6请关闭IPV6的DHCP服务否则会造成连接异常"
msgid "Tip: you can update the version in the global settings page"
msgstr "Tip: 您可以在全局设置页面进行版本更新操作"
msgid "Note: if the update fails, you can manually download and upload"
msgstr "注意:如更新失败可手动下载并上传"
msgid "Note: the client may not support update, because the firmware with squashfs format will not release flash space after updating"
msgstr "注意客户端可能无法更新因为squashfs格式的固件更新后不会释放闪存空间"
msgid "Compiled Version Selected"
msgstr "已选择编译版本"
msgid "CPU Architecture (OS)"
msgstr "处理器架构OS"
msgid "Last Check Update"
msgstr "上次检查更新时间"
msgid "CPU Architecture (OPKG)"
msgstr "处理器架构OPKG"
msgid "Current Core"
msgstr "当前内核版本"
msgid "Latest Core"
msgstr "最新内核版本"
msgid "Core path:"
msgstr "内核路径:"
msgid "Update Core"
msgstr "更新内核"
msgid "Download Latest Core"
msgstr "下载最新版本内核"
msgid "Client Update"
msgstr "客户端版本更新"
msgid "Current Client"
msgstr "当前客户端版本"
msgid "Update Client"
msgstr "更新客户端"
msgid "Latest Client"
msgstr "最新客户端版本"
msgid "Download Latest Client"
msgstr "下载最新版本客户端"
msgid "Download"
msgstr "下载到本地"
msgid "Restore Default Configuration"
msgstr "还原默认配置"
msgid "One Click Check Update"
msgstr "一键检查更新"
msgid "Failed to get the latest version. Please try again later!"
msgstr "最新版本获取失败,请稍后再试!"
msgid "Are you sure want to restore the default configuration?"
msgstr "确定要还原默认配置吗?"
msgid "Restore succeeded!"
msgstr "还原默认配置成功!"
msgid "Restore failed!"
msgstr "还原默认配置失败!"
msgid "Support syntax check, press"
msgstr "支持语法检查,按下"
msgid "to enter full screen editing mode"
msgstr "进入全屏编辑模式"
msgid "Switch page to Fake-IP mode"
msgstr "切换页面到 Fake-IP 模式"
msgid "Switch page to Redir-Host mode"
msgstr "切换页面到 Redir-Host 模式"
msgid "Page has been switched to Fake-IP mode!"
msgstr "页面已切换为Fake-IP模式"
msgid "Page has been switched to Redir-Host mode!"
msgstr "页面已切换为Redir-Host模式"
msgid "IP Address"
msgstr "IP 地址"
msgid "Mainland"
msgstr "国内"
msgid "Abroad"
msgstr "国外"
msgid "Website Access Check"
msgstr "网站访问检查"
msgid "Baidu Search"
msgstr "百度搜索"
msgid "NetEase Music"
msgstr "网易云音乐"
msgid "Querying..."
msgstr "查询中..."
msgid "Testing..."
msgstr "检测中..."
msgid "Access Timed Out"
msgstr "连接超时"
msgid "Access Normal"
msgstr "连接正常"
msgid "Access Denied"
msgstr "无法访问"
msgid "Bind Network Interface"
msgstr "绑定网络接口"
msgid "Default Interface Name:"
msgstr "当前系统默认接口:"
msgid ",Try Enable If Network Loopback"
msgstr ", 如发生回环死机请尝试启用"

View File

@ -1,6 +1,9 @@
config openclash 'config'
option proxy_port '7892'
option mixed_port '7893'
option socks_port '7891'
option http_port '7890'
option enable '0'
option update '0'
option en_mode '0'
@ -29,6 +32,7 @@ config openclash 'config'
option enable_rule_proxy '0'
option redirect_dns '0'
option small_flash_memory '0'
option interface_name '0'
config dns_servers
option group 'nameserver'

File diff suppressed because it is too large Load Diff

View File

@ -45,6 +45,8 @@ if [ -f "/tmp/openclash.bak" ]; then
mv "/tmp/openclash_custom_fake_filter.list.bak" "/etc/openclash/custom/openclash_custom_fake_filter.list" >/dev/null 2>&1
mv "/tmp/openclash_custom_domain_dns.list.bak" "/etc/openclash/custom/openclash_custom_domain_dns.list" >/dev/null 2>&1
rm -rf "/etc/openclash/openclash" >/dev/null 2>&1
rm -rf "/etc/openclash/fake_filter.list" >/dev/null 2>&1
rm -rf "/etc/openclash/openclash_servers_fake_filter.conf" >/dev/null 2>&1
rm -rf /tmp/openclash* >/dev/null 2>&1
fi

View File

@ -11,7 +11,8 @@ LAST_OPVER="/tmp/clash_last_version"
if [ "$CKTIME" != "$(grep "CheckTime" $LAST_OPVER 2>/dev/null |awk -F ':' '{print $2}')" ]; then
if pidof clash >/dev/null; then
curl -sL --connect-timeout 10 --retry 2 https://raw.githubusercontent.com/vernesong/OpenClash/master/core_version -o $LAST_OPVER >/dev/null 2>&1
else
fi
if [ "$?" -ne "0" ] || ! pidof clash >/dev/null; then
curl -sL --connect-timeout 10 --retry 2 https://cdn.jsdelivr.net/gh/vernesong/OpenClash@master/core_version -o $LAST_OPVER >/dev/null 2>&1
fi
if [ "$?" -eq "0" ] && [ -s "$LAST_OPVER" ]; then

View File

@ -1,19 +1,17 @@
{
"files": {
"main.css": "./static/css/main.83e4b341.chunk.css",
"main.js": "./static/js/main.3ba71f82.chunk.js",
"runtime-main.js": "./static/js/runtime-main.fefd5bb9.js",
"static/js/2.6366a4a0.chunk.js": "./static/js/2.6366a4a0.chunk.js",
"main.css": "./static/css/main.e4724b81.chunk.css",
"main.js": "./static/js/main.b9320252.chunk.js",
"runtime-main.js": "./static/js/runtime-main.b905e4f3.js",
"static/js/2.d14c2fca.chunk.js": "./static/js/2.d14c2fca.chunk.js",
"index.html": "./index.html",
"service-worker.js": "./service-worker.js",
"static/js/2.6366a4a0.chunk.js.LICENSE.txt": "./static/js/2.6366a4a0.chunk.js.LICENSE.txt",
"static/media/logo.45983944.png": "./static/media/logo.45983944.png",
"workbox-8a532145.js": "./workbox-8a532145.js"
"static/js/2.d14c2fca.chunk.js.LICENSE.txt": "./static/js/2.d14c2fca.chunk.js.LICENSE.txt",
"static/media/logo.45983944.png": "./static/media/logo.45983944.png"
},
"entrypoints": [
"static/js/runtime-main.fefd5bb9.js",
"static/js/2.6366a4a0.chunk.js",
"static/css/main.83e4b341.chunk.css",
"static/js/main.3ba71f82.chunk.js"
"static/js/runtime-main.b905e4f3.js",
"static/js/2.d14c2fca.chunk.js",
"static/css/main.e4724b81.chunk.css",
"static/js/main.b9320252.chunk.js"
]
}

View File

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" type="image/x-icon" href="https://cdn.jsdelivr.net/gh/Dreamacro/clash/docs/logo.png"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"/><meta name="description" content="Clash web port"/><title>Clash</title><link href="./static/css/main.83e4b341.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,a,l=r[0],f=r[1],i=r[2],p=0,s=[];p<l.length;p++)a=l[p],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&s.push(o[a][0]),o[a]=0;for(n in f)Object.prototype.hasOwnProperty.call(f,n)&&(e[n]=f[n]);for(c&&c(r);s.length;)s.shift()();return u.push.apply(u,i||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,l=1;l<t.length;l++){var f=t[l];0!==o[f]&&(n=!1)}n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={1:0},u=[];function a(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,function(r){return e[r]}.bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="./";var l=this["webpackJsonpclash-dashboard"]=this["webpackJsonpclash-dashboard"]||[],f=l.push.bind(l);l.push=r,l=l.slice();for(var i=0;i<l.length;i++)r(l[i]);var c=f;t()}([])</script><script src="./static/js/2.6366a4a0.chunk.js"></script><script src="./static/js/main.3ba71f82.chunk.js"></script></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" type="image/x-icon" href="https://cdn.jsdelivr.net/gh/Dreamacro/clash/docs/logo.png"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"/><meta name="description" content="Clash web port"/><title>Clash</title><link href="./static/css/main.e4724b81.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,a,l=r[0],f=r[1],i=r[2],p=0,s=[];p<l.length;p++)a=l[p],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&s.push(o[a][0]),o[a]=0;for(n in f)Object.prototype.hasOwnProperty.call(f,n)&&(e[n]=f[n]);for(c&&c(r);s.length;)s.shift()();return u.push.apply(u,i||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,l=1;l<t.length;l++){var f=t[l];0!==o[f]&&(n=!1)}n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={1:0},u=[];function a(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,function(r){return e[r]}.bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="./";var l=this["webpackJsonpclash-dashboard"]=this["webpackJsonpclash-dashboard"]||[],f=l.push.bind(l);l.push=r,l=l.slice();for(var i=0;i<l.length;i++)r(l[i]);var c=f;t()}([])</script><script src="./static/js/2.d14c2fca.chunk.js"></script><script src="./static/js/main.b9320252.chunk.js"></script></body></html>

View File

@ -1 +0,0 @@
if(!self.define){const e=e=>{"require"!==e&&(e+=".js");let s=Promise.resolve();return r[e]||(s=new Promise(async s=>{if("document"in self){const r=document.createElement("script");r.src=e,document.head.appendChild(r),r.onload=s}else importScripts(e),s()})),s.then(()=>{if(!r[e])throw new Error(`Module ${e} didnt register its module`);return r[e]})},s=(s,r)=>{Promise.all(s.map(e)).then(e=>r(1===e.length?e[0]:e))},r={require:Promise.resolve(s)};self.define=(s,i,t)=>{r[s]||(r[s]=Promise.resolve().then(()=>{let r={};const c={uri:location.origin+s.slice(1)};return Promise.all(i.map(s=>{switch(s){case"exports":return r;case"module":return c;default:return e(s)}})).then(e=>{const s=t(...e);return r.default||(r.default=s),r})}))}}define("./service-worker.js",["./workbox-8a532145"],(function(e){"use strict";self.addEventListener("message",e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()}),e.clientsClaim(),e.precacheAndRoute([{url:"./index.html",revision:"ff336a0edf18fc90c7f03fb0e43250a0"},{url:"./static/css/main.83e4b341.chunk.css",revision:"5a48466e5ff2a8ceec3348c3c498c260"},{url:"./static/js/2.6366a4a0.chunk.js",revision:"7a8970333d728cf369978e1fa658787e"},{url:"./static/js/2.6366a4a0.chunk.js.LICENSE.txt",revision:"6557abd439259b9580e2e2d5633cdacb"},{url:"./static/js/main.3ba71f82.chunk.js",revision:"2c4d6d7f7a1d7c843c445be62f92109f"},{url:"./static/js/runtime-main.fefd5bb9.js",revision:"98f4f314ef9abb714a6c74c41e1e5a04"},{url:"./static/media/logo.45983944.png",revision:"198a55c9efe85ab0145d4402c07cfe65"}],{}),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("./index.html"),{denylist:[/^\/_/,/\/[^/?]+\.[^/]+$/]}))}));

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -10,6 +10,15 @@ object-assign
http://jedwatson.github.io/classnames
*/
/**
* @license
* Lodash <https://lodash.com/>
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
* Released under MIT license <https://lodash.com/license>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/
/** @license React v0.20.1
* scheduler.production.min.js
*
@ -19,7 +28,7 @@ object-assign
* LICENSE file in the root directory of this source tree.
*/
/** @license React v16.13.0
/** @license React v16.13.1
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,7 @@
#!/bin/bash
. /lib/functions.sh
. /usr/share/openclash/openclash_ps.sh
. /usr/share/openclash/ruby.sh
status=$(unify_ps_status "openclash.sh")
[ "$status" -gt 3 ] && exit 0
@ -103,12 +104,6 @@ config_su_check()
{
echo "配置文件下载成功,检查是否有更新..." >$START_LOG
sed -i 's/!<str> //g' "$CFG_FILE" >/dev/null 2>&1
#关键字还原
if [ -z "$(grep "^Proxy:#d" "$CFG_FILE")" ]; then
sed -i "s/^Proxy:/proxies:/g" "$CFG_FILE" 2>/dev/null
else
sed -i "s/^Proxy:#d/proxies:/g" "$CFG_FILE" 2>/dev/null
fi
if [ -f "$CONFIG_FILE" ]; then
cmp -s "$BACKPACK_FILE" "$CFG_FILE"
if [ "$?" -ne 0 ]; then
@ -131,11 +126,6 @@ config_su_check()
fi
}
config_encode()
{
/usr/share/openclash/yml_field_name_ch.sh "$CFG_FILE"
}
config_error()
{
echo "配置文件【$name】下载失败,请检查网络或稍后再试!" >$START_LOG
@ -168,7 +158,7 @@ change_dns()
config_download_direct()
{
if pidof clash >/dev/null; then
echo "配置文件【$name下载失败,尝试不使用代理下载配置文件..." >$START_LOG
echo "配置文件【$name订阅失败,尝试不使用代理下载配置文件..." >$START_LOG
kill_watchdog
@ -301,21 +291,14 @@ sub_info_get()
config_download
if [ "$?" -eq 0 ] && [ -s "$CFG_FILE" ]; then
config_encode
if [ -n "$(grep "^ \{0,\}proxy-groups:" "$CFG_FILE")" ]; then
if [ -n "$(grep "^ \{0,\}Proxy:" "$CFG_FILE" 2>/dev/null)" ] || [ -n "$(grep "^ \{0,\}proxy-providers:" "$CFG_FILE" 2>/dev/null)" ]; then
if [ -n "$(grep "^ \{0,\}rules:" "$CFG_FILE" 2>/dev/null)" ] || [ -n "$(grep "^ \{0,\}script:" "$CFG_FILE" 2>/dev/null)" ]; then
config_su_check
else
config_download_direct
fi
else
config_download_direct
fi
else
if [ -n "$(ruby_read "$CFG_FILE" "['proxy-groups']")" ]; then
config_su_check
else
echo "${LOGTIME} Config 【$name】 Grammar Check Faild" >>$LOG_FILE
config_download_direct
fi
fi
else
echo "${LOGTIME} Config 【$name】 Download Faild" >>$LOG_FILE
config_download_direct
fi
}
@ -327,7 +310,7 @@ uci delete openclash.config.config_update_path >/dev/null 2>&1
uci commit openclash
if [ "$if_restart" -eq 1 ]; then
/etc/init.d/openclash restart >/dev/null 2>&1
/etc/init.d/openclash restart >/dev/null 2>&1 &
else
sed -i '/openclash.sh/d' $CRON_FILE 2>/dev/null
[ "$(uci get openclash.config.auto_update 2>/dev/null)" -eq 1 ] && [ "$(uci get openclash.config.config_auto_update_mode 2>/dev/null)" -ne 1 ] && echo "0 $(uci get openclash.config.auto_update_time 2>/dev/null) * * $(uci get openclash.config.config_update_week_time 2>/dev/null) /usr/share/openclash/openclash.sh" >> $CRON_FILE

View File

@ -12,7 +12,8 @@
echo "开始下载大陆IP白名单..." >$START_LOG
if pidof clash >/dev/null; then
curl -sL --connect-timeout 10 --retry 2 https://raw.githubusercontent.com/DivineEngine/Profiles/master/Clash/RuleSet/Extra/ChinaIP.yaml -o /tmp/ChinaIP.yaml >/dev/null 2>&1
else
fi
if [ "$?" -ne "0" ] || ! pidof clash >/dev/null; then
curl -sL --connect-timeout 10 --retry 2 https://cdn.jsdelivr.net/gh/DivineEngine/Profiles@master/Clash/RuleSet/Extra/ChinaIP.yaml -o /tmp/ChinaIP.yaml >/dev/null 2>&1
fi
if [ "$?" -eq "0" ] && [ -s "/tmp/ChinaIP.yaml" ]; then
@ -24,22 +25,20 @@
echo "删除下载缓存..." >$START_LOG
rm -rf /tmp/ChinaIP.yaml >/dev/null 2>&1
rm -rf /usr/share/openclash/res/china_ip_route.ipset >/dev/null 2>&1
[ "$china_ip_route" -eq 1 ] && [ "$(unify_ps_prevent)" -eq 0 ] && /etc/init.d/openclash restart
[ "$china_ip_route" -eq 1 ] && [ "$(unify_ps_prevent)" -eq 0 ] && /etc/init.d/openclash restart >/dev/null 2>&1 &
echo "大陆IP白名单更新成功" >$START_LOG
echo "${LOGTIME} Chnroute Lists Update Successful" >>$LOG_FILE
sleep 10
echo "" >$START_LOG
sleep 5
else
echo "大陆IP白名单没有更新停止继续操作..." >$START_LOG
echo "${LOGTIME} Updated Chnroute Lists No Change, Do Nothing" >>$LOG_FILE
rm -rf /tmp/ChinaIP.yaml >/dev/null 2>&1
sleep 5
echo "" >$START_LOG
fi
else
echo "大陆IP白名单下载失败请检查网络或稍后再试" >$START_LOG
rm -rf /tmp/ChinaIP.yaml >/dev/null 2>&1
echo "${LOGTIME} Chnroute Lists Update Error" >>$LOG_FILE
sleep 10
echo "" >$START_LOG
fi
fi
echo "" >$START_LOG

View File

@ -62,29 +62,30 @@ if [ "$CORE_CV" != "$CORE_LV" ] || [ -z "$CORE_CV" ]; then
case $CORE_TYPE in
"Tun")
echo "正在下载【Tun】版本内核如下载失败请尝试手动下载并上传..." >$START_LOG
curl -sL -m 30 --retry 2 https://github.com/vernesong/OpenClash/releases/download/TUN-Premium/clash-"$CPU_MODEL"-"$CORE_LV".gz -o /tmp/clash_tun.gz >/dev/null 2>&1
curl -sL -m 10 --retry 2 https://github.com/vernesong/OpenClash/releases/download/TUN-Premium/clash-"$CPU_MODEL"-"$CORE_LV".gz -o /tmp/clash_tun.gz >/dev/null 2>&1
;;
"Game")
echo "正在下载【Game】版本内核如下载失败请尝试手动下载并上传..." >$START_LOG
curl -sL -m 30 --retry 2 https://github.com/vernesong/OpenClash/releases/download/TUN/clash-"$CPU_MODEL".tar.gz -o /tmp/clash_game.tar.gz >/dev/null 2>&1
curl -sL -m 10 --retry 2 https://github.com/vernesong/OpenClash/releases/download/TUN/clash-"$CPU_MODEL".tar.gz -o /tmp/clash_game.tar.gz >/dev/null 2>&1
;;
*)
echo "正在下载【Dev】版本内核如下载失败请尝试手动下载并上传..." >$START_LOG
curl -sL -m 30 --retry 2 https://github.com/vernesong/OpenClash/releases/download/Clash/clash-"$CPU_MODEL".tar.gz -o /tmp/clash.tar.gz >/dev/null 2>&1
curl -sL -m 10 --retry 2 https://github.com/vernesong/OpenClash/releases/download/Clash/clash-"$CPU_MODEL".tar.gz -o /tmp/clash.tar.gz >/dev/null 2>&1
esac
else
fi
if [ "$?" -ne "0" ] || ! pidof clash >/dev/null; then
case $CORE_TYPE in
"Tun")
echo "正在下载【Tun】版本内核如下载失败请尝试手动下载并上传..." >$START_LOG
curl -sL -m 30 --retry 2 https://cdn.jsdelivr.net/gh/vernesong/OpenClash@master/core-lateset/premium/clash-"$CPU_MODEL"-"$CORE_LV".gz -o /tmp/clash_tun.gz >/dev/null 2>&1
curl -sL -m 10 --retry 2 https://cdn.jsdelivr.net/gh/vernesong/OpenClash@master/core-lateset/premium/clash-"$CPU_MODEL"-"$CORE_LV".gz -o /tmp/clash_tun.gz >/dev/null 2>&1
;;
"Game")
echo "正在下载【Game】版本内核如下载失败请尝试手动下载并上传..." >$START_LOG
curl -sL -m 30 --retry 2 https://cdn.jsdelivr.net/gh/vernesong/OpenClash@master/core-lateset/game/clash-"$CPU_MODEL".tar.gz -o /tmp/clash_game.tar.gz >/dev/null 2>&1
curl -sL -m 10 --retry 2 https://cdn.jsdelivr.net/gh/vernesong/OpenClash@master/core-lateset/game/clash-"$CPU_MODEL".tar.gz -o /tmp/clash_game.tar.gz >/dev/null 2>&1
;;
*)
echo "正在下载【Dev】版本内核如下载失败请尝试手动下载并上传..." >$START_LOG
curl -sL -m 30 --retry 2 https://cdn.jsdelivr.net/gh/vernesong/OpenClash@master/core-lateset/dev/clash-"$CPU_MODEL".tar.gz -o /tmp/clash.tar.gz >/dev/null 2>&1
curl -sL -m 10 --retry 2 https://cdn.jsdelivr.net/gh/vernesong/OpenClash@master/core-lateset/dev/clash-"$CPU_MODEL".tar.gz -o /tmp/clash.tar.gz >/dev/null 2>&1
esac
fi
if [ "$?" -eq "0" ]; then

View File

@ -1,14 +1,13 @@
#!/bin/bash
. /lib/functions.sh
. /usr/share/openclash/openclash_ps.sh
. /usr/share/openclash/ruby.sh
status=$(unify_ps_status "openclash_debug.sh")
[ "$status" -gt "3" ] && exit 0
DEBUG_LOG="/tmp/openclash_debug.log"
LOGTIME=$(date "+%Y-%m-%d %H:%M:%S")
CHANGE_FILE="/tmp/yaml_change.yaml"
DNS_FILE="/tmp/yaml_dns.yaml"
uci commit openclash
enable_custom_dns=$(uci get openclash.config.enable_custom_dns 2>/dev/null)
@ -22,7 +21,8 @@ intranet_allowed=$(uci get openclash.config.intranet_allowed 2>/dev/null)
enable_udp_proxy=$(uci get openclash.config.enable_udp_proxy 2>/dev/null)
enable_rule_proxy=$(uci get openclash.config.enable_rule_proxy 2>/dev/null)
en_mode=$(uci get openclash.config.en_mode 2>/dev/null)
CONFIG_FILE=$(uci get openclash.config.config_path 2>/dev/null)
RAW_CONFIG_FILE=$(uci get openclash.config.config_path 2>/dev/null)
CONFIG_FILE="/etc/openclash/$(uci get openclash.config.config_path 2>/dev/null |awk -F '/' '{print $5}' 2>/dev/null)"
core_type=$(uci get openclash.config.core_version 2>/dev/null)
cpu_model=$(opkg status libc 2>/dev/null |grep 'Architecture' |awk -F ': ' '{print $2}' 2>/dev/null)
core_version=$(/etc/openclash/core/clash -v 2>/dev/null |awk -F ' ' '{print $2}' 2>/dev/null)
@ -32,10 +32,11 @@ servers_update=$(uci get openclash.config.servers_update 2>/dev/null)
op_version=$(sed -n 1p /usr/share/openclash/res/openclash_version 2>/dev/null)
china_ip_route=$(uci get openclash.config.china_ip_route 2>/dev/null)
if [ -z "$CONFIG_FILE" ] || [ ! -f "$CONFIG_FILE" ]; then
if [ -z "$RAW_CONFIG_FILE" ] || [ ! -f "$RAW_CONFIG_FILE" ]; then
CONFIG_NAME=$(ls -lt /etc/openclash/config/ | grep -E '.yaml|.yml' | head -n 1 |awk '{print $9}')
if [ ! -z "$CONFIG_NAME" ]; then
CONFIG_FILE="/etc/openclash/config/$CONFIG_NAME"
RAW_CONFIG_FILE="/etc/openclash/config/$CONFIG_NAME"
CONFIG_FILE="/etc/openclash/$CONFIG_NAME"
fi
fi
@ -62,6 +63,7 @@ cat >> "$DEBUG_LOG" <<-EOF
生成时间: $LOGTIME
插件版本: $op_version
隐私提示: 上传此日志前请注意检查、屏蔽公网IP、节点、密码等相关敏感信息
\`\`\`
EOF
@ -101,6 +103,8 @@ iptables-mod-tproxy: $(ts_re "$(opkg status iptables-mod-tproxy 2>/dev/null |gre
iptables-mod-extra: $(ts_re "$(opkg status iptables-mod-extra 2>/dev/null |grep 'Status' |awk -F ': ' '{print $2}' 2>/dev/null)")
libcap: $(ts_re "$(opkg status libcap 2>/dev/null |grep 'Status' |awk -F ': ' '{print $2}' 2>/dev/null)")
libcap-bin: $(ts_re "$(opkg status libcap-bin 2>/dev/null |grep 'Status' |awk -F ': ' '{print $2}' 2>/dev/null)")
ruby: $(ts_re "$(opkg status ruby 2>/dev/null |grep 'Status' |awk -F ': ' '{print $2}' 2>/dev/null)")
ruby-yaml: $(ts_re "$(opkg status ruby-yaml 2>/dev/null |grep 'Status' |awk -F ': ' '{print $2}' 2>/dev/null)")
kmod-tun(TUN模式): $(ts_re "$(opkg status kmod-tun 2>/dev/null |grep 'Status' |awk -F ': ' '{print $2}' 2>/dev/null)")
luci-compat(Luci-19.07): $(ts_re "$(opkg status luci-compat 2>/dev/null |grep 'Status' |awk -F ': ' '{print $2}' 2>/dev/null)")
EOF
@ -203,7 +207,8 @@ fi
cat >> "$DEBUG_LOG" <<-EOF
#===================== 插件设置 =====================#
当前配置文件: $CONFIG_FILE
当前配置文件: $RAW_CONFIG_FILE
启动配置文件: $CONFIG_FILE
运行模式: $en_mode
默认代理模式: $proxy_mode
UDP流量转发: $(ts_cf "$enable_udp_proxy")
@ -269,28 +274,14 @@ fi
cat >> "$DEBUG_LOG" <<-EOF
#===================== 配置文件 =====================#
EOF
if [ -n "$(grep OpenClash-General-Settings "$CONFIG_FILE")" ]; then
sed '/OpenClash-General-Settings/,$d' "$CONFIG_FILE" >> "$DEBUG_LOG" 2>/dev/null
if [ -f "$CONFIG_FILE" ]; then
ruby_read "$CONFIG_FILE" ".select {|x| 'proxies' != x and 'proxy-providers' != x }.to_yaml" 2>/dev/null >> "$DEBUG_LOG"
else
/usr/share/openclash/yml_field_name_ch.sh "$CONFIG_FILE" 2>/dev/null
#取出general部分
/usr/share/openclash/yml_field_cut.sh "general" "$CHANGE_FILE" "$CONFIG_FILE" 2>/dev/null
#取出dns部分
nameserver_len=$(sed -n '/^ \{0,\}nameserver:/=' "$CONFIG_FILE" 2>/dev/null)
if [ -n "$nameserver_len" ]; then
/usr/share/openclash/yml_field_cut.sh "$nameserver_len" "$DNS_FILE" "$CONFIG_FILE" 2>/dev/null
else
fallback_len=$(sed -n '/^ \{0,\}fallback:/=' "$CONFIG_FILE" 2>/dev/null)
if [ -n "$fallback_len" ]; then
/usr/share/openclash/yml_field_cut.sh "$fallback_len" "$DNS_FILE" "$CONFIG_FILE" 2>/dev/null
fi
fi 2>/dev/null
rm -rf /tmp/yaml_general 2>/dev/null
cat "$CHANGE_FILE" "$DNS_FILE" >> "$DEBUG_LOG" 2>/dev/null
ruby_read "$RAW_CONFIG_FILE" ".select {|x| 'proxies' != x and 'proxy-providers' != x }.to_yaml" 2>/dev/null >> "$DEBUG_LOG"
fi
sed -i '/^ \{0,\}secret:/d' "$DEBUG_LOG" 2>/dev/null
#firewall

View File

@ -23,13 +23,15 @@
if [ "$RULE_TYPE" = "game" ]; then
if pidof clash >/dev/null; then
curl -sL --connect-timeout 5 --retry 2 https://raw.githubusercontent.com/FQrabbit/SSTap-Rule/master/rules/"$DOWNLOAD_PATH" -o "$TMP_RULE_DIR" >/dev/null 2>&1
else
fi
if [ "$?" -ne "0" ] || ! pidof clash >/dev/null; then
curl -sL --connect-timeout 5 --retry 2 https://cdn.jsdelivr.net/gh/FQrabbit/SSTap-Rule@master/rules/"$DOWNLOAD_PATH" -o "$TMP_RULE_DIR" >/dev/null 2>&1
fi
elif [ "$RULE_TYPE" = "provider" ]; then
if pidof clash >/dev/null; then
curl -sL --connect-timeout 5 --retry 2 https://raw.githubusercontent.com/"$DOWNLOAD_PATH" -o "$TMP_RULE_DIR" >/dev/null 2>&1
else
fi
if [ "$?" -ne "0" ] || ! pidof clash >/dev/null; then
curl -sL --connect-timeout 5 --retry 2 https://cdn.jsdelivr.net/gh/"$(echo "$DOWNLOAD_PATH" |awk -F '/master' '{print $1}' 2>/dev/null)"@master"$(echo "$DOWNLOAD_PATH" |awk -F 'master' '{print $2}')" -o "$TMP_RULE_DIR" >/dev/null 2>&1
fi
fi

View File

@ -3,8 +3,8 @@
START_LOG="/tmp/openclash_start.log"
CUSTOM_FILE="/etc/openclash/custom/openclash_custom_fake_filter.list"
FAKE_FILTER_FILE="/etc/openclash/fake_filter.list"
SER_FAKE_FILTER_FILE="/etc/openclash/servers_fake_filter.conf"
FAKE_FILTER_FILE="/tmp/openclash_fake_filter.list"
SER_FAKE_FILTER_FILE="/tmp/openclash_servers_fake_filter.conf"
echo "正在设置Fake-IP黑名单..." >$START_LOG
@ -13,14 +13,13 @@ if [ -s "$CUSTOM_FILE" ]; then
cat "$CUSTOM_FILE" |while read -r line || [[ -n ${line} ]];
do
if [ -z "$(echo $line |grep '^ \{0,\}#' 2>/dev/null)" ]; then
echo " - '$line'" >> "$FAKE_FILTER_FILE"
echo " - '$line'" >> "$FAKE_FILTER_FILE"
else
continue
fi
done 2>/dev/null
if [ -s "$FAKE_FILTER_FILE" ]; then
sed -i '1i\##Custom fake-ip-filter##' "$FAKE_FILTER_FILE"
echo "##Custom fake-ip-filter END##" >> "$FAKE_FILTER_FILE"
sed -i '1i\fake-ip-filter:' "$FAKE_FILTER_FILE"
else
rm -rf "$FAKE_FILTER_FILE" 2>/dev/null
fi

View File

@ -5,11 +5,14 @@ CURL_GROUP_CACHE="/tmp/openclash_history_gorup.json"
CURL_NOW_CACHE="/tmp/openclash_history_now.json"
CURL_CACHE="/tmp/openclash_history_curl.json"
CONFIG_FILE=$(unify_ps_cfgname)
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $4}' 2>/dev/null)
HISTORY_PATH="/etc/openclash/history/$CONFIG_NAME"
HISTORY_TMP="/tmp/openclash_history_tmp.yaml"
SECRET=$(uci get openclash.config.dashboard_password 2>/dev/null)
LAN_IP=$(uci get network.lan.ipaddr 2>/dev/null |awk -F '/' '{print $1}' 2>/dev/null)
PORT=$(uci get openclash.config.cn_port 2>/dev/null)
LOG_FILE="/tmp/openclash.log"
LOGTIME=$(date "+%Y-%m-%d %H:%M:%S")
if [ -n "$(pidof clash)" ] && [ -f "$CONFIG_FILE" ]; then
curl -m 5 --retry 2 -w %{http_code}"\n" -H "Authorization: Bearer ${SECRET}" -H "Content-Type:application/json" -X GET http://"$LAN_IP":"$PORT"/proxies > "$CURL_CACHE" 2>/dev/null
@ -17,7 +20,14 @@ if [ -n "$(pidof clash)" ] && [ -f "$CONFIG_FILE" ]; then
mkdir -p /etc/openclash/history 2>/dev/null
cat "$CURL_CACHE" |jsonfilter -e '@["proxies"][@.type="Selector"]["name"]' > "$CURL_GROUP_CACHE" 2>/dev/null
cat "$CURL_CACHE" |jsonfilter -e '@["proxies"][@.type="Selector"]["now"]' > "$CURL_NOW_CACHE" 2>/dev/null
awk 'NR==FNR{a[i]=$0;i++}NR>FNR{print a[j]"#*#"$0;j++}' "$CURL_GROUP_CACHE" "$CURL_NOW_CACHE" > "$HISTORY_PATH" 2>/dev/null
awk 'NR==FNR{a[i]=$0;i++}NR>FNR{print a[j]"#*#"$0;j++}' "$CURL_GROUP_CACHE" "$CURL_NOW_CACHE" > "$HISTORY_TMP" 2>/dev/null
cmp -s "$HISTORY_TMP" "$HISTORY_PATH"
if [ "$?" -ne "0" ] && [ -s "$HISTORY_TMP" ]; then
mv "$HISTORY_TMP" "$HISTORY_PATH" 2>/dev/null
echo "${LOGTIME} History:【${CONFIG_NAME}】 Update Successful" >> $LOG_FILE
fi
else
echo "${LOGTIME} History:【${CONFIG_NAME}】 Update Faild" >> $LOG_FILE
fi
fi
rm -rf /tmp/openclash_history_* 2>/dev/null

View File

@ -1,12 +1,15 @@
#!/bin/sh
. /lib/functions.sh
. /usr/share/openclash/openclash_ps.sh
CONFIG_FILE=$(uci get openclash.config.config_path 2>/dev/null)
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
CONFIG_FILE=$(unify_ps_cfgname)
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $4}' 2>/dev/null)
HISTORY_PATH="/etc/openclash/history/$CONFIG_NAME"
SECRET=$(uci get openclash.config.dashboard_password 2>/dev/null)
LAN_IP=$(uci get network.lan.ipaddr 2>/dev/null |awk -F '/' '{print $1}' 2>/dev/null)
PORT=$(uci get openclash.config.cn_port 2>/dev/null)
LOG_FILE="/tmp/openclash.log"
LOGTIME=$(date "+%Y-%m-%d %H:%M:%S")
urlencode() {
local data
@ -27,9 +30,9 @@ restore_history() {
NOW_NAME=$(echo $line |awk -F '#*#' '{print $3}')
GROUP_STATE=$(GROUP_STATE "$GROUP_NAME")
GROUP_STATE_NUM=0
while ( [ ! -z "$(pidof clash)" ] && [ "$GROUP_STATE" != "200" ] && [ "$GROUP_STATE_NUM" -le 3 ] )
while ( [ "$GROUP_STATE" != "200" ] && [ "$GROUP_STATE_NUM" -le 3 ] )
do
sleep 3
sleep 1
GROUP_STATE_NUM=$(expr "$GROUP_STATE_NUM" + 1)
GROUP_STATE=$(GROUP_STATE "$GROUP_NAME")
done
@ -40,7 +43,7 @@ close_all_conection() {
curl -m 5 --retry 2 -H "Authorization: Bearer ${SECRET}" -H "Content-Type:application/json" -X DELETE http://"$LAN_IP":"$PORT"/connections >/dev/null 2>&1
}
if [ -s "$HISTORY_PATH" ]; then
if [ -s "$HISTORY_PATH" ] && [ ! -z "$(pidof clash)" ]; then
cat "$HISTORY_PATH" |while read -r line
do
GROUP_NAME=$(echo $line |awk -F '#*#' '{print $1}')
@ -55,4 +58,7 @@ if [ -s "$HISTORY_PATH" ]; then
fi
done >/dev/null 2>&1
close_all_conection
echo "${LOGTIME} History:【${CONFIG_NAME}】 Restore Successful" >> $LOG_FILE
else
echo "${LOGTIME} History:【${CONFIG_NAME}】 Restore Faild" >> $LOG_FILE
fi

View File

@ -19,7 +19,8 @@
echo "开始下载 GEOIP 数据库..." >$START_LOG
if pidof clash >/dev/null; then
curl -sL --connect-timeout 10 --retry 2 https://raw.githubusercontent.com/alecthw/mmdb_china_ip_list/release/Country.mmdb -o /tmp/Country.mmdb >/dev/null 2>&1
else
fi
if [ "$?" -ne "0" ] || ! pidof clash >/dev/null; then
curl -sL --connect-timeout 10 --retry 2 http://www.ideame.top/mmdb/Country.mmdb -o /tmp/Country.mmdb >/dev/null 2>&1
fi
if [ "$?" -eq "0" ] && [ -s "/tmp/Country.mmdb" ]; then
@ -33,19 +34,17 @@
echo "GEOIP 数据库更新成功!" >$START_LOG
echo "${LOGTIME} GEOIP Database Update Successful" >>$LOG_FILE
sleep 5
[ "$(unify_ps_prevent)" -eq 0 ] && /etc/init.d/openclash restart
echo "" >$START_LOG
[ "$(unify_ps_prevent)" -eq 0 ] && /etc/init.d/openclash restart >/dev/null 2>&1 &
else
echo "数据库版本没有更新,停止继续操作..." >$START_LOG
echo "${LOGTIME} Updated GEOIP Database No Change, Do Nothing" >>$LOG_FILE
rm -rf /tmp/Country.mmdb >/dev/null 2>&1
sleep 5
echo "" >$START_LOG
fi
else
echo "GEOIP 数据库下载失败,请检查网络或稍后再试!" >$START_LOG
rm -rf /tmp/Country.mmdb >/dev/null 2>&1
echo "${LOGTIME} GEOIP Database Update Error" >>$LOG_FILE
sleep 10
echo "" >$START_LOG
fi
fi
echo "" >$START_LOG

View File

@ -1,6 +1,7 @@
#!/bin/sh
. /usr/share/openclash/openclash_ps.sh
. /lib/functions.sh
. /usr/share/openclash/ruby.sh
status=$(unify_ps_status "openclash_rule.sh")
[ "$status" -gt 3 ] && exit 0
@ -10,85 +11,66 @@
LOG_FILE="/tmp/openclash.log"
echo "开始获取使用中的第三方规则名称..." >$START_LOG
RUlE_SOURCE=$(uci get openclash.config.rule_source 2>/dev/null)
OTHER_RULE_PROVIDER_FILE="/tmp/other_rule_provider.yaml"
OTHER_SCRIPT_FILE="/tmp/other_rule_script.yaml"
OTHER_RULE_FILE="/tmp/other_rule.yaml"
echo "开始下载使用中的第三方规则..." >$START_LOG
if [ "$RUlE_SOURCE" = "lhie1" ]; then
if pidof clash >/dev/null; then
curl -sL --connect-timeout 10 --retry 2 https://raw.githubusercontent.com/lhie1/Rules/master/Clash/Rule.yaml -o /tmp/rules.yaml >/dev/null 2>&1
else
fi
if [ "$?" -ne "0" ] || ! pidof clash >/dev/null; then
curl -sL --connect-timeout 10 --retry 2 https://cdn.jsdelivr.net/gh/lhie1/Rules@master/Clash/Rule.yaml -o /tmp/rules.yaml >/dev/null 2>&1
fi
sed -i '1i rules:' /tmp/rules.yaml
elif [ "$RUlE_SOURCE" = "ConnersHua" ]; then
if pidof clash >/dev/null; then
curl -sL --connect-timeout 10 --retry 2 https://raw.githubusercontent.com/DivineEngine/Profiles/master/Clash/Global.yaml -o /tmp/rules.yaml >/dev/null 2>&1
else
fi
if [ "$?" -ne "0" ] || ! pidof clash >/dev/null; then
curl -sL --connect-timeout 10 --retry 2 https://cdn.jsdelivr.net/gh/DivineEngine/Profiles@master/Clash/Global.yaml -o /tmp/rules.yaml >/dev/null 2>&1
fi
sed -i -n '/^rule-providers:/,$p' /tmp/rules.yaml 2>/dev/null
sed -i "s/# - RULE-SET,ChinaIP,DIRECT/- RULE-SET,ChinaIP,DIRECT/g" /tmp/rules.yaml 2>/dev/null
sed -i "s/- GEOIP,/#- GEOIP,/g" /tmp/rules.yaml 2>/dev/null
elif [ "$RUlE_SOURCE" = "ConnersHua_return" ]; then
if pidof clash >/dev/null; then
curl -sL --connect-timeout 10 --retry 2 https://raw.githubusercontent.com/ConnersHua/Profiles/master/Clash/China.yaml -o /tmp/rules.yaml >/dev/null 2>&1
else
fi
if [ "$?" -ne "0" ] || ! pidof clash >/dev/null; then
curl -sL --connect-timeout 10 --retry 2 https://cdn.jsdelivr.net/gh/DivineEngine/Profiles@master/Clash/China.yaml -o /tmp/rules.yaml >/dev/null 2>&1
fi
sed -i -n '/^rules:/,$p' /tmp/rules.yaml 2>/dev/null
fi
if [ "$?" -eq "0" ] && [ "$RUlE_SOURCE" != 0 ] && [ -s "/tmp/rules.yaml" ]; then
echo "下载成功,开始预处理规则文件..." >$START_LOG
sed -i "/^rules:/a\##source:${RUlE_SOURCE}" /tmp/rules.yaml >/dev/null 2>&1
#处理rule_provider位置
rule_provider_len=$(sed -n '/^ \{0,\}rule-providers:/=' "/tmp/rules.yaml" 2>/dev/null)
if [ -n "$rule_provider_len" ]; then
/usr/share/openclash/yml_field_cut.sh "$rule_provider_len" "$OTHER_RULE_PROVIDER_FILE" "/tmp/rules.yaml"
fi 2>/dev/null
#处理script位置
script_len=$(sed -n '/^ \{0,\}script:/=' "/tmp/rules.yaml" 2>/dev/null)
if [ -n "$script_len" ]; then
/usr/share/openclash/yml_field_cut.sh "$script_len" "$OTHER_SCRIPT_FILE" "/tmp/rules.yaml"
fi 2>/dev/null
#处理备份rule位置
rule_bak_len=$(sed -n '/^ \{0,\}rules:/=' "/tmp/rules.yaml" 2>/dev/null)
if [ -n "$rule_bak_len" ]; then
/usr/share/openclash/yml_field_cut.sh "$rule_bak_len" "$OTHER_RULE_FILE" "/tmp/rules.yaml"
fi 2>/dev/null
#取出规则部分
ruby_read "/tmp/rules.yaml" ".select {|x| 'rule-providers' == x or 'script' == x or 'rules' == x }.to_yaml" > "$OTHER_RULE_FILE"
#合并
cat "$OTHER_RULE_PROVIDER_FILE" "$OTHER_SCRIPT_FILE" "$OTHER_RULE_FILE" > "/tmp/rules.yaml" 2>/dev/null
cat "$OTHER_RULE_FILE" > "/tmp/rules.yaml" 2>/dev/null
rm -rf /tmp/other_rule* 2>/dev/null
rm -rf /tmp/yaml_general 2>/dev/null
echo "检查下载的规则文件是否有更新..." >$START_LOG
cmp -s /usr/share/openclash/res/"$RUlE_SOURCE".yaml /tmp/rules.yaml
if [ "$?" -ne "0" ]; then
echo "检测到下载的规则文件有更新,开始替换..." >$START_LOG
mv /tmp/rules.yaml /usr/share/openclash/res/"$RUlE_SOURCE".yaml >/dev/null 2>&1
sed -i '/^rules:/a\##updated' /usr/share/openclash/res/"$RUlE_SOURCE".yaml >/dev/null 2>&1
echo "替换成功,重新加载 OpenClash 应用新规则..." >$START_LOG
echo "${LOGTIME} Other Rules 【$RUlE_SOURCE】 Update Successful" >>$LOG_FILE
[ "$(unify_ps_prevent)" -eq 0 ] && /etc/init.d/openclash restart
[ "$(unify_ps_prevent)" -eq 0 ] && /etc/init.d/openclash restart >/dev/null 2>&1 &
else
echo "检测到下载的规则文件没有更新,停止继续操作..." >$START_LOG
rm -rf /tmp/rules.yaml >/dev/null 2>&1
echo "${LOGTIME} Updated Other Rules 【$RUlE_SOURCE】 No Change, Do Nothing" >>$LOG_FILE
sleep 10
echo "" >$START_LOG
sleep 5
fi
elif [ "$RUlE_SOURCE" = 0 ]; then
echo "未启用第三方规则,更新程序终止!" >$START_LOG
rm -rf /tmp/rules.yaml >/dev/null 2>&1
echo "${LOGTIME} Other Rules Not Enable, Update Stop" >>$LOG_FILE
sleep 10
echo "" >$START_LOG
sleep 5
else
echo "第三方规则下载失败,请检查网络或稍后再试!" >$START_LOG
rm -rf /tmp/rules.yaml >/dev/null 2>&1
echo "${LOGTIME} Other Rules 【$RUlE_SOURCE】 Update Error" >>$LOG_FILE
sleep 10
echo "" >$START_LOG
sleep 5
fi
echo "" >$START_LOG

View File

@ -26,9 +26,10 @@ OP_LV=$(sed -n 1p $LAST_OPVER 2>/dev/null |awk -F '-' '{print $1}' |awk -F 'v' '
if [ "$(expr "$OP_LV" \> "$OP_CV")" -eq 1 ] && [ -f "$LAST_OPVER" ]; then
echo "开始下载 OpenClash-v$LAST_VER ..." >$START_LOG
if pidof clash >/dev/null; then
curl -sL -m 30 --retry 5 https://github.com/vernesong/OpenClash/releases/download/v"$LAST_VER"/luci-app-openclash_"$LAST_VER"_all.ipk -o /tmp/openclash.ipk >/dev/null 2>&1
else
curl -sL -m 30 --retry 5 https://cdn.jsdelivr.net/gh/vernesong/OpenClash@master/luci-app-openclash_"$LAST_VER"_all.ipk -o /tmp/openclash.ipk >/dev/null 2>&1
curl -sL -m 10 --retry 2 https://github.com/vernesong/OpenClash/releases/download/v"$LAST_VER"/luci-app-openclash_"$LAST_VER"_all.ipk -o /tmp/openclash.ipk >/dev/null 2>&1
fi
if [ "$?" -ne "0" ] || ! pidof clash >/dev/null; then
curl -sL -m 10 --retry 2 https://cdn.jsdelivr.net/gh/vernesong/OpenClash@master/luci-app-openclash_"$LAST_VER"_all.ipk -o /tmp/openclash.ipk >/dev/null 2>&1
fi
if [ "$?" -eq "0" ] && [ -s "/tmp/openclash.ipk" ]; then
echo "OpenClash-$LAST_VER 下载成功,开始进行更新前测试 ..." >$START_LOG

View File

@ -7,7 +7,8 @@ OP_LV=$(sed -n 1p $LAST_OPVER 2>/dev/null |awk -F '-' '{print $1}' |awk -F 'v' '
if [ "$CKTIME" != "$(grep "CheckTime" $LAST_OPVER 2>/dev/null |awk -F ':' '{print $2}')" ]; then
if pidof clash >/dev/null; then
curl -sL --connect-timeout 10 --retry 2 https://raw.githubusercontent.com/vernesong/OpenClash/master/version -o $LAST_OPVER >/dev/null 2>&1
else
fi
if [ "$?" -ne "0" ] || ! pidof clash >/dev/null; then
curl -sL --connect-timeout 10 --retry 2 https://cdn.jsdelivr.net/gh/vernesong/OpenClash@master/version -o $LAST_OPVER >/dev/null 2>&1
fi
if [ "$?" -eq "0" ] && [ -s "$LAST_OPVER" ]; then

View File

@ -41,14 +41,16 @@ if [ "$enable" -eq 1 ]; then
if ! pidof clash >/dev/null; then
CRASH_NUM=$(expr "$CRASH_NUM" + 1)
if [ "$CRASH_NUM" -le 3 ]; then
CONFIG_FILE=$(uci get openclash.config.config_path 2>/dev/null)
RAW_CONFIG_FILE=$(uci get openclash.config.config_path 2>/dev/null)
CONFIG_FILE="/etc/openclash/$(uci get openclash.config.config_path 2>/dev/null |awk -F '/' '{print $5}' 2>/dev/null)"
echo "${LOGTIME} Watchdog: Clash Core Problem, Restart." >> $LOG_FILE
touch /tmp/openclash.log 2>/dev/null
chmod o+w /etc/openclash/proxy_provider/* 2>/dev/null
chmod o+w /etc/openclash/rule_provider/* 2>/dev/null
chmod o+w /tmp/openclash.log 2>/dev/null
chown nobody:nogroup /etc/openclash/core/* 2>/dev/null
capabilties="cap_sys_resource,cap_dac_override,cap_net_raw,cap_net_bind_service,cap_net_admin"
capsh --caps="${capabilties}+eip" -- -c "capsh --user=nobody --addamb='${capabilties}' -- -c 'nohup $CLASH -d $CLASH_CONFIG -f \"$CONFIG_FILE\" >> $LOG_FILE 2>&1 &'"
capsh --caps="${capabilties}+eip" -- -c "capsh --user=nobody --addamb='${capabilties}' -- -c 'nohup $CLASH -d $CLASH_CONFIG -f \"$CONFIG_FILE\" >> $LOG_FILE 2>&1 &'" >> $LOG_FILE 2>&1
sleep 3
if [ "$core_type" = "Tun" ]; then
ip route replace default dev utun table "$PROXY_ROUTE_TABLE" 2>/dev/null

View File

@ -333,6 +333,7 @@ proxy-groups: # 此参数必须保留,不能删除
# load-balance: The request of the same eTLD will be dial on the same proxy.
- name: "load-balance"
type: load-balance
strategy: consistent-hashing # or round-robin
proxies:
- ss1
- ss2

View File

@ -2,289 +2,289 @@ rule-providers:
Reject:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Reject.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Reject.yaml'
path: ./Rules/Reject
interval: 86400
Special:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Special.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Special.yaml'
path: ./Rules/Special
interval: 86400
Netflix:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Netflix.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Netflix.yaml'
path: ./Rules/Media/Netflix
interval: 86400
Spotify:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Spotify.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Spotify.yaml'
path: ./Rules/Media/Spotify
interval: 86400
# YouTube Music:
# type: http
# behavior: classical
# url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/YouTube%20Music.yaml'
# url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/YouTube%20Music.yaml'
# path: ./Rules/Media/YouTube_Music
# interval: 86400
YouTube:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/YouTube.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/YouTube.yaml'
path: ./Rules/Media/YouTube
interval: 86400
Bilibili:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Bilibili.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Bilibili.yaml'
path: ./Rules/Media/Bilibili
interval: 86400
iQiyi:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/iQiyi.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/iQiyi.yaml'
path: ./Rules/Media/iQiyi
interval: 86400
Letv:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Letv.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Letv.yaml'
path: ./Rules/Media/Letv
interval: 86400
# MOO:
# type: http
# behavior: classical
# url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/MOO.yaml'
# url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/MOO.yaml'
# path: ./Rules/Media/MOO
# interval: 86400
Netease Music:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Netease%20Music.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Netease%20Music.yaml'
path: ./Rules/Media/Netease_Music
interval: 86400
Tencent Video:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Tencent%20Video.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Tencent%20Video.yaml'
path: ./Rules/Media/Tencent_Video
interval: 86400
Youku:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Youku.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Youku.yaml'
path: ./Rules/Media/Youku
interval: 86400
ABC:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/ABC.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/ABC.yaml'
path: ./Rules/Media/ABC
interval: 86400
Abema TV:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Abema%20TV.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Abema%20TV.yaml'
path: ./Rules/Media/Abema_TV
interval: 86400
Amazon:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Amazon.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Amazon.yaml'
path: ./Rules/Media/Amazon
interval: 86400
Apple News:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Apple%20News.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Apple%20News.yaml'
path: ./Rules/Media/Apple_News
interval: 86400
Apple TV:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Apple%20TV.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Apple%20TV.yaml'
path: ./Rules/Media/Apple_TV
interval: 86400
Bahamut:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Bahamut.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Bahamut.yaml'
path: ./Rules/Media/Bahamut
interval: 86400
BBC iPlayer:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/BBC%20iPlayer.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/BBC%20iPlayer.yaml'
path: ./Rules/Media/BBC_iPlayer
interval: 86400
DAZN:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/DAZN.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/DAZN.yaml'
path: ./Rules/Media/DAZN
interval: 86400
Disney Plus:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Disney%20Plus.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Disney%20Plus.yaml'
path: ./Rules/Media/Disney_Plus
interval: 86400
encoreTVB:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/encoreTVB.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/encoreTVB.yaml'
path: ./Rules/Media/encoreTVB
interval: 86400
Fox Now:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Fox%20Now.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Fox%20Now.yaml'
path: ./Rules/Media/Fox_Now
interval: 86400
Fox+:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Fox%2B.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Fox%2B.yaml'
path: ./Rules/Media/Fox+
interval: 86400
HBO:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/HBO.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/HBO.yaml'
path: ./Rules/Media/HBO
interval: 86400
Hulu Japan:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Hulu%20Japan.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Hulu%20Japan.yaml'
path: ./Rules/Media/Hulu_Japan
interval: 86400
Hulu:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Hulu.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Hulu.yaml'
path: ./Rules/Media/Hulu
interval: 86400
Japonx:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Japonx.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Japonx.yaml'
path: ./Rules/Media/Japonx
interval: 86400
JOOX:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/JOOX.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/JOOX.yaml'
path: ./Rules/Media/JOOX
interval: 86400
KKBOX:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/KKBOX.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/KKBOX.yaml'
path: ./Rules/Media/KKBOX
interval: 86400
KKTV:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/KKTV.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/KKTV.yaml'
path: ./Rules/Media/KKTV
interval: 86400
Line TV:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Line%20TV.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Line%20TV.yaml'
path: ./Rules/Media/Line_TV
interval: 86400
myTV SUPER:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/myTV%20SUPER.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/myTV%20SUPER.yaml'
path: ./Rules/Media/myTV_SUPER
interval: 86400
Pandora:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Pandora.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Pandora.yaml'
path: ./Rules/Media/Pandora
interval: 86400
PBS:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/PBS.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/PBS.yaml'
path: ./Rules/Media/PBS
interval: 86400
Pornhub:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Pornhub.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Pornhub.yaml'
path: ./Rules/Media/Pornhub
interval: 86400
Soundcloud:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/Soundcloud.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/Soundcloud.yaml'
path: ./Rules/Media/Soundcloud
interval: 86400
ViuTV:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Media/ViuTV.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Media/ViuTV.yaml'
path: ./Rules/Media/ViuTV
interval: 86400
Telegram:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Telegram.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Telegram.yaml'
path: ./Rules/Telegram
interval: 86400
Steam:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Steam.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Steam.yaml'
path: ./Rules/Steam
interval: 86400
Speedtest:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Speedtest.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Speedtest.yaml'
path: ./Rules/Speedtest
interval: 86400
PayPal:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/PayPal.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/PayPal.yaml'
path: ./Rules/PayPal
interval: 86400
Microsoft:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Microsoft.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Microsoft.yaml'
path: ./Rules/Microsoft
interval: 86400
PROXY:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Proxy.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Proxy.yaml'
path: ./Rules/Proxy
interval: 86400
Domestic:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Domestic.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Domestic.yaml'
path: ./Rules/Domestic
interval: 86400
Apple:
type: http
behavior: classical
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Apple.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Apple.yaml'
path: ./Rules/Apple
interval: 86400
Domestic IPs:
type: http
behavior: ipcidr
url: 'https://git.dler.io/lhie1/Rules/master/Clash/Provider/Domestic%20IPs.yaml'
url: 'https://gitee.com/lhie1/Rules/raw/master/Clash/Provider/Domestic%20IPs.yaml'
path: ./Rules/Domestic_IPs
interval: 86400
script:

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,100 @@
#!/bin/sh
ruby_read()
{
local Value RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
fi
RUBY_YAML_PARSE="Thread.new{Value = YAML.load_file('$1'); puts Value$2}.join"
if [ -n "$(echo "$2" |grep '.to_yaml' 2>/dev/null)" ]; then
ruby -ryaml -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null |sed '1d' 2>/dev/null
else
ruby -ryaml -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
fi
}
ruby_read_hash()
{
local Value RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
fi
RUBY_YAML_PARSE="Thread.new{Value = $1; puts Value$2}.join"
ruby -ryaml -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
}
ruby_edit()
{
local Value RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
fi
RUBY_YAML_PARSE="Thread.new{Value = YAML.load_file('$1'); Value$2; File.open('$1','w') {|f| YAML.dump(Value, f)}}.join"
ruby -ryaml -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
}
#数组覆盖
ruby_cover()
{
local Value Value_1 RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
fi
RUBY_YAML_PARSE="Thread.new{Value = YAML.load_file('$1'); Value_1 = YAML.load_file('$3'); Value$2=Value_1$4; File.open('$1','w') {|f| YAML.dump(Value, f)}}.join"
ruby -ryaml -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
}
#hash增加
ruby_merge()
{
local Value Value_1 RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
fi
RUBY_YAML_PARSE="Thread.new{Value = YAML.load_file('$1'); Value_1 = YAML.load_file('$3'); Value$2.merge!(Value_1$4); File.open('$1','w') {|f| YAML.dump(Value, f)}}.join"
ruby -ryaml -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
}
#数组指定位置前添加一组值(不要key)
ruby_arr_add_file()
{
local Value Value_1 RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
fi
RUBY_YAML_PARSE="Thread.new{Value = YAML.load_file('$1'); Value_1 = YAML.load_file('$4').reverse!; Value_1$5.each{|x| Value$2.insert($3,x)}; Value$2=Value$2.uniq; File.open('$1','w') {|f| YAML.dump(Value, f)}}.join"
ruby -ryaml -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
}
#数组开头添加一组值(含key)
ruby_arr_head_add_file()
{
local Value Value_1 RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
fi
RUBY_YAML_PARSE="Thread.new{Value = YAML.load_file('$1'); Value_1 = YAML.load_file('$3'); Value$2=(Value_1$4+Value$2).uniq; File.open('$1','w') {|f| YAML.dump(Value, f)}}.join"
ruby -ryaml -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
}
#数组指定位置前增加值
ruby_arr_insert()
{
local Value RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
fi
RUBY_YAML_PARSE="Thread.new{Value = YAML.load_file('$1'); Value$2=Value$2.insert($3,'$4').uniq; File.open('$1','w') {|f| YAML.dump(Value, f)}}.join"
ruby -ryaml -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
}
ruby_read_hash_arr()
{
local Value RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
fi
RUBY_YAML_PARSE="Thread.new{Value = YAML.load_file('$1'); Value$2.each do |i| puts i$3 end}.join"
ruby -ryaml -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
}

View File

@ -1,249 +1,165 @@
#!/bin/sh
. /usr/share/openclash/ruby.sh
LOG_FILE="/tmp/openclash.log"
START_LOG="/tmp/openclash_start.log"
LOGTIME=$(date "+%Y-%m-%d %H:%M:%S")
#删除旧hosts配置
hostlen=$(sed -n '/hosts:/=' "$7" 2>/dev/null)
dnslen=$(sed -n '/dns:/=' "$7" 2>/dev/null)
dnsheadlen=$(expr "$dnslen" - 1)
if [ ! -z "$hostlen" ] && [ "$hostlen" -gt "$dnslen" ]; then
sed -i '/^ \{0,\}hosts:/,$d' "$7" 2>/dev/null
elif [ ! -z "$hostlen" ]; then
sed -i '/##Custom HOSTS##/,/##Custom HOSTS END##/d' "$7" 2>/dev/null
if [ -z "$(awk '/^ {0,}hosts:/,/^dns:/{print}' "$7" 2>/dev/null |awk -F ':' '{print $2}' 2>/dev/null)" ]; then
sed -i "/${hostlen}p/,/${dnsheadlen}p/d" "$7" 2>/dev/null
sed -i '/^ \{0,\}hosts:/d' "$7" 2>/dev/null
fi
fi
if [ -z "$(grep "^ enhanced-mode: $2" "$7" 2>/dev/null)" ]; then
if [ ! -z "$(grep "^ \{0,\}enhanced-mode:" "$7" 2>/dev/null)" ]; then
sed -i "/^ \{0,\}enhanced-mode:/c\ enhanced-mode: ${2}" "$7" 2>/dev/null
else
sed -i "/^dns:/a\ enhanced-mode: ${2}" "$7" 2>/dev/null
fi
fi
if [ "$2" = "fake-ip" ]; then
if [ -z "$(grep "^ \{0,\}fake-ip-range: 198.18.0.1/16" "$7" 2>/dev/null)" ]; then
if [ ! -z "$(grep "^ \{0,\}fake-ip-range:" "$7" 2>/dev/null)" ]; then
sed -i "/^ \{0,\}fake-ip-range:/c\ fake-ip-range: 198.18.0.1/16" "$7" 2>/dev/null
else
sed -i "/^ \{0,\}enhanced-mode:/a\ fake-ip-range: 198.18.0.1/16" "$7" 2>/dev/null
fi
fi
else
sed -i '/^ \{0,\}fake-ip-range:/d' "$7" 2>/dev/null
fi
sed -i '/##Custom DNS##/d' "$7" 2>/dev/null
if [ "$14" != "1" ]; then
controller_address="0.0.0.0"
bind_address="*"
elif [ "$18" != "Tun" ] && [ "$14" = "1" ]; then
controller_address=$11
bind_address=$11
elif [ "$18" = "Tun" ] && [ "$14" = "1" ]; then
echo "Warning: Stop Set The Bind Address Option In TUN Mode, Because The Router Will Not Be Able To Connect To The Internet" >> $LOG_FILE
echo "警告: 在TUN内核下启用仅允许内网会导致路由器无法联网已忽略此项修改" >$START_LOG
controller_address="0.0.0.0"
bind_address="*"
fi
if [ -n "$(ruby_read "$7" "['tun']")" ]; then
if [ -n "$(ruby_read "$7" "['tun']['device-url']")" ]; then
if [ "$15" -eq 1 ] || [ "$15" -eq 3 ]; then
uci set openclash.config.config_reload=0
fi
else
uci set openclash.config.config_reload=0
fi
else
if [ -n "$15" ]; then
uci set openclash.config.config_reload=0
fi
fi
if [ -z "$(grep "^redir-port: $6" "$7" 2>/dev/null)" ]; then
if [ ! -z "$(grep "^ \{0,\}redir-port:" "$7" 2>/dev/null)" ]; then
sed -i "/^ \{0,\}redir-port:/c\redir-port: ${6}" "$7" 2>/dev/null
else
sed -i "/^dns:/i\redir-port: ${6}" "$7" 2>/dev/null
fi
fi
if [ -z "$(grep "^port: $9" "$7" 2>/dev/null)" ]; then
if [ ! -z "$(grep "^ \{0,\}port:" "$7" 2>/dev/null)" ]; then
sed -i "/^ \{0,\}port:/c\port: ${9}" "$7" 2>/dev/null
else
sed -i "/^dns:/i\port: ${9}" "$7" 2>/dev/null
fi
fi
if [ -z "$(grep "^socks-port: $10" "$7" 2>/dev/null)" ]; then
if [ ! -z "$(grep "^ \{0,\}socks-port:" "$7" 2>/dev/null)" ]; then
sed -i "/^ \{0,\}socks-port:/c\socks-port: ${10}" "$7" 2>/dev/null
else
sed -i "/^dns:/i\socks-port: ${10}" "$7" 2>/dev/null
fi
fi
if [ -z "$(grep "^mode: $13" "$7" 2>/dev/null)" ]; then
if [ ! -z "$(grep "^ \{0,\}mode:" "$7" 2>/dev/null)" ]; then
sed -i "/^ \{0,\}mode:/c\mode: ${13}" "$7" 2>/dev/null
else
sed -i "/^dns:/i\mode: ${13}" "$7" 2>/dev/null
fi
fi
if [ -z "$(grep "^log-level: $12" "$7" 2>/dev/null)" ]; then
if [ ! -z "$(grep "^ \{0,\}log-level:" "$7" 2>/dev/null)" ]; then
sed -i "/^ \{0,\}log-level:/c\log-level: ${12}" "$7" 2>/dev/null
else
sed -i "/^dns:/i\log-level: ${12}" "$7" 2>/dev/null
fi
fi
if [ "$14" != "1" ]; then
controller_address="0.0.0.0"
bind_address="*"
elif [ "$18" != "Tun" ] && [ "$14" = "1" ]; then
controller_address=$11
bind_address=$11
elif [ "$18" = "Tun" ] && [ "$14" = "1" ]; then
echo "Warning: Stop Set The Bind Address Option In TUN Mode, Because The Router Will Not Be Able To Connect To The Internet" >> $LOG_FILE
echo "警告: 在TUN内核下启用仅允许内网会导致路由器无法联网已忽略此项修改" >$START_LOG
controller_address="0.0.0.0"
bind_address="*"
sleep 3
fi
if [ -z "$(grep "^external-controller: $controller_address:$5" "$7" 2>/dev/null)" ]; then
if [ ! -z "$(grep "^ \{0,\}external-controller:" "$7" 2>/dev/null)" ]; then
sed -i "/^ \{0,\}external-controller:/c\external-controller: ${controller_address}:${5}" "$7" 2>/dev/null
else
sed -i "/^dns:/i\external-controller: ${controller_address}:${5}" "$7" 2>/dev/null
fi
uci set openclash.config.config_reload=0
fi
if [ -z "$(grep "^secret: \"$4\"" "$7" 2>/dev/null)" ]; then
if [ ! -z "$(grep "^ \{0,\}secret:" "$7" 2>/dev/null)" ]; then
sed -i "/^ \{0,\}secret:/c\secret: \"${4}\"" "$7" 2>/dev/null
else
sed -i "/^dns:/i\secret: \"${4}\"" "$7" 2>/dev/null
fi
uci set openclash.config.config_reload=0
fi
if [ -z "$(grep "^ \{0,\}device-url:" "$7" 2>/dev/null)" ] && [ "$15" -eq 2 ]; then
uci set openclash.config.config_reload=0
elif [ -z "$(grep "^ \{0,\}tun:" "$7" 2>/dev/null)" ] && [ -n "$15" ]; then
uci set openclash.config.config_reload=0
elif [ -n "$(grep "^ \{0,\}tun:" "$7" 2>/dev/null)" ] && [ -z "$15" ]; then
uci set openclash.config.config_reload=0
elif [ -n "$(grep "^ \{0,\}device-url:" "$7" 2>/dev/null)" ] && [ "$15" -eq 1 ]; then
uci set openclash.config.config_reload=0
elif [ -n "$(grep "^ \{0,\}device-url:" "$7" 2>/dev/null)" ] && [ "$15" -eq 3 ]; then
uci set openclash.config.config_reload=0
fi
uci commit openclash
if [ -z "$15" ]; then
en_mode_tun=0
else
en_mode_tun=$15
fi
if [ -z "$(grep "^ enable: true" "$7" 2>/dev/null)" ]; then
if [ ! -z "$(grep "^ \{0,\}enable:" "$7" 2>/dev/null)" ]; then
sed -i "/^ \{0,\}enable:/c\ enable: true" "$7" 2>/dev/null
else
sed -i "/^dns:/a\ enable: true" "$7" 2>/dev/null
fi
fi
if [ -z "$(grep "^allow-lan: true" "$7" 2>/dev/null)" ]; then
if [ ! -z "$(grep "^ \{0,\}allow-lan:" "$7" 2>/dev/null)" ]; then
sed -i "/^ \{0,\}allow-lan:/c\allow-lan: true" "$7" 2>/dev/null
else
sed -i "/^dns:/i\allow-lan: true" "$7" 2>/dev/null
fi
fi
sed -i '/bind-address:/d' "$7" 2>/dev/null
sed -i "/^allow-lan:/a\bind-address: \"${bind_address}\"" "$7" 2>/dev/null
if [ -n "$(grep "^ \{0,\}listen:" "$7" 2>/dev/null)" ]; then
if [ "$8" != "1" ]; then
sed -i "/^ \{0,\}listen:/c\ listen: 127.0.0.1:${17}" "$7" 2>/dev/null
else
sed -i "/^ \{0,\}listen:/c\ listen: 0.0.0.0:${17}" "$7" 2>/dev/null
fi
else
if [ "$8" != "1" ]; then
sed -i "/^dns:/a\ listen: 127.0.0.1:${17}" "$7" 2>/dev/null
else
sed -i "/^dns:/a\ listen: 0.0.0.0:${17}" "$7" 2>/dev/null
fi
fi 2>/dev/null
if [ -z "$(grep '^external-ui: "/usr/share/openclash/dashboard"' "$7" 2>/dev/null)" ]; then
if [ ! -z "$(grep "^ \{0,\}external-ui:" "$7" 2>/dev/null)" ]; then
sed -i '/^ \{0,\}external-ui:/c\external-ui: "/usr/share/openclash/dashboard"' "$7" 2>/dev/null
else
sed -i '/^dns:/i\external-ui: "/usr/share/openclash/dashboard"' "$7" 2>/dev/null
fi
fi
if [ -z "$16" ]; then
stack_type=system
else
stack_type=$16
fi
if [ "$8" -eq 1 ]; then
sed -i '/^ \{0,\}ipv6:/d' "$7" 2>/dev/null
sed -i "/^ \{0,\}enable: true/a\ ipv6: true" "$7" 2>/dev/null
sed -i "/^ \{0,\}mode:/i\ipv6: true" "$7" 2>/dev/null
else
sed -i '/^ \{0,\}ipv6:/d' "$7" 2>/dev/null 2>/dev/null
sed -i "/^ \{0,\}enable: true/a\ ipv6: false" "$7" 2>/dev/null
sed -i "/^ \{0,\}mode:/i\ipv6: false" "$7" 2>/dev/null
fi
if [ "$(ruby_read "$7" "['external-controller']")" != "$controller_address:$5" ]; then
uci set openclash.config.config_reload=0
fi
if [ "$(ruby_read "$7" "['secret']")" != "$4" ]; then
uci set openclash.config.config_reload=0
fi
uci commit openclash
#TUN
if [ "$15" -eq 1 ] || [ "$15" -eq 3 ]; then
sed -i "/^dns:/i\tun:" "$7" 2>/dev/null
sed -i "/^dns:/i\ enable: true" "$7" 2>/dev/null
if [ -n "$16" ]; then
sed -i "/^dns:/i\ stack: ${16}" "$7" 2>/dev/null
else
sed -i "/^dns:/i\ stack: system" "$7" 2>/dev/null
fi
sed -i "/^dns:/i\ dns-hijack:" "$7" 2>/dev/null
# sed -i "/^dns:/i\ - 8.8.8.8:53" "$7"
sed -i "/^dns:/i\ - tcp://8.8.8.8:53" "$7" 2>/dev/null
# sed -i "/^dns:/i\ - 8.8.4.4:53" "$7"
sed -i "/^dns:/i\ - tcp://8.8.4.4:53" "$7" 2>/dev/null
elif [ "$15" -eq 2 ]; then
sed -i "/^dns:/i\tun:" "$7" 2>/dev/null
sed -i "/^dns:/i\ enable: true" "$7" 2>/dev/null
sed -i "/^dns:/i\ device-url: dev://clash0" "$7" 2>/dev/null
sed -i "/^dns:/i\ dns-listen: 0.0.0.0:53" "$7" 2>/dev/null
fi
if [ "$2" = "fake-ip" ]; then
if [ ! -f "/tmp/openclash_fake_filter.list" ] || [ ! -z "$(grep "config servers" /etc/config/openclash 2>/dev/null)" ]; then
/usr/share/openclash/openclash_fake_filter.sh
fi
if [ -s "/tmp/openclash_servers_fake_filter.conf" ]; then
mkdir -p /tmp/dnsmasq.d
ln -s /tmp/openclash_servers_fake_filter.conf /tmp/dnsmasq.d/dnsmasq_openclash.conf
fi
fi
ruby -ryaml -E UTF-8 -e "
begin
Value = YAML.load_file('$7');
rescue Exception => e
puts '${LOGTIME} Load File Error: ' + e.message
end
begin
Value['redir-port']=$6;
Value['port']=$9;
Value['socks-port']=$10;
Value['mixed-port']=$19;
Value['mode']='$13';
Value['log-level']='$12';
Value['allow-lan']=true;
Value['external-controller']='$controller_address:$5';
Value['secret']='$4';
Value['bind-address']='$bind_address';
Value['external-ui']='/usr/share/openclash/dashboard';
if not Value.key?('dns') then
Value_1={'dns'=>{'enable'=>true}}
Value['dns']=Value_1['dns']
else
Value['dns']['enable']=true
end;
if $8 == 1 then
Value['dns']['ipv6']=true
Value['ipv6']=true
else
Value['dns']['ipv6']=false
Value['ipv6']=false
end;
Value['dns']['enhanced-mode']='$2';
if '$2' == 'fake-ip' then
Value['dns']['fake-ip-range']='198.18.0.1/16'
else
Value['dns'].delete('fake-ip-range')
end;
if $8 != 1 then
Value['dns']['listen']='127.0.0.1:$17'
else
Value['dns']['listen']='0.0.0.0:$17'
end;
Value_2={'tun'=>{'enable'=>true}};
if $en_mode_tun == 1 or $en_mode_tun == 3 then
Value['tun']=Value_2['tun']
Value['tun']['stack']='$stack_type'
Value_2={'dns-hijack'=>['tcp://8.8.8.8:53','tcp://8.8.4.4:53']}
Value['tun'].merge!(Value_2)
elsif $en_mode_tun == 2
Value['tun']=Value_2['tun']
Value['tun']['device-url']='dev://clash0'
Value['tun']['dns-listen']='0.0.0.0:53'
elsif $en_mode_tun == 0
if Value.key?('tun') then
Value['tun'].clear
end
end;
rescue Exception => e
puts '${LOGTIME} Set General Error: ' + e.message
end
begin
#添加自定义Hosts设置
if [ "$2" = "redir-host" ]; then
if [ -z "$(grep "^ \{0,\}hosts:" "$7" 2>/dev/null)" ]; then
sed -i '/^dns:/i\hosts:' "$7" 2>/dev/null
else
if [ ! -z "$(grep "^ \{1,\}hosts:" "$7" 2>/dev/null)" ]; then
sed -i "/^ \{0,\}hosts:/c\hosts:" "$7" 2>/dev/null
fi
fi
if [ -z "$(grep "^ \{0,\}use-hosts:" "$7" 2>/dev/null)" ]; then
sed -i "/^dns:/a\ use-hosts: true" "$7" 2>/dev/null
else
if [ ! -z "$(grep "^ \{0,\}use-hosts:" "$7" 2>/dev/null)" ]; then
sed -i "/^ \{0,\}use-hosts:/c\ use-hosts: true" "$7" 2>/dev/null
fi
fi
sed -i '/^hosts:/a\##Custom HOSTS END##' "$7" 2>/dev/null
sed -i '/^hosts:/a\##Custom HOSTS##' "$7" 2>/dev/null
sed -i '/##Custom HOSTS##/r/etc/openclash/custom/openclash_custom_hosts.list' "$7" 2>/dev/null
sed -i "/^hosts:/,/^dns:/ {s/^ \{0,\}'/ '/}" "$7" 2>/dev/null #修改参数空格
fi
if [ ! -z "$(grep "^ \{0,\}default-nameserver:" "$7" 2>/dev/null)" ]; then
sed -i "/^ \{0,\}default-nameserver:/c\ default-nameserver:" "$7" 2>/dev/null
sed -i "/^ \{0,\}default-nameserver:/,/,$/ {s/^ \{0,\}- / - /g}" "$7" 2>/dev/null #修改参数空格
fi
if '$2' == 'redir-host' then
if File::exist?('/etc/openclash/custom/openclash_custom_hosts.list') then
Value_3 = YAML.load_file('/etc/openclash/custom/openclash_custom_hosts.list')
if Value_3 != false then
Value['dns']['use-hosts']=true
if Value.has_key?('hosts') and not Value['hosts'].to_a.empty? then
Value['hosts'].merge!(Value_3)
Value['hosts'].uniq
else
Value['hosts']=Value_3
end
end
end
end;
rescue Exception => e
puts '${LOGTIME} Set Hosts Rules Error: ' + e.message
end
begin
#fake-ip-filter
sed -i '/##Custom fake-ip-filter##/,/##Custom fake-ip-filter END##/d' "$7" 2>/dev/null
if [ "$2" = "fake-ip" ]; then
if [ ! -f "/etc/openclash/fake_filter.list" ] || [ ! -z "$(grep "config servers" /etc/config/openclash 2>/dev/null)" ]; then
/usr/share/openclash/openclash_fake_filter.sh
fi
if [ -s "/etc/openclash/servers_fake_filter.conf" ]; then
mkdir -p /tmp/dnsmasq.d
ln -s /etc/openclash/servers_fake_filter.conf /tmp/dnsmasq.d/dnsmasq_openclash.conf
fi
if [ -s "/etc/openclash/fake_filter.list" ]; then
if [ ! -z "$(grep "^ \{0,\}fake-ip-filter:" "$7" 2>/dev/null)" ]; then
sed -i "/^ \{0,\}fake-ip-filter:/c\ fake-ip-filter:" "$7" 2>/dev/null
sed -i '/^ \{0,\}fake-ip-filter:/r/etc/openclash/fake_filter.list' "$7" 2>/dev/null
sed -i "/^ \{0,\}fake-ip-filter:/,/,$/ {s/^ \{0,\}- / - /g}" "$7" 2>/dev/null #修改参数空格
else
echo " fake-ip-filter:" >> "$7"
sed -i '/^ \{0,\}fake-ip-filter:/r/etc/openclash/fake_filter.list' "$7" 2>/dev/null
fi
fi
fi
if '$2' == 'fake-ip' then
if File::exist?('/tmp/openclash_fake_filter.list') then
Value_4 = YAML.load_file('/tmp/openclash_fake_filter.list')
if Value_4 != false then
if Value['dns'].has_key?('fake-ip-filter') and not Value['dns']['fake-ip-filter'].to_a.empty? then
Value_5 = Value_4['fake-ip-filter'].reverse!
Value_5.each{|x| Value['dns']['fake-ip-filter'].insert(-1,x)}
Value['dns']['fake-ip-filter']=Value['dns']['fake-ip-filter'].uniq
else
Value['dns']['fake-ip-filter']=Value_4['fake-ip-filter']
end
end
end
end;
rescue Exception => e
puts '${LOGTIME} Set Fake IP Filter Error: ' + e.message
ensure
File.open('$7','w') {|f| YAML.dump(Value, f)}
end" 2>/dev/null >> $LOG_FILE

View File

@ -1,121 +0,0 @@
#!/bin/sh
. /lib/functions.sh
field_cut()
{
local i lines end_len
if [ "$4" != "dns" ]; then
proxy_len=$(sed -n '/^Proxy:/=' "$3" 2>/dev/null)
provider_len=$(sed -n '/^proxy-providers:/=' "$3" 2>/dev/null)
group_len=$(sed -n '/^proxy-groups:/=' "$3" 2>/dev/null)
rule_len=$(sed -n '/^rules:/=' "$3" 2>/dev/null)
rule_provider_len=$(sed -n '/^rule-providers:/=' "$3" 2>/dev/null)
script_len=$(sed -n '/^script:/=' "$3" 2>/dev/null)
nameserver_len=$(sed -n '/^ \{0,\}nameserver:/=' "$3" 2>/dev/null)
if [ -z "$nameserver_len" ]; then
fallback_len=$(sed -n '/^ \{0,\}fallback:/=' "$3" 2>/dev/null)
lines="$general_len $fallback_len $proxy_len $provider_len $group_len $rule_len $rule_provider_len $script_len"
else
lines="$general_len $nameserver_len $proxy_len $provider_len $group_len $rule_len $rule_provider_len $script_len"
fi
else
fallback_filter_len=$(sed -n '/^ \{0,\}fallback-filter:/=' "$3" 2>/dev/null)
cfw_bypass_len=$(sed -n '/^ \{0,\}cfw-bypass:/=' "$3" 2>/dev/null)
cfw_latency_timeout_len=$(sed -n '/^ \{0,\}cfw-latency-timeout:/=' "$3" 2>/dev/null)
nameserver_len=$(sed -n '/^ \{0,\}nameserver:/=' "$3" 2>/dev/null)
if [ -z "$nameserver_len" ]; then
fallback_len=$(sed -n '/^ \{0,\}fallback:/=' "$3" 2>/dev/null)
lines="$fallback_len $fallback_filter_len $cfw_bypass_len $cfw_latency_timeout_len"
else
lines="$nameserver_len $fallback_filter_len $cfw_bypass_len $cfw_latency_timeout_len"
fi
fi
for i in $lines; do
if [ -z "$1" ]; then
break
fi
if [ "$1" -ge "$i" ]; then
continue
fi
if [ "$end_len" -gt "$i" ] || [ -z "$end_len" ]; then
end_len="$i"
fi
done 2>/dev/null
if [ -n "$1" ] && [ -z "$end_len" ]; then
end_len=$(sed -n '$=' "$3")
elif [ -n "$end_len" ]; then
end_len=$(expr "$end_len" - 1)
fi
if [ "$4" = "yaml_get" ]; then
sed -n "${1},${end_len}p" "$3" |sed 's/\"//g' 2>/dev/null |sed "s/\'//g" 2>/dev/null |sed 's/\t/ /g' 2>/dev/null > "$2" 2>/dev/null
elif [ "$4" = "dns" ]; then
sed -n "${1},${end_len}p" "$3" > "$2" 2>/dev/null
sed -i "${1},${end_len}d" "$3" 2>/dev/null
else
sed -n "${1},${end_len}p" "$3" > "$2" 2>/dev/null
fi
}
if [ ! -f "/tmp/yaml_general" ]; then
#识别general部分
space_num=$(grep "^ \{0,\}socks-port:" "$3" 2>/dev/null |awk -F ':' '{print $1}' |grep -c " ")
if [ -z "$space_num" ]; then
space_num=$(grep "^ \{0,\}allow-lan:" "$3" 2>/dev/null |awk -F ':' '{print $1}' |grep -c " ")
fi
cat "/usr/share/openclash/res/default.yaml" |awk '1;/dns:/{exit}' 2>/dev/null |sed '/^ \{0,\}#\|^ \{0,\}-\|^ \{0,\}$/d' 2>/dev/null |awk -F ':' '{print $1}' |while read -r line
do
if [ -z "$line" ]; then
continue
fi
line_len=$(sed -n "/^ \{0,${space_num}\}${line}:/=" "$3" 2>/dev/null)
if [ -z "$line_len" ] || [ "$(echo $line_len |awk -F ' ' '{print NF}' 2>/dev/null)" -ge 2 ]; then
continue
fi
if [ -z "$general_len" ]; then
general_len=$line_len
echo $general_len >/tmp/yaml_general
continue
fi
if [ "$general_len" -gt "$line_len" ]; then
general_len=$line_len
echo $general_len >/tmp/yaml_general
fi
done 2>/dev/null
fi
general_len=$(cat /tmp/yaml_general 2>/dev/null)
if [ "$1" = "general" ]; then
field_cut "$general_len" "$2" "$3"
else
field_cut "$1" "$2" "$3" "$4"
fi
dns_hijack_len=$(sed -n '/dns-hijack:/=' "$2" 2>/dev/null)
if [ -n "$dns_hijack_len" ]; then
dns_hijack_end_len=$dns_hijack_len
while ( [ -n "$(echo "$hijack_line" |grep "^ \{0,\}-")" ] || [ -n "$(echo "$hijack_line" |grep "^ \{0,\}$")" ] || [ -z "$hijack_line" ] )
do
dns_hijack_end_len=$(expr "$dns_hijack_end_len" + 1)
hijack_line=$(sed -n "${dns_hijack_end_len}p" "$2")
done 2>/dev/null
dns_hijack_end_len=$(expr "$dns_hijack_end_len" - 1)
sed -i "${dns_hijack_len},${dns_hijack_end_len}d" "$2" 2>/dev/null
fi
sed -i '/^ \{0,\}tun:/,/^ \{0,\}enable:/d' "$2" 2>/dev/null
sed -i '/^ \{0,\}dns-hijack:/d' "$2" 2>/dev/null
sed -i '/^ \{0,\}macOS-auto-route:/d' "$2" 2>/dev/null
sed -i '/^ \{0,\}macOS-auto-detect-interface:/d' "$2" 2>/dev/null
sed -i '/^ \{0,\}stack:/d' "$2" 2>/dev/null
sed -i '/^ \{0,\}device-url:/d' "$2" 2>/dev/null
sed -i '/^ \{0,\}dns-listen:/d' "$2" 2>/dev/null

View File

@ -1,52 +0,0 @@
#!/bin/sh
YML_FILE="$1"
#proxy-providers
[ -z "$(grep "^proxy-providers:" "$YML_FILE")" ] && {
sed -i "s/^ \{1,\}proxy-providers:/proxy-providers:/g" "$YML_FILE" 2>/dev/null
}
[ -z "$(grep "^proxy-providers:" "$YML_FILE")" ] && {
sed -i "s/^ \{0,\}proxy-provider:/proxy-providers:/g" "$YML_FILE" 2>/dev/null
}
#proxy-groups
[ -z "$(grep "^proxy-groups:" "$YML_FILE")" ] && {
sed -i "s/^ \{0,\}\'Proxy Group\':/proxy-groups:/g" "$YML_FILE" 2>/dev/null
sed -i 's/^ \{0,\}\"Proxy Group\":/proxy-groups:/g' "$YML_FILE" 2>/dev/null
sed -i "s/^ \{1,\}proxy-groups:/proxy-groups:/g" "$YML_FILE" 2>/dev/null
}
[ -z "$(grep "^proxy-groups:" "$YML_FILE")" ] && {
sed -i "s/^ \{0,\}Proxy Group:/proxy-groups:/g" "$YML_FILE" 2>/dev/null
}
#proxies
if [ -n "$(grep "^Proxy:" "$YML_FILE")" ] && [ -n "$(grep "^proxies:" "$YML_FILE")" ]; then
sed -i "s/^proxies:/Proxy:#d/g" "$YML_FILE" 2>/dev/null
else
sed -i "s/^proxies:/Proxy:/g" "$YML_FILE" 2>/dev/null
fi
[ -z "$(grep "^Proxy:" "$YML_FILE")" ] && {
group_len=$(sed -n '/^Proxy Group:/=' "$YML_FILE" 2>/dev/null)
proxies_len=$(sed -n '/proxies:/=' "$YML_FILE" 2>/dev/null |sed -n 1p)
if [ "$proxies_len" -lt "$group_len" ]; then
sed -i "${proxies_len}s/ \{0,\}proxies:/Proxy:/" "$YML_FILE" 2>/dev/null
fi 2>/dev/null
}
#rules
[ -z "$(grep "^rules:" "$YML_FILE")" ] && {
sed -i "s/^ \{1,\}rules:/rules:/g" "$YML_FILE" 2>/dev/null
}
[ -z "$(grep "^rules:" "$YML_FILE")" ] && {
sed -i "s/^ \{0,\}Rule:/rules:/g" "$YML_FILE" 2>/dev/null
}
#rule-providers:
[ -z "$(grep "^rule-providers:" "$YML_FILE")" ] && {
sed -i "s/^ \{1,\}rule-providers:/rule-providers:/g" "$YML_FILE" 2>/dev/null
}
#script:
[ -z "$(grep "^script:" "$YML_FILE")" ] && {
sed -i "s/^ \{1,\}script:/script:/g" "$YML_FILE" 2>/dev/null
}

View File

@ -1,18 +1,22 @@
#!/bin/bash
. /lib/functions.sh
. /usr/share/openclash/openclash_ps.sh
. /usr/share/openclash/ruby.sh
status=$(unify_ps_status "yml_groups_get.sh")
[ "$status" -gt "3" ] && exit 0
START_LOG="/tmp/openclash_start.log"
CFG_FILE="/etc/config/openclash"
other_group_file="/tmp/yaml_other_group.yaml"
servers_update=$(uci get openclash.config.servers_update 2>/dev/null)
servers_if_update=$(uci get openclash.config.servers_if_update 2>/dev/null)
CONFIG_FILE=$(uci get openclash.config.config_path 2>/dev/null)
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
UPDATE_CONFIG_FILE=$(uci get openclash.config.config_update_path 2>/dev/null)
UPDATE_CONFIG_NAME=$(echo "$UPDATE_CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
LOGTIME=$(date "+%Y-%m-%d %H:%M:%S")
LOG_FILE="/tmp/openclash.log"
if [ ! -z "$UPDATE_CONFIG_FILE" ]; then
CONFIG_FILE="$UPDATE_CONFIG_FILE"
@ -48,11 +52,6 @@ echo "开始更新【$CONFIG_NAME】的策略组配置..." >$START_LOG
exit 0
}
#判断各个区位置
group_len=$(sed -n '/^ \{0,\}proxy-groups:/=' "$CONFIG_FILE" 2>/dev/null)
/usr/share/openclash/yml_field_cut.sh "$group_len" "/tmp/yaml_group.yaml" "$CONFIG_FILE" "yaml_get"
rm -rf /tmp/yaml_general 2>/dev/null
#判断当前配置文件是否有策略组信息
cfg_group_name()
{
@ -115,138 +114,114 @@ else
cfg_delete
fi
count=1
file_count=1
count=0
match_group_file="/tmp/Proxy_Group"
group_file="/tmp/yaml_group.yaml"
sed -i "s/\'//g" $group_file 2>/dev/null
sed -i 's/\"//g' $group_file 2>/dev/null
line=$(sed -n '/name:/=' $group_file 2>/dev/null)
num=$(grep -c "name:" $group_file 2>/dev/null)
cfg_get()
{
echo "$(grep "$1" "$2" 2>/dev/null |awk -v tag=$1 'BEGIN{FS=tag} {print $2}' 2>/dev/null |sed 's/,.*//' 2>/dev/null |sed 's/\}.*//' 2>/dev/null |sed 's/^ \{0,\}//g' 2>/dev/null |sed 's/ \{0,\}$//g' 2>/dev/null)"
}
#提取策略组部分
group_hash=$(ruby_read "$CONFIG_FILE" ".select {|x| 'proxy-groups' == x}")
num=$(ruby_read_hash "$group_hash" "['proxy-groups'].count")
for n in $line
if [ -z "$num" ]; then
echo "配置文件校验失败,请检查配置文件后重试!" >$START_LOG
echo "${LOGTIME} Error: Unable To Parse Config File, Please Check And Try Again!" >> $LOG_FILE
sleep 3
exit 0
fi
while [ "$count" -lt "$num" ]
do
single_group="/tmp/group_$file_count.yaml"
[ "$count" -eq 1 ] && {
startLine="$n"
}
count=$(expr "$count" + 1)
if [ "$count" -gt "$num" ]; then
endLine=$(sed -n '$=' $group_file)
else
endLine=$(expr $(echo "$line" | sed -n "${count}p") - 1)
fi
sed -n "${startLine},${endLine}p" $group_file >$single_group
startLine=$(expr "$endLine" + 1)
#type
group_type="$(cfg_get "type:" "$single_group")"
group_type=$(ruby_read_hash "$group_hash" "['proxy-groups'][$count]['type']")
#name
group_name="$(cfg_get "name:" "$single_group")"
#test_url
group_test_url="$(cfg_get "url:" "$single_group")"
#test_interval
group_test_interval="$(cfg_get "interval:" "$single_group")"
#test_tolerance
group_test_tolerance="$(cfg_get "tolerance:" "$single_group")"
group_name=$(ruby_read_hash "$group_hash" "['proxy-groups'][$count]['name']")
echo "正在读取【$CONFIG_NAME】-【$group_type】-【$group_name】策略组配置..." >$START_LOG
if [ -z "$group_type" ] || [ -z "$group_name" ]; then
let count++
continue
fi
echo "正在读取【$CONFIG_NAME】-【$group_type】-【$group_name】策略组配置..." > $START_LOG
name=openclash
uci_name_tmp=$(uci add $name groups)
uci_set="uci -q set $name.$uci_name_tmp."
uci_add="uci -q add_list $name.$uci_name_tmp."
${uci_set}config="$CONFIG_NAME"
${uci_set}name="$group_name"
${uci_set}old_name="$group_name"
${uci_set}old_name_cfg="$group_name"
${uci_set}type="$group_type"
${uci_set}test_url="$group_test_url"
${uci_set}test_interval="$group_test_interval"
${uci_set}tolerance="$group_test_tolerance"
#other_group
cat $single_group |while read -r line
do
if [ -z "$line" ]; then
continue
fi
group_name1=$(echo "$line" |grep -v "name:" 2>/dev/null |grep "^ \{0,\}-" 2>/dev/null |awk -F '^ \{0,\}-' '{print $2}' 2>/dev/null |sed 's/^ \{0,\}//' 2>/dev/null |sed 's/ \{0,\}$//' 2>/dev/null |sed "s/^\'//g" 2>/dev/null |sed "s/\'$//g" 2>/dev/null)
group_name2=$(echo "$line" |awk -F 'proxies: \\[' '{print $2}' 2>/dev/null |sed 's/].*//' 2>/dev/null |sed 's/^ \{0,\}//' 2>/dev/null |sed 's/ \{0,\}$//' 2>/dev/null |sed "s/^\'//g" 2>/dev/null |sed "s/\'$//g" 2>/dev/null |sed 's/ \{0,\}, \{0,\}/#,#/g' 2>/dev/null)
proxies_len=$(sed -n '/proxies:/=' $single_group 2>/dev/null)
use_len=$(sed -n '/use:/=' $single_group 2>/dev/null)
name1_len=$(sed -n "/${group_name1}/=" $single_group 2>/dev/null)
name2_len=$(sed -n "/${group_name2}/=" $single_group 2>/dev/null)
if [ -z "$group_name1" ] && [ -z "$group_name2" ]; then
continue
fi
if [ "$group_type" != "select" ] && [ "$group_type" != "relay" ]; then
if [ "$group_name1" != "DIRECT" ] && [ "$group_name2" != "DIRECT" ] && [ "$group_name1" != "REJECT" ] && [ "$group_name2" != "REJECT" ]; then
continue
fi
fi
if [ ! -z "$group_name1" ] && [ -z "$group_name2" ]; then
if [ "$proxies_len" -le "$use_len" ]; then
if [ "$name1_len" -le "$use_len" ] && [ ! -z "$(grep -F "$group_name1" $match_group_file)" ] && [ "$group_name1" != "$group_name" ]; then
if [ "$group_type" = "select" ] || [ "$group_type" = "relay" ]; then
${uci_add}other_group="$group_name1"
elif [ "$group_name1" = "DIRECT" ] || [ "$group_name1" = "REJECT" ]; then
${uci_add}other_group_dr="$group_name1"
fi
fi
else
if [ "$name1_len" -ge "$proxies_len" ] && [ ! -z "$(grep -F "$group_name1" $match_group_file)" ] && [ "$group_name1" != "$group_name" ]; then
if [ "$group_type" = "select" ] || [ "$group_type" = "relay" ]; then
${uci_add}other_group="$group_name1"
elif [ "$group_name1" = "DIRECT" ] || [ "$group_name1" = "REJECT" ]; then
${uci_add}other_group_dr="$group_name1"
fi
fi
fi 2>/dev/null
elif [ -z "$group_name1" ] && [ ! -z "$group_name2" ]; then
group_num=$(expr $(echo "$group_name2" |grep -c "#,#") + 1)
if [ "$group_num" -le 1 ]; then
if [ ! -z "$(grep -F "$group_name2" $match_group_file)" ] && [ "$group_name2" != "$group_name" ]; then
if [ "$group_type" = "select" ] || [ "$group_type" = "relay" ]; then
${uci_add}other_group="$group_name2"
elif [ "$group_name2" = "DIRECT" ] || [ "$group_name2" = "REJECT" ]; then
${uci_add}other_group_dr="$group_name2"
fi
fi
else
group_nums=1
while [[ "$group_nums" -le "$group_num" ]]
do
other_group_name=$(echo "$group_name2" |awk -v t="${group_nums}" -F '#,#' '{print $t}' 2>/dev/null)
if [ ! -z "$(grep -F "$other_group_name" $match_group_file 2>/dev/null)" ] && [ "$other_group_name" != "$group_name" ]; then
if [ "$group_type" = "select" ] || [ "$group_type" = "relay" ]; then
${uci_add}other_group="$other_group_name"
elif [ "$other_group_name" = "DIRECT" ] || [ "$other_group_name" = "REJECT" ]; then
${uci_add}other_group_dr="$other_group_name"
fi
fi
group_nums=$(expr "$group_nums" + 1)
done
fi
fi
done
file_count=$(expr "$file_count" + 1)
ruby -ryaml -E UTF-8 -e "
begin
Value = $group_hash;
Thread.new{
#strategy
if Value['proxy-groups'][$count].key?('strategy') then
group_strategy = '${uci_set}strategy=' + Value['proxy-groups'][$count]['strategy'].to_s
system(group_strategy)
end
}.join;
Thread.new{
#disable-udp
if Value['proxy-groups'][$count].key?('disable-udp') then
group_disable_udp = '${uci_set}disable_udp=' + Value['proxy-groups'][$count]['disable-udp'].to_s
system(group_disable_udp)
end
}.join;
Thread.new{
#test_url
if Value['proxy-groups'][$count].key?('url') then
group_test_url = '${uci_set}test_url=' + Value['proxy-groups'][$count]['url'].to_s
system(group_test_url)
end
}.join;
Thread.new{
#test_interval
if Value['proxy-groups'][$count].key?('interval') then
group_test_interval = '${uci_set}test_interval=' + Value['proxy-groups'][$count]['interval'].to_s
system(group_test_interval)
end
}.join;
Thread.new{
#test_tolerance
if Value['proxy-groups'][$count].key?('tolerance') then
group_test_tolerance = '${uci_set}tolerance=' + Value['proxy-groups'][$count]['tolerance'].to_s
system(group_test_tolerance)
end
}.join;
Thread.new{
#other_group
Value_1=YAML.load_file('/tmp/Proxy_Group');
if Value['proxy-groups'][$count].key?('proxies') then
Value['proxy-groups'][$count]['proxies'].each{
|x|
if Value_1.include?(x) then
if '$group_type' == 'select' or '$group_type' == 'relay' then
uci = '${uci_add}other_group=\"' + x.to_s + '\"'
system(uci)
elsif x == 'DIRECT' or x == 'REJECT' then
uci = '${uci_add}other_group_dr=' + x.to_s
system(uci)
end
end
}
end
}.join;
rescue Exception => e
puts '${LOGTIME} Resolve Proxy-group【${CONFIG_NAME} - ${group_type} - ${group_name}】 Error: ' + e.message
end
" 2>/dev/null >> $LOG_FILE &
let count++
done
wait
uci commit openclash
/usr/share/openclash/yml_proxys_get.sh

View File

@ -1,8 +1,8 @@
#!/bin/sh
. /usr/share/openclash/ruby.sh
CFG_FILE=$(uci get openclash.config.config_path 2>/dev/null)
UPDATE_CONFIG_FILE=$(uci get openclash.config.config_update_path 2>/dev/null)
GROUP_FILE="/tmp/yaml_group_cache.yaml"
if [ ! -z "$UPDATE_CONFIG_FILE" ]; then
CFG_FILE="$UPDATE_CONFIG_FILE"
@ -13,21 +13,10 @@ if [ -z "$CFG_FILE" ]; then
fi
if [ -f "$CFG_FILE" ]; then
#检查关键字避免后续操作出错
/usr/share/openclash/yml_field_name_ch.sh "$CFG_FILE"
#取出group部分
group_len=$(sed -n '/^proxy-groups:/=' "$CFG_FILE" 2>/dev/null)
if [ -n "$group_len" ]; then
/usr/share/openclash/yml_field_cut.sh "$group_len" "$GROUP_FILE" "$CFG_FILE"
rm -rf /tmp/yaml_general 2>/dev/null
fi 2>/dev/null
cat "$GROUP_FILE" |sed "s/\'//g" 2>/dev/null |sed 's/\"//g' 2>/dev/null |sed 's/\t/ /g' 2>/dev/null |grep name: |awk -F 'name:' '{print $2}' |sed 's/,.*//' |sed 's/^ \{0,\}//' 2>/dev/null |sed 's/ \{0,\}$//' 2>/dev/null |sed 's/ \{0,\}\}\{0,\}$//g' 2>/dev/null >/tmp/Proxy_Group 2>&1
rm -rf "$GROUP_FILE" 2>/dev/null
rm -rf "/tmp/Proxy_Group" 2>/dev/null
ruby_read_hash_arr "$CFG_FILE" "['proxy-groups']" "['name']" >/tmp/Proxy_Group 2>&1
if [ "$?" -eq "0" ]; then
if [ -f "/tmp/Proxy_Group" ]; then
echo 'DIRECT' >>/tmp/Proxy_Group
echo 'REJECT' >>/tmp/Proxy_Group
else

View File

@ -7,7 +7,6 @@ status=$(unify_ps_status "yml_groups_set.sh")
START_LOG="/tmp/openclash_start.log"
GROUP_FILE="/tmp/yaml_groups.yaml"
CONFIG_GROUP_FILE="/tmp/yaml_group.yaml"
CFG_FILE="/etc/config/openclash"
servers_update=$(uci get openclash.config.servers_update 2>/dev/null)
CONFIG_FILE=$(uci get openclash.config.config_path 2>/dev/null)
@ -83,7 +82,7 @@ yml_servers_add()
config_list_foreach "$section" "groups" set_groups "$name" "$2"
fi
if [ ! -z "$if_game_group" ] && [ -z "$(grep -F $name /tmp/yaml_proxy.yaml)" ]; then
if [ ! -z "$if_game_group" ] && [ -z "$(ruby -ryaml -E UTF-8 -e "Value = YAML.load_file('$CONFIG_FILE'); Value['proxies'].each{|x| if x['name'].eql?('$name') then puts x['name'] end}" 2>/dev/null)" ]; then
/usr/share/openclash/yml_proxys_set.sh "$name" "proxy"
fi
fi
@ -120,7 +119,7 @@ set_proxy_provider()
config_list_foreach "$section" "groups" set_provider_groups "$name" "$2"
fi
if [ ! -z "$if_game_group" ] && [ -z "$(grep "^ \{0,\}$name" /tmp/yaml_proxy_provider.yaml)" ]; then
if [ ! -z "$if_game_group" ] && [ -z "$(ruby -ryaml -E UTF-8 -e "Value = YAML.load_file('$CONFIG_FILE'); Value['proxy-providers'].keys.each{|x| if x.eql?('$name') then puts x end}" 2>/dev/null)" ]; then
/usr/share/openclash/yml_proxys_set.sh "$name" "proxy-provider"
fi
fi
@ -147,6 +146,8 @@ yml_groups_set()
config_get "config" "$section" "config" ""
config_get "type" "$section" "type" ""
config_get "name" "$section" "name" ""
config_get "disable_udp" "$section" "disable_udp" ""
config_get "strategy" "$section" "strategy" ""
config_get "old_name" "$section" "old_name" ""
config_get "test_url" "$section" "test_url" ""
config_get "test_interval" "$section" "test_interval" ""
@ -183,13 +184,20 @@ yml_groups_set()
echo " - name: $name" >>$GROUP_FILE
echo " type: $type" >>$GROUP_FILE
if [ "$type" = "load-balance" ]; then
[ -n "$strategy" ] && {
echo " strategy: $strategy" >>$GROUP_FILE
}
fi
[ -n "$disable_udp" ] && {
echo " disable-udp: $disable_udp" >>$GROUP_FILE
}
group_name="$name"
echo " proxies: $group_name" >>$GROUP_FILE
#名字变化时处理规则部分
if [ "$name" != "$old_name" ] && [ ! -z "$old_name" ]; then
sed -i "s/,${old_name}/,${name}#d/g" "$CONFIG_FILE" 2>/dev/null
sed -i "s/:${old_name}$/:${name}#d/g" "$CONFIG_FILE" 2>/dev/null #修改第三方规则分组对应标签
sed -i "s/old_name \'${old_name}/old_name \'${name}/g" "$CFG_FILE" 2>/dev/null
config_load "openclash"
fi
@ -261,7 +269,6 @@ if [ "$create_config" = "0" ] || [ "$servers_if_update" = "1" ] || [ ! -z "$if_g
config_foreach yml_groups_set "groups"
sed -i "s/#d//g" "$CONFIG_FILE" 2>/dev/null
rm -rf /tmp/relay_server.list 2>/dev/null
echo "配置文件【$CONFIG_NAME】的策略组写入完成!" >$START_LOG
fi
fi
if [ -z "$if_game_group" ]; then

View File

@ -1,6 +1,7 @@
#!/bin/sh
. /lib/functions.sh
. /usr/share/openclash/openclash_ps.sh
. /usr/share/openclash/ruby.sh
status=$(unify_ps_status "yml_proxys_set.sh")
[ "$status" -gt "3" ] && exit 0
@ -589,7 +590,7 @@ rm -rf $proxy_provider_name
rule_sources=$(uci get openclash.config.rule_sources 2>/dev/null)
create_config=$(uci get openclash.config.create_config 2>/dev/null)
echo "开始写入配置文件【$CONFIG_NAME】的服务器节点信息..." >$START_LOG
echo "Proxy:" >$SERVER_FILE
echo "proxies:" >$SERVER_FILE
config_foreach yml_servers_set "servers"
egrep '^ {0,}-' $SERVER_FILE |grep name: |awk -F 'name: ' '{print $2}' |sed 's/,.*//' 2>/dev/null >/tmp/Proxy_Server 2>&1
if [ -s "/tmp/Proxy_Server" ]; then
@ -764,6 +765,7 @@ cat /tmp/Proxy_Provider >> $SERVER_FILE 2>/dev/null
cat >> "$SERVER_FILE" <<-EOF
- name: Youtube
type: select
disable-udp: true
proxies:
- GlobalTV
- DIRECT
@ -970,40 +972,23 @@ if [ "$create_config" != "0" ] && [ "$servers_if_update" != "1" ] && [ -z "$if_g
/usr/share/openclash/yml_groups_get.sh >/dev/null 2>&1
elif [ -z "$if_game_proxy" ]; then
echo "服务器、代理集、策略组信息修改完成,正在更新配置文件【$CONFIG_NAME】..." >$START_LOG
#判断各个区位置
proxy_len=$(sed -n '/^Proxy:/=' "$CONFIG_FILE" 2>/dev/null)
group_len=$(sed -n '/^ \{0,\}proxy-groups:/=' "$CONFIG_FILE" 2>/dev/null)
provider_len=$(sed -n '/^proxy-providers:/=' "$CONFIG_FILE" 2>/dev/null)
if [ "$provider_len" -le "$proxy_len" ]; then
sed -i '/^ \{0,\}proxy-providers:/i\#change server#' "$CONFIG_FILE" 2>/dev/null
sed -i '/^ \{0,\}rules:/i\#change server end#' "$CONFIG_FILE" 2>/dev/null
sed -i '/^ \{0,\}proxy-providers:/,/#change server end#/d' "$CONFIG_FILE" 2>/dev/null
elif [ "$provider_len" -le "$group_len" ] && [ -z "$proxy_len" ]; then
sed -i '/^ \{0,\}proxy-providers:/i\#change server#' "$CONFIG_FILE" 2>/dev/null
sed -i '/^ \{0,\}rules:/i\#change server end#' "$CONFIG_FILE" 2>/dev/null
sed -i '/^ \{0,\}proxy-providers:/,/#change server end#/d' "$CONFIG_FILE" 2>/dev/null
elif [ "$provider_len" -ge "$group_len" ] && [ -z "$proxy_len" ]; then
sed -i '/^ \{0,\}proxy-groups:/i\#change server#' "$CONFIG_FILE" 2>/dev/null
sed -i '/^ \{0,\}rules:/i\#change server end#' "$CONFIG_FILE" 2>/dev/null
sed -i '/^ \{0,\}proxy-groups:/,/#change server end#/d' "$CONFIG_FILE" 2>/dev/null
config_hash=$(ruby -ryaml -E UTF-8 -e "Value = YAML.load_file('$CONFIG_FILE'); puts Value" 2>/dev/null)
if [ "$config_hash" != "false" ] && [ -n "$config_hash" ]; then
ruby_cover "$CONFIG_FILE" "['proxies']" "$SERVER_FILE" "['proxies']"
ruby_cover "$CONFIG_FILE" "['proxy-providers']" "$PROXY_PROVIDER_FILE" "['proxy-providers']"
ruby_cover "$CONFIG_FILE" "['proxy-groups']" "/tmp/yaml_groups.yaml" "['proxy-groups']"
else
sed -i '/^ \{0,\}Proxy:/i\#change server#' "$CONFIG_FILE" 2>/dev/null
sed -i '/^ \{0,\}rules:/i\#change server end#' "$CONFIG_FILE" 2>/dev/null
sed -i '/^ \{0,\}Proxy:/,/#change server end#/d' "$CONFIG_FILE" 2>/dev/null
cat "$SERVER_FILE" "$PROXY_PROVIDER_FILE" "/tmp/yaml_groups.yaml" > "$CONFIG_FILE" 2>/dev/null
fi
sed -i '/#change server#/r/tmp/yaml_groups.yaml' "$CONFIG_FILE" 2>/dev/null
sed -i '/#change server#/r/tmp/yaml_servers.yaml' "$CONFIG_FILE" 2>/dev/null
sed -i '/#change server#/r/tmp/yaml_provider.yaml' "$CONFIG_FILE" 2>/dev/null
sed -i '/#change server#/d' "$CONFIG_FILE" 2>/dev/null
fi
echo "配置文件【$CONFIG_NAME】写入完成!" >$START_LOG
sleep 3
echo "" >$START_LOG
if [ -z "$if_game_proxy" ]; then
rm -rf $SERVER_FILE 2>/dev/null
rm -rf $PROXY_PROVIDER_FILE 2>/dev/null
rm -rf /tmp/yaml_groups.yaml 2>/dev/null
echo "配置文件【$CONFIG_NAME】写入完成!" >$START_LOG
sleep 3
echo "" >$START_LOG
fi
rm -rf /tmp/Proxy_Server 2>/dev/null
rm -rf /tmp/Proxy_Provider 2>/dev/null

View File

@ -1,92 +1,100 @@
#!/bin/bash
SCRIPT_FILE="/tmp/yaml_script.yaml"
RULE_PROVIDER_FILE="/tmp/yaml_rule_provider.yaml"
OTHER_RULE_PROVIDER_FILE="/tmp/other_rule_provider.yaml"
OTHER_RULE_FILE="/tmp/other_rule.yaml"
RULE_PROVIDER_BAK_FILE="/tmp/yaml_rule_provider_bak.yaml"
RULE_BAK_FILE="/tmp/yaml_rules_bak.yaml"
SCRIPT_BAK_FILE="/tmp/yaml_script_bak.yaml"
check_def=0
#!/bin/sh
. /lib/functions.sh
. /usr/share/openclash/ruby.sh
/usr/share/openclash/yml_groups_name_get.sh
LOGTIME=$(date "+%Y-%m-%d %H:%M:%S")
LOG_FILE="/tmp/openclash.log"
yml_other_set()
{
sed -i "s/'//g" "$4" 2>/dev/null
sed -i '/^##Custom Rules##/,/^##Custom Rules End##/d' "$4" 2>/dev/null
sed -i '/^##Custom Rules##/d' "$4" 2>/dev/null
sed -i '/^##Custom Rules End##/d' "$4" 2>/dev/null
sed -i '/^##Custom Rules 2##/,/^##Custom Rules 2 End##/d' "$4" 2>/dev/null
sed -i '/^##Custom Rules 2##/d' "$4" 2>/dev/null
sed -i '/^##Custom Rules 2 End##/d' "$4" 2>/dev/null
sed -i '/- DOMAIN-KEYWORD,tracker,DIRECT/d' "$4" 2>/dev/null
sed -i '/- DOMAIN-KEYWORD,announce.php?passkey=,DIRECT/d' "$4" 2>/dev/null
sed -i '/- DOMAIN-KEYWORD,torrent,DIRECT/d' "$4" 2>/dev/null
sed -i '/- DOMAIN-KEYWORD,peer_id=,DIRECT/d' "$4" 2>/dev/null
sed -i '/- DOMAIN-KEYWORD,info_hash,DIRECT/d' "$4" 2>/dev/null
sed -i '/- DOMAIN-KEYWORD,get_peers,DIRECT/d' "$4" 2>/dev/null
sed -i '/- DOMAIN-KEYWORD,find_node,DIRECT/d' "$4" 2>/dev/null
sed -i '/- DOMAIN-KEYWORD,BitTorrent,DIRECT/d' "$4" 2>/dev/null
sed -i '/- DOMAIN-KEYWORD,announce_peer,DIRECT/d' "$4" 2>/dev/null
if [ -z "$(grep '^ \{0,\}- IP-CIDR,198.18.0.1/16,REJECT,no-resolve' "$4")" ]; then
if [ ! -z "$(grep "^ \{0,\}- IP-CIDR,198.18.0.1/16" "$4")" ]; then
sed -i "/^ \{0,\}- IP-CIDR,198.18.0.1\/16/c\- IP-CIDR,198.18.0.1\/16,REJECT,no-resolve" "$4" 2>/dev/null
else
sed -i '1,/^ \{0,\}- GEOIP/{/^ \{0,\}- GEOIP/s/^ \{0,\}- GEOIP/- IP-CIDR,198.18.0.1\/16,REJECT,no-resolve\n&/}' "$4" 2>/dev/null
if [ -z "$(grep '^- IP-CIDR,198.18.0.1/16,REJECT,no-resolve' "$4")" ]; then
sed -i '1,/^ \{0,\}- MATCH/{/^ \{0,\}- MATCH/s/^ \{0,\}- MATCH/- IP-CIDR,198.18.0.1\/16,REJECT,no-resolve\n&/}' "$4" 2>/dev/null
fi
fi
fi
if [ "$7" = 1 ]; then
sed -i '1,/^ \{0,\}- GEOIP/{/^ \{0,\}- GEOIP/s/^ \{0,\}- GEOIP/- DOMAIN-KEYWORD,tracker,DIRECT\n&/}' "$4" 2>/dev/null
if [ -z "$(grep '^- DOMAIN-KEYWORD,tracker,DIRECT' "$4")" ]; then
sed -i '1,/^ \{0,\}- MATCH/{/^ \{0,\}- MATCH/s/^ \{0,\}- MATCH/- DOMAIN-KEYWORD,tracker,DIRECT\n&/}' "$4" 2>/dev/null
fi
if [ -z "$(grep '^- DOMAIN-KEYWORD,tracker,DIRECT' "$4")" ]; then
echo "- DOMAIN-KEYWORD,tracker,DIRECT" >> "$4" 2>/dev/null
fi
sed -i "/- DOMAIN-KEYWORD,tracker,DIRECT/a\- DOMAIN-KEYWORD,announce.php?passkey=,DIRECT" "$4" 2>/dev/null
sed -i "/- DOMAIN-KEYWORD,tracker,DIRECT/a\- DOMAIN-KEYWORD,torrent,DIRECT" "$4" 2>/dev/null
sed -i "/- DOMAIN-KEYWORD,tracker,DIRECT/a\- DOMAIN-KEYWORD,peer_id=,DIRECT" "$4" 2>/dev/null
sed -i "/- DOMAIN-KEYWORD,tracker,DIRECT/a\- DOMAIN-KEYWORD,info_hash,DIRECT" "$4" 2>/dev/null
sed -i "/- DOMAIN-KEYWORD,tracker,DIRECT/a\- DOMAIN-KEYWORD,get_peers,DIRECT" "$4" 2>/dev/null
sed -i "/- DOMAIN-KEYWORD,tracker,DIRECT/a\- DOMAIN-KEYWORD,find_node,DIRECT" "$4" 2>/dev/null
sed -i "/- DOMAIN-KEYWORD,tracker,DIRECT/a\- DOMAIN-KEYWORD,BitTorrent,DIRECT" "$4" 2>/dev/null
sed -i "/- DOMAIN-KEYWORD,tracker,DIRECT/a\- DOMAIN-KEYWORD,announce_peer,DIRECT" "$4" 2>/dev/null
if [ -z "$(grep "###- MATCH," "$4")" ] && [ -z "$(grep "###- FINAL," "$4")" ]; then
sed -i 's/- MATCH,/###&/' "$4" 2>/dev/null
echo "- MATCH,DIRECT" >> "$4" 2>/dev/null
fi
ruby -ryaml -E UTF-8 -e "
begin
Value = YAML.load_file('$4');
rescue Exception => e
puts '${LOGTIME} Load File Error: ' + e.message
end
begin
if $3 == 1 then
if Value.has_key?('rules') and not Value['rules'].to_a.empty? then
if File::exist?('/etc/openclash/custom/openclash_custom_rules.list') then
Value_1 = YAML.load_file('/etc/openclash/custom/openclash_custom_rules.list')
if Value_1 != false then
Value_2 = Value_1.reverse!
Value_2.each{|x| Value['rules'].insert(0,x)}
Value['rules']=Value['rules'].uniq
end
end
if File::exist?('/etc/openclash/custom/openclash_custom_rules_2.list') then
Value_3 = YAML.load_file('/etc/openclash/custom/openclash_custom_rules_2.list')
if Value_3 != false then
ruby_add_index = Value['rules'].index(Value['rules'].grep(/(GEOIP|MATCH|FINAL)/).first)
ruby_add_index ||= -1
Value_4 = Value_3.reverse!
Value_4.each{|x| Value['rules'].insert(ruby_add_index,x)}
Value['rules']=Value['rules'].uniq
end
end
else
if [ ! -z "$(grep "###- MATCH," "$4")" ] || [ ! -z "$(grep "###- FINAL," "$4")" ]; then
sed -i '/^- MATCH,DIRECT/d' "$4" 2>/dev/null
sed -i "s/###- MATCH,/- MATCH,/" "$4" 2>/dev/null
fi
fi
if [ "$3" = 1 ]; then
sed -i '/^rules:/a\##Custom Rules End##' "$4" 2>/dev/null
sed -i '/^rules:/a\##Custom Rules##' "$4" 2>/dev/null
sed -i '/^##Custom Rules##/r/etc/openclash/custom/openclash_custom_rules.list' "$4" 2>/dev/null
sed -i '/^ \{0,\}- MATCH,/i\##Custom Rules 2##' "$4" 2>/dev/null
if [ -z "$(grep '^##Custom Rules 2##' "$4")" ]; then
echo "##Custom Rules 2##" >> "$4" 2>/dev/null
fi
sed -i '/^##Custom Rules 2##/a\##Custom Rules 2 End##' "$4" 2>/dev/null
sed -i '/^##Custom Rules 2##/r/etc/openclash/custom/openclash_custom_rules_2.list' "$4" 2>/dev/null
fi
if [ "$5" = 1 ] || [ "$3" = 1 ] || [ "$7" = 1 ] || [ -z "$(grep '- IP-CIDR,198.18.0.1/16,REJECT,no-resolve' "$4")" ]; then
sed -i "s/^ \{0,\}-/-/" "$4" 2>/dev/null #修改参数空格
sed -i "s/^\t\{0,\}-/-/" "$4" 2>/dev/null #修改参数tab
fi
if File::exist?('/etc/openclash/custom/openclash_custom_rules.list') then
Value_1 = YAML.load_file('/etc/openclash/custom/openclash_custom_rules.list')
if Value_1 != false then
Value['rules']=Value_1
Value['rules']=Value['rules'].uniq
end
end
if File::exist?('/etc/openclash/custom/openclash_custom_rules_2.list') then
Value_2 = YAML.load_file('/etc/openclash/custom/openclash_custom_rules_2.list')
if Value_2 != false then
if Value['rules'].to_a.empty? then
Value['rules']=Value_2
else
ruby_add_index = Value['rules'].index(Value['rules'].grep(/(GEOIP|MATCH|FINAL)/).first)
ruby_add_index ||= -1
Value_3 = Value_2.reverse!
Value_3.each{|x| Value['rules'].insert(ruby_add_index,x)}
end
Value['rules']=Value['rules'].uniq
end
end
end
end;
rescue Exception => e
puts '${LOGTIME} Set Custom Rules Error: ' + e.message
end
begin
if $7 == 1 and Value.has_key?('rules') then
ruby_add_index = Value['rules'].index(Value['rules'].grep(/(GEOIP|MATCH|FINAL)/).first)
ruby_add_index ||= -1
Value['rules']=Value['rules'].to_a.insert(ruby_add_index,
'DOMAIN-KEYWORD,tracker,DIRECT',
'DOMAIN-KEYWORD,announce.php?passkey=,DIRECT',
'DOMAIN-KEYWORD,torrent,DIRECT',
'DOMAIN-KEYWORD,peer_id=,DIRECT',
'DOMAIN-KEYWORD,info_hash,DIRECT',
'DOMAIN-KEYWORD,get_peers,DIRECT',
'DOMAIN-KEYWORD,find_node,DIRECT',
'DOMAIN-KEYWORD,BitTorrent,DIRECT',
'DOMAIN-KEYWORD,announce_peer,DIRECT'
)
Value['rules'].to_a.collect!{|x|x.to_s.gsub(/(^MATCH.*|^FINAL.*)/, 'MATCH,DIRECT')}
end;
rescue Exception => e
puts '${LOGTIME} Set Bt DIRECT Rules Error: ' + e.message
end
begin
if Value.has_key?('rules') and Value['rules'].to_a.grep(/(?=.*198.18)(?=.*REJECT)/).empty? then
ruby_add_index = Value['rules'].index(Value['rules'].grep(/(GEOIP|MATCH|FINAL)/).first)
ruby_add_index ||= -1
Value['rules']=Value['rules'].to_a.insert(ruby_add_index,'IP-CIDR,198.18.0.1/16,REJECT,no-resolve')
end;
rescue Exception => e
puts '${LOGTIME} Set 198.18.0.1/16 REJECT Rule Error: ' + e.message
ensure
File.open('$4','w') {|f| YAML.dump(Value, f)}
end" 2>/dev/null >> $LOG_FILE
}
if [ "$2" != 0 ]; then
#判断策略组是否存在
GlobalTV=$(uci get openclash.config.GlobalTV 2>/dev/null)
@ -106,38 +114,38 @@ if [ "$2" != 0 ]; then
Domestic=$(uci get openclash.config.Domestic 2>/dev/null)
Others=$(uci get openclash.config.Others 2>/dev/null)
if [ "$2" = "ConnersHua_return" ]; then
if [ -z "$(grep "$Proxy" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$Others" /tmp/Proxy_Group)" ];then
if [ -z "$(grep -F "$Proxy" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$Others" /tmp/Proxy_Group)" ];then
echo "${1} Warning: Because of The Different Porxy-Group's Name, Stop Setting The Other Rules!" >>/tmp/openclash.log
yml_other_set "$1" "$2" "$3" "$4" "$5" "$6" "$7"
exit 0
fi
elif [ "$2" = "ConnersHua" ]; then
if [ -z "$(grep "$GlobalTV" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$AsianTV" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$Proxy" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$Others" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$Domestic" /tmp/Proxy_Group)" ]; then
|| [ -z "$(grep -F "$AsianTV" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$Proxy" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$Others" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$Domestic" /tmp/Proxy_Group)" ]; then
echo "${1} Warning: Because of The Different Porxy-Group's Name, Stop Setting The Other Rules!" >>/tmp/openclash.log
yml_other_set "$1" "$2" "$3" "$4" "$5" "$6" "$7"
exit 0
fi
elif [ "$2" = "lhie1" ]; then
if [ -z "$(grep "$GlobalTV" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$AsianTV" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$Proxy" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$Youtube" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$Apple" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$Netflix" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$Spotify" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$Steam" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$AdBlock" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$Speedtest" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$Telegram" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$Microsoft" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$PayPal" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$Others" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$Domestic" /tmp/Proxy_Group)" ]; then
if [ -z "$(grep -F "$GlobalTV" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$AsianTV" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$Proxy" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$Youtube" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$Apple" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$Netflix" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$Spotify" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$Steam" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$AdBlock" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$Speedtest" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$Telegram" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$Microsoft" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$PayPal" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$Others" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$Domestic" /tmp/Proxy_Group)" ]; then
echo "${1} Warning: Because of The Different Porxy-Group's Name, Stop Setting The Other Rules!" >>/tmp/openclash.log
yml_other_set "$1" "$2" "$3" "$4" "$5" "$6" "$7"
exit 0
@ -148,240 +156,110 @@ if [ "$2" != 0 ]; then
yml_other_set "$1" "$2" "$3" "$4" "$5" "$6" "$7"
exit 0
else
rulesource=$(grep '##source:' "$4" |awk -F ':' '{print $2}')
[ "$rulesource" != "$2" ] && {
check_def=1
}
[ "$check_def" -ne 1 ] && {
grep "^##updated$" /usr/share/openclash/res/"$2".yaml 1>/dev/null
[ "$?" -eq 0 ] && {
sed -i '/^##updated$/d' /usr/share/openclash/res/"$2".yaml
check_def=1
}
}
[ "$check_def" -ne 1 ] && {
GlobalTV_YAML=$(grep '##GlobalTV:' "$4" |awk -F ':' '{print $2}')
AsianTV_YAML=$(grep '##AsianTV:' "$4" |awk -F ':' '{print $2}')
Proxy_YAML=$(grep '##Proxy:' "$4" |awk -F ':' '{print $2}')
Youtube_YAML=$(grep '##Youtube:' "$4" |awk -F ':' '{print $2}')
Apple_YAML=$(grep '##Apple:' "$4" |awk -F ':' '{print $2}')
Netflix_YAML=$(grep '##Netflix:' "$4" |awk -F ':' '{print $2}')
Spotify_YAML=$(grep '##Spotify:' "$4" |awk -F ':' '{print $2}')
Steam_YAML=$(grep '##Steam:' "$4" |awk -F ':' '{print $2}')
AdBlock_YAML=$(grep '##AdBlock:' "$4" |awk -F ':' '{print $2}')
Others_YAML=$(grep '##Others:' "$4" |awk -F ':' '{print $2}')
Domestic_YAML=$(grep '##Domestic:' "$4" |awk -F ':' '{print $2}')
Speedtest_YAML=$(grep '##Speedtest:' "$4" |awk -F ':' '{print $2}')
Telegram_YAML=$(grep '##Telegram:' "$4" |awk -F ':' '{print $2}')
PayPal_YAML=$(grep '##PayPal:' "$4" |awk -F ':' '{print $2}')
Microsoft_YAML=$(grep '##Microsoft:' "$4" |awk -F ':' '{print $2}')
if [ "$2" = "ConnersHua_return" ]; then
if [ "$Proxy" != "$Proxy_YAML" ]\
|| [ "$Others" != "$Others_YAML" ];then
check_def=1
fi
elif [ "$2" = "ConnersHua" ]; then
if [ "$GlobalTV" != "$GlobalTV_YAML" ]\
|| [ "$AsianTV" != "$AsianTV_YAML" ]\
|| [ "$Proxy" != "$Proxy_YAML" ]\
|| [ "$Others" != "$Others_YAML" ]\
|| [ "$Domestic" != "$Domestic_YAML" ]; then
check_def=1
#删除原有的部分,防止冲突
if [ -n "$(ruby_read "$4" "['script']")" ]; then
ruby_edit "$4" "['script'].clear"
fi
elif [ "$2" = "lhie1" ]; then
if [ "$GlobalTV" != "$GlobalTV_YAML" ]\
|| [ "$AsianTV" != "$AsianTV_YAML" ]\
|| [ "$Proxy" != "$Proxy_YAML" ]\
|| [ "$Youtube" != "$Youtube_YAML" ]\
|| [ "$Apple" != "$Apple_YAML" ]\
|| [ "$Netflix" != "$Netflix_YAML" ]\
|| [ "$Spotify" != "$Spotify_YAML" ]\
|| [ "$Steam" != "$Steam_YAML" ]\
|| [ "$AdBlock" != "$AdBlock_YAML" ]\
|| [ "$Speedtest" != "$Speedtest_YAML" ]\
|| [ "$Telegram" != "$Telegram_YAML" ]\
|| [ "$Microsoft" != "$Microsoft_YAML" ]\
|| [ "$PayPal" != "$PayPal_YAML" ]\
|| [ "$Others" != "$Others_YAML" ]\
|| [ "$Domestic" != "$Domestic_YAML" ]; then
check_def=1
if [ -n "$(ruby_read "$4" "['rules']")" ]; then
ruby_edit "$4" "['rules'].clear"
fi
fi
}
if [ "$check_def" -eq 1 ]; then
sed -i '/^rules:/,$d' "$4" 2>/dev/null
sed -i '/##Other-rule-providers##/,/##Other-rule-providers-end##/d' "$9" 2>/dev/null
if [ "$2" = "lhie1" ]; then
#删除原有的script部分防止冲突
rm -rf "$SCRIPT_FILE" 2>/dev/null
cp /usr/share/openclash/res/lhie1.yaml "$OTHER_RULE_PROVIDER_FILE"
sed -n '/^ \{0,\}rules:/,$p' "$OTHER_RULE_PROVIDER_FILE" > "$OTHER_RULE_FILE" 2>/dev/null
sed -i '/^ \{0,\}rules:/,$d' "$OTHER_RULE_PROVIDER_FILE" 2>/dev/null
sed -n '/^ \{0,\}script:/,$p' "$OTHER_RULE_PROVIDER_FILE" > "$SCRIPT_FILE" 2>/dev/null
sed -i '/^ \{0,\}script:/,$d' "$OTHER_RULE_PROVIDER_FILE" 2>/dev/null
sed -i "/^ \{0,\}script:/c\script:" "$SCRIPT_FILE" 2>/dev/null
sed -i "/^ \{0,\}rules:/c\rules:" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/^ \{0,\}rule-providers:/c\rule-providers:" "$OTHER_RULE_PROVIDER_FILE" 2>/dev/null
echo "##Other-rule-providers-end##" >> "$OTHER_RULE_PROVIDER_FILE"
if [ -z "$(sed -n '/^ \{0,\}rule-providers:/=' "$9" 2>/dev/null)" ]; then
sed -i "s/,GlobalTV$/,${GlobalTV}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/: \"GlobalTV\"/: \"${GlobalTV}#d\"/g" "$SCRIPT_FILE" 2>/dev/null
sed -i "s/,GlobalTV,no-resolve$/,${GlobalTV},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##GlobalTV:${GlobalTV}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,AsianTV$/,${AsianTV}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/: \"AsianTV\"/: \"${AsianTV}#d\"/g" "$SCRIPT_FILE" 2>/dev/null
sed -i "s/,AsianTV,no-resolve$/,${AsianTV},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##AsianTV:${AsianTV}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,Proxy$/,${Proxy}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/: \"Proxy\"/: \"${Proxy}#d\"/g" "$SCRIPT_FILE" 2>/dev/null
sed -i "s/,Proxy,no-resolve$/,${Proxy},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##Proxy:${Proxy}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,YouTube$/,${Youtube}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/: \"YouTube\"/: \"${Youtube}#d\"/g" "$SCRIPT_FILE" 2>/dev/null
sed -i "s/,YouTube,no-resolve$/,${Youtube},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##Youtube:${Youtube}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,Apple$/,${Apple}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/: \"Apple\"/: \"${Apple}#d\"/g" "$SCRIPT_FILE" 2>/dev/null
sed -i "s/,Apple,no-resolve$/,${Apple},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##Apple:${Apple}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,Netflix$/,${Netflix}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/: \"Netflix\"/: \"${Netflix}#d\"/g" "$SCRIPT_FILE" 2>/dev/null
sed -i "s/,Netflix,no-resolve$/,${Netflix},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##Netflix:${Netflix}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,Spotify$/,${Spotify}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/: \"Spotify\"/: \"${Spotify}#d\"/g" "$SCRIPT_FILE" 2>/dev/null
sed -i "s/,Spotify,no-resolve$/,${Spotify},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##Spotify:${Spotify}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,Steam$/,${Steam}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/: \"Steam\"/: \"${Steam}#d\"/g" "$SCRIPT_FILE" 2>/dev/null
sed -i "s/,Steam,no-resolve$/,${Steam},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##Steam:${Steam}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,AdBlock$/,${AdBlock}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/: \"AdBlock\"/: \"${AdBlock}#d\"/g" "$SCRIPT_FILE" 2>/dev/null
sed -i "s/,AdBlock,no-resolve$/,${AdBlock},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##AdBlock:${AdBlock}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,Speedtest$/,${Speedtest}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/: \"Speedtest\"/: \"${Speedtest}#d\"/g" "$SCRIPT_FILE" 2>/dev/null
sed -i "s/,Speedtest$/,${Speedtest},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##Speedtest:${Speedtest}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,Telegram$/,${Telegram}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/: \"Telegram\"/: \"${Telegram}#d\"/g" "$SCRIPT_FILE" 2>/dev/null
sed -i "s/,Telegram$/,${Telegram},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##Telegram:${Telegram}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,Microsoft$/,${Microsoft}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/: \"Microsoft\"/: \"${Microsoft}#d\"/g" "$SCRIPT_FILE" 2>/dev/null
sed -i "s/,Microsoft$/,${Microsoft},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##Microsoft:${Microsoft}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,PayPal$/,${PayPal}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/: \"PayPal\"/: \"${PayPal}#d\"/g" "$SCRIPT_FILE" 2>/dev/null
sed -i "s/,PayPal$/,${PayPal},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##PayPal:${PayPal}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,Domestic$/,${Domestic}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/: \"Domestic\"/: \"${Domestic}#d\"/g" "$SCRIPT_FILE" 2>/dev/null
sed -i "s/return \"Domestic\"$/return \"${Domestic}#d\"/g" "$SCRIPT_FILE" 2>/dev/null
sed -i "s/,Domestic$/,${Domestic},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##Domestic:${Domestic}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,Others$/,${Others}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/: \"Others\"/: \"${Others}#d\"/g" "$SCRIPT_FILE" 2>/dev/null
sed -i "s/return \"Others\"$/return \"${Others}#d\"/g" "$SCRIPT_FILE" 2>/dev/null
sed -i "s/,Others$/,${Others},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##Others:${Others}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/#d//g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/#d//g" "$SCRIPT_FILE" 2>/dev/null
sed -i "/^rule-providers:/c\rule-providers: ##Other-rule-providers##" "$OTHER_RULE_PROVIDER_FILE" 2>/dev/null
cat "$OTHER_RULE_PROVIDER_FILE" >> "$9" 2>/dev/null
else
#处理缩进
sed -i '/^ *$/d' "$9" 2>/dev/null
sed -i 's/\t/ /g' "$9" 2>/dev/null
sed -i '/^ \{0,\}#/d' "$9" 2>/dev/null
sed -i 's/^ \{1,\}/ /g' "$9" 2>/dev/null
sed -i 's/^ \{1,\}type:/ type:/g' "$9" 2>/dev/null
sed -i 's/^ \{1,\}behavior:/ behavior:/g' "$9" 2>/dev/null
sed -i 's/^ \{1,\}path:/ path:/g' "$9" 2>/dev/null
sed -i 's/^ \{1,\}url:/ url:/g' "$9" 2>/dev/null
sed -i 's/^ \{1,\}interval:/ interval:/g' "$9" 2>/dev/null
sed -i 's/^ \{1,\}rule-providers:/rule-providers:/g' "$9" 2>/dev/null
sed -i '/^ \{0,\}rule-providers:/a\##Other-rule-providers##' "$OTHER_RULE_PROVIDER_FILE" 2>/dev/null
sed -i '/^ \{0,\}rule-providers:/d' "$OTHER_RULE_PROVIDER_FILE" 2>/dev/null
sed -i '/rule-providers:/r/tmp/other_rule_provider.yaml' "$9" 2>/dev/null
fi
ruby -ryaml -E UTF-8 -e "
begin
Value = YAML.load_file('$4');
Value_1 = YAML.load_file('/usr/share/openclash/res/lhie1.yaml');
if Value_1.has_key?('rule-providers') and not Value_1['rule-providers'].to_a.empty? then
if Value.has_key?('rule-providers') and not Value['rule-providers'].to_a.empty? then
Value['rule-providers'].merge!(Value_1['rule-providers'])
else
Value['rule-providers']=Value_1['rule-providers']
end
end;
Value['script']=Value_1['script'];
Value['rules']=Value_1['rules'];
Value['rules'].to_a.collect!{|x|
x.to_s.gsub(/,GlobalTV$/, ',$GlobalTV#d')
.gsub(/,AsianTV$/, ',$AsianTV#d')
.gsub(/,Proxy$/, ',$Proxy#d')
.gsub(/,YouTube$/, ',$Youtube#d')
.gsub(/,Apple$/, ',$Apple#d')
.gsub(/,Netflix$/, ',$Netflix#d')
.gsub(/,Spotify$/, ',$Spotify#d')
.gsub(/,Steam$/, ',$Steam#d')
.gsub(/,AdBlock$/, ',$AdBlock#d')
.gsub(/,Speedtest$/, ',$Speedtest#d')
.gsub(/,Telegram$/, ',$Telegram#d')
.gsub(/,Microsoft$/, ',$Microsoft#d')
.to_s.gsub(/,PayPal$/, ',$PayPal#d')
.gsub(/,Domestic$/, ',$Domestic#d')
.gsub(/,Others$/, ',$Others#d')
.gsub(/#d/, '')
};
Value['script']['code'].to_s.gsub!(/: \"GlobalTV\"/,': \"$GlobalTV#d\"')
.gsub!(/: \"AsianTV\"/,': \"$AsianTV#d\"')
.gsub!(/: \"Proxy\"/,': \"$Proxy#d\"')
.gsub!(/: \"YouTube\"/,': \"$Youtube#d\"')
.gsub!(/: \"Apple\"/,': \"$Apple#d\"')
.gsub!(/: \"Netflix\"/,': \"$Netflix#d\"')
.gsub!(/: \"Spotify\"/,': \"$Spotify#d\"')
.gsub!(/: \"Steam\"/,': \"$Steam#d\"')
.gsub!(/: \"AdBlock\"/,': \"$AdBlock#d\"')
.gsub!(/: \"Speedtest\"/,': \"$Speedtest#d\"')
.gsub!(/: \"Telegram\"/,': \"$Telegram#d\"')
.gsub!(/: \"Microsoft\"/,': \"$Microsoft#d\"')
.gsub!(/: \"PayPal\"/,': \"$PayPal#d\"')
.gsub!(/: \"Domestic\"/,': \"$Domestic#d\"')
.gsub!(/return \"Domestic\"$/, 'return \"$Domestic#d\"')
.gsub!(/return \"Others\"$/, 'return \"$Others#d\"')
.gsub!(/#d/, '');
File.open('$4','w') {|f| YAML.dump(Value, f)};
rescue Exception => e
puts '${LOGTIME} Set lhie1 Rules Error: ' + e.message
end" 2>/dev/null >> $LOG_FILE
elif [ "$2" = "ConnersHua" ]; then
cp /usr/share/openclash/res/ConnersHua.yaml "$OTHER_RULE_PROVIDER_FILE"
sed -n '/^rules:/,$p' "$OTHER_RULE_PROVIDER_FILE" > "$OTHER_RULE_FILE" 2>/dev/null
sed -i '/^rules:/,$d' "$OTHER_RULE_PROVIDER_FILE" 2>/dev/null
sed -i "/^ \{0,\}rule-providers:/c\rule-providers:" "$OTHER_RULE_PROVIDER_FILE" 2>/dev/null
echo "##Other-rule-providers-end##" >> "$OTHER_RULE_PROVIDER_FILE"
if [ -z "$(sed -n '/^ \{0,\}rule-providers:/=' "$9" 2>/dev/null)" ]; then
sed -i "s/,Streaming$/,${GlobalTV}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,Streaming,no-resolve$/,${GlobalTV},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##GlobalTV:${GlobalTV}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,StreamingSE$/,${AsianTV}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,StreamingSE,no-resolve$/,${AsianTV},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##AsianTV:${AsianTV}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,PROXY$/,${Proxy}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,PROXY,no-resolve$/,${Proxy},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,IP-Blackhole$/,${Proxy}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,IP-Blackhole,no-resolve$/,${Proxy},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##Proxy:${Proxy}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,China,DIRECT$/,China,${Domestic}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,China,DIRECT,no-resolve$/,China,${Domestic},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,ChinaIP,DIRECT$/,ChinaIP,${Domestic}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,ChinaIP,DIRECT,no-resolve$/,ChinaIP,${Domestic},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,CN,DIRECT$/,CN,${Domestic}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,CN,DIRECT,no-resolve$/,CN,${Domestic},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##Domestic:${Domestic}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,MATCH$/,${Others}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,MATCH,no-resolve$/,${Others},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##Others:${Others}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/#d//g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/^rule-providers:/c\rule-providers: ##Other-rule-providers##" "$OTHER_RULE_PROVIDER_FILE" 2>/dev/null
cat "$OTHER_RULE_PROVIDER_FILE" >> "$9" 2>/dev/null
else
#处理缩进
sed -i '/^ *$/d' "$9" 2>/dev/null
sed -i 's/\t/ /g' "$9" 2>/dev/null
sed -i '/^ \{0,\}#/d' "$9" 2>/dev/null
sed -i 's/^ \{1,\}/ /g' "$9" 2>/dev/null
sed -i 's/^ \{1,\}type:/ type:/g' "$9" 2>/dev/null
sed -i 's/^ \{1,\}behavior:/ behavior:/g' "$9" 2>/dev/null
sed -i 's/^ \{1,\}path:/ path:/g' "$9" 2>/dev/null
sed -i 's/^ \{1,\}url:/ url:/g' "$9" 2>/dev/null
sed -i 's/^ \{1,\}interval:/ interval:/g' "$9" 2>/dev/null
sed -i 's/^ \{1,\}rule-providers:/rule-providers:/g' "$9" 2>/dev/null
sed -i '/^ \{0,\}rule-providers:/a\##Other-rule-providers##' "$OTHER_RULE_PROVIDER_FILE" 2>/dev/null
sed -i '/^ \{0,\}rule-providers:/d' "$OTHER_RULE_PROVIDER_FILE" 2>/dev/null
sed -i '/rule-providers:/r/tmp/other_rule_provider.yaml' "$9" 2>/dev/null
fi
ruby -ryaml -E UTF-8 -e "
begin
Value = YAML.load_file('$4');
Value_1 = YAML.load_file('/usr/share/openclash/res/ConnersHua.yaml');
if Value_1.has_key?('rule-providers') and not Value_1['rule-providers'].to_a.empty? then
if Value.has_key?('rule-providers') and not Value['rule-providers'].to_a.empty? then
Value['rule-providers'].merge!(Value_1['rule-providers'])
else
Value['rule-providers']=Value_1['rule-providers']
end
end;
Value['rules']=Value_1['rules'];
Value['rules'].to_a.collect!{|x|
x.to_s.gsub(/,Streaming$/, ',$GlobalTV#d')
.gsub(/,StreamingSE$/, ',$AsianTV#d')
.gsub(/(,PROXY$|,IP-Blackhole$)/, ',$Proxy#d')
.gsub(/,China,DIRECT$/, ',China,$Domestic#d')
.gsub(/,ChinaIP,DIRECT$/, ',ChinaIP,$Domestic#d')
.gsub(/,CN,DIRECT$/, ',CN,$Domestic#d')
.gsub(/,MATCH$/, ',$Others#d')
.gsub(/#d/, '')
};
File.open('$4','w') {|f| YAML.dump(Value, f)};
rescue Exception => e
puts '${LOGTIME} Set lhie1 Rules Error: ' + e.message
end" 2>/dev/null >> $LOG_FILE
else
cp /usr/share/openclash/res/ConnersHua_return.yaml "$OTHER_RULE_FILE"
sed -i "s/,PROXY$/,${Proxy}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,PROXY,no-resolve$/,${Proxy},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##Proxy:${Proxy}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,DIRECT$/,${Others}#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/,DIRECT,no-resolve$/,${Others},no-resolve#d/g" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "/rules:/a\##Others:${Others}" "$OTHER_RULE_FILE" 2>/dev/null
sed -i "s/#d//g" "$OTHER_RULE_FILE" 2>/dev/null
ruby -ryaml -E UTF-8 -e "
begin
Value = YAML.load_file('$4');
Value_1 = YAML.load_file('/usr/share/openclash/res/ConnersHua_return.yaml');
Value['rules']=Value_1['rules'];
Value['rules'].to_a.collect!{|x|
x.to_s.gsub(/,PROXY$/, ',$Proxy#d')
.gsub(/MATCH,DIRECT$/, 'MATCH,$Others#d')
.gsub(/#d/, '')
};
File.open('$4','w') {|f| YAML.dump(Value, f)};
rescue Exception => e
puts '${LOGTIME} Set lhie1 Rules Error: ' + e.message
end" 2>/dev/null >> $LOG_FILE
fi
cat "$OTHER_RULE_FILE" >> "$4" 2>/dev/null
rm -rf /tmp/other_rule* 2>/dev/null
fi
fi
elif [ "$2" = 0 ]; then
[ -f "$8" ] && {
grep '##source:' "$4" 1>/dev/null
if [ "$?" -eq "0" ]; then
cp -f "$RULE_PROVIDER_BAK_FILE" "$RULE_PROVIDER_FILE" 2>/dev/null
cp -f "SCRIPT_BAK_FILE" "$SCRIPT_FILE" 2>/dev/null
cp -f "$RULE_BAK_FILE" "$4" 2>/dev/null
fi
}
fi
yml_other_set "$1" "$2" "$3" "$4" "$5" "$6" "$7"
yml_other_set "$1" "$2" "$3" "$4" "$5" "$6" "$7"

View File

@ -0,0 +1,6 @@
.CodeMirror-fullscreen {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
height: auto;
z-index: 9;
}

View File

@ -0,0 +1,41 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineOption("fullScreen", false, function(cm, val, old) {
if (old == CodeMirror.Init) old = false;
if (!old == !val) return;
if (val) setFullscreen(cm);
else setNormal(cm);
});
function setFullscreen(cm) {
var wrap = cm.getWrapperElement();
cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset,
width: wrap.style.width, height: wrap.style.height};
wrap.style.width = "";
wrap.style.height = "auto";
wrap.className += " CodeMirror-fullscreen";
document.documentElement.style.overflow = "hidden";
cm.refresh();
}
function setNormal(cm) {
var wrap = cm.getWrapperElement();
wrap.className = wrap.className.replace(/\s*CodeMirror-fullscreen\b/, "");
document.documentElement.style.overflow = "";
var info = cm.state.fullScreenRestore;
wrap.style.width = info.width; wrap.style.height = info.height;
window.scrollTo(info.scrollLeft, info.scrollTop);
cm.refresh();
}
});

View File

@ -0,0 +1,158 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
var ie_lt8 = /MSIE \d/.test(navigator.userAgent) &&
(document.documentMode == null || document.documentMode < 8);
var Pos = CodeMirror.Pos;
var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<", "<": ">>", ">": "<<"};
function bracketRegex(config) {
return config && config.bracketRegex || /[(){}[\]]/
}
function findMatchingBracket(cm, where, config) {
var line = cm.getLineHandle(where.line), pos = where.ch - 1;
var afterCursor = config && config.afterCursor
if (afterCursor == null)
afterCursor = /(^| )cm-fat-cursor($| )/.test(cm.getWrapperElement().className)
var re = bracketRegex(config)
// A cursor is defined as between two characters, but in in vim command mode
// (i.e. not insert mode), the cursor is visually represented as a
// highlighted box on top of the 2nd character. Otherwise, we allow matches
// from before or after the cursor.
var match = (!afterCursor && pos >= 0 && re.test(line.text.charAt(pos)) && matching[line.text.charAt(pos)]) ||
re.test(line.text.charAt(pos + 1)) && matching[line.text.charAt(++pos)];
if (!match) return null;
var dir = match.charAt(1) == ">" ? 1 : -1;
if (config && config.strict && (dir > 0) != (pos == where.ch)) return null;
var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));
var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);
if (found == null) return null;
return {from: Pos(where.line, pos), to: found && found.pos,
match: found && found.ch == match.charAt(0), forward: dir > 0};
}
// bracketRegex is used to specify which type of bracket to scan
// should be a regexp, e.g. /[[\]]/
//
// Note: If "where" is on an open bracket, then this bracket is ignored.
//
// Returns false when no bracket was found, null when it reached
// maxScanLines and gave up
function scanForBracket(cm, where, dir, style, config) {
var maxScanLen = (config && config.maxScanLineLength) || 10000;
var maxScanLines = (config && config.maxScanLines) || 1000;
var stack = [];
var re = bracketRegex(config)
var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1)
: Math.max(cm.firstLine() - 1, where.line - maxScanLines);
for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) {
var line = cm.getLine(lineNo);
if (!line) continue;
var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1;
if (line.length > maxScanLen) continue;
if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);
for (; pos != end; pos += dir) {
var ch = line.charAt(pos);
if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) {
var match = matching[ch];
if (match && (match.charAt(1) == ">") == (dir > 0)) stack.push(ch);
else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};
else stack.pop();
}
}
}
return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null;
}
function matchBrackets(cm, autoclear, config) {
// Disable brace matching in long lines, since it'll cause hugely slow updates
var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;
var marks = [], ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, config);
if (match && cm.getLine(match.from.line).length <= maxHighlightLen) {
var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));
if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen)
marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style}));
}
}
if (marks.length) {
// Kludge to work around the IE bug from issue #1193, where text
// input stops going to the textare whever this fires.
if (ie_lt8 && cm.state.focused) cm.focus();
var clear = function() {
cm.operation(function() {
for (var i = 0; i < marks.length; i++) marks[i].clear();
});
};
if (autoclear) setTimeout(clear, 800);
else return clear;
}
}
function doMatchBrackets(cm) {
cm.operation(function() {
if (cm.state.matchBrackets.currentlyHighlighted) {
cm.state.matchBrackets.currentlyHighlighted();
cm.state.matchBrackets.currentlyHighlighted = null;
}
cm.state.matchBrackets.currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);
});
}
CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
function clear(cm) {
if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) {
cm.state.matchBrackets.currentlyHighlighted();
cm.state.matchBrackets.currentlyHighlighted = null;
}
}
if (old && old != CodeMirror.Init) {
cm.off("cursorActivity", doMatchBrackets);
cm.off("focus", doMatchBrackets)
cm.off("blur", clear)
clear(cm);
}
if (val) {
cm.state.matchBrackets = typeof val == "object" ? val : {};
cm.on("cursorActivity", doMatchBrackets);
cm.on("focus", doMatchBrackets)
cm.on("blur", clear)
}
});
CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
CodeMirror.defineExtension("findMatchingBracket", function(pos, config, oldConfig){
// Backwards-compatibility kludge
if (oldConfig || typeof config == "boolean") {
if (!oldConfig) {
config = config ? {strict: true} : null
} else {
oldConfig.strict = config
config = oldConfig
}
}
return findMatchingBracket(this, pos, config)
});
CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){
return scanForBracket(this, pos, dir, style, config);
});
});

View File

@ -0,0 +1,157 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
function doFold(cm, pos, options, force) {
if (options && options.call) {
var finder = options;
options = null;
} else {
var finder = getOption(cm, options, "rangeFinder");
}
if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0);
var minSize = getOption(cm, options, "minFoldSize");
function getRange(allowFolded) {
var range = finder(cm, pos);
if (!range || range.to.line - range.from.line < minSize) return null;
var marks = cm.findMarksAt(range.from);
for (var i = 0; i < marks.length; ++i) {
if (marks[i].__isFold && force !== "fold") {
if (!allowFolded) return null;
range.cleared = true;
marks[i].clear();
}
}
return range;
}
var range = getRange(true);
if (getOption(cm, options, "scanUp")) while (!range && pos.line > cm.firstLine()) {
pos = CodeMirror.Pos(pos.line - 1, 0);
range = getRange(false);
}
if (!range || range.cleared || force === "unfold") return;
var myWidget = makeWidget(cm, options, range);
CodeMirror.on(myWidget, "mousedown", function(e) {
myRange.clear();
CodeMirror.e_preventDefault(e);
});
var myRange = cm.markText(range.from, range.to, {
replacedWith: myWidget,
clearOnEnter: getOption(cm, options, "clearOnEnter"),
__isFold: true
});
myRange.on("clear", function(from, to) {
CodeMirror.signal(cm, "unfold", cm, from, to);
});
CodeMirror.signal(cm, "fold", cm, range.from, range.to);
}
function makeWidget(cm, options, range) {
var widget = getOption(cm, options, "widget");
if (typeof widget == "function") {
widget = widget(range.from, range.to);
}
if (typeof widget == "string") {
var text = document.createTextNode(widget);
widget = document.createElement("span");
widget.appendChild(text);
widget.className = "CodeMirror-foldmarker";
} else if (widget) {
widget = widget.cloneNode(true)
}
return widget;
}
// Clumsy backwards-compatible interface
CodeMirror.newFoldFunction = function(rangeFinder, widget) {
return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); };
};
// New-style interface
CodeMirror.defineExtension("foldCode", function(pos, options, force) {
doFold(this, pos, options, force);
});
CodeMirror.defineExtension("isFolded", function(pos) {
var marks = this.findMarksAt(pos);
for (var i = 0; i < marks.length; ++i)
if (marks[i].__isFold) return true;
});
CodeMirror.commands.toggleFold = function(cm) {
cm.foldCode(cm.getCursor());
};
CodeMirror.commands.fold = function(cm) {
cm.foldCode(cm.getCursor(), null, "fold");
};
CodeMirror.commands.unfold = function(cm) {
cm.foldCode(cm.getCursor(), null, "unfold");
};
CodeMirror.commands.foldAll = function(cm) {
cm.operation(function() {
for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)
cm.foldCode(CodeMirror.Pos(i, 0), null, "fold");
});
};
CodeMirror.commands.unfoldAll = function(cm) {
cm.operation(function() {
for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)
cm.foldCode(CodeMirror.Pos(i, 0), null, "unfold");
});
};
CodeMirror.registerHelper("fold", "combine", function() {
var funcs = Array.prototype.slice.call(arguments, 0);
return function(cm, start) {
for (var i = 0; i < funcs.length; ++i) {
var found = funcs[i](cm, start);
if (found) return found;
}
};
});
CodeMirror.registerHelper("fold", "auto", function(cm, start) {
var helpers = cm.getHelpers(start, "fold");
for (var i = 0; i < helpers.length; i++) {
var cur = helpers[i](cm, start);
if (cur) return cur;
}
});
var defaultOptions = {
rangeFinder: CodeMirror.fold.auto,
widget: "\u2194",
minFoldSize: 0,
scanUp: false,
clearOnEnter: true
};
CodeMirror.defineOption("foldOptions", null);
function getOption(cm, options, name) {
if (options && options[name] !== undefined)
return options[name];
var editorOptions = cm.options.foldOptions;
if (editorOptions && editorOptions[name] !== undefined)
return editorOptions[name];
return defaultOptions[name];
}
CodeMirror.defineExtension("foldOption", function(options, name) {
return getOption(this, options, name);
});
});

View File

@ -0,0 +1,20 @@
.CodeMirror-foldmarker {
color: blue;
text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px;
font-family: arial;
line-height: .3;
cursor: pointer;
}
.CodeMirror-foldgutter {
width: .7em;
}
.CodeMirror-foldgutter-open,
.CodeMirror-foldgutter-folded {
cursor: pointer;
}
.CodeMirror-foldgutter-open:after {
content: "\25BE";
}
.CodeMirror-foldgutter-folded:after {
content: "\25B8";
}

View File

@ -0,0 +1,163 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("./foldcode"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "./foldcode"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineOption("foldGutter", false, function(cm, val, old) {
if (old && old != CodeMirror.Init) {
cm.clearGutter(cm.state.foldGutter.options.gutter);
cm.state.foldGutter = null;
cm.off("gutterClick", onGutterClick);
cm.off("changes", onChange);
cm.off("viewportChange", onViewportChange);
cm.off("fold", onFold);
cm.off("unfold", onFold);
cm.off("swapDoc", onChange);
}
if (val) {
cm.state.foldGutter = new State(parseOptions(val));
updateInViewport(cm);
cm.on("gutterClick", onGutterClick);
cm.on("changes", onChange);
cm.on("viewportChange", onViewportChange);
cm.on("fold", onFold);
cm.on("unfold", onFold);
cm.on("swapDoc", onChange);
}
});
var Pos = CodeMirror.Pos;
function State(options) {
this.options = options;
this.from = this.to = 0;
}
function parseOptions(opts) {
if (opts === true) opts = {};
if (opts.gutter == null) opts.gutter = "CodeMirror-foldgutter";
if (opts.indicatorOpen == null) opts.indicatorOpen = "CodeMirror-foldgutter-open";
if (opts.indicatorFolded == null) opts.indicatorFolded = "CodeMirror-foldgutter-folded";
return opts;
}
function isFolded(cm, line) {
var marks = cm.findMarks(Pos(line, 0), Pos(line + 1, 0));
for (var i = 0; i < marks.length; ++i) {
if (marks[i].__isFold) {
var fromPos = marks[i].find(-1);
if (fromPos && fromPos.line === line)
return marks[i];
}
}
}
function marker(spec) {
if (typeof spec == "string") {
var elt = document.createElement("div");
elt.className = spec + " CodeMirror-guttermarker-subtle";
return elt;
} else {
return spec.cloneNode(true);
}
}
function updateFoldInfo(cm, from, to) {
var opts = cm.state.foldGutter.options, cur = from - 1;
var minSize = cm.foldOption(opts, "minFoldSize");
var func = cm.foldOption(opts, "rangeFinder");
// we can reuse the built-in indicator element if its className matches the new state
var clsFolded = typeof opts.indicatorFolded == "string" && classTest(opts.indicatorFolded);
var clsOpen = typeof opts.indicatorOpen == "string" && classTest(opts.indicatorOpen);
cm.eachLine(from, to, function(line) {
++cur;
var mark = null;
var old = line.gutterMarkers;
if (old) old = old[opts.gutter];
if (isFolded(cm, cur)) {
if (clsFolded && old && clsFolded.test(old.className)) return;
mark = marker(opts.indicatorFolded);
} else {
var pos = Pos(cur, 0);
var range = func && func(cm, pos);
if (range && range.to.line - range.from.line >= minSize) {
if (clsOpen && old && clsOpen.test(old.className)) return;
mark = marker(opts.indicatorOpen);
}
}
if (!mark && !old) return;
cm.setGutterMarker(line, opts.gutter, mark);
});
}
// copied from CodeMirror/src/util/dom.js
function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") }
function updateInViewport(cm) {
var vp = cm.getViewport(), state = cm.state.foldGutter;
if (!state) return;
cm.operation(function() {
updateFoldInfo(cm, vp.from, vp.to);
});
state.from = vp.from; state.to = vp.to;
}
function onGutterClick(cm, line, gutter) {
var state = cm.state.foldGutter;
if (!state) return;
var opts = state.options;
if (gutter != opts.gutter) return;
var folded = isFolded(cm, line);
if (folded) folded.clear();
else cm.foldCode(Pos(line, 0), opts);
}
function onChange(cm) {
var state = cm.state.foldGutter;
if (!state) return;
var opts = state.options;
state.from = state.to = 0;
clearTimeout(state.changeUpdate);
state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600);
}
function onViewportChange(cm) {
var state = cm.state.foldGutter;
if (!state) return;
var opts = state.options;
clearTimeout(state.changeUpdate);
state.changeUpdate = setTimeout(function() {
var vp = cm.getViewport();
if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) {
updateInViewport(cm);
} else {
cm.operation(function() {
if (vp.from < state.from) {
updateFoldInfo(cm, vp.from, state.from);
state.from = vp.from;
}
if (vp.to > state.to) {
updateFoldInfo(cm, state.to, vp.to);
state.to = vp.to;
}
});
}
}, opts.updateViewportTimeSpan || 400);
}
function onFold(cm, from) {
var state = cm.state.foldGutter;
if (!state) return;
var line = from.line;
if (line >= state.from && line < state.to)
updateFoldInfo(cm, line, line + 1);
}
});

View File

@ -0,0 +1,48 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
function lineIndent(cm, lineNo) {
var text = cm.getLine(lineNo)
var spaceTo = text.search(/\S/)
if (spaceTo == -1 || /\bcomment\b/.test(cm.getTokenTypeAt(CodeMirror.Pos(lineNo, spaceTo + 1))))
return -1
return CodeMirror.countColumn(text, null, cm.getOption("tabSize"))
}
CodeMirror.registerHelper("fold", "indent", function(cm, start) {
var myIndent = lineIndent(cm, start.line)
if (myIndent < 0) return
var lastLineInFold = null
// Go through lines until we find a line that definitely doesn't belong in
// the block we're folding, or to the end.
for (var i = start.line + 1, end = cm.lastLine(); i <= end; ++i) {
var indent = lineIndent(cm, i)
if (indent == -1) {
} else if (indent > myIndent) {
// Lines with a greater indent are considered part of the block.
lastLineInFold = i;
} else {
// If this line has non-space, non-comment content, and is
// indented less or equal to the start line, it is the start of
// another block.
break;
}
}
if (lastLineInFold) return {
from: CodeMirror.Pos(start.line, cm.getLine(start.line).length),
to: CodeMirror.Pos(lastLineInFold, cm.getLine(lastLineInFold).length)
};
});
});

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,71 @@
/* The lint marker gutter */
.CodeMirror-lint-markers {
width: 16px;
}
.CodeMirror-lint-tooltip {
background-color: #ffd;
border: 1px solid black;
border-radius: 4px 4px 4px 4px;
color: black;
font-family: monospace;
font-size: 10pt;
overflow: hidden;
padding: 2px 5px;
position: fixed;
white-space: pre;
white-space: pre-wrap;
z-index: 100;
max-width: 600px;
opacity: 0;
transition: opacity .4s;
-moz-transition: opacity .4s;
-webkit-transition: opacity .4s;
-o-transition: opacity .4s;
-ms-transition: opacity .4s;
}
.CodeMirror-lint-mark {
background-position: left bottom;
background-repeat: repeat-x;
}
.CodeMirror-lint-mark-warning {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII=");
}
.CodeMirror-lint-mark-error {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==");
}
.CodeMirror-lint-marker {
background-position: center center;
background-repeat: no-repeat;
cursor: pointer;
display: inline-block;
height: 16px;
width: 16px;
vertical-align: middle;
position: relative;
}
.CodeMirror-lint-message {
padding-left: 18px;
background-position: top left;
background-repeat: no-repeat;
}
.CodeMirror-lint-marker-warning, .CodeMirror-lint-message-warning {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII=");
}
.CodeMirror-lint-marker-error, .CodeMirror-lint-message-error {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII=");
}
.CodeMirror-lint-marker-multiple {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAMAAADzjKfhAAAACVBMVEUAAAAAAAC/v7914kyHAAAAAXRSTlMAQObYZgAAACNJREFUeNo1ioEJAAAIwmz/H90iFFSGJgFMe3gaLZ0od+9/AQZ0ADosbYraAAAAAElFTkSuQmCC");
background-repeat: no-repeat;
background-position: right bottom;
width: 100%; height: 100%;
}

View File

@ -0,0 +1,255 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var GUTTER_ID = "CodeMirror-lint-markers";
function showTooltip(cm, e, content) {
var tt = document.createElement("div");
tt.className = "CodeMirror-lint-tooltip cm-s-" + cm.options.theme;
tt.appendChild(content.cloneNode(true));
if (cm.state.lint.options.selfContain)
cm.getWrapperElement().appendChild(tt);
else
document.body.appendChild(tt);
function position(e) {
if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position);
tt.style.top = Math.max(0, e.clientY - tt.offsetHeight - 5) + "px";
tt.style.left = (e.clientX + 5) + "px";
}
CodeMirror.on(document, "mousemove", position);
position(e);
if (tt.style.opacity != null) tt.style.opacity = 1;
return tt;
}
function rm(elt) {
if (elt.parentNode) elt.parentNode.removeChild(elt);
}
function hideTooltip(tt) {
if (!tt.parentNode) return;
if (tt.style.opacity == null) rm(tt);
tt.style.opacity = 0;
setTimeout(function() { rm(tt); }, 600);
}
function showTooltipFor(cm, e, content, node) {
var tooltip = showTooltip(cm, e, content);
function hide() {
CodeMirror.off(node, "mouseout", hide);
if (tooltip) { hideTooltip(tooltip); tooltip = null; }
}
var poll = setInterval(function() {
if (tooltip) for (var n = node;; n = n.parentNode) {
if (n && n.nodeType == 11) n = n.host;
if (n == document.body) return;
if (!n) { hide(); break; }
}
if (!tooltip) return clearInterval(poll);
}, 400);
CodeMirror.on(node, "mouseout", hide);
}
function LintState(cm, options, hasGutter) {
this.marked = [];
this.options = options;
this.timeout = null;
this.hasGutter = hasGutter;
this.onMouseOver = function(e) { onMouseOver(cm, e); };
this.waitingFor = 0
}
function parseOptions(_cm, options) {
if (options instanceof Function) return {getAnnotations: options};
if (!options || options === true) options = {};
return options;
}
function clearMarks(cm) {
var state = cm.state.lint;
if (state.hasGutter) cm.clearGutter(GUTTER_ID);
for (var i = 0; i < state.marked.length; ++i)
state.marked[i].clear();
state.marked.length = 0;
}
function makeMarker(cm, labels, severity, multiple, tooltips) {
var marker = document.createElement("div"), inner = marker;
marker.className = "CodeMirror-lint-marker CodeMirror-lint-marker-" + severity;
if (multiple) {
inner = marker.appendChild(document.createElement("div"));
inner.className = "CodeMirror-lint-marker CodeMirror-lint-marker-multiple";
}
if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) {
showTooltipFor(cm, e, labels, inner);
});
return marker;
}
function getMaxSeverity(a, b) {
if (a == "error") return a;
else return b;
}
function groupByLine(annotations) {
var lines = [];
for (var i = 0; i < annotations.length; ++i) {
var ann = annotations[i], line = ann.from.line;
(lines[line] || (lines[line] = [])).push(ann);
}
return lines;
}
function annotationTooltip(ann) {
var severity = ann.severity;
if (!severity) severity = "error";
var tip = document.createElement("div");
tip.className = "CodeMirror-lint-message CodeMirror-lint-message-" + severity;
if (typeof ann.messageHTML != 'undefined') {
tip.innerHTML = ann.messageHTML;
} else {
tip.appendChild(document.createTextNode(ann.message));
}
return tip;
}
function lintAsync(cm, getAnnotations, passOptions) {
var state = cm.state.lint
var id = ++state.waitingFor
function abort() {
id = -1
cm.off("change", abort)
}
cm.on("change", abort)
getAnnotations(cm.getValue(), function(annotations, arg2) {
cm.off("change", abort)
if (state.waitingFor != id) return
if (arg2 && annotations instanceof CodeMirror) annotations = arg2
cm.operation(function() {updateLinting(cm, annotations)})
}, passOptions, cm);
}
function startLinting(cm) {
var state = cm.state.lint, options = state.options;
/*
* Passing rules in `options` property prevents JSHint (and other linters) from complaining
* about unrecognized rules like `onUpdateLinting`, `delay`, `lintOnChange`, etc.
*/
var passOptions = options.options || options;
var getAnnotations = options.getAnnotations || cm.getHelper(CodeMirror.Pos(0, 0), "lint");
if (!getAnnotations) return;
if (options.async || getAnnotations.async) {
lintAsync(cm, getAnnotations, passOptions)
} else {
var annotations = getAnnotations(cm.getValue(), passOptions, cm);
if (!annotations) return;
if (annotations.then) annotations.then(function(issues) {
cm.operation(function() {updateLinting(cm, issues)})
});
else cm.operation(function() {updateLinting(cm, annotations)})
}
}
function updateLinting(cm, annotationsNotSorted) {
clearMarks(cm);
var state = cm.state.lint, options = state.options;
var annotations = groupByLine(annotationsNotSorted);
for (var line = 0; line < annotations.length; ++line) {
var anns = annotations[line];
if (!anns) continue;
var maxSeverity = null;
var tipLabel = state.hasGutter && document.createDocumentFragment();
for (var i = 0; i < anns.length; ++i) {
var ann = anns[i];
var severity = ann.severity;
if (!severity) severity = "error";
maxSeverity = getMaxSeverity(maxSeverity, severity);
if (options.formatAnnotation) ann = options.formatAnnotation(ann);
if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann));
if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, {
className: "CodeMirror-lint-mark CodeMirror-lint-mark-" + severity,
__annotation: ann
}));
}
if (state.hasGutter)
cm.setGutterMarker(line, GUTTER_ID, makeMarker(cm, tipLabel, maxSeverity, anns.length > 1,
state.options.tooltips));
}
if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm);
}
function onChange(cm) {
var state = cm.state.lint;
if (!state) return;
clearTimeout(state.timeout);
state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
}
function popupTooltips(cm, annotations, e) {
var target = e.target || e.srcElement;
var tooltip = document.createDocumentFragment();
for (var i = 0; i < annotations.length; i++) {
var ann = annotations[i];
tooltip.appendChild(annotationTooltip(ann));
}
showTooltipFor(cm, e, tooltip, target);
}
function onMouseOver(cm, e) {
var target = e.target || e.srcElement;
if (!/\bCodeMirror-lint-mark-/.test(target.className)) return;
var box = target.getBoundingClientRect(), x = (box.left + box.right) / 2, y = (box.top + box.bottom) / 2;
var spans = cm.findMarksAt(cm.coordsChar({left: x, top: y}, "client"));
var annotations = [];
for (var i = 0; i < spans.length; ++i) {
var ann = spans[i].__annotation;
if (ann) annotations.push(ann);
}
if (annotations.length) popupTooltips(cm, annotations, e);
}
CodeMirror.defineOption("lint", false, function(cm, val, old) {
if (old && old != CodeMirror.Init) {
clearMarks(cm);
if (cm.state.lint.options.lintOnChange !== false)
cm.off("change", onChange);
CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver);
clearTimeout(cm.state.lint.timeout);
delete cm.state.lint;
}
if (val) {
var gutters = cm.getOption("gutters"), hasLintGutter = false;
for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true;
var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter);
if (state.options.lintOnChange !== false)
cm.on("change", onChange);
if (state.options.tooltips != false && state.options.tooltips != "gutter")
CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver);
startLinting(cm);
}
});
CodeMirror.defineExtension("performLint", function() {
if (this.state.lint) startLinting(this);
});
});

View File

@ -0,0 +1,41 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
// Depends on js-yaml.js from https://github.com/nodeca/js-yaml
// declare global: jsyaml
CodeMirror.registerHelper("lint", "yaml", function(text) {
var found = [];
if (!window.jsyaml) {
if (window.console) {
window.console.error("Error: window.jsyaml not defined, CodeMirror YAML linting cannot run.");
}
return found;
}
try { jsyaml.loadAll(text); }
catch(e) {
var loc = e.mark,
// js-yaml YAMLException doesn't always provide an accurate lineno
// e.g., when there are multiple yaml docs
// ---
// ---
// foo:bar
from = loc ? CodeMirror.Pos(loc.line, loc.column) : CodeMirror.Pos(0, 0),
to = from;
found.push({ from: from, to: to, message: e.message });
}
return found;
});
});

View File

@ -0,0 +1,72 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var WRAP_CLASS = "CodeMirror-activeline";
var BACK_CLASS = "CodeMirror-activeline-background";
var GUTT_CLASS = "CodeMirror-activeline-gutter";
CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) {
var prev = old == CodeMirror.Init ? false : old;
if (val == prev) return
if (prev) {
cm.off("beforeSelectionChange", selectionChange);
clearActiveLines(cm);
delete cm.state.activeLines;
}
if (val) {
cm.state.activeLines = [];
updateActiveLines(cm, cm.listSelections());
cm.on("beforeSelectionChange", selectionChange);
}
});
function clearActiveLines(cm) {
for (var i = 0; i < cm.state.activeLines.length; i++) {
cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS);
cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS);
cm.removeLineClass(cm.state.activeLines[i], "gutter", GUTT_CLASS);
}
}
function sameArray(a, b) {
if (a.length != b.length) return false;
for (var i = 0; i < a.length; i++)
if (a[i] != b[i]) return false;
return true;
}
function updateActiveLines(cm, ranges) {
var active = [];
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i];
var option = cm.getOption("styleActiveLine");
if (typeof option == "object" && option.nonEmpty ? range.anchor.line != range.head.line : !range.empty())
continue
var line = cm.getLineHandleVisualStart(range.head.line);
if (active[active.length - 1] != line) active.push(line);
}
if (sameArray(cm.state.activeLines, active)) return;
cm.operation(function() {
clearActiveLines(cm);
for (var i = 0; i < active.length; i++) {
cm.addLineClass(active[i], "wrap", WRAP_CLASS);
cm.addLineClass(active[i], "background", BACK_CLASS);
cm.addLineClass(active[i], "gutter", GUTT_CLASS);
}
cm.state.activeLines = active;
});
}
function selectionChange(cm, sel) {
updateActiveLines(cm, sel.ranges);
}
});

View File

@ -0,0 +1,350 @@
/* BASICS */
.CodeMirror {
/* Set height, width, borders, and global font properties here */
font-family: monospace;
height: 300px;
color: black;
direction: ltr;
}
/* PADDING */
.CodeMirror-lines {
padding: 4px 0; /* Vertical padding around content */
}
.CodeMirror pre.CodeMirror-line,
.CodeMirror pre.CodeMirror-line-like {
padding: 0 4px; /* Horizontal padding of content */
}
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
background-color: white; /* The little square between H and V scrollbars */
}
/* GUTTER */
.CodeMirror-gutters {
border-right: 1px solid #ddd;
background-color: #f7f7f7;
white-space: nowrap;
}
.CodeMirror-linenumbers {}
.CodeMirror-linenumber {
padding: 0 3px 0 5px;
min-width: 20px;
text-align: right;
color: #999;
white-space: nowrap;
}
.CodeMirror-guttermarker { color: black; }
.CodeMirror-guttermarker-subtle { color: #999; }
/* CURSOR */
.CodeMirror-cursor {
border-left: 1px solid black;
border-right: none;
width: 0;
}
/* Shown when moving in bi-directional text */
.CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid silver;
}
.cm-fat-cursor .CodeMirror-cursor {
width: auto;
border: 0 !important;
background: #7e7;
}
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
.cm-fat-cursor-mark {
background-color: rgba(20, 255, 20, 0.5);
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
}
.cm-animate-fat-cursor {
width: auto;
border: 0;
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
background-color: #7e7;
}
@-moz-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@-webkit-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
/* Can style cursor different in overwrite (non-insert) mode */
.CodeMirror-overwrite .CodeMirror-cursor {}
.cm-tab { display: inline-block; text-decoration: inherit; }
.CodeMirror-rulers {
position: absolute;
left: 0; right: 0; top: -50px; bottom: 0;
overflow: hidden;
}
.CodeMirror-ruler {
border-left: 1px solid #ccc;
top: 0; bottom: 0;
position: absolute;
}
/* DEFAULT THEME */
.cm-s-default .cm-header {color: blue;}
.cm-s-default .cm-quote {color: #090;}
.cm-negative {color: #d44;}
.cm-positive {color: #292;}
.cm-header, .cm-strong {font-weight: bold;}
.cm-em {font-style: italic;}
.cm-link {text-decoration: underline;}
.cm-strikethrough {text-decoration: line-through;}
.cm-s-default .cm-keyword {color: #708;}
.cm-s-default .cm-atom {color: #219;}
.cm-s-default .cm-number {color: #164;}
.cm-s-default .cm-def {color: #00f;}
.cm-s-default .cm-variable,
.cm-s-default .cm-punctuation,
.cm-s-default .cm-property,
.cm-s-default .cm-operator {}
.cm-s-default .cm-variable-2 {color: #05a;}
.cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;}
.cm-s-default .cm-comment {color: #a50;}
.cm-s-default .cm-string {color: #a11;}
.cm-s-default .cm-string-2 {color: #f50;}
.cm-s-default .cm-meta {color: #555;}
.cm-s-default .cm-qualifier {color: #555;}
.cm-s-default .cm-builtin {color: #30a;}
.cm-s-default .cm-bracket {color: #997;}
.cm-s-default .cm-tag {color: #170;}
.cm-s-default .cm-attribute {color: #00c;}
.cm-s-default .cm-hr {color: #999;}
.cm-s-default .cm-link {color: #00c;}
.cm-s-default .cm-error {color: #f00;}
.cm-invalidchar {color: #f00;}
.CodeMirror-composing { border-bottom: 2px solid; }
/* Default styles for common addons */
div.CodeMirror span.CodeMirror-matchingbracket {color: #0b0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
.CodeMirror-activeline-background {background: #e8f2ff;}
/* STOP */
/* The rest of this file contains styles related to the mechanics of
the editor. You probably shouldn't touch them. */
.CodeMirror {
position: relative;
overflow: hidden;
background: white;
}
.CodeMirror-scroll {
overflow: scroll !important; /* Things will break if this is overridden */
/* 50px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -50px; margin-right: -50px;
padding-bottom: 50px;
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
}
.CodeMirror-sizer {
position: relative;
border-right: 50px solid transparent;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
before actual scrolling happens, thus preventing shaking and
flickering artifacts. */
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
position: absolute;
z-index: 6;
display: none;
outline: none;
}
.CodeMirror-vscrollbar {
right: 0; top: 0;
overflow-x: hidden;
overflow-y: scroll;
}
.CodeMirror-hscrollbar {
bottom: 0; left: 0;
overflow-y: hidden;
overflow-x: scroll;
}
.CodeMirror-scrollbar-filler {
right: 0; bottom: 0;
}
.CodeMirror-gutter-filler {
left: 0; bottom: 0;
}
.CodeMirror-gutters {
position: absolute; left: 0; top: 0;
min-height: 100%;
z-index: 3;
}
.CodeMirror-gutter {
white-space: normal;
height: 100%;
display: inline-block;
vertical-align: top;
margin-bottom: -50px;
}
.CodeMirror-gutter-wrapper {
position: absolute;
z-index: 4;
background: none !important;
border: none !important;
}
.CodeMirror-gutter-background {
position: absolute;
top: 0; bottom: 0;
z-index: 4;
}
.CodeMirror-gutter-elt {
position: absolute;
cursor: default;
z-index: 4;
}
.CodeMirror-gutter-wrapper ::selection { background-color: transparent }
.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
.CodeMirror-lines {
cursor: text;
min-height: 1px; /* prevents collapsing before first draw */
}
.CodeMirror pre.CodeMirror-line,
.CodeMirror pre.CodeMirror-line-like {
/* Reset some styles that the rest of the page might have set */
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
border-width: 0;
background: transparent;
font-family: inherit;
font-size: inherit;
margin: 0;
white-space: pre;
word-wrap: normal;
line-height: inherit;
color: inherit;
z-index: 2;
position: relative;
overflow: visible;
-webkit-tap-highlight-color: transparent;
-webkit-font-variant-ligatures: contextual;
font-variant-ligatures: contextual;
}
.CodeMirror-wrap pre.CodeMirror-line,
.CodeMirror-wrap pre.CodeMirror-line-like {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;
}
.CodeMirror-linebackground {
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
z-index: 0;
}
.CodeMirror-linewidget {
position: relative;
z-index: 2;
padding: 0.1px; /* Force widget margins to stay inside of the container */
}
.CodeMirror-widget {}
.CodeMirror-rtl pre { direction: rtl; }
.CodeMirror-code {
outline: none;
}
/* Force content-box sizing for the elements where we expect it */
.CodeMirror-scroll,
.CodeMirror-sizer,
.CodeMirror-gutter,
.CodeMirror-gutters,
.CodeMirror-linenumber {
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.CodeMirror-measure {
position: absolute;
width: 100%;
height: 0;
overflow: hidden;
visibility: hidden;
}
.CodeMirror-cursor {
position: absolute;
pointer-events: none;
}
.CodeMirror-measure pre { position: static; }
div.CodeMirror-cursors {
visibility: hidden;
position: relative;
z-index: 3;
}
div.CodeMirror-dragcursors {
visibility: visible;
}
.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible;
}
.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
.CodeMirror-crosshair { cursor: crosshair; }
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
.cm-searching {
background-color: #ffa;
background-color: rgba(255, 255, 0, .4);
}
/* Used to force a border model for a node */
.cm-force-border { padding-right: .1px; }
@media print {
/* Hide the cursor when printing */
.CodeMirror div.CodeMirror-cursors {
visibility: hidden;
}
}
/* See issue #2901 */
.cm-tab-wrap-hack:after { content: ''; }
/* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext { background: none; }

View File

@ -0,0 +1,120 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode("yaml", function() {
var cons = ['true', 'false', 'on', 'off', 'yes', 'no'];
var keywordRegex = new RegExp("\\b(("+cons.join(")|(")+"))$", 'i');
return {
token: function(stream, state) {
var ch = stream.peek();
var esc = state.escaped;
state.escaped = false;
/* comments */
if (ch == "#" && (stream.pos == 0 || /\s/.test(stream.string.charAt(stream.pos - 1)))) {
stream.skipToEnd();
return "comment";
}
if (stream.match(/^('([^']|\\.)*'?|"([^"]|\\.)*"?)/))
return "string";
if (state.literal && stream.indentation() > state.keyCol) {
stream.skipToEnd(); return "string";
} else if (state.literal) { state.literal = false; }
if (stream.sol()) {
state.keyCol = 0;
state.pair = false;
state.pairStart = false;
/* document start */
if(stream.match(/---/)) { return "def"; }
/* document end */
if (stream.match(/\.\.\./)) { return "def"; }
/* array list item */
if (stream.match(/\s*-\s+/)) { return 'meta'; }
}
/* inline pairs/lists */
if (stream.match(/^(\{|\}|\[|\])/)) {
if (ch == '{')
state.inlinePairs++;
else if (ch == '}')
state.inlinePairs--;
else if (ch == '[')
state.inlineList++;
else
state.inlineList--;
return 'meta';
}
/* list seperator */
if (state.inlineList > 0 && !esc && ch == ',') {
stream.next();
return 'meta';
}
/* pairs seperator */
if (state.inlinePairs > 0 && !esc && ch == ',') {
state.keyCol = 0;
state.pair = false;
state.pairStart = false;
stream.next();
return 'meta';
}
/* start of value of a pair */
if (state.pairStart) {
/* block literals */
if (stream.match(/^\s*(\||\>)\s*/)) { state.literal = true; return 'meta'; };
/* references */
if (stream.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i)) { return 'variable-2'; }
/* numbers */
if (state.inlinePairs == 0 && stream.match(/^\s*-?[0-9\.\,]+\s?$/)) { return 'number'; }
if (state.inlinePairs > 0 && stream.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/)) { return 'number'; }
/* keywords */
if (stream.match(keywordRegex)) { return 'keyword'; }
}
/* pairs (associative arrays) -> key */
if (!state.pair && stream.match(/^\s*(?:[,\[\]{}&*!|>'"%@`][^\s'":]|[^,\[\]{}#&*!|>'"%@`])[^#]*?(?=\s*:($|\s))/)) {
state.pair = true;
state.keyCol = stream.indentation();
return "atom";
}
if (state.pair && stream.match(/^:\s*/)) { state.pairStart = true; return 'meta'; }
/* nothing found, continue */
state.pairStart = false;
state.escaped = (ch == '\\');
stream.next();
return null;
},
startState: function() {
return {
pair: false,
pairStart: false,
keyCol: 0,
inlinePairs: 0,
inlineList: 0,
literal: false,
escaped: false
};
},
lineComment: "#",
fold: "indent"
};
});
CodeMirror.defineMIME("text/x-yaml", "yaml");
CodeMirror.defineMIME("text/yaml", "yaml");
});

View File

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

View File

@ -1,8 +1,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-vssr
PKG_VERSION:=1.17-1
PKG_RELEASE:=20200830
PKG_VERSION:=1.18
PKG_RELEASE:=20201204
include $(INCLUDE_DIR)/package.mk
@ -13,6 +13,10 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_plugin
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray
bool "Include V2ray"
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_Xray
bool "Include Xray"
default y if i386||x86_64||arm||aarch64
config PACKAGE_$(PKG_NAME)_INCLUDE_Trojan
@ -31,6 +35,7 @@ endef
PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_plugin \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Xray \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Trojan \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server
@ -45,6 +50,7 @@ define Package/luci-app-vssr
+shadowsocks-libev-ss-local +shadowsocksr-libev-ssr-local +shadowsocks-libev-ss-redir +simple-obfs \
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_plugin:v2ray-plugin \
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray \
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:xray \
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:trojan \
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:ipt2socks \
+PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun-client \
@ -57,6 +63,11 @@ endef
define Build/Compile
endef
define Package/luci-app-vssr/conffiles
/etc/vssr/
/etc/config/vssr
endef
define Package/luci-app-vssr/install
$(INSTALL_DIR) $(1)/usr/lib/lua/luci
cp -pR ./luasrc/* $(1)/usr/lib/lua/luci

View File

@ -51,11 +51,13 @@ function get_subscribe()
local auto_update_time = luci.http.formvalue('auto_update_time')
local proxy = luci.http.formvalue('proxy')
local subscribe_url = luci.http.formvalue('subscribe_url')
local filter_words = luci.http.formvalue('filter_words')
if subscribe_url ~= '[]' then
uci:delete(name, '@server_subscribe[0]', subscribe_url)
uci:set(name, '@server_subscribe[0]', 'auto_update', auto_update)
uci:set(name, '@server_subscribe[0]', 'auto_update_time', auto_update_time)
uci:set(name, '@server_subscribe[0]', 'proxy', proxy)
uci:set(name, '@server_subscribe[0]', 'filter_words', filter_words)
uci:set_list(name, '@server_subscribe[0]', 'subscribe_url', cjson.parse(subscribe_url))
uci:commit(name)
luci.sys.exec('nohup /usr/bin/lua /usr/share/vssr/subscribe.lua >/www/check_update.htm 2>/dev/null &')

View File

@ -79,6 +79,11 @@ o.rmempty = false
o = s:option(DynamicList, 'subscribe_url', translate('Subscribe URL'))
o.rmempty = true
o.description = translate('You can manually add group names in front of the URL, splited by ,')
o = s:option(Value, "filter_words", translate("Subscribe Filter Words"))
o.rmempty = true
o.description = translate("Filter Words splited by /")
o = s:option(Flag, 'proxy', translate('Through proxy update'))
o.rmempty = false

View File

@ -91,7 +91,21 @@ obfs = {
'random_head',
'tls1.2_ticket_auth'
}
local securitys = {'auto', 'none', 'aes-128-gcm', 'chacha20-poly1305'}
local securitys = {
'auto',
'none',
'aes-128-gcm',
'chacha20-poly1305'
}
local flows = {
'xtls-rprx-origin',
'xtls-rprx-origin-udp443',
'xtls-rprx-direct',
'xtls-rprx-direct-udp443',
'xtls-rprx-splice',
'xtls-rprx-splice-udp443'
}
m = Map(vssr, translate('Edit vssr Server'))
m.redirect = luci.dispatcher.build_url('admin/services/vssr/servers')
@ -112,10 +126,12 @@ o.value = sid
o = s:option(ListValue, 'type', translate('Server Node Type'))
o:value('ssr', translate('ShadowsocksR'))
if nixio.fs.access('/usr/bin/v2ray/v2ray') or nixio.fs.access('/usr/bin/v2ray') then
if nixio.fs.access('/usr/bin/ss-redir') then
o:value('ss', translate('Shadowsocks New Version'))
end
if nixio.fs.access('/usr/bin/v2ray/v2ray') or nixio.fs.access('/usr/bin/v2ray') then
o:value('v2ray', translate('V2Ray'))
o:value('vless', translate('VLESS'))
end
if nixio.fs.access('/usr/sbin/trojan') then
@ -138,11 +154,6 @@ o = s:option(Value, 'server_port', translate('Server Port'))
o.datatype = 'port'
o.rmempty = false
-- o = s:option(Value, "timeout", translate("Connection Timeout"))
-- o.datatype = "uinteger"
-- o.default = 60
-- o.rmempty = false
o = s:option(Value, 'password', translate('Password'))
o.password = true
o.rmempty = true
@ -206,10 +217,19 @@ o.rmempty = true
o:depends('type', 'v2ray')
-- VmessId
o = s:option(Value, 'vmess_id', translate('VmessId (UUID)'))
o = s:option(Value, 'vmess_id', translate('VMESS/VLESS ID (UUID)'))
o.rmempty = true
o.default = uuid
o:depends('type', 'v2ray')
o:depends('type', 'vless')
o:depends('type', 'xray')
-- VLESS 加密方式
o = s:option(Value, 'vless_encryption', translate('VLESS Encryption'))
o.rmempty = true
o.default = 'none'
o:depends('type', 'vless')
o:depends('type', 'xray')
-- 加密方式
o = s:option(ListValue, 'security', translate('Encrypt Method'))
@ -228,6 +248,8 @@ o:value('h2', 'HTTP/2')
o:value('quic', 'QUIC')
o.rmempty = true
o:depends('type', 'v2ray')
o:depends('type', 'vless')
o:depends('type', 'xray')
-- [[ TCP部分 ]]--
@ -353,9 +375,11 @@ o.rmempty = true
-- [[ allowInsecure ]]--
o = s:option(Flag, 'insecure', translate('allowInsecure'))
o.rmempty = true
o.rmempty = false
o:depends('type', 'v2ray')
o:depends('type', 'trojan')
o:depends('type', 'vless')
o:depends('type', 'xray')
-- [[ TLS ]]--
o = s:option(Flag, 'tls', translate('TLS'))
@ -363,18 +387,45 @@ o.rmempty = true
o.default = '0'
o:depends('type', 'v2ray')
o:depends('type', 'trojan')
o:depends('type', 'vless')
o:depends('type', 'xray')
o = s:option(Value, 'tls_host', translate('TLS Host'))
--o:depends("type", "trojan")
o:depends('tls', '1')
o.rmempty = true
-- XTLS
o = s:option(Flag, 'xtls', translate('XTLS'))
o.rmempty = true
o.default = '0'
o:depends({type = 'vless', tls = '1'})
o:depends({type = 'xray', tls = '1'})
-- Flow
o = s:option(Value, 'vless_flow', translate('Flow'))
for _, v in ipairs(flows) do
o:value(v, v)
end
o.rmempty = true
o.default = 'xtls-rprx-origin'
o:depends('xtls', '1')
-- [[ Mux ]]--
o = s:option(Flag, 'mux', translate('Mux'))
o.rmempty = true
o.default = '0'
o:depends('type', 'v2ray')
o:depends('type', 'vless')
o = s:option(Value, 'concurrency', translate('Concurrency'))
o.datatype = 'uinteger'
o.rmempty = true
o.default = '8'
o:depends('mux', '1')
-- [[NO self cert]]
o = s:option(Flag, 'fast_open', translate('TCP Fast Open'))
o.rmempty = true
o.default = '0'

View File

@ -102,7 +102,7 @@ local route_label = {
}
-- [[ Global Setting ]]--
s = m:section(TypedSection, 'global', translate('Basic Settings [SS|SSR|V2ray|Trojan]'))
s = m:section(TypedSection, 'global', translate('Basic Settings [SS|SSR|V2ray|Xray|Trojan]'))
s.anonymous = true
o = s:option(ListValue, 'global_server', translate('Main Server'))
@ -120,6 +120,9 @@ for _, key in pairs(key_table) do
o:value(key, server_table[key])
end
o = s:option(Flag, 'use_xray', translate('Use Xray instead of V2ray'))
o.rmempty = false
o = s:option(Flag, 'v2ray_flow', translate('Open v2ray route'))
o.rmempty = false
o.description = translate('When open v2ray routed,Apply may take more time.')

View File

@ -49,12 +49,13 @@
} else {
var proxy = "0";
}
var filter_words = $("[name='" + prefix + ".filter_words']").val();
var data = {
auto_update: auto_update,
auto_update_time: auto_update_time,
subscribe_url: JSON.stringify(subscribe_url),
proxy: proxy
proxy: proxy,
filter_words: filter_words
}
//console.log(data);
$.ajax({

View File

@ -386,8 +386,8 @@ msgstr "通过代理更新"
msgid "GFW List"
msgstr "GFW列表"
msgid "Basic Settings [SS|SSR|V2ray|Trojan]"
msgstr "基本设置 [SS|SSR|V2ray|Trojan]"
msgid "Basic Settings [SS|SSR|V2ray|Xray|Trojan]"
msgstr "基本设置 [SS|SSR|V2ray|Xray|Trojan]"
msgid "Main Server"
msgstr "主服务器"
@ -420,7 +420,7 @@ msgid "Server Count"
msgstr "节点数量"
msgid "IP black-and-white list"
msgstr "黑白名单"
msgstr "禁止/通行名单"
msgid "WAN IP AC"
msgstr "广域网访问控制"
@ -659,3 +659,18 @@ msgstr "许可"
msgid "Area"
msgstr "国家或地区"
msgid "Use Xray instead of V2ray"
msgstr "使用Xray替代V2ray"
msgid "Subscribe Filter Words"
msgstr "订阅过滤关键词"
msgid "Filter Words splited by /"
msgstr "使用 / 分隔关键词"
msgid "VLESS Encryption"
msgstr "VLESS 加密"
msgid "You can manually add group names in front of the URL, splited by ,"
msgstr "你可以在URL前面手动添加组名使用 , 分隔"

View File

@ -2,7 +2,7 @@
config global
option tunnel_forward '8.8.4.4:53'
option tunnel_address '0.0.0.0'
option run_mode 'router'
option run_mode 'gfw'
option pdnsd_enable '1'
option monitor_enable '1'
option global_server 'nil'
@ -11,6 +11,7 @@ config global
option switch_time '667'
option switch_try_count '3'
option adblock '0'
option dports '2'
config socks5_proxy
option enable_server '0'

View File

@ -73,7 +73,7 @@ count_shunt() {
}
count_shunt
run_mode=$(uci_get_by_type global run_mode)
is_xray=$(uci_get_by_type global use_xray)
gen_config_file() {
local hostip=$(uci_get_by_name $1 server)
@ -96,6 +96,9 @@ gen_config_file() {
local stype=$(uci_get_by_name $1 type)
local port=$(uci_get_by_name $1 local_port)
if [ "$stype" == "vless" ]; then
stype="v2ray"
fi
if [ "$stype" == "trojan" ]; then
if [ "$re_type" == "udp" ]; then
re_type="client"
@ -194,18 +197,18 @@ start_rules() {
fi
/usr/bin/vssr-rules \
-s "$server" \
-l "$local_port" \
-S "$udp_server" \
-L "$udp_local_port" \
-a "$ac_ips" \
-i "$(uci_get_by_type access_control wan_bp_list)" \
-b "$(uci_get_by_type access_control wan_bp_ips)" \
-w "$(uci_get_by_type access_control wan_fw_ips)" \
-p "$(uci_get_by_type access_control lan_fp_ips)" \
-G "$(uci_get_by_type access_control lan_gm_ips)" \
-D "$proxyport" \
$(get_arg_out) $gfwmode $ARG_UDP
-s "$server" \
-l "$local_port" \
-S "$udp_server" \
-L "$udp_local_port" \
-a "$ac_ips" \
-i "$(uci_get_by_type access_control wan_bp_list)" \
-b "$(uci_get_by_type access_control wan_bp_ips)" \
-w "$(uci_get_by_type access_control wan_fw_ips)" \
-p "$(uci_get_by_type access_control lan_fp_ips)" \
-G "$(uci_get_by_type access_control lan_gm_ips)" \
-D "$proxyport" \
$(get_arg_out) $gfwmode $ARG_UDP
return $?
}
@ -272,7 +275,12 @@ find_bin() {
ssr) ret="/usr/bin/ssr-redir" ;;
ssr-local) ret="/usr/bin/ssr-local" ;;
ssr-server) ret="/usr/bin/ssr-server" ;;
v2ray) ret="/usr/bin/v2ray/v2ray" && [ ! -f "$ret" ] && ret="/usr/bin/v2ray" ;;
v2ray | vless)
ret="/usr/bin/v2ray/v2ray" && [ ! -f "$ret" ] && ret="/usr/bin/v2ray"
if [ $is_xray = "1" ]; then
ret="/usr/bin/xray" && [ ! -f "$ret" ] && ret="/usr/bin/xray/xray"
fi
;;
trojan) ret="/usr/sbin/trojan" ;;
socks5 | tun) ret="/usr/sbin/redsocks2" ;;
esac
@ -285,6 +293,9 @@ start_shunt() {
local server_port=${shunt_port[i]}
local server_type=$(uci_get_by_name $server_index type)
local server_ip=$(uci_get_by_name $server_index server)
if ["$server_type" == "vless"]; then
server_type="v2ray"
fi
[ "$server_type" == "trojan" ] && re_type="client" || re_type="tcp"
if [ "$server_type" != "v2ray" -a "$server_type" != "" ]; then
local config_file=/var/etc/${NAME}_${shunt_type[i]}.json
@ -326,8 +337,8 @@ start_redir() {
local kcp_param=$(uci_get_by_name $GLOBAL_SERVER kcp_param)
[ "$password" != "" ] && password="--key "${password}
service_start /usr/bin/kcptun-client \
-r $kcp_server:$kcp_port \
-l :$server_port $password $kcp_param
-r $kcp_server:$kcp_port \
-l :$server_port $password $kcp_param
kcp_enable_flag=1
fi
@ -357,7 +368,7 @@ start_redir() {
done
echo "$(date "+%Y-%m-%d %H:%M:%S") $name $threads 线程 已启动!" >>/tmp/vssr.log
;;
v2ray)
v2ray | vless)
$sscmd -config $last_config_file >/dev/null 2>&1 &
echo $sscmd
echo "$(date "+%Y-%m-%d %H:%M:%S") $($sscmd -version | head -1) 已启动!" >>/tmp/vssr.log
@ -398,7 +409,7 @@ start_redir() {
$ucmd -c $last_config_file $ARG_OTA -U -f /var/run/ssr-reudp.pid >/dev/null 2>&1
echo "$(date "+%Y-%m-%d %H:%M:%S") UDP TPROXY Relay: $name 已启动!" >>/tmp/vssr.log
;;
v2ray)
v2ray | vless)
$ucmd -config $last_config_file >/dev/null 2>&1 &
echo "$(date "+%Y-%m-%d %H:%M:%S") UDP TPROXY Relay: V2ray 已启动!" >>/tmp/vssr.log
;;
@ -599,7 +610,7 @@ stop() {
if [ $(uci_get_by_type global monitor_enable) = 1 ]; then
kill -9 $(busybox ps -w | grep vssr-monitor | grep -v grep | awk '{print $1}') >/dev/null 2>&1
fi
killall -q -9 ss-redir ss-local obfs-local ssr-redir ssr-local ssr-server v2ray v2ray-plugin trojan microsocks ipt2socks dns2socks redsocks2 pdnsd
killall -q -9 ss-redir ss-local obfs-local ssr-redir ssr-local ssr-server v2ray v2ray-plugin trojan microsocks ipt2socks dns2socks redsocks2 pdnsd xray
if [ -f "/tmp/dnsmasq.d/dnsmasq-ssr.conf" ]; then
rm -f /tmp/dnsmasq.d/dnsmasq-ssr.conf

View File

@ -1,5 +1,5 @@
echo "create china hash:net family inet hashsize 1024 maxelem 65536" >/tmp/china.ipset
awk '!/^$/&&!/^#/{printf("add china %s'" "'\n",$0)}' /etc/china_ssr.txt >>/tmp/china.ipset
awk '!/^$/&&!/^#/{printf("add china %s'" "'\n",$0)}' /etc/vssr/china_ssr.txt >>/tmp/china.ipset
ipset -! flush china
ipset -! restore </tmp/china.ipset 2>/dev/null
rm -f /tmp/china.ipset

View File

@ -7,6 +7,7 @@ local local_port = arg[3]
local outbounds_table = {}
local rules_table = {}
local v2ray_flow = ucursor:get_first(name, 'global', 'v2ray_flow', '0')
local proxy_domain_name = ucursor:get_list(name, '@access_control[0]', 'proxy_domain_name')
local flow_table = {
@ -145,13 +146,45 @@ local flow_table = {
}
}
local bt_rules = {
type = 'field',
outboundTag = 'bt',
protocol = {
'bittorrent'
}
}
local bt_rules1 = {
type = 'field',
outboundTag = 'bt',
domain = {
'torrent',
'peer_id=',
'info_hash',
'get_peers',
'find_node',
'BitTorrent',
'announce_peer',
'announce.php?passkey='
},
}
function gen_outbound(server_node, tags, local_ports)
local bound = {}
if server_node == nil or server_node == 'nil' then
bound = nil
else
local server = ucursor:get_all(name, server_node)
if server.type ~= 'v2ray' then
local outbound_security = "none"
if (server.xtls == '1') then
outbound_security = "xtls"
elseif (server.tls == '1') then
outbound_security = "tls"
elseif (server.tls == "0") then
outbound_security = "none"
end
local node_type = server.type == "vless" and "vless" or "vmess"
if server.type ~= 'v2ray' and server.type ~= 'vless' then
bound = {
tag = tags,
protocol = 'socks',
@ -164,7 +197,7 @@ function gen_outbound(server_node, tags, local_ports)
else
bound = {
tag = tags,
protocol = 'vmess',
protocol = node_type,
settings = {
vnext = {
{
@ -173,8 +206,10 @@ function gen_outbound(server_node, tags, local_ports)
users = {
{
id = server.vmess_id,
alterId = tonumber(server.alter_id),
security = server.security
alterId = server.type == "v2ray" and tonumber(server.alter_id) or nil,
security = server.type == "v2ray" and server.security or nil,
flow = (server.xtls == '1') and (server.vless_flow and server.vless_flow or "xtls-rprx-origin") or nil,
encryption = server.type == "vless" and server.vless_encryption or nil
}
}
}
@ -183,11 +218,9 @@ function gen_outbound(server_node, tags, local_ports)
-- 底层传输配置
streamSettings = {
network = server.transport,
security = (server.tls == '1') and 'tls' or 'none',
tlsSettings = {
allowInsecure = (server.insecure == '1') and true or false,
serverName = server.ws_host
},
security = outbound_security,
tlsSettings = (outbound_security == "tls") and {allowInsecure = (server.insecure ~= "0") and true or false,serverName=server.tls_host,} or nil,
xtlsSettings = (outbound_security == "xtls") and {allowInsecure = (server.insecure ~= "0") and true or false,serverName=server.tls_host,} or nil,
kcpSettings = (server.transport == 'kcp') and
{
mtu = tonumber(server.mtu),
@ -197,8 +230,7 @@ function gen_outbound(server_node, tags, local_ports)
congestion = (server.congestion == '1') and true or false,
readBufferSize = tonumber(server.read_buffer_size),
writeBufferSize = tonumber(server.write_buffer_size),
header = {type = server.kcp_guise},
seed = server.seed
header = {type = server.kcp_guise}
} or
nil,
wsSettings = (server.transport == 'ws') and (server.ws_path ~= nil or server.ws_host ~= nil) and
@ -226,6 +258,17 @@ function gen_outbound(server_node, tags, local_ports)
return bound
end
function gen_bt_outbounds()
local bound = {
tag = 'bt',
protocol = 'freedom',
settings = {
a = 1
}
}
return bound
end
if v2ray_flow == '1' then
table.insert(outbounds_table, gen_outbound(server_section, 'global', 2080))
for i, v in pairs(flow_table) do
@ -237,6 +280,10 @@ else
table.insert(outbounds_table, gen_outbound(server_section, 'main', local_port))
end
table.insert(outbounds_table, gen_bt_outbounds())
table.insert(rules_table, bt_rules)
table.insert(rules_table, bt_rules1)
local v2ray = {
log = {
-- error = "/var/vssrsss.log",

View File

@ -31,6 +31,7 @@ local ucic = luci.model.uci.cursor()
local proxy = ucic:get_first(name, 'server_subscribe', 'proxy', '0')
local switch = '0'
local subscribe_url = ucic:get_first(name, 'server_subscribe', 'subscribe_url', {})
local filter_words = ucic:get_first(name, 'server_subscribe', 'filter_words', '过期时间/剩余流量')
local log = function(...)
print(os.date('%Y-%m-%d %H:%M:%S ') .. table.concat({...}, ' '))
@ -104,7 +105,7 @@ local function base64Decode(text)
end
end
-- 处理数据
local function processData(szType, content)
local function processData(szType, content, groupName)
local result = {
-- auth_enable = '0',
-- switch_enable = '1',
@ -145,7 +146,7 @@ local function processData(szType, content)
result.transport = info.net
result.alter_id = info.aid
result.vmess_id = info.id
result.alias = info.ps
result.alias = groupName .. info.ps
-- result.mux = 1
-- result.concurrency = 8
if info.net == 'ws' then
@ -197,7 +198,7 @@ local function processData(szType, content)
local userinfo = base64Decode(hostInfo[1])
local method = userinfo:sub(1, userinfo:find(':') - 1)
local password = userinfo:sub(userinfo:find(':') + 1, #userinfo)
result.alias = UrlDecode(alias)
result.alias = groupName .. UrlDecode(alias)
result.type = 'ss'
result.server = host[1]
if host[2]:find('/%?') then
@ -234,7 +235,7 @@ local function processData(szType, content)
local hostInfo = split(info, '@')
local host = split(hostInfo[2], ':')
local password = hostInfo[1]
result.alias = UrlDecode(alias)
result.alias = groupName .. UrlDecode(alias)
result.type = 'trojan'
result.server = host[1]
result.insecure = '0'
@ -293,6 +294,18 @@ local function wget(url)
return trim(stdout)
end
local function check_filer(result)
do
local filter_word = split(filter_words, "/")
for i, v in pairs(filter_word) do
if result.alias:find(v) then
log('订阅节点关键字过滤:“' .. v ..'” ,该节点被丢弃')
return true
end
end
end
end
local execute = function()
-- exec
do
@ -301,6 +314,10 @@ local execute = function()
luci.sys.init.stop(name)
end
for k, url in ipairs(subscribe_url) do
local groupName = ""
urlTable = split(url, ",")
groupName = table.getn(urlTable) > 1 and '[' .. urlTable[1] .. '] ' or ""
url = table.getn(urlTable) > 1 and urlTable[2] or url
local raw = wget(url)
if #raw > 0 then
local nodes, szType
@ -334,15 +351,15 @@ local execute = function()
if v then
local result
if szType == 'ssd' then
result = processData(szType, v)
result = processData(szType, v, groupName)
elseif not szType then
local node = trim(v)
local dat = split(node, '://')
if dat and dat[1] and dat[2] then
if dat[1] == 'ss' then
result = processData(dat[1], dat[2])
result = processData(dat[1], dat[2], groupName)
else
result = processData(dat[1], base64Decode(dat[2]))
result = processData(dat[1], base64Decode(dat[2]), groupName)
end
end
else
@ -351,10 +368,11 @@ local execute = function()
-- log(result)
if result then
if
result.alias:find('过期时间') or result.alias:find('剩余流量') or result.alias:find('QQ群') or
result.alias:find('不支持') or
result.alias:find('官网') or
not result.server
not result.server or
not result.server_port or
result.alias == "NULL" or
check_filer(result) or
result.server:match("[^0-9a-zA-Z%-%.%s]") -- 中文做地址的 也没有人拿中文域名搞就算中文域也有Puny Code SB 机场
then
log('丢弃无效节点: ' .. result.type .. ' 节点, ' .. result.alias)
else

View File

@ -21,8 +21,7 @@ define Package/default-settings
CATEGORY:=LuCI
TITLE:=LuCI support for Default Settings
PKGARCH:=all
DEPENDS:=+luci-base +@LUCI_LANG_zh-cn \
+bash
DEPENDS:=+luci-base +@LUCI_LANG_en +@LUCI_LANG_zh-cn
endef
define Package/default-settings/description

View File

@ -35,7 +35,7 @@ sed -i '/openwrt_packages/ { s/snapshots/releases\/18.06.9/g; }' /etc/opkg/dist
sed -i "s/# //g" /etc/opkg/distfeeds.conf
sed -i 's/root::0:0:99999:7:::/root:$1$V4UetPzk$CYXluq4wUazHjmCDBCqXF.:0:0:99999:7:::/g' /etc/shadow
sed -i 's|root:x:0:0:root:/root:/bin/ash|root:x:0:0:root:/root:/bin/bash|g' /etc/passwd
[ -f '/bin/bash' ] && sed -i 's|root:x:0:0:root:/root:/bin/ash|root:x:0:0:root:/root:/bin/bash|g' /etc/passwd
sed -i '/option disabled/d' /etc/config/wireless
sed -i '/set wireless.radio${devidx}.disabled/d' /lib/wifi/mac80211.sh

View File

@ -1,32 +1,41 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-ssr-plus
PKG_VERSION:=180
PKG_RELEASE:=10
PKG_VERSION:=181
PKG_RELEASE:=2
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)/conffiles
/etc/config/shadowsocksr
/etc/ssr/
endef
define Package/$(PKG_NAME)/config
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_plugin
bool "Include Shadowsocks V2ray Plugin"
default y if i386||x86_64||arm||aarch64
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray
bool "Include V2ray"
config PACKAGE_$(PKG_NAME)_INCLUDE_Xray
bool "Include Xray"
default y if i386||x86_64||arm||aarch64
config PACKAGE_$(PKG_NAME)_INCLUDE_Trojan
bool "Include Trojan"
default y if i386||x86_64||arm||aarch64
config PACKAGE_$(PKG_NAME)_INCLUDE_Redsocks2
bool "Include Redsocks2"
default y if i386||x86_64||arm||aarch64
config PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy
bool "Include NaiveProxy"
depends on !(arc||armeb||mips||mips64||powerpc)
default y if i386||x86_64||arm||aarch64
config PACKAGE_$(PKG_NAME)_INCLUDE_Redsocks2
bool "Include Redsocks2"
default y if i386||x86_64||arm||aarch64
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray
bool "Include V2ray"
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun
bool "Include Kcptun"
@ -40,18 +49,20 @@ endef
PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_plugin \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Xray \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Trojan \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Redsocks2 \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server
LUCI_TITLE:=SS/SSR/V2Ray/Trojan/NaiveProxy/Socks5/Tun LuCI interface
LUCI_TITLE:=SS/SSR/V2Ray/Xray/Trojan/NaiveProxy/Socks5/Tun LuCI interface
LUCI_PKGARCH:=all
LUCI_DEPENDS:=+shadowsocksr-libev-alt +ipset +ip-full +iptables-mod-tproxy +dnsmasq-full +coreutils +coreutils-base64 +pdnsd-alt +wget +lua +libuci-lua \
+microsocks +dns2socks +shadowsocks-libev-ss-local +shadowsocksr-libev-ssr-local +shadowsocks-libev-ss-redir +simple-obfs +tcping +resolveip\
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_plugin:v2ray-plugin \
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray \
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:xray \
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:trojan \
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:ipt2socks \
+PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy:naiveproxy \

View File

@ -99,7 +99,7 @@ function refresh_data()
if type == "gfw_data" or type == "ad_data" then
luci.sys.exec("/usr/share/shadowsocksr/gfw2ipset.sh")
else
luci.sys.exec("/etc/init.d/shadowsocksr restart &")
luci.sys.exec("/usr/share/shadowsocksr/chinaipset.sh /tmp/etc/china_ssr.txt")
end
end
else
@ -111,7 +111,7 @@ function refresh_data()
update(uci:get_first("shadowsocksr", "global", "gfwlist_url", "https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt"), "/etc/ssr/gfw_list.conf", set, "/tmp/dnsmasq.ssr/gfw_list.conf")
end
if set == "ip_data" then
update(uci:get_first("shadowsocksr", "global", "chnroute_url","https://ispip.clang.cn/all_cn.txt"), "/etc/ssr/china_ssr.txt", set)
update(uci:get_first("shadowsocksr", "global", "chnroute_url","https://ispip.clang.cn/all_cn.txt"), "/etc/ssr/china_ssr.txt", set, "/tmp/etc/china_ssr.txt")
end
if set == "ad_data" then
update(uci:get_first("shadowsocksr", "global", "adblock_url","https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt"), "/etc/ssr/ad.conf", set, "/tmp/dnsmasq.ssr/ad.conf")

Some files were not shown because too many files have changed in this diff Show More