💐 Sync 2026-06-16 03:30:28

This commit is contained in:
github-actions[bot] committed 2026-06-16 03:30:28 +08:00
1 parent 8ec851d7f4
commit add0d22fb0
149 files changed
+13 -23537

No files matched your search

-165
View File
@@ -1,165 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
-175
View File
@@ -1,175 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-clash
PKG_VERSION:=v1.8.0
PKG_RELEASE:=1
PKG_MAINTAINER:=frainzy1477
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=luci
CATEGORY:=LuCI
SUBMENU:=2. Clash For OpenWRT
TITLE:=LuCI app for clash
DEPENDS:=+luci-base +wget +iptables +coreutils-base64 +coreutils +coreutils-nohup +bash +ipset +libustream-openssl +curl +jsonfilter +ca-certificates +iptables-mod-tproxy +kmod-tun
PKGARCH:=all
MAINTAINER:=frainzy1477
endef
define Package/$(PKG_NAME)/description
Luci Interface for clash.
endef
define Build/Prepare
po2lmo ${CURDIR}/po/zh-cn/clash.po ${CURDIR}/po/zh-cn/clash.zh-cn.lmo
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/$(PKG_NAME)/conffiles
/etc/config/clash
endef
define Package/$(PKG_NAME)/prerm
#!/bin/sh
# check if we are on real system
if [ -z "$${IPKG_INSTROOT}" ]; then
echo "Removing rc.d symlink for clash"
/etc/init.d/clash disable
/etc/init.d/clash stop
echo "Removing firewall rule for clash"
uci -q batch <<-EOF >/dev/null
delete firewall.clash
commit firewall
EOF
fi
exit 0
endef
define Package/$(PKG_NAME)/preinst
#!/bin/sh
/etc/init.d/clash disable 2>/dev/null
if [ -z "$${IPKG_INSTROOT}" ]; then
rm -rf /tmp/dnsmasq.d/custom_list.conf 2>/dev/null
rm -rf /tmp/dnsmasq.clash 2>/dev/null
mv /etc/config/clash /etc/config/clash.bak 2>/dev/null
rm -rf /usr/lib/lua/luci/model/cbi/clash 2>/dev/null
rm -rf /usr/lib/lua/luci/view/clash 2>/dev/null
rm -rf /usr/share/clash/new_core_version 2>/dev/null
rm -rf /usr/share/clash/new_clashr_core_version 2>/dev/null
rm -rf /usr/share/clash/new_luci_version 2>/dev/null
rm -rf /usr/share/clash/web 2>/dev/null
mv /usr/share/clash/config/sub/config.yaml /usr/share/clashbackup/config.bak1 2>/dev/null
mv /usr/share/clash/config/upload/config.yaml /usr/share/clashbackup/config.bak2 2>/dev/null
mv /usr/share/clash/config/custom/config.yaml /usr/share/clashbackup/config.bak3 2>/dev/null
mv /usr/share/clash/rule.yaml /usr/share/clashbackup/rule.bak 2>/dev/null
fi
exit 0
endef
define Package/$(PKG_NAME)/postinst
#!/bin/sh
if [ -z "$${IPKG_INSTROOT}" ]; then
rm -rf /tmp/luci*
mv /etc/config/clash.bak /etc/config/clash 2>/dev/null
mv /usr/share/clashbackup/config.bak1 /usr/share/clash/config/sub/config.yaml 2>/dev/null
mv /usr/share/clashbackup/config.bak2 /usr/share/clash/config/upload/config.yaml 2>/dev/null
mv /usr/share/clashbackup/config.bak3 /usr/share/clash/config/custom/config.yaml 2>/dev/null
mv /usr/share/clashbackup/rule.bak /usr/share/clash/rule.yaml 2>/dev/null
/etc/init.d/clash disable 2>/dev/null
fi
/etc/init.d/clash disable 2>/dev/null
exit 0
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/controller
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi/clash
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi/clash/config
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi/clash/dns
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi/clash/client
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi/clash/game
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi/clash/geoip
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi/clash/logs
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi/clash/update
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/view/clash
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DIR) $(1)/etc/clash
$(INSTALL_DIR) $(1)/usr/lib/lua/luci
$(INSTALL_DIR) $(1)/usr/share/
$(INSTALL_DIR) $(1)/usr/share/clash
$(INSTALL_DIR) $(1)/usr/share/rpcd
$(INSTALL_DIR) $(1)/usr/share/rpcd/acl.d
$(INSTALL_DIR) $(1)/usr/share/clash/rules
$(INSTALL_DIR) $(1)/usr/share/clash/rules/g_rules
$(INSTALL_DIR) $(1)/etc/clash/dashboard
$(INSTALL_DIR) $(1)/etc/clash/dashboard/img
$(INSTALL_DIR) $(1)/etc/clash/dashboard/js
$(INSTALL_DIR) $(1)/usr/share/clash/yacd
$(INSTALL_DIR) $(1)/etc/clash/clashtun
$(INSTALL_DIR) $(1)/etc/clash/dtun
$(INSTALL_DIR) $(1)/usr/share/clashbackup
$(INSTALL_DIR) $(1)/usr/share/clash/create
$(INSTALL_DIR) $(1)/etc/clash/provider
$(INSTALL_DIR) $(1)/etc/clash/proxyprovider
$(INSTALL_DIR) $(1)/etc/clash/ruleprovider
$(INSTALL_DIR) $(1)/usr/share/clash/config
$(INSTALL_DIR) $(1)/usr/share/clash/config/sub
$(INSTALL_DIR) $(1)/usr/share/clash/config/upload
$(INSTALL_DIR) $(1)/usr/share/clash/config/custom
$(INSTALL_BIN) ./root/etc/init.d/clash $(1)/etc/init.d/clash
$(INSTALL_CONF) ./root/etc/config/clash $(1)/etc/config/clash
$(INSTALL_CONF) ./root/etc/clash/Country.mmdb $(1)/etc/clash
$(INSTALL_BIN) ./root/usr/share/clash/create/* $(1)/usr/share/clash/create
$(INSTALL_BIN) ./root/usr/share/clash/*.sh $(1)/usr/share/clash
$(INSTALL_BIN) ./root/usr/share/rpcd/acl.d/luci-app-clash.json $(1)/usr/share/rpcd/acl.d
$(INSTALL_BIN) ./root/usr/share/clash/rules/g_rules/Steam.rules $(1)/usr/share/clash/rules/g_rules
$(INSTALL_BIN) ./root//usr/share/clash/rules/rules.list $(1)/usr/share/clash/rules
$(INSTALL_BIN) ./root/usr/share/clash/luci_version $(1)/usr/share/clash
$(INSTALL_BIN) ./root/usr/share/clash/rule.yaml $(1)/usr/share/clash
$(INSTALL_BIN) ./root/usr/share/clash/server.list $(1)/usr/share/clash
$(INSTALL_BIN) ./root/usr/share/clash/clash_real.txt $(1)/usr/share/clash
$(INSTALL_BIN) ./root/usr/share/clash/logstatus_check $(1)/usr/share/clash
$(INSTALL_BIN) ./root/usr/share/clash/clash.txt $(1)/usr/share/clash
$(INSTALL_BIN) ./root/usr/share/clash/chinaipset.sh $(1)/usr/share/clash
$(INSTALL_BIN) ./root/usr/share/clash/china_ip.txt $(1)/usr/share/clash
$(INSTALL_BIN) ./root/usr/share/clash/dashboard/index.html $(1)/etc/clash/dashboard
$(INSTALL_BIN) ./root/usr/share/clash/dashboard/main.658aa6a6e3feec8f168b.css $(1)/etc/clash/dashboard
$(INSTALL_BIN) ./root/usr/share/clash/dashboard/img/ffac0fa1d89f15922b4594863b8b32e9.png $(1)/etc/clash/dashboard/img
$(INSTALL_BIN) ./root/usr/share/clash/dashboard/js/1.bundle.658aa6a6e3feec8f168b.min.js $(1)/etc/clash/dashboard/js
$(INSTALL_BIN) ./root/usr/share/clash/dashboard/js/bundle.658aa6a6e3feec8f168b.min.js $(1)/etc/clash/dashboard/js
$(INSTALL_BIN) ./root/usr/share/clash/yacd/* $(1)/usr/share/clash/yacd
$(INSTALL_DATA) ./luasrc/clash.lua $(1)/usr/lib/lua/luci
$(INSTALL_DATA) ./luasrc/controller/*.lua $(1)/usr/lib/lua/luci/controller
$(INSTALL_DATA) ./luasrc/model/cbi/clash/*.lua $(1)/usr/lib/lua/luci/model/cbi/clash
$(INSTALL_DATA) ./luasrc/model/cbi/clash/config/*.lua $(1)/usr/lib/lua/luci/model/cbi/clash/config
$(INSTALL_DATA) ./luasrc/model/cbi/clash/client/*.lua $(1)/usr/lib/lua/luci/model/cbi/clash/client
$(INSTALL_DATA) ./luasrc/model/cbi/clash/dns/*.lua $(1)/usr/lib/lua/luci/model/cbi/clash/dns
$(INSTALL_DATA) ./luasrc/model/cbi/clash/game/*.lua $(1)/usr/lib/lua/luci/model/cbi/clash/game
$(INSTALL_DATA) ./luasrc/model/cbi/clash/geoip/*.lua $(1)/usr/lib/lua/luci/model/cbi/clash/geoip
$(INSTALL_DATA) ./luasrc/model/cbi/clash/logs/*.lua $(1)/usr/lib/lua/luci/model/cbi/clash/logs
$(INSTALL_DATA) ./luasrc/model/cbi/clash/update/*.lua $(1)/usr/lib/lua/luci/model/cbi/clash/update
$(INSTALL_DATA) ./luasrc/view/clash/* $(1)/usr/lib/lua/luci/view/clash
$(INSTALL_DATA) ./po/zh-cn/clash.zh-cn.lmo $(1)/usr/lib/lua/luci/i18n
endef
$(eval $(call BuildPackage,$(PKG_NAME)))
-104
View File
@@ -1,104 +0,0 @@
<h2 align="center">
<img src="https://cdn.jsdelivr.net/gh/Dreamacro/clash/docs/logo.png" alt="Clash" width="200">
<br>Luci App For Clash <br>
</h2>
<p align="center">
A rule based custom proxy client for Openwrt based on <a href="https://github.com/Dreamacro/clash" target="_blank">Clash</a>.
</p>
<p align="center">
<a target="_blank" href="https://github.com/frainzy1477/luci-app-clash/releases/tag/v1.7.5.7">
<img src="https://img.shields.io/badge/luci%20for%20clash-v1.7.5.7-blue.svg">
</a>
<a href="https://github.com/frainzy1477/luci-app-clash/releases" target="_blank">
<img src="https://img.shields.io/github/downloads/frainzy1477/luci-app-clash/total.svg?style=flat-square"/>
</a>
</p>
## Install
- Upload ipk file to tmp folder
- cd /tmp
- opkg update
- opkg install luci-app-clash_v1.7.5.7_all.ipk
- opkg install luci-app-clash_v1.7.5.7_all.ipk --force-depends
## Uninstall
- opkg remove luci-app-clash
- opkg remove luci-app-clash --force-remove
## Features
- Subscription Config
- Config Upload
- Create Config
- GeoIP Database Update
- TProxy UDP
- IP Query
- DNS Forwarding
- Support Trojan(Trojan-GFW & Trojan-Go)
- Support SSR
- Support SS
- Support V2ray
- Support Snell
- Ping Custom Proxy Servers
- Tun Support
- Access Control
- Support Provider,
- Game Rules
- Restore Config
## Dependency
- bash
- coreutils
- coreutils-nohup
- coreutils-base64
- ipset
- iptables
- luci
- luci-base
- wget
- libustream-openssl
- curl
- jsonfilter
- ca-certificates
- iptables-mod-tproxy
- kmod-tun
## compile
---
- Download [SDK](https://wiki.openwrt.org/doc/howto/obtain.firmware.sdk), and it's depends:
```bash
sudo apt-get install gawk libncurses5-dev libz-dev zlib1g-dev git ccache
```
- Download your own SDK
```bash
# Untar ar71xx platform
tar xjf OpenWrt-SDK-15.05-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64.tar.bz2
cd OpenWrt-SDK-*
# update feeds
./scripts/feeds update packages
# Clone
git clone https://github.com/frainzy1477/luci-app-clash.git package/luci-app-clash
# select this package
make menuconfig
# Compile and install po2lmo bin for build i18n language files
pushd package/luci-app-clash/tools/po2lmo
make && sudo make install
popd
# I18n language files
po2lmo ./package/luci-app-clash/po/zh-cn/clash.po ./package/luci-app-clash/po/zh-cn/clash.zh-cn.lmo
# Compile
make package/luci-app-clash/compile V=99
```
## License
Luci App For Clash - OpenWrt is released under the GPL v3.0 License - see detailed [LICENSE](https://github.com/frainzy1477/luci-app-clash/blob/master/LICENSE) .
-244
View File
@@ -1,244 +0,0 @@
--[[
LuCI - Filesystem tools
Description:
A module offering often needed filesystem manipulation functions
FileId:
$Id$
License:
Copyright 2008 Steven Barth <steven@midlink.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
]]--
local io = require "io"
local os = require "os"
local ltn12 = require "luci.ltn12"
local fs = require "nixio.fs"
local nutil = require "nixio.util"
local type = type
--- LuCI filesystem library.
module "luci.clash"
--- Test for file access permission on given path.
-- @class function
-- @name access
-- @param str String value containing the path
-- @return Number containing the return code, 0 on sucess or nil on error
-- @return String containing the error description (if any)
-- @return Number containing the os specific errno (if any)
access = fs.access
--- Evaluate given shell glob pattern and return a table containing all matching
-- file and directory entries.
-- @class function
-- @name glob
-- @param filename String containing the path of the file to read
-- @return Table containing file and directory entries or nil if no matches
-- @return String containing the error description (if no matches)
-- @return Number containing the os specific errno (if no matches)
function glob(...)
local iter, code, msg = fs.glob(...)
if iter then
return nutil.consume(iter)
else
return nil, code, msg
end
end
--- Checks wheather the given path exists and points to a regular file.
-- @param filename String containing the path of the file to test
-- @return Boolean indicating wheather given path points to regular file
function isfile(filename)
return fs.stat(filename, "type") == "reg"
end
--- Checks wheather the given path exists and points to a directory.
-- @param dirname String containing the path of the directory to test
-- @return Boolean indicating wheather given path points to directory
function isdirectory(dirname)
return fs.stat(dirname, "type") == "dir"
end
--- Read the whole content of the given file into memory.
-- @param filename String containing the path of the file to read
-- @return String containing the file contents or nil on error
-- @return String containing the error message on error
readfile = fs.readfile
--- Write the contents of given string to given file.
-- @param filename String containing the path of the file to read
-- @param data String containing the data to write
-- @return Boolean containing true on success or nil on error
-- @return String containing the error message on error
writefile = fs.writefile
--- Copies a file.
-- @param source Source file
-- @param dest Destination
-- @return Boolean containing true on success or nil on error
copy = fs.datacopy
--- Renames a file.
-- @param source Source file
-- @param dest Destination
-- @return Boolean containing true on success or nil on error
rename = fs.move
--- Get the last modification time of given file path in Unix epoch format.
-- @param path String containing the path of the file or directory to read
-- @return Number containing the epoch time or nil on error
-- @return String containing the error description (if any)
-- @return Number containing the os specific errno (if any)
function mtime(path)
return fs.stat(path, "mtime")
end
--- Set the last modification time of given file path in Unix epoch format.
-- @param path String containing the path of the file or directory to read
-- @param mtime Last modification timestamp
-- @param atime Last accessed timestamp
-- @return 0 in case of success nil on error
-- @return String containing the error description (if any)
-- @return Number containing the os specific errno (if any)
function utime(path, mtime, atime)
return fs.utimes(path, atime, mtime)
end
--- Return the last element - usually the filename - from the given path with
-- the directory component stripped.
-- @class function
-- @name basename
-- @param path String containing the path to strip
-- @return String containing the base name of given path
-- @see dirname
basename = fs.basename
--- Return the directory component of the given path with the last element
-- stripped of.
-- @class function
-- @name dirname
-- @param path String containing the path to strip
-- @return String containing the directory component of given path
-- @see basename
dirname = fs.dirname
--- Return a table containing all entries of the specified directory.
-- @class function
-- @name dir
-- @param path String containing the path of the directory to scan
-- @return Table containing file and directory entries or nil on error
-- @return String containing the error description on error
-- @return Number containing the os specific errno on error
function dir(...)
local iter, code, msg = fs.dir(...)
if iter then
local t = nutil.consume(iter)
t[#t+1] = "."
t[#t+1] = ".."
return t
else
return nil, code, msg
end
end
--- Create a new directory, recursively on demand.
-- @param path String with the name or path of the directory to create
-- @param recursive Create multiple directory levels (optional, default is true)
-- @return Number with the return code, 0 on sucess or nil on error
-- @return String containing the error description on error
-- @return Number containing the os specific errno on error
function mkdir(path, recursive)
return recursive and fs.mkdirr(path) or fs.mkdir(path)
end
--- Remove the given empty directory.
-- @class function
-- @name rmdir
-- @param path String containing the path of the directory to remove
-- @return Number with the return code, 0 on sucess or nil on error
-- @return String containing the error description on error
-- @return Number containing the os specific errno on error
rmdir = fs.rmdir
local stat_tr = {
reg = "regular",
dir = "directory",
lnk = "link",
chr = "character device",
blk = "block device",
fifo = "fifo",
sock = "socket"
}
--- Get information about given file or directory.
-- @class function
-- @name stat
-- @param path String containing the path of the directory to query
-- @return Table containing file or directory properties or nil on error
-- @return String containing the error description on error
-- @return Number containing the os specific errno on error
function stat(path, key)
local data, code, msg = fs.stat(path)
if data then
data.mode = data.modestr
data.type = stat_tr[data.type] or "?"
end
return key and data and data[key] or data, code, msg
end
--- Set permissions on given file or directory.
-- @class function
-- @name chmod
-- @param path String containing the path of the directory
-- @param perm String containing the permissions to set ([ugoa][+-][rwx])
-- @return Number with the return code, 0 on sucess or nil on error
-- @return String containing the error description on error
-- @return Number containing the os specific errno on error
chmod = fs.chmod
--- Create a hard- or symlink from given file (or directory) to specified target
-- file (or directory) path.
-- @class function
-- @name link
-- @param path1 String containing the source path to link
-- @param path2 String containing the destination path for the link
-- @param symlink Boolean indicating wheather to create a symlink (optional)
-- @return Number with the return code, 0 on sucess or nil on error
-- @return String containing the error description on error
-- @return Number containing the os specific errno on error
function link(src, dest, sym)
return sym and fs.symlink(src, dest) or fs.link(src, dest)
end
--- Remove the given file.
-- @class function
-- @name unlink
-- @param path String containing the path of the file to remove
-- @return Number with the return code, 0 on sucess or nil on error
-- @return String containing the error description on error
-- @return Number containing the os specific errno on error
unlink = fs.unlink
--- Retrieve target of given symlink.
-- @class function
-- @name readlink
-- @param path String containing the path of the symlink to read
-- @return String containing the link target or nil on error
-- @return String containing the error description on error
-- @return Number containing the os specific errno on error
readlink = fs.readlink
-442
View File
@@ -1,442 +0,0 @@
module("luci.controller.clash", package.seeall)
local fs=require"nixio.fs"
local http=require"luci.http"
local uci=require"luci.model.uci".cursor()
function index()
if not nixio.fs.access("/etc/config/clash") then
return
end
local page = entry({"admin", "services", "clash"},alias("admin", "services", "clash", "overview"), _("Clash"), 1)
page.dependent = true
page.acl_depends = {"luci-app-clash"}
entry({"admin", "services", "clash", "overview"},cbi("clash/overview"),_("Overview"), 10).leaf = true
entry({"admin", "services", "clash", "client"},cbi("clash/client/client"),_("Client"), 20).leaf = true
entry({"admin", "services", "clash", "config"}, firstchild(),_("Config"), 25)
entry({"admin", "services", "clash", "config", "import"},cbi("clash/config/import"),_("Import Config"), 25).leaf = true
entry({"admin", "services", "clash", "config", "config"},cbi("clash/config/config"),_("Select Config"), 30).leaf = true
entry({"admin", "services", "clash", "config", "create"},cbi("clash/config/create"),_("Create Config"), 35).leaf = true
entry({"admin", "services", "clash", "proxyprovider"},cbi("clash/config/proxy_provider"), nil).leaf = true
entry({"admin", "services", "clash", "servers"},cbi("clash/config/servers-config"), nil).leaf = true
entry({"admin", "services", "clash", "ruleprovider"},cbi("clash/config/rule_provider"), nil).leaf = true
entry({"admin", "services", "clash", "rules"},cbi("clash/config/rules"), nil).leaf = true
entry({"admin", "services", "clash", "pgroups"},cbi("clash/config/groups"), nil).leaf = true
entry({"admin", "services", "clash", "rulemanager"},cbi("clash/config/ruleprovider_manager"), nil).leaf = true
entry({"admin", "services", "clash", "settings"}, firstchild(),_("Settings"), 40)
entry({"admin", "services", "clash", "settings", "port"},cbi("clash/dns/port"),_("Proxy Ports"), 60).leaf = true
entry({"admin", "services", "clash", "settings", "geoip"},cbi("clash/geoip/geoip"),_("Update GeoIP"), 80).leaf = true
entry({"admin", "services", "clash", "settings", "grules"},cbi("clash/game/game-settings"),_("Game Rules"), 91).dependent = false
entry({"admin", "services", "clash", "g-rules"},cbi("clash/game/game-rule"), nil).leaf = true
entry({"admin", "services", "clash", "settings", "other"},cbi("clash/other"),_("Other Settings"), 92).leaf = true
entry({"admin", "services", "clash", "ip-rules"},cbi("clash/config/ip-rules"), nil).leaf = true
entry({"admin", "services", "clash", "settings", "dns"},firstchild(),_("DNS Settings"), 65)
entry({"admin", "services", "clash", "settings", "dns", "dns"},cbi("clash/dns/dns"),_("Clash DNS"), 70).leaf = true
entry({"admin", "services", "clash", "settings", "dns", "advance"},cbi("clash/dns/advance"),_("Advance DNS"), 75).leaf = true
entry({"admin", "services", "clash", "update"},cbi("clash/update/update"),_("Update"), 45).leaf = true
entry({"admin", "services", "clash", "log"},cbi("clash/logs/log"),_("Log"), 50).leaf = true
entry({"admin","services","clash","check_status"},call("check_status")).leaf=true
entry({"admin", "services", "clash", "ping"}, call("act_ping")).leaf=true
entry({"admin", "services", "clash", "readlog"},call("action_read")).leaf=true
entry({"admin","services","clash", "status"},call("action_status")).leaf=true
entry({"admin", "services", "clash", "check"}, call("check_update_log")).leaf=true
entry({"admin", "services", "clash", "doupdate"}, call("do_update")).leaf=true
entry({"admin", "services", "clash", "start"}, call("do_start")).leaf=true
entry({"admin", "services", "clash", "stop"}, call("do_stop")).leaf=true
entry({"admin", "services", "clash", "reload"}, call("do_reload")).leaf=true
entry({"admin", "services", "clash", "geo"}, call("geoip_check")).leaf=true
entry({"admin", "services", "clash", "geoipupdate"}, call("geoip_update")).leaf=true
entry({"admin", "services", "clash", "check_geoip"}, call("check_geoip_log")).leaf=true
entry({"admin", "services", "clash", "corelog"},call("down_check")).leaf=true
entry({"admin", "services", "clash", "logstatus"},call("logstatus_check")).leaf=true
entry({"admin", "services", "clash", "conf"},call("action_conf")).leaf=true
entry({"admin", "services", "clash", "update_config"},call("action_update")).leaf=true
entry({"admin", "services", "clash", "game_rule"},call("action_update_rule")).leaf=true
entry({"admin", "services", "clash", "ruleproviders"},call("action_update_rule_providers")).leaf=true
entry({"admin", "services", "clash", "ping_check"},call("action_ping_status")).leaf=true
end
local fss = require "luci.clash"
local function download_rule_provider()
local filename = luci.http.formvalue("filename")
local status = luci.sys.call(string.format('/usr/share/clash/create/clash_rule_provider.sh "%s" >/dev/null 2>&1',filename))
return status
end
function action_update_rule_providers()
luci.http.prepare_content("application/json")
luci.http.write_json({
rulep = download_rule_provider();
})
end
local function uhttp_port()
local uhttp_port = luci.sys.exec("uci get uhttpd.main.listen_http |awk -F ':' '{print $NF}'")
if uhttp_port ~= "80" then
return ":" .. uhttp_port
end
end
local function download_rule()
local filename = luci.http.formvalue("filename")
local rule_file_dir="/usr/share/clash/rules/g_rules/" .. filename
luci.sys.call(string.format('sh /usr/share/clash/clash_game_rule.sh "%s" >/dev/null 2>&1',filename))
if not fss.isfile(rule_file_dir) then
return "0"
else
return "1"
end
end
function action_update_rule()
luci.http.prepare_content("application/json")
luci.http.write_json({
game_rule = download_rule()
})
end
function action_update()
luci.sys.exec("kill $(pgrep /usr/share/clash/update.sh) ; (bash /usr/share/clash/update.sh >/usr/share/clash/clash.txt 2>&1) &")
end
local function in_use()
return luci.sys.exec("uci get clash.config.config_type")
end
local function conf_path()
if nixio.fs.access(string.sub(luci.sys.exec("uci get clash.config.use_config"), 1, -2)) then
return fss.basename(string.sub(luci.sys.exec("uci get clash.config.use_config"), 1, -2))
else
return ""
end
end
local function typeconf()
return luci.sys.exec("uci get clash.config.config_type")
end
function action_conf()
luci.http.prepare_content("application/json")
luci.http.write_json({
conf_path = conf_path(),
typeconf = typeconf()
})
end
local function dash_port()
return luci.sys.exec("uci get clash.config.dash_port 2>/dev/null")
end
local function dash_pass()
return luci.sys.exec("uci get clash.config.dash_pass 2>/dev/null")
end
local function is_running()
return luci.sys.call("pidof clash >/dev/null") == 0
end
local function is_web()
return luci.sys.call("pidof clash >/dev/null") == 0
end
local function localip()
return luci.sys.exec("uci get network.lan.ipaddr")
end
local function check_version()
return luci.sys.exec("sh /usr/share/clash/check_luci_version.sh")
end
local function check_core()
return luci.sys.exec("sh /usr/share/clash/check_core_version.sh")
end
local function check_clashtun_core()
return luci.sys.exec("sh /usr/share/clash/check_clashtun_core_version.sh")
end
local function current_version()
return luci.sys.exec("sed -n 1p /usr/share/clash/luci_version")
end
local function new_version()
return luci.sys.exec("sed -n 1p /usr/share/clash/new_luci_version")
end
local function new_core_version()
return luci.sys.exec("sed -n 1p /usr/share/clash/new_core_version")
end
local function new_clashtun_core_version()
return luci.sys.exec("sed -n 1p /usr/share/clash/new_clashtun_core_version")
end
local function check_dtun_core()
return luci.sys.call(string.format("sh /usr/share/clash/check_dtun_core_version.sh"))
end
local function new_dtun_core()
return luci.sys.exec("sed -n 1p /usr/share/clash/new_clashdtun_core_version")
end
local function e_mode()
return luci.sys.exec("egrep '^ {0,}enhanced-mode' /etc/clash/config.yaml |grep enhanced-mode: |awk -F ': ' '{print $2}'")
end
local function clash_core()
if nixio.fs.access("/etc/clash/clash") then
local core=luci.sys.exec("/etc/clash/clash -v 2>/dev/null |awk -F ' ' '{print $2}'")
if core ~= "" then
return luci.sys.exec("/etc/clash/clash -v 2>/dev/null |awk -F ' ' '{print $2}'")
else
return luci.sys.exec("sed -n 1p /usr/share/clash/core_version")
end
else
return "0"
end
end
local function clashtun_core()
if nixio.fs.access("/etc/clash/clashtun/clash") then
local tun=luci.sys.exec("/etc/clash/clashtun/clash -v 2>/dev/null |awk -F ' ' '{print $2}'")
if tun ~= "" then
return luci.sys.exec("/etc/clash/clashtun/clash -v 2>/dev/null |awk -F ' ' '{print $2}'")
else
return luci.sys.exec("sed -n 1p /usr/share/clash/tun_version")
end
else
return "0"
end
end
local function dtun_core()
if nixio.fs.access("/etc/clash/dtun/clash") then
local tun=luci.sys.exec("/etc/clash/dtun/clash -v 2>/dev/null |awk -F ' ' '{print $2}'")
if tun ~= "" then
return luci.sys.exec("/etc/clash/dtun/clash -v 2>/dev/null |awk -F ' ' '{print $2}'")
else
return luci.sys.exec("sed -n 1p /usr/share/clash/dtun_core_version")
end
else
return "0"
end
end
local function readlog()
return luci.sys.exec("sed -n '$p' /usr/share/clash/clash_real.txt 2>/dev/null")
end
local function geo_data()
return os.date("%Y-%m-%d %H:%M:%S",fss.mtime("/etc/clash/Country.mmdb"))
end
local function downcheck()
if nixio.fs.access("/var/run/core_update_error") then
return "0"
elseif nixio.fs.access("/var/run/core_update") then
return "1"
elseif nixio.fs.access("/usr/share/clash/core_down_complete") then
return "2"
end
end
function action_read()
luci.http.prepare_content("application/json")
luci.http.write_json({
readlog = readlog();
})
end
function down_check()
luci.http.prepare_content("application/json")
luci.http.write_json({
downcheck = downcheck();
})
end
local function geoipcheck()
if nixio.fs.access("/var/run/geoip_update_error") then
return "0"
elseif nixio.fs.access("/var/run/geoip_update") then
return "1"
elseif nixio.fs.access("/var/run/geoip_down_complete") then
return "2"
end
end
function geoip_check()
luci.http.prepare_content("application/json")
luci.http.write_json({
geoipcheck = geoipcheck();
})
end
function check_status()
luci.http.prepare_content("application/json")
luci.http.write_json({
check_version = check_version(),
check_core = check_core(),
current_version = current_version(),
new_version = new_version(),
clash_core = clash_core(),
check_dtun_core = check_dtun_core(),
new_dtun_core = new_dtun_core(),
clashtun_core = clashtun_core(),
dtun_core = dtun_core(),
new_core_version = new_core_version(),
new_clashtun_core_version =new_clashtun_core_version(),
check_clashtun_core = check_clashtun_core(),
conf_path = conf_path(),
typeconf = typeconf()
})
end
function action_status()
luci.http.prepare_content("application/json")
luci.http.write_json({
web = is_web(),
clash = is_running(),
localip = localip(),
dash_port = dash_port(),
current_version = current_version(),
new_dtun_core = new_dtun_core(),
new_core_version = new_core_version(),
new_clashtun_core_version =new_clashtun_core_version(),
new_version = new_version(),
clash_core = clash_core(),
dtun_core = dtun_core(),
dash_pass = dash_pass(),
clashtun_core = clashtun_core(),
e_mode = e_mode(),
in_use = in_use(),
conf_path = conf_path(),
uhttp_port = uhttp_port(),
typeconf = typeconf()
})
end
function action_ping_status()
luci.http.prepare_content("application/json")
luci.http.write_json({
ping_enable = ping_enable()
})
end
function act_ping()
local e={}
e.index=luci.http.formvalue("index")
e.ping=luci.sys.exec("ping -c 1 -W 1 -w 5 %q 2>&1 | grep -o 'time=[0-9]*.[0-9]' | awk -F '=' '{print$2}'"%luci.http.formvalue("domain"))
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function geoip_update()
fs.writefile("/var/run/geoiplog","0")
luci.sys.exec("(rm /var/run/geoip_update_error ; touch /var/run/geoip_update ; sh /usr/share/clash/geoip.sh >/tmp/geoip_update.txt 2>&1 || touch /var/run/geoip_update_error ;rm /var/run/geoip_update) &")
end
function do_update()
fs.writefile("/var/run/clashlog","0")
luci.sys.exec("(rm /var/run/core_update_error ; touch /var/run/core_update ; sh /usr/share/clash/core_download.sh >/tmp/clash_update.txt 2>&1 || touch /var/run/core_update_error ;rm /var/run/core_update) &")
end
function do_start()
luci.sys.exec('uci set clash.config.enable="1" && uci commit clash')
luci.sys.exec("/etc/init.d/clash restart 2>&1 &")
end
function do_stop()
luci.sys.exec('uci set clash.config.enable="0" && uci commit clash')
luci.sys.exec("/etc/init.d/clash stop 2>&1 &")
end
function do_reload()
if luci.sys.call("pidof clash >/dev/null") == 0 then
luci.sys.exec("/etc/init.d/clash reload 2>&1 &")
end
end
function check_update_log()
luci.http.prepare_content("text/plain; charset=utf-8")
local fdp=tonumber(fs.readfile("/var/run/clashlog")) or 0
local f=io.open("/tmp/clash_update.txt", "r+")
f:seek("set",fdp)
local a=f:read(2048000) or ""
fdp=f:seek()
fs.writefile("/var/run/clashlog",tostring(fdp))
f:close()
if fs.access("/var/run/core_update") then
luci.http.write(a)
else
luci.http.write(a.."\0")
end
end
function check_geoip_log()
luci.http.prepare_content("text/plain; charset=utf-8")
local fdp=tonumber(fs.readfile("/var/run/geoiplog")) or 0
local f=io.open("/tmp/geoip_update.txt", "r+")
f:seek("set",fdp)
local a=f:read(2048000) or ""
fdp=f:seek()
fs.writefile("/var/run/geoiplog",tostring(fdp))
f:close()
if fs.access("/var/run/geoip_update") then
luci.http.write(a)
else
luci.http.write(a.."\0")
end
end
function logstatus_check()
luci.http.prepare_content("text/plain; charset=utf-8")
local fdp=tonumber(fs.readfile("/usr/share/clash/logstatus_check")) or 0
local f=io.open("/usr/share/clash/clash.txt", "r+")
f:seek("set",fdp)
local a=f:read(2048000) or ""
fdp=f:seek()
fs.writefile("/usr/share/clash/logstatus_check",tostring(fdp))
f:close()
if fs.access("/var/run/logstatus") then
luci.http.write(a)
else
luci.http.write(a.."\0")
end
end
@@ -1,56 +0,0 @@
local NXFS = require "nixio.fs"
local SYS = require "luci.sys"
local HTTP = require "luci.http"
local DISP = require "luci.dispatcher"
local UTIL = require "luci.util"
local uci = require("luci.model.uci").cursor()
local fs = require "luci.clash"
local clash = "clash"
m = Map("clash")
s = m:section(TypedSection, "clash")
s.anonymous = true
m.pageaction = false
o = s:option(ListValue, "core", translate("Core"))
o.default = "clashcore"
if nixio.fs.access("/etc/clash/clash") then
o:value("1", translate("Clash"))
end
if nixio.fs.access("/etc/clash/clashtun/clash") then
o:value("3", translate("Clash(cTun)"))
end
if nixio.fs.access("/etc/clash/dtun/clash") then
o:value("4", translate("Clash(premium)"))
end
o = s:option(ListValue, "g_rules", translate("Game Rules"))
o.default = "0"
o:value("0", translate("Disable"))
o:value("1", translate("Enable"))
o.description = translate("Set rules under Setting=>Game Rules, will take effect when client start")
o = s:option(ListValue, "append_rules", translate("Append Customs Rules"))
o.default = "0"
o:value("0", translate("Disable"))
o:value("1", translate("Enable"))
o.description = translate("Set custom rules under Setting=>Others , will take effect when client start")
o = s:option(Button, "Apply")
o.title = luci.util.pcdata(translate("Save & Apply"))
o.inputtitle = translate("Save & Apply")
o.inputstyle = "apply"
o.write = function()
m.uci:commit("clash")
end
o = s:option(Button,"action")
o.title = translate("Operation")
o.template = "clash/start_stop"
return m
@@ -1,365 +0,0 @@
local NXFS = require "nixio.fs"
local SYS = require "luci.sys"
local HTTP = require "luci.http"
local DISP = require "luci.dispatcher"
local UTIL = require "luci.util"
local uci = luci.model.uci.cursor()
local fs = require "luci.clash"
local http = luci.http
local clash = "clash"
c = Map("clash")
c.template="clash/conf"
m = Map("clash")
s = m:section(TypedSection, "clash")
m.pageaction = false
s.anonymous = true
s.addremove=false
local conf = string.sub(luci.sys.exec("uci get clash.config.use_config"), 1, -2)
sev = s:option(TextValue, "conf")
sev.rows = 20
sev.wrap = "off"
sev.cfgvalue = function(self, section)
return NXFS.readfile(conf) or ""
end
sev.write = function(self, section, value)
NXFS.writefile(conf, value:gsub("\r\n", "\n"))
end
o=s:option(Button,"apply")
o.inputtitle = translate("Save & Apply")
o.inputstyle = "reload"
o.write = function()
m.uci:commit("clash")
end
local e,a={}
for t,o in ipairs(fs.glob("/usr/share/clash/config/sub/*.yaml"))do
a=fs.stat(o)
if a then
e[t]={}
e[t].name=fs.basename(o)
e[t].mtime=os.date("%Y-%m-%d %H:%M:%S",a.mtime)
e[t].size=tostring(a.size)
e[t].remove1=0
e[t].enable=false
end
end
function IsYamlFile(e)
e=e or""
local e=string.lower(string.sub(e,-5,-1))
return e==".yaml"
end
f=Form("config_listst")
f.reset=false
f.submit=false
tb=f:section(Table,e, translate("Subcription Config List"))
nm=tb:option(DummyValue,"name",translate("File Name"))
mt=tb:option(DummyValue,"mtime",translate("Update Time"))
sz=tb:option(DummyValue,"size",translate("Size"))
btnis=tb:option(Button,"switch1",translate("Use Config"))
btnis.template="clash/other_button"
btnis.render=function(o,t,a)
if not e[t]then return false end
if IsYamlFile(e[t].name)then
a.display=""
else
a.display="none"
end
o.inputstyle="apply"
Button.render(o,t,a)
end
btnis.write=function(a,t)
luci.sys.exec(string.format('uci set clash.config.use_config="/usr/share/clash/config/sub/%s"',e[t].name ))
luci.sys.exec('uci set clash.config.config_type="1"')
luci.sys.exec('uci commit clash')
if luci.sys.call("pidof clash >/dev/null") == 0 then
SYS.call("/etc/init.d/clash restart >/dev/null 2>&1 &")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash"))
else
HTTP.redirect(luci.dispatcher.build_url("admin", "services", "clash", "config","config"))
end
end
btnist=tb:option(Button,"update1",translate("Update"))
btnist.template="clash/other_button"
btnist.render=function(o,t,a)
if not e[t]then return false end
o.inputstyle="apply"
Button.render(o,t,a)
end
btnist.write=function(a,t)
luci.sys.exec(string.format('uci set clash.config.config_update_name="%s"',e[t].name))
luci.sys.exec('uci commit clash')
luci.sys.exec('bash /usr/share/clash/update.sh >>/usr/share/clash/clash.txt 2>&1 &')
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash"))
end
btndl = tb:option(Button,"download1",translate("Download"))
btndl.template="clash/other_button"
btndl.render=function(e,t,a)
e.inputstyle="remove"
Button.render(e,t,a)
end
btndl.write = function (a,t)
local sPath, sFile, fd, block
sPath = "/usr/share/clash/config/sub/"..e[t].name
sFile = NXFS.basename(sPath)
if fs.isdirectory(sPath) then
fd = io.popen('yaml -C "%s" -cz .' % {sPath}, "r")
sFile = sFile .. ".yaml"
else
fd = nixio.open(sPath, "r")
end
if not fd then
return
end
HTTP.header('Content-Disposition', 'attachment; filename="%s"' % {sFile})
HTTP.prepare_content("application/octet-stream")
while true do
block = fd:read(nixio.const.buffersize)
if (not block) or (#block ==0) then
break
else
HTTP.write(block)
end
end
fd:close()
HTTP.close()
end
btnrm=tb:option(Button,"remove1",translate("Remove"))
btnrm.render=function(e,t,a)
e.inputstyle="remove"
Button.render(e,t,a)
end
btnrm.write=function(a,t)
local a=fs.unlink("/usr/share/clash/config/sub/"..fs.basename(e[t].name))
luci.sys.exec(string.format('uci set clash.config.config_name_remove="%s"',e[t].name))
luci.sys.exec('uci commit clash')
luci.sys.exec('bash /usr/share/clash/rmlist.sh 2>&1 &')
if a then table.remove(e,t)end
return a
end
local p,x={}
for q,v in ipairs(fs.glob("/usr/share/clash/config/upload/*.yaml"))do
x=fs.stat(v)
if x then
p[q]={}
p[q].name=fs.basename(v)
p[q].mtime=os.date("%Y-%m-%d %H:%M:%S",x.mtime)
p[q].size=tostring(x.size)
p[q].remove2=0
p[q].enable=false
end
end
fr=Form("config_list")
fr.reset=false
fr.submit=false
tb=fr:section(Table,p, translate("Upload Config List"))
nm=tb:option(DummyValue,"name",translate("File Name"))
mt=tb:option(DummyValue,"mtime",translate("Update Time"))
sz=tb:option(DummyValue,"size",translate("Size"))
function IsYamlFile(p)
p=p or""
local p=string.lower(string.sub(p,-5,-1))
return p==".yaml"
end
btniss=tb:option(Button,"switch2",translate("Use Config"))
btniss.template="clash/other_button"
btniss.render=function(v,q,x)
if not p[q]then return false end
if IsYamlFile(p[q].name)then
x.display=""
else
x.display="none"
end
v.inputstyle="apply"
Button.render(v,q,x)
end
btniss.write=function(x,q)
luci.sys.exec(string.format('uci set clash.config.use_config="/usr/share/clash/config/upload/%s"',p[q].name ))
luci.sys.exec('uci set clash.config.config_type="2"')
luci.sys.exec('uci commit clash')
if luci.sys.call("pidof clash >/dev/null") == 0 then
SYS.call("/etc/init.d/clash restart >/dev/null 2>&1 &")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash"))
else
HTTP.redirect(luci.dispatcher.build_url("admin", "services", "clash", "config" ,"config"))
end
end
btndll = tb:option(Button,"download2",translate("Download"))
btndll.template="clash/other_button"
btndll.render=function(p,q,x)
p.inputstyle="remove"
Button.render(p,q,x)
end
btndll.write = function (x,q)
local sPath, sFile, fd, block
sPath = "/usr/share/clash/config/upload/"..p[q].name
sFile = NXFS.basename(sPath)
if fs.isdirectory(sPath) then
fd = io.popen('yaml -C "%s" -cz .' % {sPath}, "r")
sFile = sFile .. ".yaml"
else
fd = nixio.open(sPath, "r")
end
if not fd then
return
end
HTTP.header('Content-Disposition', 'attachment; filename="%s"' % {sFile})
HTTP.prepare_content("application/octet-stream")
while true do
block = fd:read(nixio.const.buffersize)
if (not block) or (#block ==0) then
break
else
HTTP.write(block)
end
end
fd:close()
HTTP.close()
end
btnrml=tb:option(Button,"remove2",translate("Remove"))
btnrml.render=function(p,q,x)
p.inputstyle="remove"
Button.render(p,q,x)
end
btnrml.write=function(x,q)
local x=fs.unlink("/usr/share/clash/config/upload/"..fs.basename(p[q].name))
luci.sys.exec(string.format('uci set clash.config.config_up_remove="%s"',p[q].name))
luci.sys.exec('uci commit clash')
luci.sys.exec('bash /usr/share/clash/uplist.sh 2>&1 &')
if x then table.remove(p,q)end
return x
end
local k,v={}
for c,z in ipairs(fs.glob("/usr/share/clash/config/custom/*.yaml"))do
v=fs.stat(z)
if v then
k[c]={}
k[c].name=fs.basename(z)
k[c].mtime=os.date("%Y-%m-%d %H:%M:%S",v.mtime)
k[c].size=tostring(v.size)
k[c].remove3=0
k[c].enable=false
end
end
fro=Form("config_listts")
fro.reset=false
fro.submit=false
tb=fro:section(Table,k,translate("Custom Config List"))
nm=tb:option(DummyValue,"name",translate("File Name"))
mt=tb:option(DummyValue,"mtime",translate("Update Time"))
sz=tb:option(DummyValue,"size",translate("Size"))
function IsYamlFile(k)
k=k or""
local k=string.lower(string.sub(k,-5,-1))
return k==".yaml"
end
btnisz=tb:option(Button,"switch3",translate("Use Config"))
btnisz.template="clash/other_button"
btnisz.render=function(z,c,v)
if not k[c]then return false end
if IsYamlFile(k[c].name)then
v.display=""
else
v.display="none"
end
z.inputstyle="apply"
Button.render(z,c,v)
end
btnisz.write=function(v,c)
luci.sys.exec(string.format('uci set clash.config.use_config="/usr/share/clash/config/custom/%s"',k[c].name ))
luci.sys.exec('uci set clash.config.config_type="3"')
luci.sys.exec('uci commit clash')
if luci.sys.call("pidof clash >/dev/null") == 0 then
SYS.call("/etc/init.d/clash restart >/dev/null 2>&1 &")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash"))
else
HTTP.redirect(luci.dispatcher.build_url("admin", "services", "clash", "config", "config"))
end
end
btndlz = tb:option(Button,"download3",translate("Download"))
btndlz.template="clash/other_button"
btndlz.render=function(k,c,v)
k.inputstyle="remove"
Button.render(k,c,v)
end
btndlz.write = function (v,c)
local sPath, sFile, fd, block
sPath = "/usr/share/clash/config/custom/"..k[c].name
sFile = NXFS.basename(sPath)
if fs.isdirectory(sPath) then
fd = io.popen('yaml -C "%s" -cz .' % {sPath}, "r")
sFile = sFile .. ".yaml"
else
fd = nixio.open(sPath, "r")
end
if not fd then
return
end
HTTP.header('Content-Disposition', 'attachment; filename="%s"' % {sFile})
HTTP.prepare_content("application/octet-stream")
while true do
block = fd:read(nixio.const.buffersize)
if (not block) or (#block ==0) then
break
else
HTTP.write(block)
end
end
fd:close()
HTTP.close()
end
btnrmz=tb:option(Button,"remove3",translate("Remove"))
btnrmz.render=function(k,c,v)
k.inputstyle="remove"
Button.render(k,c,v)
end
btnrmz.write=function(v,c)
local v=fs.unlink("/usr/share/clash/config/custom/"..fs.basename(k[c].name))
luci.sys.exec(string.format('uci set clash.config.config_cus_remove="%s"',k[c].name))
luci.sys.exec('uci commit clash')
luci.sys.exec('/usr/share/clash/cuslist.sh 2>&1 &')
if v then table.remove(k,c)end
return v
end
return c,f,fr,fro,m
@@ -1,386 +0,0 @@
local clash = "clash"
local NXFS = require "nixio.fs"
local SYS = require "luci.sys"
local HTTP = require "luci.http"
local DISP = require "luci.dispatcher"
local UTIL = require "luci.util"
local fs = require "luci.clash"
local uci = require "luci.model.uci".cursor()
local s, o, krk, z, r
local http = luci.http
font_blue = [[<font color="blue">]]
font_off = [[</font>]]
bold_on = [[<strong>]]
bold_off = [[</strong>]]
krk = Map(clash)
s = krk:section(TypedSection, "clash", translate("Create Config"))
s.anonymous = true
--krk.pageaction = false
o = s:option(Flag, "provider_config", translate("Enable Create"))
o.default = 1
o.description = translate("Enable to create configuration")
o = s:option(Flag, "prox", translate("Use Proxy"))
o.description = translate("Use Proxy")
o = s:option(Flag, "ppro", translate("Use Proxy Provider"))
o.description = translate("Use Proxy Provider")
o = s:option(Flag, "rulprp", translate("Use Rule Provider"))
o.description = translate("Use Rule Provider")
o:depends("orul", 0)
o = s:option(Flag, "rul", translate("Use Rules"))
o.description = translate("Use Rules")
o:depends("orul", 0)
o = s:option(Flag, "orul", translate("Use Other Rules"))
o.description = translate("Use Other Rules")
o:depends("rul", 0)
o = s:option(Flag, "script", translate("Use Script"))
o.description = translate("Use Script")
o:depends("rul", 1)
o:depends("rulprp", 1)
o = s:option(Value, "name_tag")
o.title = translate("Config Name")
o.rmempty = true
o.description = translate("Give a name for your config")
cc = s:option(Flag, "same_tag", translate("Force Same Name"))
cc.default = 1
cc.description = translate("Enable to overwrite config file")
o = s:option(Button,"Manager")
o.title = translate("Rule Providers Manager")
o.inputtitle = translate("Rule Providers Manager")
o.inputstyle = "reload"
o.write = function()
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash", "rulemanager"))
end
local t = {
{Creat_Config, Delete_Groups, Delete_ProxyPro, Delete_RulePro,Delete_Rules}
}
b = krk:section(Table, t)
o = b:option(Button,"Creat_Config")
o.inputtitle = translate("Create Config")
o.inputstyle = "apply"
o.write = function()
krk.uci:commit("clash")
luci.sys.call("bash /usr/share/clash/create/create.sh >/dev/null 2>&1 &")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash"))
end
o = b:option(Button,"Delete Severs")
o.inputtitle = translate("Delete Severs")
o.inputstyle = "reset"
o.write = function()
krk.uci:delete_all("clash", "servers", function(s) return true end)
krk.uci:commit("clash")
end
o = b:option(Button,"Delete_ProxyPro")
o.inputtitle = translate("Delete Proxy Provider")
o.inputstyle = "reset"
o.write = function()
krk.uci:delete_all("clash", "proxyprovider", function(s) return true end)
krk.uci:commit("clash")
end
o = b:option(Button,"Delete_RulePro")
o.inputtitle = translate("Delete Rule Provider")
o.inputstyle = "reset"
o.write = function()
krk.uci:delete_all("clash", "ruleprovider", function(s) return true end)
krk.uci:commit("clash")
end
o = b:option(Button,"Delete_Rules")
o.inputtitle = translate("Delete Rules")
o.inputstyle = "reset"
o.write = function()
krk.uci:delete_all("clash", "rules", function(s) return true end)
krk.uci:commit("clash")
end
o = b:option(Button,"Delete_Groups")
o.inputtitle = translate("Delete Groups")
o.inputstyle = "reset"
o.write = function()
krk.uci:delete_all("clash", "pgroups", function(s) return true end)
krk.uci:commit("clash")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash", "config", "create"))
end
-- [[ Proxies ]]--
s = krk:section(TypedSection, "servers", translate("Proxies"))
s.anonymous = true
s.addremove = true
s.sortable = false
s.template = "cbi/tblsection"
s.extedit = luci.dispatcher.build_url("admin/services/clash/servers/%s")
function s.create(...)
local sid = TypedSection.create(...)
if sid then
luci.http.redirect(s.extedit % sid)
return
end
end
o = s:option(Flag, "enabled", translate("Enable"))
o.rmempty = false
o.default = o.enabled
o.cfgvalue = function(...)
return Flag.cfgvalue(...) or "1"
end
o = s:option(DummyValue, "type", translate("Type"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
o = s:option(DummyValue, "name", translate("Alias"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
o = s:option(DummyValue, "server", translate("Server Address"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
o = s:option(DummyValue, "port", translate("Server Port"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
o = s:option(DummyValue, "server" ,translate("Latency"))
o.template="clash/ping"
o.width="10%"
-- [[ Groups Manage ]]--
x = krk:section(TypedSection, "pgroups", translate("Policy Groups"))
x.description = font_blue..bold_on..translate(" https://lancellc.gitbook.io/clash/clash-config-file/proxy-groups")..bold_off..font_off..' '
x.anonymous = true
x.addremove = true
x.sortable = true
x.template = "cbi/tblsection"
x.extedit = luci.dispatcher.build_url("admin/services/clash/pgroups/%s")
function x.create(...)
local sid = TypedSection.create(...)
if sid then
luci.http.redirect(x.extedit % sid)
return
end
end
o = x:option(Flag, "enabled", translate("Enable"))
o.rmempty = false
o.default = o.enabled
o.cfgvalue = function(...)
return Flag.cfgvalue(...) or "1"
end
o = x:option(DummyValue, "type", translate("Group Type"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
o = x:option(DummyValue, "name", translate("Group Name"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
-- [[ Proxy-Provider Manage ]]--
z = krk:section(TypedSection, "proxyprovider", translate("Proxy Provider"))
z.description = font_blue..bold_on..translate(" https://lancellc.gitbook.io/clash/clash-config-file/proxy-provider")..bold_off..font_off..' '
z.anonymous = true
z.addremove = true
z.sortable = true
z.template = "cbi/tblsection"
z.extedit = luci.dispatcher.build_url("admin/services/clash/proxyprovider/%s")
function z.create(...)
local sid = TypedSection.create(...)
if sid then
luci.http.redirect(z.extedit % sid)
return
end
end
o = z:option(Flag, "enabled", translate("Enable"))
o.rmempty = false
o.default = o.enabled
o.cfgvalue = function(...)
return Flag.cfgvalue(...) or "1"
end
o = z:option(DummyValue, "name", translate("Provider Name"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
o = z:option(DummyValue, "type", translate("Provider Type"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
-- [[ Rule-Provider Manage ]]--
r = krk:section(TypedSection, "ruleprovider", translate("Rule Provider"))
r.description = font_blue..bold_on..translate(" https://lancellc.gitbook.io/clash/clash-config-file/rule-provider")..bold_off..font_off..' '
r.anonymous = true
r.addremove = true
r.sortable = true
r.template = "cbi/tblsection"
r.extedit = luci.dispatcher.build_url("admin/services/clash/ruleprovider/%s")
function r.create(...)
local sid = TypedSection.create(...)
if sid then
luci.http.redirect(r.extedit % sid)
return
end
end
o = r:option(Flag, "enabled", translate("Enable"))
o.rmempty = false
o.default = o.enabled
o.cfgvalue = function(...)
return Flag.cfgvalue(...) or "1"
end
o = r:option(DummyValue, "name", translate("Provider Name"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
o = r:option(DummyValue, "type", translate("Provider Type"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
o = r:option(DummyValue, "behavior", translate("Provider Behavior"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
-- [[ Rule Manage ]]--
q = krk:section(TypedSection, "rules", translate("Rules"))
q.description = font_blue..bold_on..translate(" https://lancellc.gitbook.io/clash/clash-config-file/rules")..bold_off..font_off..' '
q.anonymous = true
q.addremove = true
q.sortable = true
q.template = "cbi/tblsection"
q.extedit = luci.dispatcher.build_url("admin/services/clash/rules/%s")
function q.create(...)
local sid = TypedSection.create(...)
if sid then
luci.http.redirect(q.extedit % sid)
return
end
end
o = q:option(Flag, "enabled", translate("Enable"))
o.rmempty = false
o.default = o.enabled
o.cfgvalue = function(...)
return Flag.cfgvalue(...) or "1"
end
o = q:option(DummyValue, "type", translate("Rule Type"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
o = q:option(DummyValue, "rulename", translate("Description"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("-")
end
o = q:option(DummyValue, "rulegroups", translate("Groups"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
m = Map("clash")
y = m:section(TypedSection, "clash" , translate("Script"))
y.anonymous = true
y.addremove=false
local script="/usr/share/clash/create/script.yaml"
sev = y:option(TextValue, "scriptt")
sev.description =translate("NB: Set Clash Mode to Script if want to use")..font_blue..bold_on..translate(" https://lancellc.gitbook.io/clash/clash-config-file/script")..bold_off..font_off..' '
sev.rows = 10
sev.wrap = "off"
sev.cfgvalue = function(self, section)
return NXFS.readfile(script) or ""
end
sev.write = function(self, section, value)
NXFS.writefile(script, value:gsub("\r\n", "\n"))
end
l = Map("clash")
v = l:section(TypedSection, "clash" , translate("Other Rules"))
v.anonymous = true
v.addremove=false
o = v:option(Value, "rule_url")
o.title = translate("Custom Rule Url")
o.description = translate("Insert your custom rule Url and click download")
o.rmempty = true
o = v:option(Button,"rule_update")
o.title = translate("Download Rule")
o.inputtitle = translate("Download Rule")
o.description = translate("Download Rule")
o.inputstyle = "reload"
o.write = function()
uci:commit("clash")
luci.sys.call("bash /usr/share/clash/rule.sh >>/usr/share/clash/clash.txt >/dev/null 2>&1 &")
end
local rule = "/usr/share/clash/rule.yaml"
sev = v:option(TextValue, "rule")
sev.description = translate("NB: Attention to Proxy Group and Rule when making changes to this section")
sev.rows = 20
sev.wrap = "off"
sev.cfgvalue = function(self, section)
return NXFS.readfile(rule) or ""
end
sev.write = function(self, section, value)
NXFS.writefile(rule, value:gsub("\r\n", "\n"))
end
o = v:option(Button,"del_rule")
o.inputtitle = translate("Delete Rule")
o.write = function()
SYS.call("rm -rf /usr/share/clash/rule.yaml >/dev/null 2>&1 &")
end
krk:append(Template("clash/list"))
return krk,m,l
@@ -1,94 +0,0 @@
local m, s, o
local clash = "clash"
local uci = luci.model.uci.cursor()
local fs = require "nixio.fs"
local sys = require "luci.sys"
local sid = arg[1]
m = Map(clash, translate("Edit Group"))
m.pageaction = false
m.redirect = luci.dispatcher.build_url("admin/services/clash/config/create")
if m.uci:get(clash, sid) ~= "pgroups" then
luci.http.redirect(m.redirect)
return
end
-- [[ Groups Setting ]]--
s = m:section(NamedSection, sid, "pgroups")
s.anonymous = true
s.addremove = false
o = s:option(ListValue, "type", translate("Group Type"))
o.rmempty = true
o.description = translate("Choose The Operation Mode")
o:value("select", translate("Select"))
o:value("url-test", translate("URL-Test"))
o:value("fallback", translate("Fallback"))
o:value("load-balance", translate("Load-Balance"))
o:value("relay", translate("Relay"))
o = s:option(Value, "name", translate("Group Name"))
o.rmempty = false
o = s:option(Value, "test_url", translate("Test URL"))
o.default = "http://www.gstatic.com/generate_204"
o.rmempty = true
o:depends("type", "url-test")
o:depends("type", "fallback")
o:depends("type", "load-balance")
o = s:option(Value, "test_interval", translate("Test Interval(s)"))
o.default = "300"
o.rmempty = true
o:depends("type", "url-test")
o:depends("type", "fallback")
o:depends("type", "load-balance")
o = s:option(DynamicList, "other_group", translate("Other Group"))
o.rmempty = true
o.description = translate("Proxy Groups Must Exist In Rule")
o:value("ALL", translate("All Servers"))
uci:foreach("clash", "pgroups",
function(s)
if s.name ~= "" and s.name ~= nil and s.name ~= m.uci:get(clash, sid, "name") then
o:value(s.name)
end
end)
uci:foreach("clash", "servers",
function(s)
if s.name ~= "" and s.name ~= nil and s.name ~= m.uci:get(clash, sid, "name") then
o:value(s.name)
end
end)
o:value("DIRECT")
o:value("REJECT")
local t = {
{Apply, Return}
}
b = m:section(Table, t)
o = b:option(Button,"Apply")
o.inputtitle = translate("Save & Apply")
o.inputstyle = "apply"
o.write = function()
m.uci:commit("clash")
sys.call("/usr/share/clash/create/pgroups.sh start >/dev/null 2>&1 &")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash", "config", "create"))
end
o = b:option(Button,"Return")
o.inputtitle = translate("Back to Overview")
o.inputstyle = "reset"
o.write = function()
m.uci:revert(clash)
luci.http.redirect(m.redirect)
--luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash", "config", "providers"))
end
return m
@@ -1,156 +0,0 @@
local NXFS = require "nixio.fs"
local SYS = require "luci.sys"
local HTTP = require "luci.http"
local DISP = require "luci.dispatcher"
local UTIL = require "luci.util"
local uci = luci.model.uci.cursor()
local fs = require "luci.clash"
local http = luci.http
local clash = "clash"
kr = Map(clash)
s = kr:section(TypedSection, "clash", translate("Subscription Config"))
s.anonymous = true
kr.pageaction = false
o = s:option(ListValue, "subcri", translate("Subcription Type"))
o.default = clash
o:value("clash", translate("clash"))
o:value("ssr2clash", translate("ssr2clash"))
o:value("v2clash", translate("v2clash"))
o.description = translate("Select Subcription Type")
o = s:option(Value, "config_name")
o.title = translate("Config Name")
o.description = translate("Config Name. Do not use a config name that already exist")
o = s:option(Value, "clash_url")
o.title = translate("Subcription Url")
o.description = translate("Clash Subscription Address")
o.rmempty = true
o:depends("subcri", 'clash')
o = s:option(Button,"update")
o.title = translate("Download Config")
o.inputtitle = translate("Download Config")
o.inputstyle = "reload"
o.write = function()
kr.uci:commit("clash")
SYS.call("sh /usr/share/clash/clash.sh >>/usr/share/clash/clash.txt 2>&1 &")
SYS.call("sleep 1")
HTTP.redirect(DISP.build_url("admin", "services", "clash"))
end
o:depends("subcri", 'clash')
o = s:option(Value, "ssr_url")
o.title = translate("Subcription Url")
o.placeholder = translate("https://www.example.com/link/QkjokZXktyyr35gfj")
o.rmempty = true
o:depends("subcri", 'ssr2clash')
o = s:option(Button,"updatee")
o.title = translate("Download Config")
o.inputtitle = translate("Download Config")
o.inputstyle = "reload"
o.write = function()
kr.uci:commit("clash")
luci.sys.call("bash /usr/share/clash/clash.sh >>/usr/share/clash/clash.txt 2>&1 &")
HTTP.redirect(DISP.build_url("admin", "services", "clash"))
end
o:depends("subcri", 'ssr2clash')
o = s:option(Value, "v2_url")
o.title = translate("Subcription Url")
o.placeholder = translate("https://www.example.com/link/QkjokZXktyyr35gfj")
o.rmempty = true
o:depends("subcri", 'v2clash')
o = s:option(Button,"updateee")
o.title = translate("Download Config")
o.inputtitle = translate("Download Config")
o.inputstyle = "reload"
o.write = function()
kr.uci:commit("clash")
luci.sys.call("bash /usr/share/clash/clash.sh >>/usr/share/clash/clash.txt 2>&1 &")
HTTP.redirect(DISP.build_url("admin", "services", "clash"))
end
o:depends("subcri", 'v2clash')
function IsYamlFile(e)
e=e or""
local e=string.lower(string.sub(e,-5,-1))
return e == ".yaml"
end
function IsYmlFile(e)
e=e or""
local e=string.lower(string.sub(e,-4,-1))
return e == ".yml"
end
ko = Map(clash)
ko.reset = false
ko.submit = false
sul =ko:section(TypedSection, "clash", translate("Upload Config"))
sul.anonymous = true
sul.addremove=false
o = sul:option(FileUpload, "")
--o.description = translate("NB: Only upload file with name .yaml.It recommended to rename each upload file name to avoid overwrite")
o.title = translate(" ")
o.template = "clash/clash_upload"
um = sul:option(DummyValue, "", nil)
um.template = "clash/clash_dvalue"
local dir, fd
dir = "/usr/share/clash/config/upload/"
http.setfilehandler(
function(meta, chunk, eof)
if not fd then
if not meta then return end
if meta and chunk then fd = nixio.open(dir .. meta.file, "w") end
if not fd then
um.value = translate("upload file error.")
return
end
end
if chunk and fd then
fd:write(chunk)
end
if eof and fd then
fd:close()
fd = nil
local e=string.lower(string.sub(meta.file,-4,-1))
local yml2=string.lower(string.sub(meta.file,0,-5))
if e == '.yml' then
local yml=string.lower(string.sub(meta.file,0,-5))
local c=fs.rename(dir .. meta.file,"/usr/share/clash/config/upload/".. yml .. ".yaml")
um.value = translate("File saved to") .. ' "/usr/share/clash/config/upload/'..yml..'.yaml"'
else
um.value = translate("File saved to") .. ' "/usr/share/clash/config/upload/'..yml2..'yaml"'
end
end
end
)
if luci.http.formvalue("upload") then
local f = luci.http.formvalue("ulfile")
if #f <= 0 then
um.value = translate("No specify upload file.")
end
end
return kr,ko
@@ -1,59 +0,0 @@
local m, s, o
local clash = "clash"
local uci = luci.model.uci.cursor()
local fs = require "nixio.fs"
local sys = require "luci.sys"
local sid = arg[1]
m = Map(clash, translate("Edit Custom Rule & Group"))
--m.pageaction = false
m.redirect = luci.dispatcher.build_url("admin/services/clash/settings/other")
if m.uci:get(clash, sid) ~= "addtype" then
luci.http.redirect(m.redirect)
return
end
s = m:section(NamedSection, sid, "addtype")
s.anonymous = true
s.addremove = false
o = s:option(ListValue, "type", translate("Rule Type"))
o.rmempty = false
o.description = translate("Choose Type")
o:value("DST-PORT", translate("DST-PORT"))
o:value("SRC-PORT", translate("SRC-PORT"))
o:value("SRC-IP-CIDR", translate("SRC-IP-CIDR"))
o:value("IP-CIDR", translate("IP-CIDR"))
o:value("IP-CIDR6", translate("IP-CIDR6"))
o:value("DOMAIN", translate("DOMAIN"))
o:value("DOMAIN-KEYWORD", translate("DOMAIN-KEYWORD"))
o:value("DOMAIN-SUFFIX", translate("DOMAIN-SUFFIX"))
o:value("GEOIP", translate("GEOIP"))
o = s:option(ListValue, "pgroup", translate("Select Proxy Group"))
uci:foreach("clash", "conf_groups",
function(s)
if s.name ~= "" and s.name ~= nil then
o:value(s.name)
end
end)
o:value("DIRECT")
o:value("REJECT")
o.rmempty = false
o.description = translate("Select a policy group to add rule")
o = s:option(Value, "ipaaddr", translate("IP/Domain/Address/Keyword/Port"))
o.rmempty = false
o = s:option(Flag, "res", translate("No Resolve"))
o.default = 0
o:depends("type", "IP-CIDR")
o:depends("type", "IP-CIDR6")
o:depends("type", "GEOIP")
return m
@@ -1,160 +0,0 @@
local m, s, o
local clash = "clash"
local uci = luci.model.uci.cursor()
local fs = require "nixio.fs"
local sys = require "luci.sys"
local sid = arg[1]
local http = luci.http
local fss = require "luci.clash"
function IsYamlFile(e)
e=e or""
local e=string.lower(string.sub(e,-5,-1))
return e == ".yaml"
end
function IsYmlFile(e)
e=e or""
local e=string.lower(string.sub(e,-4,-1))
return e == ".yml"
end
m = Map(clash, translate("Edit Proxy Provider"))
m.pageaction = false
m.redirect = luci.dispatcher.build_url("admin/services/clash/config/create")
if m.uci:get(clash, sid) ~= "proxyprovider" then
luci.http.redirect(m.redirect)
return
end
s = m:section(NamedSection, sid, "proxyprovider")
s.anonymous = true
s.addremove = false
o = s:option(ListValue, "type", translate("Provider Type"))
o.rmempty = false
o.description = translate("Provider Type")
o:value("http")
o:value("file")
o = s:option(FileUpload, "",translate("Upload Provider File"))
o.title = translate("Provider File")
o.template = "clash/clash_upload"
o:depends("type", "file")
um = s:option(DummyValue, "", nil)
um.template = "clash/clash_dvalue"
local dir, fd
dir = "/etc/clash/proxyprovider/"
http.setfilehandler(
function(meta, chunk, eof)
if not fd then
if not meta then return end
if meta and chunk then fd = nixio.open(dir .. meta.file, "w") end
if not fd then
um.value = translate("upload file error.")
return
end
end
if chunk and fd then
fd:write(chunk)
end
if eof and fd then
fd:close()
fd = nil
um.value = translate("File saved to") .. ' "/etc/clash/proxyprovider/"'
end
end
)
if luci.http.formvalue("upload") then
local f = luci.http.formvalue("ulfile")
if #f <= 0 then
um.value = translate("No specify upload file.")
end
end
o = s:option(Value, "name", translate("Provider Name"))
o.rmempty = false
o = s:option(ListValue, "path", translate("Provider Path"))
o.description = translate("Upload Provider File If Empty")
local p,h={}
for t,f in ipairs(fss.glob("/etc/clash/proxyprovider/*"))do
h=fss.stat(f)
if h then
p[t]={}
p[t].name=fss.basename(f)
if IsYamlFile(p[t].name) or IsYmlFile(p[t].name) then
o:value("./proxyprovider/"..p[t].name)
end
end
end
o.rmempty = true
o:depends("type", "file")
o = s:option(Value, "provider_url", translate("Provider URL"))
o.description = translate("【HTTP】./hk.yaml")
o.rmempty = true
o:depends("type", "http")
o = s:option(Value, "provider_interval", translate("Provider Interval"))
o.default = "3600"
o.rmempty = true
o:depends("type", "http")
o = s:option(ListValue, "health_check", translate("Provider Health Check"))
o:value("false", translate("Disable"))
o:value("true", translate("Enable"))
o.default=true
o = s:option(Value, "health_check_url", translate("Health Check URL"))
o.default = "http://www.gstatic.com/generate_204"
o.rmempty = true
o = s:option(Value, "health_check_interval", translate("Health Check Interval"))
o.default = "300"
o.rmempty = true
o = s:option(DynamicList, "pgroups", translate("Policy Group"))
o.rmempty = true
m.uci:foreach("clash", "pgroups",
function(s)
if s.name ~= "" and s.name ~= nil and s.type ~= "relay" then
o:value(s.name)
end
end)
local t = {
{Apply, Return}
}
b = m:section(Table, t)
o = b:option(Button,"Apply")
o.inputtitle = translate("Save & Apply")
o.inputstyle = "apply"
o.write = function()
m.uci:commit("clash")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash", "config", "create"))
end
o = b:option(Button,"Return")
o.inputtitle = translate("Back to Overview")
o.inputstyle = "reset"
o.write = function()
m.uci:revert(clash)
luci.http.redirect(m.redirect)
--luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash", "config", "providers"))
end
return m
@@ -1,150 +0,0 @@
local m, s, o
local clash = "clash"
local uci = luci.model.uci.cursor()
local fs = require "nixio.fs"
local sys = require "luci.sys"
local sid = arg[1]
local http = luci.http
local fss = require "luci.clash"
function IsYamlFile(e)
e=e or""
local e=string.lower(string.sub(e,-5,-1))
return e == ".yaml"
end
function IsYmlFile(e)
e=e or""
local e=string.lower(string.sub(e,-4,-1))
return e == ".yml"
end
function IsFile(e)
e=e or""
local e=string.lower(string.sub(e,-5,-1))
return e == ".list"
end
m = Map(clash, translate("Edit Rule Provider"))
m.pageaction = false
m.redirect = luci.dispatcher.build_url("admin/services/clash/config/create")
if m.uci:get(clash, sid) ~= "ruleprovider" then
luci.http.redirect(m.redirect)
return
end
s = m:section(NamedSection, sid, "ruleprovider")
s.anonymous = true
s.addremove = false
o = s:option(Value, "name", translate("Rule Provider Name"))
o.rmempty = false
o = s:option(ListValue, "type", translate("Provider Type"))
o.rmempty = false
o.description = translate("Provider Type")
o:value("http")
o:value("file")
o = s:option(ListValue, "behavior", translate("Provider Behavior"))
o.rmempty = false
o.description = translate("ipcidr # or domain")
o:value("ipcidr")
o:value("domain")
o:value("classical")
o = s:option(FileUpload, "",translate("Upload Provider File"))
o.title = translate("Provider File")
o.template = "clash/clash_upload"
o:depends("type", "file")
um = s:option(DummyValue, "", nil)
um.template = "clash/clash_dvalue"
local dir, fd
dir = "/etc/clash/ruleprovider/"
http.setfilehandler(
function(meta, chunk, eof)
if not fd then
if not meta then return end
if meta and chunk then fd = nixio.open(dir .. meta.file, "w") end
if not fd then
um.value = translate("upload file error.")
return
end
end
if chunk and fd then
fd:write(chunk)
end
if eof and fd then
fd:close()
fd = nil
um.value = translate("File saved to") .. ' "/etc/clash/ruleprovider/"'
end
end
)
if luci.http.formvalue("upload") then
local f = luci.http.formvalue("ulfile")
if #f <= 0 then
um.value = translate("No specify upload file.")
end
end
o = s:option(ListValue, "path", translate("Provider Path"))
o.description = translate("Upload Provider File If Empty")
local p,h={}
for t,f in ipairs(fss.glob("/etc/clash/ruleprovider/*"))do
h=fss.stat(f)
if h then
p[t]={}
p[t].name=fss.basename(f)
if IsYamlFile(p[t].name) or IsYmlFile(p[t].name) or IsFile(p[t].name) then
o:value("./ruleprovider/"..p[t].name)
end
end
end
o:depends("type", "file")
o = s:option(Value, "url", translate("Provider URL"))
o.description = translate("【HTTP】./hk.yaml")
o:depends("type", "http")
o = s:option(Value, "interval", translate("Provider Interval"))
o.default = "3600"
o:depends("type", "http")
local t = {
{Apply, Return}
}
b = m:section(Table, t)
o = b:option(Button,"Apply")
o.inputtitle = translate("Save & Apply")
o.inputstyle = "apply"
o.write = function()
m.uci:commit("clash")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash", "config", "create"))
end
o = b:option(Button,"Return")
o.inputtitle = translate("Back to Overview")
o.inputstyle = "reset"
o.write = function()
m.uci:revert(clash)
luci.http.redirect(m.redirect)
--luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash", "config", "providers"))
end
return m
@@ -1,96 +0,0 @@
local f, s, o
local clash = "clash"
local uci = luci.model.uci.cursor()
local fs = require "nixio.fs"
local sys = require "luci.sys"
local sid = arg[1]
local http = luci.http
local fss = require "luci.clash"
local NXFS = require "nixio.fs"
local HTTP = require "luci.http"
local DISP = require "luci.dispatcher"
local UTIL = require "luci.util"
m = Map("clash", translate("Rule Providers List"))
m.reset = false
m.submit = false
local t = {
{Apply}
}
a = m:section(Table, t)
o = a:option(Button, "Apply")
o.inputtitle = translate("Back to Overview")
o.inputstyle = "reset"
o.write = function()
HTTP.redirect(DISP.build_url("admin", "services", "clash", "config", "create"))
end
sys.call("awk -F ',' '{print $4}' /usr/share/clash/create/rule_provider.list > /tmp/rule_providers 2>/dev/null")
file = io.open("/tmp/rule_providers", "r");
local e={},a,o,t
a=nixio.fs.access("/tmp/rule_providers")
if a then
for o in file:lines() do
table.insert(e,o)
end
for t,o in ipairs(e) do
e[t]={}
e[t].num=string.format(t)
e[t].name=string.sub(luci.sys.exec(string.format("grep -F ',%s' /usr/share/clash/create/rule_provider.list |awk -F ',' '{print $1}' 2>/dev/null",o)),1,-2)
e[t].behaviour=string.sub(luci.sys.exec(string.format("grep -F ',%s' /usr/share/clash/create/rule_provider.list |awk -F ',' '{print $2}' 2>/dev/null",o)),1,-2)
e[t].filename=string.sub(luci.sys.exec(string.format("grep -F '%s,' /usr/share/clash/create/rule_provider.list |awk -F ',' '{print $4}' 2>/dev/null",o)),1,-2)
if e[t].filename == "" then
e[t].filename=o
end
RULE_FILE="/etc/clash/ruleprovider/".. e[t].filename
if fss.mtime(RULE_FILE) then
e[t].mtime=os.date("%Y-%m-%d %H:%M:%S",fss.mtime(RULE_FILE))
else
e[t].mtime="/"
end
if fss.isfile(RULE_FILE) then
e[t].exist=translate("Exist")
else
e[t].exist=translate("Not Exist")
end
e[t].remove=0
end
end
file:close()
f=Form("filelist")
tb=f:section(Table,e)
nu=tb:option(DummyValue,"num",translate("Order Number"))
st=tb:option(DummyValue,"exist",translate("State"))
nm=tb:option(DummyValue,"name",translate("Rule Name"))
tp=tb:option(DummyValue,"behaviour",translate("Type"))
fm=tb:option(DummyValue,"filename",translate("File Name"))
mt=tb:option(DummyValue,"mtime",translate("Update Time"))
btnis=tb:option(DummyValue,"filename",translate("Download Rule"))
btnis.template="clash/rulep"
btnrm=tb:option(Button,"remove",translate("Remove"))
btnrm.render=function(e,t,a)
e.inputstyle="reset"
Button.render(e,t,a)
end
btnrm.write=function(a,t)
local a=fs.unlink("/etc/clash/ruleprovider/"..e[t].filename)
HTTP.redirect(luci.dispatcher.build_url("admin", "services", "clash", "rulemanager"))
end
return m, f
@@ -1,105 +0,0 @@
local m, s, o
local clash = "clash"
local uci = luci.model.uci.cursor()
local fs = require "nixio.fs"
local sys = require "luci.sys"
local sid = arg[1]
m = Map(clash, translate("Edit Rules"))
--m.pageaction = false
m.redirect = luci.dispatcher.build_url("admin/services/clash/config/create")
if m.uci:get(clash, sid) ~= "rules" then
luci.http.redirect(m.redirect)
return
end
s = m:section(NamedSection, sid, "rules")
s.anonymous = true
s.addremove = false
m.pageaction = false
o = s:option(ListValue, "type", translate("Rule Type"))
o.rmempty = false
o.description = translate("Choose Type")
o:value("RULE-SET", translate("RULE-SET"))
o:value("DST-PORT", translate("DST-PORT"))
o:value("SRC-PORT", translate("SRC-PORT"))
o:value("SRC-IP-CIDR", translate("SRC-IP-CIDR"))
o:value("IP-CIDR", translate("IP-CIDR"))
o:value("IP-CIDR6", translate("IP-CIDR6"))
o:value("DOMAIN", translate("DOMAIN"))
o:value("DOMAIN-KEYWORD", translate("DOMAIN-KEYWORD"))
o:value("DOMAIN-SUFFIX", translate("DOMAIN-SUFFIX"))
o:value("GEOIP", translate("GEOIP"))
o:value("MATCH", translate("MATCH"))
o = s:option(ListValue, "rulename", translate("Description"))
uci:foreach("clash", "ruleprovider",
function(s)
if s.name ~= "" and s.name ~= nil then
o:value(s.name)
end
end)
o.description = translate("Select rule provider name")
o:depends("type", "RULE-SET")
o = s:option(ListValue, "rulegroups", translate("Select Proxy Group"))
uci:foreach("clash", "pgroups",
function(s)
if s.name ~= "" and s.name ~= nil then
o:value(s.name)
end
end)
o:value("DIRECT")
o:value("REJECT")
o.description = translate("Select a policy group to add rule")
o = s:option(Value, "rulenamee", translate("Description"))
o:depends("type", "DST-PORT")
o:depends("type", "SRC-PORT")
o:depends("type", "SRC-IP-CIDR")
o:depends("type", "IP-CIDR")
o:depends("type", "DOMAIN")
o:depends("type", "DOMAIN-KEYWORD")
o:depends("type", "DOMAIN-SUFFIX")
o:depends("type", "GEOIP")
o:depends("type", "IP-CIDR6")
o = s:option(Flag, "res", translate("No Resolve"))
o.default = 0
o:depends("type", "IP-CIDR")
o:depends("type", "IP-CIDR6")
o:depends("type", "GEOIP")
local t = {
{Apply, Return}
}
b = m:section(Table, t)
o = b:option(Button,"Apply")
o.inputtitle = translate("Save & Apply")
o.inputstyle = "apply"
o.write = function()
m.uci:commit("clash")
sys.call("/usr/share/clash/create/rules.sh start >/dev/null 2>&1 &")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash", "config", "create"))
end
o = b:option(Button,"Return")
o.inputtitle = translate("Back to Overview")
o.inputstyle = "reset"
o.write = function()
m.uci:revert(clash)
luci.http.redirect(m.redirect)
--luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash", "config", "providers"))
end
return m
@@ -1,320 +0,0 @@
local m, s, o
local clash = "clash"
local uci = luci.model.uci.cursor()
local fs = require "nixio.fs"
local sys = require "luci.sys"
local sid = arg[1]
local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid")
local server_table = {}
local encrypt_methods_ss = {
"rc4-md5",
"aes-128-cfb",
"aes-192-cfb",
"aes-256-cfb",
"aes-128-ctr",
"aes-192-ctr",
"aes-256-ctr",
"aes-128-gcm",
"aes-192-gcm",
"aes-256-gcm",
"chacha20-ietf",
"xchacha20",
"chacha20-ietf-poly1305",
"xchacha20-ietf-poly1305",
}
local securitys = {
"auto",
"none",
"aes-128-gcm",
"chacha20-poly1305"
}
local encrypt_methods_ssr = {
"aes-128-cfb",
"aes-192-cfb",
"aes-256-cfb",
"aes-128-ctr",
"aes-192-ctr",
"aes-256-ctr",
"rc4-md5",
"chacha20-ietf",
"xchacha20",
}
local protocol_ssr = {
"origin",
"auth_sha1_v4",
"auth_aes128_md5",
"auth_aes128_sha1",
"auth_chain_a",
"auth_chain_b",
}
local obfs_ssr_list = {
"plain",
"http_simple",
"http_post",
"tls1.2_ticket_auth",
"tls1.2_ticket_fastauth",
"random_head",
}
m = Map(clash, translate("Edit Server"))
m.redirect = luci.dispatcher.build_url("admin/services/clash/config/create")
if m.uci:get(clash, sid) ~= "servers" then
luci.http.redirect(m.redirect)
return
end
-- [[ Servers Setting ]]--
s = m:section(NamedSection, sid, "servers")
s.anonymous = true
s.addremove = false
o = s:option(DummyValue,"ssr_url",translate("Import config info"))
o.rawhtml = true
o.template = "clash/ssrurl"
o.value =sid
o = s:option(ListValue, "type", translate("Server Node Type"))
o:value("ss", translate("Shadowsocks"))
o:value("ssr", translate("ShadowsocksR"))
o:value("vmess", translate("Vmess"))
o:value("socks5", translate("Socks5"))
o:value("http", translate("HTTP(S)"))
o:value("snell", translate("Snell"))
o:value("trojan", translate("trojan"))
o.description = translate("Using incorrect encryption mothod may causes service fail to start")
o = s:option(Value, "name", translate("Alias"))
o.default = "Server"
o.rmempty = false
o = s:option(Value, "server", translate("Server Address"))
o.datatype = "host"
o.rmempty = false
o = s:option(Value, "port", translate("Server Port"))
o.datatype = "port"
o.rmempty = false
o = s:option(Value, "password", translate("Password"))
o.password = true
o.rmempty = true
o:depends("type", "ss")
o:depends("type", "ssr")
o:depends("type", "trojan")
o = s:option(Value, "psk", translate("Psk"))
o.rmempty = false
o:depends("type", "snell")
o = s:option(ListValue, "cipher", translate("Encrypt Method"))
for _, v in ipairs(encrypt_methods_ss) do o:value(v) end
o.rmempty = true
o:depends("type", "ss")
o = s:option(ListValue, "cipher_ssr", translate("Encrypt Method"))
for _, v in ipairs(encrypt_methods_ssr) do o:value(v) end
o.rmempty = true
o:depends("type", "ssr")
o = s:option(ListValue, "protocol", translate("Protocol"))
for _, v in ipairs(protocol_ssr) do o:value(v) end
o.rmempty = true
o:depends("type", "ssr")
o = s:option(Value, "protocolparam", translate("Protocol Param"))
o.rmempty = true
o:depends("type", "ssr")
o = s:option(ListValue, "obfs_ssr", translate("Obfs"))
for _, v in ipairs(obfs_ssr_list) do o:value(v) end
o.rmempty = true
o:depends("type", "ssr")
o = s:option(ListValue, "obfs_snell", translate("obfs-mode"))
o.rmempty = true
o.default = "none"
o:value("none")
o:value("tls")
o:value("http")
o:depends("type", "snell")
o = s:option(Value, "obfsparam", translate("Obfs Param"))
o.rmempty = true
o:depends("type", "ssr")
o = s:option(ListValue, "securitys", translate("Encrypt Method"))
for _, v in ipairs(securitys) do o:value(v, v:upper()) end
o.rmempty = true
o:depends("type", "vmess")
o = s:option(ListValue, "obfs", translate("obfs-mode"))
o.default = " "
o:value(" ", translate("none"))
o:value("tls")
o:value("http")
o:value("websocket", translate("websocket (ws)"))
o:depends("type", "ss")
o = s:option(ListValue, "obfs_vmess", translate("obfs-mode"))
o.default = "none"
o:value("none")
o:value("websocket", translate("websocket (ws)"))
o:value("http", translate("http"))
o:depends("type", "vmess")
o = s:option(Value, "host", translate("hosts"))
o.datatype = "host"
o.rmempty = true
o:depends("obfs", "tls")
o:depends("obfs", "http")
o:depends("obfs", "websocket")
o:depends("obfs_snell", "tls")
o:depends("obfs_snell", "http")
o = s:option(ListValue, "udp", translate("udp"))
o:value("true")
o:value("false")
o:depends("type", "ss")
o:depends("type", "ssr")
o:depends("type", "vmess")
o:depends("type", "socks5")
o:depends("type", "trojan")
o = s:option(ListValue, "tls_custom", translate("tls"))
o.default = "false"
o:value("true")
o:value("false")
o:depends("obfs", "websocket")
-- [[ WS部分 ]]--
-- WS路径
o = s:option(Value, "path", translate("Path"))
o.rmempty = true
o:depends("obfs", "websocket")
o:depends("obfs_vmess", "websocket")
o = s:option(DynamicList, "http_path", translate("path"))
o.rmempty = true
o:value("/")
o:value("/video")
o:depends("obfs_vmess", "http")
o = s:option(Value, "custom", translate("headers"))
o.rmempty = true
o:depends("obfs", "websocket")
o:depends("obfs_vmess", "websocket")
o = s:option(Value, "keep_alive", translate("keep-alive"))
o.rmempty = true
o.default = "true"
o:value("true")
o:value("false")
o:depends("obfs_vmess", "http")
o = s:option(ListValue, "mux", translate("Mux"))
o.default = "false"
o:value("true")
o:value("false")
o:depends("obfs", "websocket")
-- AlterId
o = s:option(Value, "alterId", translate("AlterId"))
o.datatype = "port"
o.default = 32
o.rmempty = true
o:depends("type", "vmess")
-- VmessId
o = s:option(Value, "uuid", translate("VmessId (UUID)"))
o.rmempty = true
o.default = uuid
o:depends("type", "vmess")
-- 验证用户名
o = s:option(Value, "auth_name", translate("Auth Username"))
o:depends("type", "socks5")
o:depends("type", "http")
o.rmempty = true
-- 验证密码
o = s:option(Value, "auth_pass", translate("Auth Password"))
o:depends("type", "socks5")
o:depends("type", "http")
o.rmempty = true
-- [[ skip-cert-verify ]]--
o = s:option(ListValue, "skip_cert_verify", translate("Skip Cert Verify"))
o.rmempty = true
o.default = "false"
o:value("true")
o:value("false")
o:depends("obfs", "websocket")
o:depends("type", "vmess")
o:depends("type", "socks5")
o:depends("type", "http")
o:depends("obfs_vmess", "none")
o:depends("type", "trojan")
o:depends("obfs_vmess", "websocket")
-- [[ TLS ]]--
o = s:option(ListValue, "tls", translate("TLS"))
o.rmempty = true
o.default = "false"
o:value("true")
o:value("false")
o:depends("obfs", "websocket")
o:depends("obfs_vmess", "none")
o:depends("obfs_vmess", "websocket")
o:depends("obfs_vmess", "http")
o:depends("type", "socks5")
o:depends("type", "http")
o = s:option(Value, "servername", translate("SNI"))
o.rmempty = true
o.datatype = "host"
o.placeholder = translate("example.com")
o:depends("obfs_vmess", "websocket")
-- [[ sni ]]--
o = s:option(Value, "sni", translate("sni"))
o.datatype = "host"
o.placeholder = translate("example.com")
o.rmempty = true
o:depends("type", "trojan")
-- [[ alpn ]]--
o = s:option(Flag, "alpn_h2", translate("alpn-h2"))
o:depends("type", "trojan")
o = s:option(Flag, "alpn_http", translate("alpn-http/1.1"))
o:depends("type", "trojan")
local apply = luci.http.formvalue("cbi.apply")
if apply then
m.uci:commit("clash")
end
return m
@@ -1,70 +0,0 @@
local NXFS = require "nixio.fs"
local SYS = require "luci.sys"
local HTTP = require "luci.http"
local DISP = require "luci.dispatcher"
local UTIL = require "luci.util"
local uci = require("luci.model.uci").cursor()
local clash = "clash"
local http = luci.http
m = Map("clash")
s = m:section(TypedSection, "clash")
m.pageaction = false
s.anonymous = true
s.addremove=false
y = s:option(ListValue, "dnsforwader", translate("DNS Forwarding"))
y:value("0", translate("disabled"))
y:value("1", translate("enabled"))
y.description = translate("Set custom DNS forwarder in DHCP and DNS Settings and forward all dns traffic to clash")
y = s:option(ListValue, "dnscache", translate("DNS Cache"))
y:value("0", translate("disabled"))
y:value("1", translate("enabled"))
y.description = translate("Set to enable or disable dns cache")
y = s:option(ListValue, "access_control", translate("Access Control"))
y:value("0", translate("disabled"))
y:value("1", translate("Whitelist IPs"))
y:value("2", translate("Blacklist Ips"))
y.description = translate("Whitelist or Blacklist IPs to use Clash ( Only support enhanced-mode: redir-host )")
o = s:option(DynamicList, "proxy_lan_ips", translate("Proxy Lan List"))
o.datatype = "ipaddr"
o.description = translate("Only selected IPs will be proxied")
luci.ip.neighbors({ family = 4 }, function(entry)
if entry.reachable then
o:value(entry.dest:string())
end
end)
o:depends("access_control", 1)
o = s:option(DynamicList, "reject_lan_ips", translate("Bypass Lan List"))
o.datatype = "ipaddr"
o.description = translate("Selected IPs will not be proxied")
luci.ip.neighbors({ family = 4 }, function(entry)
if entry.reachable then
o:value(entry.dest:string())
end
end)
o:depends("access_control", 2)
o = s:option(Button, "Apply")
o.title = luci.util.pcdata(translate("Save & Apply"))
o.inputtitle = translate("Save & Apply")
o.inputstyle = "apply"
o.write = function()
m.uci:commit("clash")
if luci.sys.call("pidof clash >/dev/null") == 0 then
SYS.call("/etc/init.d/clash restart >/dev/null 2>&1 &")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash"))
else
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash" , "settings", "dns", "advance"))
end
end
return m
@@ -1,189 +0,0 @@
local NXFS = require "nixio.fs"
local SYS = require "luci.sys"
local HTTP = require "luci.http"
local DISP = require "luci.dispatcher"
local UTIL = require "luci.util"
local uci = require("luci.model.uci").cursor()
local clash = "clash"
local http = luci.http
m = Map("clash")
s = m:section(TypedSection, "clash")
--m.pageaction = false
s.anonymous = true
s.addremove=false
y = s:option(Flag, "interf", translate("Interface Name"))
y.default = 1
y.description = translate("Enable Interface Name")
y = s:option(Value, "interf_name", translate("Set Interface Name"))
y.description = translate("Set Interface Name")
y:depends("interf", 1)
y = s:option(Flag, "tun_mode", translate("Tun Mode"))
y.default = 0
y.description = translate("Enable Tun and make sure you are using tun supported core")
y = s:option(ListValue, "stack", translate("Stack"))
y:value("system", translate("system"))
y:value("gvisor", translate("gvisor"))
y.description = translate("Select Stack Mode")
y:depends("tun_mode", 1)
y = s:option(Flag, "enable_dns", translate("Enable Clash DNS"))
y.default = 1
y.description = translate("Enable Clash DNS")
y = s:option(Value, "listen_port", translate("DNS Listen Port"))
y.description = translate("Set DNS Listen Port")
y.default = "5300"
y = s:option(DynamicList, "default_nameserver", translate("Default NameServer"))
y.description = translate("Default Nameserver List")
y = s:option(ListValue, "enhanced_mode", translate("Enhanced Mode"))
y:value("redir-host", translate("Redir Host"))
y:value("fake-ip", translate("Fake IP"))
y.description = translate("Select Enhanced Mode")
y = s:option(Value, "fake_ip_range", translate("Fake IP Range"))
y.description = translate("Set Fake IP Range")
y.default = "198.18.0.1/16"
y:depends("enhanced_mode", "fake-ip")
y = s:option(DynamicList, "fake_ip_filter", translate("Fake IP Filter"))
y.description = translate("Fake IP Filter List")
y.default = "*.lan"
y:depends("enhanced_mode", "fake-ip")
s = m:section(TypedSection, "dnshijack", translate("DNS Hijack"))
s.anonymous = true
s.addremove = true
s.sortable = false
s.template = "cbi/tblsection"
s.rmempty = false
o = s:option(Flag, "enabled", translate("Enable"))
o.rmempty = false
o.default = o.enabled
o.cfgvalue = function(...)
return Flag.cfgvalue(...) or "1"
end
o = s:option(ListValue, "type", translate("Protocol"))
o:value("none", translate("No Protocol"))
o:value("tcp://", translate("TCP"))
o:value("udp://", translate("UDP"))
o:value("tls://", translate("TLS"))
o:value("https://", translate("HTTPS"))
o.default = "none"
o.rempty = false
o = s:option(Value, "ip", translate("Address"))
o.placeholder = translate("Not Null")
o.datatype = "or(host, string)"
o.rmempty = true
o = s:option(Value, "port", translate("Port"))
o.datatype = "port"
o.rempty = true
s = m:section(TypedSection, "authentication", translate("Authentication"))
s.anonymous = true
s.addremove = true
s.sortable = false
s.template = "cbi/tblsection"
s.rmempty = false
o = s:option(Flag, "enabled", translate("Enable"))
o.rmempty = false
o.default = o.enabled
o.cfgvalue = function(...)
return Flag.cfgvalue(...) or "1"
end
o = s:option(Value, "username", translate("Username"))
o.placeholder = translate("Cannot be Empty")
o.rempty = true
o = s:option(Value, "password", translate("Password"))
o.placeholder = translate("Cannot be Empty")
o.rmempty = true
s = m:section(TypedSection, "hosts", translate("Hosts"))
s.anonymous = true
s.addremove = true
s.sortable = false
s.template = "cbi/tblsection"
s.rmempty = false
o = s:option(Flag, "enabled", translate("Enable"))
o.rmempty = false
o.default = o.enabled
o.cfgvalue = function(...)
return Flag.cfgvalue(...) or "1"
end
o = s:option(Value, "address", translate("Address"))
o.placeholder = translate("Cannot be Empty")
o.rempty = true
o = s:option(Value, "ip", translate("IP"))
o.placeholder = translate("Cannot be Empty")
o.rmempty = true
s = m:section(TypedSection, "dnsservers", translate("Nameservers & Fallback"))
s.anonymous = true
s.addremove = true
s.sortable = false
s.template = "cbi/tblsection"
s.rmempty = false
o = s:option(Flag, "enabled", translate("Enable"))
o.rmempty = false
o.default = o.enabled
o.cfgvalue = function(...)
return Flag.cfgvalue(...) or "1"
end
o = s:option(ListValue, "ser_type", translate("Type"))
o:value("nameserver", translate("NameServer"))
o:value("fallback", translate("FallBack"))
o = s:option(ListValue, "protocol", translate("Protocol"))
o:value("none", translate("No Protocol"))
o:value("tcp://", translate("TCP"))
o:value("udp://", translate("UDP"))
o:value("tls://", translate("TLS"))
o:value("https://", translate("HTTPS"))
o = s:option(Value, "ser_address", translate("Address"))
o.placeholder = translate("Not Empty")
o.rmempty = false
o = s:option(Value, "ser_port", translate("Port"))
local apply = luci.http.formvalue("cbi.apply")
if apply then
m.uci:commit("clash")
if luci.sys.call("pidof clash >/dev/null") == 0 then
SYS.call("/etc/init.d/clash restart >/dev/null 2>&1 &")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash"))
end
end
return m
@@ -1,117 +0,0 @@
local NXFS = require "nixio.fs"
local SYS = require "luci.sys"
local HTTP = require "luci.http"
local DISP = require "luci.dispatcher"
local UTIL = require "luci.util"
local uci = require("luci.model.uci").cursor()
m = Map("clash")
s = m:section(TypedSection, "clash")
m.pageaction = false
s.anonymous = true
o = s:option(Value, "http_port")
o.title = translate("Http Port")
o.default = 7890
o.datatype = "port"
o.rmempty = false
o.description = translate("Http Port")
o = s:option(Value, "socks_port")
o.title = translate("Socks Port")
o.default = 7891
o.datatype = "port"
o.rmempty = false
o.description = translate("Socks Port")
o = s:option(Value, "redir_port")
o.title = translate("Redir Port")
o.default = 7892
o.datatype = "port"
o.rmempty = false
o.description = translate("Redir Port")
o = s:option(Value, "mixed_port")
o.title = translate("Mixed Port")
o.default = 7893
o.datatype = "port"
o.rmempty = false
o.description = translate("Mixed Port")
o = s:option(ListValue, "allow_lan")
o.title = translate("Allow Lan")
o.default = true
o.rmempty = false
o:value("true", "true")
o:value("false", "false")
o.description = translate("Allow Lan")
o = s:option(ListValue, "enable_ipv6")
o.title = translate("Enable IPv6")
o.default = false
o.rmempty = false
o:value("true", "true")
o:value("false", "false")
o.description = translate("Enable IPv6")
o = s:option(Value, "bind_addr")
o.title = translate("Bind Address")
o:value("*", translate("Bind All IP Addresses"))
luci.ip.neighbors({ family = 4 }, function(entry)
if entry.reachable then
o:value(entry.dest:string())
end
end)
luci.ip.neighbors({ family = 6 }, function(entry)
if entry.reachable then
o:value(entry.dest:string())
end
end)
o.description = translate("Bind Address")
o:depends("allow_lan", "true")
o = s:option(Value, "dash_port")
o.title = translate("Dashboard Port")
o.default = 9090
o.datatype = "port"
o.rmempty = false
o.description = translate("Dashboard Port")
o = s:option(Value, "dash_pass")
o.title = translate("Dashboard Secret")
o.default = 123456
o.rmempty = false
o.description = translate("Dashboard Secret")
o = s:option(ListValue, "p_mode", translate("Proxy Mode"))
o.description = translate("Choose proxy mode")
o:value("rule", translate("RULE"))
o:value("global", translate("GLOBAL"))
o:value("Script", translate("SCRIPT"))
o:value("direct", translate("DIRECT"))
o.default = "Rule"
o = s:option(ListValue, "level", translate("Log level"))
o.description = translate("Choose Log Level")
o:value("info", "info")
o:value("silent", "silent")
o:value("warning", "warning")
o:value("error", "error")
o:value("debug", "debug")
o = s:option(Button, "Apply")
o.title = luci.util.pcdata(translate("Save & Apply"))
o.inputtitle = translate("Save & Apply")
o.inputstyle = "apply"
o.write = function()
m.uci:commit("clash")
if luci.sys.call("pidof clash >/dev/null") == 0 then
SYS.call("/etc/init.d/clash restart >/dev/null 2>&1 &")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash"))
else
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash" , "settings", "port"))
end
end
return m
@@ -1,64 +0,0 @@
local m, s, o
local clash = "clash"
local uci = luci.model.uci.cursor()
--local fs = require "nixio.fs"
local sys = require "luci.sys"
local sid = arg[1]
local fs = require "luci.clash"
m = Map(clash, translate("Edit Game Rule & Group"))
--m.pageaction = false
m.redirect = luci.dispatcher.build_url("admin/services/clash/settings/grules")
if m.uci:get(clash, sid) ~= "game" then
luci.http.redirect(m.redirect)
return
end
function IsRuleFile(e)
e=e or""
local e=string.lower(string.sub(e,-6,-1))
return e==".rules"
end
-- [[ Groups Setting ]]--
s = m:section(NamedSection, sid, "game")
s.anonymous = true
s.addremove = false
o = s:option(Value, "tag")
o.title = translate("Rule Tag")
o.rmempty = false
o.description = translate("Give a special name for your rules")
---- Proxy Group
o = s:option(ListValue, "group", translate("Select Proxy Group"))
uci:foreach("clash", "conf_groups",
function(s)
if s.name ~= "" and s.name ~= nil then
o:value(s.name)
end
end)
o:value("DIRECT")
o:value("REJECT")
o.rmempty = true
o.description = translate("Select a policy group to add rule")
---- rule name
o = s:option(DynamicList, "rule_name", translate("Game Rule's Name"))
local e,a={}
for t,f in ipairs(fs.glob("/usr/share/clash/rules/g_rules/*"))do
a=fs.stat(f)
if a then
e[t]={}
e[t].filename=fs.basename(f)
if IsRuleFile(e[t].filename) then
e[t].name=luci.sys.exec(string.format("grep -F '%s' /usr/share/clash/rules/rules.list | awk -F ',' '{print $2}'",e[t].filename))
o:value(e[t].filename)
end
end
end
o.rmempty = true
return m
@@ -1,179 +0,0 @@
local k, m, s, o, f
local clash = "clash"
local NXFS = require "nixio.fs"
local SYS = require "luci.sys"
local HTTP = require "luci.http"
local DISP = require "luci.dispatcher"
local UTIL = require "luci.util"
local fs = require "luci.clash"
local uci = require "luci.model.uci".cursor()
font_red = [[<font color="red">]]
font_blue = [[<font color="blue">]]
font_off = [[</font>]]
bold_on = [[<strong>]]
bold_off = [[</strong>]]
m = Map(clash)
m.pageaction = false
m.description=''..font_red..bold_on..translate("Usage Steps:")..bold_off..font_off..' '
.."<br />"
..font_blue..bold_on..translate("1.Load Policy Group, make sure you have selected a config on config page")..bold_off..font_off..' '
.."<br />"
..font_blue..bold_on..translate("2.Download the game rules you want to use from the game rules list on this page")..bold_off..font_off..' '
.."<br />"
..font_blue..bold_on..translate("3. Make sure your game and servers support UDP")..bold_off..font_off..' '
.."<br />"
..font_blue..bold_on..translate("4.Click on ADD, Set the corresponding policy group of the downloaded game rules and save, recommended: FallBack")..bold_off..font_off..' '
.."<br />"
..font_blue..bold_on..translate("5.Select ClashTun Core type and start client")..bold_off..font_off..' '
SYS.call("awk -F ',' '{print $1}' /usr/share/clash/rules/rules.list > /tmp/rules_name 2>/dev/null")
file = io.open("/tmp/rules_name", "r");
r = m:section(TypedSection, "conf_groups", translate("Policy Groups"))
r.anonymous = true
r.addremove = false
r.sortable = false
r.template = "cbi/tblsection"
--r.extedit = luci.dispatcher.build_url("admin/services/clash/g-groups/%s")
function r.create(...)
local sid = TypedSection.create(...)
if sid then
luci.http.redirect(r.extedit % sid)
return
end
end
o = r:option(DummyValue, "type", translate("Group Type"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
o = r:option(DummyValue, "name", translate("Group Name"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
-- [[ Edit Game Rule ]] --
r = m:section(TypedSection, "game", translate("Game Rules & Groups"))
r.anonymous = true
r.addremove = true
r.sortable = false
r.template = "cbi/tblsection"
r.extedit = luci.dispatcher.build_url("admin/services/clash/g-rules/%s")
function r.create(...)
local sid = TypedSection.create(...)
if sid then
luci.http.redirect(r.extedit % sid)
return
end
end
o = r:option(DummyValue, "tag", translate("Game Rule Tag"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
o = r:option(DummyValue, "group", translate("Policy Groups"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
---- Rules List
local e={},a,o,t
a=nixio.fs.access("/tmp/rules_name")
if a then
for o in file:lines() do
table.insert(e,o)
end
for t,o in ipairs(e) do
e[t]={}
e[t].num=string.format(t)
e[t].name=o
e[t].filename=string.sub(luci.sys.exec(string.format("grep -F '%s,' /usr/share/clash/rules/rules.list |awk -F ',' '{print $3}' 2>/dev/null",e[t].name)),1,-2)
if e[t].filename == "" then
e[t].filename=string.sub(luci.sys.exec(string.format("grep -F '%s,' /usr/share/clash/rules/rules.list |awk -F ',' '{print $2}' 2>/dev/null",e[t].name)),1,-2)
end
RULE_FILE="/usr/share/clash/rules/g_rules/".. e[t].filename
if fs.mtime(RULE_FILE) then
e[t].mtime=os.date("%Y-%m-%d %H:%M:%S",fs.mtime(RULE_FILE))
else
e[t].mtime="/"
end
if fs.isfile(RULE_FILE) then
e[t].exist=translate("Exist")
else
e[t].exist=translate("Not Exist")
end
e[t].remove=0
end
end
file:close()
f=Form("filelist", translate("Game Rules List"))
tb=f:section(Table,e)
nu=tb:option(DummyValue,"num",translate("Order Number"))
st=tb:option(DummyValue,"exist",translate("State"))
--nm=tb:option(DummyValue,"name",translate("Rule Name"))
fm=tb:option(DummyValue,"filename",translate("File Name"))
mt=tb:option(DummyValue,"mtime",translate("Update Time"))
btnis=tb:option(DummyValue,"filename",translate("Download Rule"))
btnis.template="clash/game_rule"
btnrm=tb:option(Button,"remove",translate("Remove"))
btnrm.render=function(e,t,a)
e.inputstyle="reset"
Button.render(e,t,a)
end
btnrm.write=function(a,t)
local a=fs.unlink("/usr/share/clash/rules/g_rules/"..e[t].filename)
HTTP.redirect(luci.dispatcher.build_url("admin", "services", "clash", "settings", "grules"))
end
local t = {
{Load,Apply}
}
k = Form("apply")
k.reset = false
k.submit = false
s = k:section(Table, t)
o = s:option(Button, "Load")
o.inputtitle = translate("Load Groups")
o.inputstyle = "apply"
o.write = function()
m.uci:commit("clash")
luci.sys.call("bash /usr/share/clash/load_groups.sh >/dev/null 2>&1 &")
luci.sys.call("sleep 3")
HTTP.redirect(luci.dispatcher.build_url("admin", "services", "clash", "settings", "grules"))
end
o = s:option(Button, "Apply")
o.inputtitle = translate("Save & Apply")
o.inputstyle = "apply"
o.write = function()
m.uci:commit("clash")
if luci.sys.call("pidof clash >/dev/null") == 0 then
SYS.call("/etc/init.d/clash restart >/dev/null 2>&1 &")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "clash"))
else
HTTP.redirect(luci.dispatcher.build_url("admin", "services", "clash", "settings", "grules"))
end
end
return m, k, f
@@ -1,143 +0,0 @@
local NXFS = require "nixio.fs"
local SYS = require "luci.sys"
local HTTP = require "luci.http"
local DISP = require "luci.dispatcher"
local UTIL = require "luci.util"
local uci = require("luci.model.uci").cursor()
local clash = "clash"
local http = luci.http
font_red = [[<font color="red">]]
font_off = [[</font>]]
bold_on = [[<strong>]]
bold_off = [[</strong>]]
k = Map(clash)
k.reset = false
k.submit = false
s=k:section(TypedSection, "clash", translate("Local Update GeoIP"))
s.anonymous = true
s.addremove=false
o = s:option(FileUpload, "")
o.description = translate("NB: Upload GEOIP Database file Country.mmdb")
.."<br />"
..translate("https://github.com/Dreamacro/maxmind-geoip/releases")
.."<br />"
..translate("https://raw.githubusercontent.com/alecthw/mmdb_china_ip_list/release/Country.mmdb")
o.title = translate(" ")
o.template = "clash/clash_upload"
um = s:option(DummyValue, "", nil)
um.template = "clash/clash_dvalue"
local dir, fd
dir = "/etc/clash/"
http.setfilehandler(
function(meta, chunk, eof)
if not fd then
if not meta then return end
if meta and chunk then fd = nixio.open(dir .. meta.file, "w") end
if not fd then
um.value = translate("upload file error.")
return
end
end
if chunk and fd then
fd:write(chunk)
end
if eof and fd then
fd:close()
fd = nil
um.value = translate("File saved to") .. ' "/etc/clash/"'
SYS.call("chmod + x /etc/clash/Country.mmdb")
if luci.sys.call("pidof clash >/dev/null") == 0 then
SYS.call("/etc/init.d/clash restart >/dev/null 2>&1 &")
end
end
end
)
if luci.http.formvalue("upload") then
local f = luci.http.formvalue("ulfile")
if #f <= 0 then
um.value = translate("No specify upload file.")
end
end
m = Map("clash")
s = m:section(TypedSection, "clash" , translate("Online Update GeoIP"))
m.pageaction = false
s.anonymous = true
s.addremove=false
o = s:option(Flag, "auto_update_geoip", translate("Auto Update"))
o.description = translate("Auto Update GeoIP Database")
o = s:option(ListValue, "auto_update_geoip_time", translate("Update time (every day)"))
for t = 0,23 do
o:value(t, t..":00")
end
o.default=0
o.description = translate("GeoIP Update Time")
o = s:option(ListValue, "up_time", translate("Update Every (Week/Month)"))
o.rmempty = false
o.description = translate("Time For Update (Once a week/Month)")
o:value("weekly", translate("Weekly"))
o:value("monthly", translate("Monthly"))
o = s:option(ListValue, "geoip_update_day", translate("Update Day (Day of Week)"))
o:value("1", translate("Every Monday"))
o:value("2", translate("Every Tuesday"))
o:value("3", translate("Every Wednesday"))
o:value("4", translate("Every Thursday"))
o:value("5", translate("Every Friday"))
o:value("6", translate("Every Saturday"))
o:value("0", translate("Every Sunday"))
update_time = SYS.exec("ls -l --full-time /etc/clash/Country.mmdb|awk '{print $6,$7;}'")
o.description = translate("Update Time")..'- ' ..font_red..bold_on..update_time..bold_off..font_off..' '
o:depends("up_time", "weekly")
o = s:option(ListValue, "geo_update_week", translate("Update Day (Day of Month)"))
o:value("1", translate("Every 1st Day"))
o:value("7", translate("Every 7th Day"))
o:value("14", translate("Every 14th Day"))
o:value("21", translate("Every 21st Day"))
o:value("28", translate("Every 28th Day"))
update_time = SYS.exec("ls -l --full-time /etc/clash/Country.mmdb|awk '{print $6,$7;}'")
o.description = translate("Update Time")..'- ' ..font_red..bold_on..update_time..bold_off..font_off..' '
o:depends("up_time", "monthly")
o = s:option(ListValue, "geoip_source", translate("GeoIP Source"))
o:value("1", translate("MaxMind"))
o:value("2", translate("Github"))
o = s:option(Value, "license_key")
o.title = translate("License Key")
o.description = translate("MaxMind License Key")..translate(" https://www.maxmind.com/en/geolite2/signup")
o.rmempty = true
o:depends("geoip_source", "1")
o=s:option(Button,"update_geoip")
o.inputtitle = translate("Save & Apply")
o.title = luci.util.pcdata(translate("Save & Apply"))
o.inputstyle = "reload"
o.write = function()
m.uci:commit("clash")
end
o = s:option(Button,"download")
o.title = translate("Download")
o.template = "clash/geoip"
return m, k
@@ -1,50 +0,0 @@
local NXFS = require "nixio.fs"
local SYS = require "luci.sys"
local HTTP = require "luci.http"
local DISP = require "luci.dispatcher"
local UTIL = require "luci.util"
local uci = require("luci.model.uci").cursor()
local fs = require "luci.clash"
local http = luci.http
m = Map("clash")
s = m:section(TypedSection, "clash")
m.pageaction = false
s.anonymous = true
s.addremove=false
log = s:option(TextValue, "clog")
log.template = "clash/status_log"
o = s:option(Button, "Download")
o.inputtitle = translate("Download logs")
o.inputstyle = "apply"
o.write = function ()
local sPath, sFile, fd, block
sPath = "/usr/share/clash/clash.txt"
sFile = NXFS.basename(sPath)
if fs.isdirectory(sPath) then
fd = io.popen('txt -C "%s" -cz .' % {sPath}, "r")
sFile = sFile .. ".txt"
else
fd = nixio.open(sPath, "r")
end
if not fd then
return
end
HTTP.header('Content-Disposition', 'attachment; filename="%s"' % {sFile})
HTTP.prepare_content("application/octet-stream")
while true do
block = fd:read(nixio.const.buffersize)
if (not block) or (#block ==0) then
break
else
HTTP.write(block)
end
end
fd:close()
HTTP.close()
end
return m
@@ -1,141 +0,0 @@
local NXFS = require "nixio.fs"
local SYS = require "luci.sys"
local HTTP = require "luci.http"
local DISP = require "luci.dispatcher"
local UTIL = require "luci.util"
local uci = luci.model.uci.cursor()
local fs = require "luci.clash"
local http = luci.http
local clash = "clash"
kk = Map(clash)
s = kk:section(TypedSection, "clash", translate("Auto Update Config"))
s.anonymous = true
kk.pageaction = false
o = s:option(Flag, "auto_update", translate("Auto Update"))
o.description = translate("Auto Update Server subscription")
o = s:option(ListValue, "auto_update_time", translate("Update time (every day)"))
o:value("1", translate("Every Hour"))
o:value("6", translate("Every 6 Hours"))
o:value("12", translate("Every 12 Hours"))
o:value("24", translate("Every 24 Hours"))
o.description = translate("Daily Server subscription update time. Only update config in use")
o = s:option(Button, "Apply")
o.title = luci.util.pcdata(translate("Save & Apply"))
o.inputtitle = translate("Save & Apply")
o.inputstyle = "apply"
o.write = function()
kk.uci:commit("clash")
end
m = Map("clash")
s = m:section(TypedSection, "clash" , translate("Clear Clash Log"))
s.anonymous = true
o = s:option(Flag, "auto_clear_log", translate("Auto Clear Log"))
o.description = translate("Auto Clear Log")
o = s:option(ListValue, "clear_time", translate("Clear Time (Time of Day)"))
o:value("1", translate("Every Hour"))
o:value("6", translate("Every 6 Hours"))
o:value("12", translate("Every 12 Hours"))
o:value("24", translate("Every 24 Hours"))
o.description = translate("Clear Log Time")
o=s:option(Button,"clear_clear")
o.inputtitle = translate("Save & Apply")
o.title = luci.util.pcdata(translate("Save & Apply"))
o.inputstyle = "reload"
o.write = function()
m.uci:commit("clash")
end
w = Map("clash")
s = w:section(TypedSection, "clash" , translate("Load Groups"))
s.anonymous = true
o = s:option(Button, "Load")
o.inputtitle = translate("Load Groups")
o.title = translate("Load Groups")
o.inputstyle = "apply"
o.write = function()
w.uci:commit("clash")
luci.sys.call("bash /usr/share/clash/load_groups.sh >/dev/null 2>&1 &")
luci.sys.call("sleep 4")
HTTP.redirect(luci.dispatcher.build_url("admin", "services", "clash", "settings", "other"))
end
r = w:section(TypedSection, "conf_groups", translate("Policy Groups"))
r.anonymous = true
r.addremove = false
r.sortable = false
r.template = "cbi/tblsection"
function r.create(...)
local sid = TypedSection.create(...)
if sid then
luci.http.redirect(r.extedit % sid)
return
end
end
o = r:option(DummyValue, "type", translate("Group Type"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
o = r:option(DummyValue, "name", translate("Group Name"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
y = Map("clash")
x = y:section(TypedSection, "addtype", translate("Custom Rules"))
x.anonymous = true
x.addremove = true
x.sortable = false
x.template = "cbi/tblsection"
x.extedit = luci.dispatcher.build_url("admin/services/clash/ip-rules/%s")
function x.create(...)
local sid = TypedSection.create(...)
if sid then
luci.http.redirect(x.extedit % sid)
return
end
end
o = x:option(DummyValue, "type", translate("Rule Type"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
o = x:option(DummyValue, "ipaaddr", translate("IP/Domain/Address/Keyword/Port"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
o = x:option(DummyValue, "pgroup", translate("Policy Groups"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
return kk, m,w,y
@@ -1,13 +0,0 @@
local m
local sys = require "luci.sys"
local uci = luci.model.uci.cursor()
m = Map("clash")
m:section(SimpleSection).template = "clash/status"
m.pageaction = false
return m
@@ -1,147 +0,0 @@
local NXFS = require "nixio.fs"
local SYS = require "luci.sys"
local HTTP = require "luci.http"
local DISP = require "luci.dispatcher"
local UTIL = require "luci.util"
local uci = require("luci.model.uci").cursor()
local m , r, k
local http = luci.http
font_red = [[<font color="red">]]
font_green = [[<font color="green">]]
font_off = [[</font>]]
bold_on = [[<strong>]]
bold_off = [[</strong>]]
ko = Map("clash")
ko.reset = false
ko.submit = false
sul =ko:section(TypedSection, "clash",translate("Manual Upload"))
sul.anonymous = true
sul.addremove=false
o = sul:option(FileUpload, "")
o.description =''..font_red..bold_on..translate("Manually download, unzip and rename clash core from links below and upload")..bold_off..font_off..' '
.."<br />"
..translatef("<a href=\"%s\" target=\"_blank\">" .. "Dreamacro clash core - clash</a>", translate("https://github.com/Dreamacro/clash/releases/latest"))
.."<br />"
..translatef("<a href=\"%s\" target=\"_blank\">" .. "Frainzy1477 clashr core - clash</a>", translate("https://github.com/frainzy1477/clash_dev/releases/latest"))
.."<br />"
..translatef("<a href=\"%s\" target=\"_blank\">" .. "comzyh clash tun core - clash(ctun)</a>", translate("https://github.com/comzyh/clash/releases/latest"))
.."<br />"
..translatef("<a href=\"%s\" target=\"_blank\">" .. "Dreamacro clash tun core - clash(premium)</a>", translate("https://github.com/Dreamacro/clash/releases/tag/premium"))
o.title = translate(" ")
o.template = "clash/upload_core"
um = sul:option(DummyValue, "", nil)
um.template = "clash/clash_dvalue"
local dir, fd,dtun,ctun,cssr
dir = "/etc/clash/"
dtun="/etc/clash/dtun/"
ctun="/etc/clash/clashtun/"
http.setfilehandler(
function(meta, chunk, eof)
local fp = HTTP.formvalue("file_type")
if not fd then
if not meta then return end
if fp == "clash" then
if meta and chunk then fd = nixio.open(dir .. meta.file, "w") end
elseif fp == "clashctun" then
if meta and chunk then fd = nixio.open(ctun .. meta.file, "w") end
elseif fp == "clashdtun" then
if meta and chunk then fd = nixio.open(dtun .. meta.file, "w") end
end
if not fd then
um.value = translate("upload file error.")
return
end
end
if chunk and fd then
fd:write(chunk)
end
if eof and fd then
fd:close()
fd = nil
if fp == "clash" then
SYS.exec("chmod 755 /etc/clash/clash 2>&1 &")
SYS.exec("rm -rf /usr/share/clash/core_version 2>/dev/null && /etc/clash/clash -v | awk -F ' ' '{print $2}' >> /usr/share/clash/core_version 2>/dev/null")
um.value = translate("File saved to") .. ' "/etc/clash/'..meta.file..'"'
elseif fp == "clashctun" then
SYS.exec("chmod 755 /etc/clash/clashtun/clash 2>&1 &")
SYS.exec("rm -rf /usr/share/clash/tun_version 2>/dev/null && /etc/clash/clashtun/clash -v | awk -F ' ' '{print $2}' >> /usr/share/clash/tun_version 2>/dev/null")
um.value = translate("File saved to") .. ' "/etc/clash/clashtun/'..meta.file..'"'
elseif fp == "clashdtun" then
SYS.exec("chmod 755 /etc/clash/dtun/clash 2>&1 &")
SYS.exec("rm -rf /usr/share/clash/dtun_core_version 2>/dev/null && /etc/clash/dtun/clash -v | awk -F ' ' '{print $2}' >> /usr/share/clash/dtun_core_version 2>/dev/null")
um.value = translate("File saved to") .. ' "/etc/clash/dtun/'..meta.file..'"'
end
end
end
)
if luci.http.formvalue("upload") then
local f = luci.http.formvalue("ulfile")
if #f <= 0 then
um.value = translate("No specify upload file.")
end
end
m = Map("clash")
m:section(SimpleSection).template = "clash/update"
m.pageaction = false
k = Map("clash")
s = k:section(TypedSection, "clash",translate("Download Online"))
s.anonymous = true
o = s:option(ListValue, "dcore", translate("Core Type"))
o.default = "clashcore"
o:value("1", translate("clash"))
o:value("3", translate("clash(ctun)"))
o:value("4", translate("clash(premium)"))
local cpu_model=SYS.exec("opkg status libc 2>/dev/null |grep 'Architecture' |awk -F ': ' '{print $2}' 2>/dev/null")
o = s:option(ListValue, "download_core", translate("Select Core"))
o.description = translate("CPU Model")..': '..font_green..bold_on..cpu_model..bold_off..font_off..' '
o:value("linux-386")
o:value("linux-amd64", translate("linux-amd64(x86-64)"))
o:value("linux-armv5")
o:value("linux-armv6")
o:value("linux-armv7")
o:value("linux-armv8")
o:value("linux-mips-hardfloat")
o:value("linux-mips-softfloat")
o:value("linux-mips64")
o:value("linux-mips64le")
o:value("linux-mipsle-softfloat")
o:value("linux-mipsle-hardfloat")
o=s:option(Button,"down_core")
o.inputtitle = translate("Save & Apply")
o.title = luci.util.pcdata(translate("Save & Apply"))
o.inputstyle = "reload"
o.write = function()
k.uci:commit("clash")
end
o = s:option(Button,"download")
o.title = translate("Download")
o.template = "clash/core_check"
return m, ko,k
@@ -1,9 +0,0 @@
<%+cbi/valueheader%>
<span style="color: red">
<%
local val = self:cfgvalue(section) or self.default or ""
write(pcdata(val))
%>
</span>
<%+cbi/valuefooter%>
@@ -1,6 +0,0 @@
<%+cbi/valueheader%>
<label class="cbi-value" style="display:inline-block;" for="ulfile"></label>
<input class="cbi-input-file" style="width: 80%" type="file" id="ulfile" name="ulfile" />
<input type="submit" style="width: 100%" class="cbi-button cbi-input-apply" name="upload" value="<%:Upload%>" />
<%+cbi/valuefooter%>
-23
View File
@@ -1,23 +0,0 @@
<fieldset class="cbi-section">
<p width="100%" align="center"><font color="blue"><b><%:CONFIG IN USE%>:</b> <b id="_conf_path"></b></font></p>
</fieldset>
<script type="text/javascript">//<![CDATA[
var conf_path = document.getElementById('_conf_path');
XHR.poll(1, '<%=luci.dispatcher.build_url("admin", "services", "clash", "conf")%>', null, function(x, status) {
if ( x && x.status == 200 ) {
if(status.typeconf==1){
conf_path.innerHTML = status.conf_path ? '<b><font color="green"><%:SUBSCRIBE%> 【'+status.conf_path+'】</font></b>' : '<b><font color="red"><%:NOT SELECTED%></font></b>';
}
if(status.typeconf==2){
conf_path.innerHTML = status.conf_path ? '<b><font color="green"><%:UPLOAD%> 【'+status.conf_path+'】</font></b>' : '<b><font color="red"><%:NOT SELECTED%></font></b>';
}
if(status.typeconf==3){
conf_path.innerHTML = status.conf_path ? '<b><font color="green"><%:CUSTOM%> 【'+status.conf_path+'】</font></b>' : '<b><font color="red"><%:NOT SELECTED%></font></b>';
}
}
});
//]]></script>
@@ -1,71 +0,0 @@
<%+cbi/valueheader%>
<%local fs=require"nixio.fs"%>
<input type="button" class="cbi-button cbi-button-apply" id="apply_update_button" value="<%:Download%>" onclick=" return apply_update() "/>
<br /><br />
<textarea id="core_download" class="cbi-input-textarea" style="width: 100%;display:none" data-update="change" rows="10" cols="100" readonly="readonly" > </textarea>
<script type="text/javascript">//<![CDATA[
function apply_update(){
XHR.get('<%=url([[admin]], [[services]], [[clash]], [[doupdate]])%>',null,function(x, data){}
);
poll_check();
return
}
function poll_check(){
var lv = document.getElementById('core_download');
lv.style.display="inline"
XHR.poll(2, '<%=url([[admin]], [[services]], [[clash]], [[check]])%>', null,
function(x, data) {
var lv = document.getElementById('core_download');
if (x.responseText && lv) {
lv.innerHTML += x.responseText;
lv.scrollTop = lv.scrollHeight;
}
}
);
}
XHR.poll(3, '<%=luci.dispatcher.build_url("admin", "services", "clash", "corelog")%>', null, function(x, status) {
if ( x && x.status == 200 ) {
if(status.downcheck==0||status.downcheck==2){
hide();
}
if(status.downcheck==1){
var btn = document.getElementById('apply_update_button');
btn.disabled = false;
btn.value = '<%:Download%>';
poll_check();
}
}
});
//]]>
function hide(){
$('#core_download').hide();
var btn = document.getElementById('apply_update_button');
btn.disabled = false;
btn.value = '<%:Download%>';
}
<% if fs.access("/var/run/core_update") then %>
var btn = document.getElementById('apply_update_button');
btn.disabled = true;
btn.value = '<%:Downloading...%>';
poll_check();
<%end%>
</script>
<%+cbi/valuefooter%>
@@ -1,38 +0,0 @@
<%+cbi/valueheader%>
<script type="text/javascript">//<![CDATA[
function act_download_rule(btn,filename)
{
btn.disabled = true;
btn.value = '<%:Downloading...%> ';
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "clash","game_rule")%>',
{
filename: filename
},
function(x,status)
{
if ( x && x.status == 200 ) {
if(status.game_rule=="0")
{
btn.value = '<%:Error%>';
}
else
{
btn.value = '<%:Successful%>';
window.location.reload();
}
}
else {
btn.value = '<%:Timeout%>';
}
}
);
btn.disabled = false;
return false;
}
//]]></script>
<input type="button" class="cbi-button cbi-input-reload" value="<%:Update Rule%>" onclick="return act_download_rule(this,'<%=self:cfgvalue(section)%>')" />
<%+cbi/valuefooter%>
@@ -1,72 +0,0 @@
<%+cbi/valueheader%>
<%local fs=require"nixio.fs"%>
<input type="button" class="cbi-button cbi-button-apply" id="apply_update_geoip" value="<%:Download%>" onclick=" return apply_update() "/>
<br /><br />
<textarea id="geoip_download" class="cbi-input-textarea" style="width: 100%;display:none" data-update="change" rows="10" cols="100" readonly="readonly" > </textarea>
<script type="text/javascript">//<![CDATA[
function apply_update(){
XHR.get('<%=url([[admin]], [[services]], [[clash]], [[geoipupdate]])%>',null,function(x, data){}
);
poll_check();
return
}
function poll_check(){
var lv = document.getElementById('geoip_download');
lv.style.display="inline"
XHR.poll(2, '<%=url([[admin]], [[services]], [[clash]], [[check_geoip]])%>', null,
function(x, data) {
var lv = document.getElementById('geoip_download');
if (x.responseText && lv) {
lv.innerHTML += x.responseText;
lv.scrollTop = lv.scrollHeight;
}
}
);
}
XHR.poll(3, '<%=luci.dispatcher.build_url("admin", "services", "clash", "geo")%>', null, function(x, status) {
if ( x && x.status == 200 ) {
if(status.geoipcheck==0||status.geoipcheck==2){
hide();
}
if(status.geoipcheck==1){
var btn = document.getElementById('apply_update_geoip');
btn.disabled = false;
btn.value = '<%:Download%>';
poll_check();
}
}
});
//]]>
function hide(){
$('#geoip_download').hide();
var btn = document.getElementById('apply_update_geoip');
btn.disabled = false;
btn.value = '<%:Download%>';
}
<% if fs.access("/var/run/geoip_update") then %>
var btn = document.getElementById('apply_update_geoip');
btn.disabled = true;
btn.value = '<%:Downloading...%>';
poll_check();
<%end%>
</script>
<%+cbi/valuefooter%>
-47
View File
@@ -1,47 +0,0 @@
<%
local dsp = require "luci.dispatcher"
-%>
<script type="text/javascript">
//<![CDATA[
var pings = document.getElementsByClassName('ping');
for(var i = 0; i < pings.length; i++) {
XHR.get('<%=dsp.build_url("admin", "services", "clash", "ping")%>', {
index: i,
domain: pings[i].getAttribute("hint")
},
function(x, result) {
if (result.ping < 500) {
pings[result.index].innerHTML = (result.ping ? "<b><font color='#ee1010'>"+result.ping+"</font></b> ms" : "<b><font color=red><%:Error%></font></b>");
}
if (result.ping < 200){
pings[result.index].innerHTML = (result.ping ? "<b><font color='#7acc03'>"+result.ping+"</font></b> ms" : "<b><font color=red><%:Error%></font></b>");
}
if (result.ping < 100){
pings[result.index].innerHTML = (result.ping ? "<b><font color='#007e1a'>"+result.ping+"</font></b> ms" : "<b><font color=red><%:Error%></font></b>");
}
}
);
XHR.poll(20,'<%=dsp.build_url("admin", "services", "clash", "ping")%>',{
index: i,
domain: pings[i].getAttribute("hint")
},
function(x, result) {
if (result.ping < 500) {
pings[result.index].innerHTML = (result.ping ? "<b><font color='#ee1010'>"+result.ping+"</font></b> ms" : "<b><font color=red><%:Error%></font></b>");
}
if (result.ping < 200){
pings[result.index].innerHTML = (result.ping ? "<b><font color='#7acc03'>"+result.ping+"</font></b> ms" : "<b><font color=red><%:Error%></font></b>");
}
if (result.ping < 100){
pings[result.index].innerHTML = (result.ping ? "<b><font color='#007e1a'>"+result.ping+"</font></b> ms" : "<b><font color=red><%:Error%></font></b>");
}
}
);
}
//]]>
</script>
@@ -1,7 +0,0 @@
<%+cbi/valueheader%>
<% if self:cfgvalue(section) ~= false then %>
<input class="cbi-button cbi-input-<%=self.inputstyle or "button" %>" style="display: <%= display %>" type="submit"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> />
<% else %>
-
<% end %>
<%+cbi/valuefooter%>
@@ -1,5 +0,0 @@
<%+cbi/valueheader%>
<span class="ping" hint="<%=self:cfgvalue(section)%>"><%:Checking...%></span>
<%+cbi/valuefooter%>
@@ -1,41 +0,0 @@
<%+cbi/valueheader%>
<script type="text/javascript">//<![CDATA[
function act_download_rule(btn,filename)
{
btn.disabled = true;
btn.value = '<%:Downloading...%> ';
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "clash","ruleproviders")%>',
{
filename: filename
},
function(x,status)
{
if ( x && x.status == 200 ) {
if(status.rulep=="0")
{
btn.value = '<%:Error%>';
}
else if (status.rulep=="1")
{
btn.value = '<%:Successful%>';
window.location.reload();
}else if (status.rulep=="2")
{
btn.value = '<%:Not Updated%>';
}
}
else {
btn.value = '<%:Timeout%>';
}
}
);
btn.disabled = false;
return false;
}
//]]></script>
<input type="button" class="cbi-button cbi-input-reload" value="<%:Update Rule Providers%>" onclick="return act_download_rule(this,'<%=self:cfgvalue(section)%>')" />
<%+cbi/valuefooter%>
-252
View File
@@ -1,252 +0,0 @@
<%+cbi/valueheader%>
<script type="text/javascript">//<![CDATA[
function padright(str, cnt, pad) {
return str + Array(cnt + 1).join(pad);
}
function b64EncodeUnicode(str) {
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
return String.fromCharCode('0x' + p1);
}));
}
function b64encutf8safe(str) {
return b64EncodeUnicode(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '');
}
function b64DecodeUnicode(str) {
return decodeURIComponent(Array.prototype.map.call(atob(str), function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
}
function b64decutf8safe(str) {
var l;
str = str.replace(/-/g, "+").replace(/_/g, "/");
l = str.length;
l = (4 - l % 4) % 4;
if (l)
str = padright(str, l, "=");
return b64DecodeUnicode(str);
}
function b64encsafe(str) {
return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '')
}
function b64decsafe(str) {
var l;
str = str.replace(/-/g, "+").replace(/_/g, "/");
l = str.length;
l = (4 - l % 4) % 4;
if (l)
str = padright(str, l, "=");
return atob(str);
}
function dictvalue(d, key) {
var v = d[key];
if (typeof (v) == 'undefined' || v == '')
return '';
return b64decsafe(v);
}
function import_ssr_url(btn, urlname, sid) {
var s = document.getElementById(urlname + '-status');
if (!s)
return false;
var ssrurl = prompt("ssr:// | ss:// | vmess:// | trojan://", "");
if (ssrurl == null || ssrurl == "") {
s.innerHTML = "<font color='red'><%:Operation Aborted%></font>";
return false;
}
s.innerHTML = "";
//var ssu = ssrurl.match(/ssr:\/\/([A-Za-z0-9_-]+)/i);
var ssu = ssrurl.split('://');
console.log(ssu.length);
if ((ssu[0] != "ssr" && ssu[0] != "ss" && ssu[0] != "vmess" && ssu[0] != "trojan") || ssu[1] == "") {
s.innerHTML = "<font color='red'><%:Invalid link%></font>";
return false;
}
var event = document.createEvent("HTMLEvents");
event.initEvent("change", true, true);
if (ssu[0] == "ssr") {
var sstr = b64decsafe(ssu[1]);
var ploc = sstr.indexOf("/?");
document.getElementById('cbid.clash.' + sid + '.type').value = "ssr";
document.getElementById('cbid.clash.' + sid + '.type').dispatchEvent(event);
var url0, param = "";
if (ploc > 0) {
url0 = sstr.substr(0, ploc);
param = sstr.substr(ploc + 2);
}
var ssm = url0.match(/^(.+):([^:]+):([^:]*):([^:]+):([^:]*):([^:]+)/);
if (!ssm || ssm.length < 7)
return false;
var pdict = {};
if (param.length > 2)
{
var a = param.split('&');
for (var i = 0; i < a.length; i++) {
var b = a[i].split('=');
pdict[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || '');
}
}
document.getElementById('cbid.clash.' + sid + '.server').value = ssm[1];
document.getElementById('cbid.clash.' + sid + '.port').value = ssm[2];
document.getElementById('cbid.clash.' + sid + '.protocol').value = ssm[3];
document.getElementById('cbid.clash.' + sid + '.cipher_ssr').value = ssm[4];
document.getElementById('cbid.clash.' + sid + '.obfs_ssr').value = ssm[5];
document.getElementById('cbid.clash.' + sid + '.password').value = b64decsafe(ssm[6]);
document.getElementById('cbid.clash.' + sid + '.obfsparam').value = dictvalue(pdict, 'obfsparam');
document.getElementById('cbid.clash.' + sid + '.protocolparam').value = dictvalue(pdict, 'protoparam');
var rem = pdict['remarks'];
if (typeof (rem) != 'undefined' && rem != '' && rem.length > 0)
document.getElementById('cbid.clash.' + sid + '.name').value = b64decutf8safe(rem);
s.innerHTML = "<font color='green'><%:Import ShadowsocksR config info successful%></font>";
return false;
} else if (ssu[0] == "ss") {
var sipIndex = ssu[1].split("@");
var sstr = b64decsafe(sipIndex[0]);
var ssm = sstr.split(':');
var team = sipIndex[1].split(':');
//var obfs = port[1].split('=');
var temp = ssu[1].split("?");
if (temp[1]) {
var pluginInfo = decodeURIComponent(temp[1]);
}
document.getElementById('cbid.clash.' + sid + '.type').value = "ss";
document.getElementById('cbid.clash.' + sid + '.type').dispatchEvent(event);
document.getElementById('cbid.clash.' + sid + '.server').value = team[0];
document.getElementById('cbid.clash.' + sid + '.password').value = ssm[1];
document.getElementById('cbid.clash.' + sid + '.cipher').value = ssm[0];
if (temp[1]) {
var name = pluginInfo.split("#");
var port = team[1].split('?');
var obfslocal = name[0].split(';')
var obfs = obfslocal[1].split('=')
var obfshost = obfslocal[2].split('=')
document.getElementById('cbid.clash.' + sid + '.port').value = port[0];
document.getElementById('cbid.clash.' + sid + '.name').value = name[1];
document.getElementById('cbid.clash.' + sid + '.obfs').value = obfs[1];
document.getElementById('cbid.clash.' + sid + '.obfs').dispatchEvent(event);
document.getElementById('cbid.clash.' + sid + '.host').value = obfshost[1];
}
if (!temp[1]) {
var name2 = sipIndex[1].split('#');
var port = name2[0].split(':');
document.getElementById('cbid.clash.' + sid + '.port').value = port[1];
document.getElementById('cbid.clash.' + sid + '.name').value = name2[1];
document.getElementById('cbid.clash.' + sid + '.obfs').value = " ";
document.getElementById('cbid.clash.' + sid + '.obfs').dispatchEvent(event);
}
s.innerHTML = "<font color='green'><%:Import Shadowsocks config info successful%></font>";
return false;
} else if (ssu[0] == "trojan") {
var url0, param = "";
var ploc = ssu[1].indexOf("#");
if (ploc > 0) {
url0 = ssu[1].substr(0, ploc);
param = ssu[1].substr(ploc + 1);
} else {
url0 = ssu[1]
}
var sstr = url0;
var name = ssrurl.split('#');
document.getElementById('cbid.clash.' + sid + '.type').value = "trojan";
document.getElementById('cbid.clash.' + sid + '.type').dispatchEvent(event);
var team = sstr.split('@');
var password = team[0]
var serverPart = team[1].split(':');
var others = serverPart[1].split('?');
var port = others[0]
var queryParam = {}
if(others.length > 1) {
var queryParams = others[1]
var queryArray = queryParams.split('&')
for (i = 0; i < queryArray.length; i++) {
var params = queryArray[i].split('=');
queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || '');
}
}
document.getElementById('cbid.clash.' + sid + '.name').value = name[1];
document.getElementById('cbid.clash.' + sid + '.server').value = serverPart[0];
document.getElementById('cbid.clash.' + sid + '.port').value = port;
document.getElementById('cbid.clash.' + sid + '.password').value = password;
document.getElementById('cbid.clash.' + sid + '.sni').value = serverPart[0];
document.getElementById('cbid.clash.' + sid + '.alpn_http').checked = true;
document.getElementById('cbid.clash.' + sid + '.alpn_h2').checked = false;
s.innerHTML = "<font color='green'><%:Import Trojan config info successful%></font>";
return false;
} else if (ssu[0] == "vmess") {
var sstr = b64DecodeUnicode(ssu[1]);
var ploc = sstr.indexOf("/?");
document.getElementById('cbid.clash.' + sid + '.type').value = "vmess";
document.getElementById('cbid.clash.' + sid + '.type').dispatchEvent(event);
var url0, param = "";
if (ploc > 0) {
url0 = sstr.substr(0, ploc);
param = sstr.substr(ploc + 2);
}
var ssm = JSON.parse(sstr);
document.getElementById('cbid.clash.' + sid + '.name').value = ssm.ps;
document.getElementById('cbid.clash.' + sid + '.server').value = ssm.add;
document.getElementById('cbid.clash.' + sid + '.port').value = ssm.port;
document.getElementById('cbid.clash.' + sid + '.alterId').value = ssm.aid;
document.getElementById('cbid.clash.' + sid + '.uuid').value = ssm.id;
if (ssm.net == "tcp") {
document.getElementById('cbid.clash.' + sid + '.obfs_vmess').value = "none";
document.getElementById('cbid.clash.' + sid + '.obfs_vmess').dispatchEvent(event);
if (ssm.tls == "tls" || ssm.tls == "1" || ssm.tls == "true") {
document.getElementById('cbid.clash.' + sid + '.tls').value = "true";
document.getElementById('cbid.clash.' + sid + '.tls').dispatchEvent(event);
}
}
if (ssm.net == "ws") {
document.getElementById('cbid.clash.' + sid + '.obfs_vmess').value = "websocket";
document.getElementById('cbid.clash.' + sid + '.obfs_vmess').dispatchEvent(event);
document.getElementById('cbid.clash.' + sid + '.path').value = ssm.path;
document.getElementById('cbid.clash.' + sid + '.custom').value = ssm.host;
if (ssm.tls == "tls" || ssm.tls == "1" || ssm.tls == "true") {
document.getElementById('cbid.clash.' + sid + '.tls').value = "true";
document.getElementById('cbid.clash.' + sid + '.tls').dispatchEvent(event);
}
}
if (ssm.net == "h2") {
document.getElementById('cbid.clash.' + sid + '.obfs_vmess').value = "http";
document.getElementById('cbid.clash.' + sid + '.obfs_vmess').dispatchEvent(event);
document.getElementById('cbid.clash.' + sid + '.http_path').value = ssm.path;
document.getElementById('cbid.clash.' + sid + '.keep_alive').checked = true;
document.getElementById('cbid.clash.' + sid + '.keep_alive').dispatchEvent(event);
if (ssm.tls == "tls" || ssm.tls == "1" || ssm.tls == "true") {
document.getElementById('cbid.clash.' + sid + '.tls').value = "true";
document.getElementById('cbid.clash.' + sid + '.tls').dispatchEvent(event);
}
}
s.innerHTML = "<font color='green'><%:Import V2ray config info successful%></font>";
return false;
}
}
//]]></script>
<input type="button" class="cbi-button cbi-button-apply" value="<%:Import config info%>" onclick="return import_ssr_url(this, '<%=self.option%>', '<%=self.value%>')" />
<span id="<%=self.option%>-status"></span>
<%+cbi/valuefooter%>
@@ -1,34 +0,0 @@
<%+cbi/valueheader%>
<input type="button" class="cbi-button cbi-button-apply" value="<%:Start%>" onclick=" return start() "/>
<input type="button" class="cbi-button cbi-button-apply" value="<%:Stop%>" onclick=" return stop() "/>
<input type="button" class="cbi-button cbi-button-apply" value="<%:Reload%>" onclick=" return reload() "/>
<script type="text/javascript">
//<![CDATA[
function start(){
XHR.get('<%=url([[admin]], [[services]], [[clash]], [[start]])%>',null,function(x, data){}
);
window.setTimeout("location.href='/cgi-bin/luci/admin/services/clash/'", 500);
return
}
function stop(){
XHR.get('<%=url([[admin]], [[services]], [[clash]], [[stop]])%>',null,function(x, data){}
);
window.setTimeout("location.href='/cgi-bin/luci/admin/services/clash/'", 500);
return
}
function reload(){
XHR.get('<%=url([[admin]], [[services]], [[clash]], [[reload]])%>',null,function(x, data){}
);
window.setTimeout("location.href='/cgi-bin/luci/admin/services/clash/'", 500);
return
}
//]]>
</script>
<%+cbi/valuefooter%>
-639
View File
@@ -1,639 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="dns-prefetch" href="//cdn.jsdelivr.net">
<meta name="referrer" content="no-referrer">
<link rel="preconnect" href="https://geoip.gbxcloud.com">
<link rel="preconnect" href="https://myip.ipip.net">
<link rel="preconnect" href="https://api.ip.sb/geoip/">
<link rel="preconnect" href="https://ip4.seeip.org/json">
</head>
</html>
<style>
.pure-g{letter-spacing:-.31em;text-rendering:optimizespeed;font-family:FreeSans,Arimo,"Droid Sans",Helvetica,Arial,sans-serif;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-align-content:flex-start;-ms-flex-line-pack:start;align-content:flex-start}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){table .pure-g{display:block}}.opera-only :-o-prefocus,.pure-g{word-spacing:-.43em}.pure-u{display:inline-block;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-g [class*=pure-u]{font-family:sans-serif}.pure-u-1,.pure-u-1-1,.pure-u-1-12,.pure-u-1-2,.pure-u-1-24,.pure-u-1-3,.pure-u-1-4,.pure-u-1-5,.pure-u-1-6,.pure-u-1-8,.pure-u-10-24,.pure-u-11-12,.pure-u-11-24,.pure-u-12-24,.pure-u-13-24,.pure-u-14-24,.pure-u-15-24,.pure-u-16-24,.pure-u-17-24,.pure-u-18-24,.pure-u-19-24,.pure-u-2-24,.pure-u-2-3,.pure-u-2-5,.pure-u-20-24,.pure-u-21-24,.pure-u-22-24,.pure-u-23-24,.pure-u-24-24,.pure-u-3-24,.pure-u-3-4,.pure-u-3-5,.pure-u-3-8,.pure-u-4-24,.pure-u-4-5,.pure-u-5-12,.pure-u-5-24,.pure-u-5-5,.pure-u-5-6,.pure-u-5-8,.pure-u-6-24,.pure-u-7-12,.pure-u-7-24,.pure-u-7-8,.pure-u-8-24,.pure-u-9-24{display:inline-block;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-1-24{width:4.1667%}.pure-u-1-12,.pure-u-2-24{width:8.3333%}.pure-u-1-8,.pure-u-3-24{width:12.5%}.pure-u-1-6,.pure-u-4-24{width:16.6667%}.pure-u-1-5{width:20%}.pure-u-5-24{width:20.8333%}.pure-u-1-4,.pure-u-6-24{width:25%}.pure-u-7-24{width:29.1667%}.pure-u-1-3,.pure-u-8-24{width:33.3333%}.pure-u-3-8,.pure-u-9-24{width:37.5%}.pure-u-2-5{width:40%}.pure-u-10-24,.pure-u-5-12{width:41.6667%}.pure-u-11-24{width:45.8333%}.pure-u-1-2,.pure-u-12-24{width:50%}.pure-u-13-24{width:54.1667%}.pure-u-14-24,.pure-u-7-12{width:58.3333%}.pure-u-3-5{width:60%}.pure-u-15-24,.pure-u-5-8{width:62.5%}.pure-u-16-24,.pure-u-2-3{width:66.6667%}.pure-u-17-24{width:70.8333%}.pure-u-18-24,.pure-u-3-4{width:75%}.pure-u-19-24{width:79.1667%}.pure-u-4-5{width:80%}.pure-u-20-24,.pure-u-5-6{width:83.3333%}.pure-u-21-24,.pure-u-7-8{width:87.5%}.pure-u-11-12,.pure-u-22-24{width:91.6667%}.pure-u-23-24{width:95.8333%}.pure-u-1,.pure-u-1-1,.pure-u-24-24,.pure-u-5-5{width:100%}
.block{
margin: 0.5rem;
padding: 0;
font-weight: normal;
font-style: normal;
line-height: 1;
font-family: inherit;
min-width: inherit;
overflow-x: auto;
overflow-y: hidden;
border: 1px solid rgba(0,0,0,.05);
border-radius: .375rem;
background-color: #fff;
box-shadow: 0 0 2rem 0 rgba(136,152,170,.15);
}
.img-con{
margin: 1rem;
margin-left: -20px;
}
.green{
font-size:.9rem;
color: #2dce89;
}
.red{
font-size:.9rem;
color: #fb6340;
}
.yellow{
font-size:.9rem;
color: #fb9a05;
}
.block img{
width: 48px;
height: auto;
float:right;
}
.pure-u-5-8{
display:flex;
align-items:center;
}
.block h4{
font-size: .8125rem;
font-weight: 600;
margin: 1rem;
color:#8898aa!important;
line-height: 1.8em;
min-height: 48px;
}
.check {
cursor: pointer;
}
@media screen and (max-width: 720px) {
.block{
margin: 0.2rem;
}
.pure-u-1-4{
width: 50%;
}
.pure-u-1-2{
width: 100%;
}
}
@media screen and (max-width: 480px) {
.img-con{
margin: 1.5rem 0.5rem;
}
.block img{
width: 36px;
}
}
@media only screen and (max-width: 600px) {
.siz {
width: 100%;
}
}
@media only screen and (min-width: 768px) {
.siz {
width: 50%;
}
}
@media only screen and (min-width: 600px) {
.siz {
width: 50%;
}
}
@media only screen and (max-width: 480px) {
.siz {
width: 100%;
}
}
</style>
<fieldset class="cbi-section">
<p width="100%" align="center"><font color="blue"><b id="_realtimelog">Clash for OpenWRT</b></font></p>
<p width="100%" align="center"><%:Rule-based Custom Proxy Client%></p>
<p width="100%" align="center" id="_downloadnew"></p>
</fieldset>
<fieldset class="cbi-section">
<div class="pure-g status">
<div class="pure-u-1-4 ">
<div class="block pure-g">
<div class="pure-u-8-24">
<div class="img-con">
<img src="data:image/png;base64,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 truncated
</div>
</div>
<div class="pure-u-16-24">
<h4><%:Baidu%><br><br><span id="status_baidu" class="red"><em><%:Collecting data...%></em></span></h4>
</div>
</div>
</div>
<div class="pure-u-1-4 " >
<div class="block pure-g">
<div class="pure-u-8-24">
<div class="img-con">
<img src="data:image/png;base64,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 truncated
</div>
</div>
<div class="pure-u-16-24">
<h4><%:Google%><br><br><span id="status_google" class="red"><em><%:Collecting data...%></em></span></h4>
</div>
</div>
</div>
<div class="pure-u-1-4 ">
<div class="block pure-g">
<div class="pure-u-8-24">
<div class="img-con">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAmQAAAHNCAYAAACw6mcHAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA/wD/AP+gvaeTAAAAB3RJTUUH5AgUCx4YZXIwVQAAAAFvck5UAc+id5oAAIAASURBVHja7P1plGTHldh5/q/Ze+4eS0bkDmQCiR3gAu4buC/FUhVVpaXU6pLUavWRWtJIo56ZI3XrQ3+Zpc/09Jnp02fOfJhudbfm9LRGJYossorFBSBArMRCgOAGkgAIgNgzE8h9i939PbM7H8yeu0dkRGYkkInY7o8MpIeHh/tzD/f37jO7di8YY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjzHoga70BxpjLT197XcEBAqrpX3FQV9DtQj0LMQ79Qv5CIShUNYSQvjSC6PkPEgEnsNCD2TnoVvm+IhCG7liGLpO/H7ocA3QXCPMLdLsLaB1wvsA7QRCcDm4vCNpsrOb7lXR5+esdOEcEKDzl+CjS6YBb5vk0mxj9YLPzlwJSeGi3oNOGskw3jgpFMfScXPpXFIoSvIfSp9cezXdU5r8H4Jr7bOVtzteLDL5vOeTqA7avNmaTsw+5MW+DvvFGOrKrok2AI5JigVCjVQ0xIrGGUBHrGq2qFPDEGkKEuka7XehVUKfboxGqHmFmjqpKgY4gOBGIkenpaeZm5/KxW3BR8SFtytzMDNPT07SKEgmRGCMOKHxB1esxOz1Fd/YMTgcBmdP0VYhLz6OOhBCIIRBjpJB+xJa3Jccc4tA6oCEidUCi5jCwJkVsi4mcv8spVCnqGo3psYiK5NcQ0v3BUEy4eFOG7nv5v1FwjlogikMKjxRCRIhOUImINpGX5uAvB2QIKkJEiS6HmIXgygIRT5RIDSBF2iTpx4bpcQHnHL7w/ecdEYK0QSTFs2XByNg4nbEOzhdEl66PzXPxjvb4KK3OCGVZIiKEqNQh4IuSkc4IndFRirKVH1OJhaPVHsF12kirBOdQjeAEGR1DRjopUBQB8VC0cCMjKTAUn17cwuOcPz84dDIUTwtyzTV2DDHmMrEPk9nU9I0jSlWnI2WMxN5CGsOoK3rdLrGuUFVQpTs1DVXAO4cuzFNPT+NCpAhKmJ2lPjdF4QRRRedmCXPTUFWIc4T5ObrTs3lUKVI6oe516c4vgEZaTpC6otvtUfd6xBjwuEHgVgdiHRAU5zxeFWJNrGtCCKDgEEQEjYqGgMaIqiJAkYMyVUWjEnVxMNSEHM1lrXp5JIsckKQIx4mkQZwlAY9ozL+/eJfhljxGuq3iiAhNrLrcaJQsCaBi/3clD0k5Sc93aUCml7jXCgohP8W8RWiOKobH7/pbIrIk9FS0GWjMv5NGuNL9NCGjsnjszzm36H5THCnUShoxcy4FapJeCx0aNOzHnk6QsmD58bz0+ogTXL6v4Bx1c78ujYpGl0YPg0aKVkmr3SaECAJBHFIUdEZGEOfTX80Jzns6IyO4oiSStrFodygmtqX7FIGyxI2OIiMdonNoWSIjI/iRUdQ5oip+1x5i4RDv8a0WRbuFb5fUCkWnjS8L1Hlc4ZGyHPw1yhLZf60dn8yWYm94sy7pGweVGKHXy6NGIR2JqypdF+o0ojTfTUHQ1DTMz0MdqBfmoa4pQmRhZorZ6akUj1Vdzp06DSGgdcXM9Dm6c/MQI6GqmD97jljVOFUIgSIEWiLQq2k7h4RAqVC4NEqlocIjFE7wAkTQWOPJs1Ex9qcB06iRQkz/ikh/NEpjxOH6IYJTh1KDagpKFr0wmq9PB11V7Qdlg2m9wWiNNMGFan/mMt3HcAAl6HC0I0ORwXmhwOJAarkRr+a+HSsFY4O7F/IIVL6dz1OSoulnzczeeQ9xCXuu5tVBdZlnc96mp9BwuftfYQhOLvAUB3827W+3c0MB1jLbtFRkhYB2mW1XSaNrabY23SYOB3gCURXnhCiCaArmFIia/hZBQbwDcYSoqJP8cyWKQ8WnAE8ctYMKqDQSfQGFJ4qjRgkqhNKlUUQnlJ02I+PjtEZHCaqMTkzSGh/BFwWt9gitkVHKkVEQR2dinKLdgbKgGB1DS48WHj8xDu08ZdwZhbIFZRvy9lIW0GqlEcBW20bwzIZib1bzjtHXDiq9Cno1saqI8zPE0KWenUsBztwsOjUNszMwOwvdeXrnpujNzhK7XZibp55boLewQOj1qOcXqGfn8DGyMD1FmF/AA7GqcKq0pBnZUbxzeBzEQFkWSAxoDGk0xzm8QBnpTz32R50gT8Oly7HOgZJz/RETUc0jOUqMiiPdhxPBOUEVYoz5eC75f4MDuSONBkETb0ViHpXpjxDlgKoJ0KI2ozv5wDx0h8vFQOk2TYAlFw6UliOS8rRE84ga6XJMdx6lme5jKFoSLhRuDI+4RWlGAPMmXmD7LnHLh557/n0djJMtf3tZmp42uJzvsLmcRjSX5MQx/HfQ9DjDdzIYOxz6Cw5vS46cdbl7Xf7yIDxb/JwG43kOnKSgSiPiXP8t4xCCxjyily4j0g/QxKVpzJDOBdJLKZLy37xLQRyapkYF6ua96dIUeyCmx23eE+KoNYBPI3IhBmIeNYx4Qn4LBYRalFqEnipaejrj45SdFr5sU450KDod2iOjuHYbWu00Yjc6hhsZpTU5Ce02xbYJ3OgYjI0iE+O4osB1RnCtEtcZQbxPeYWdEeTa/XZMNGvG3nzmLdM3DysLXZhfgPkFdH6eWHXpzs7Tm51l4cxZwvwsYXYOnZ3Bzc8j07MwN0+cX6A3NUXdnWN+ZgYJgbCwgPR6+FBB1aOlIHWNV8Wp0lZwIYIqnjSa4lURDRAjTpUihU2IOGKIFPkgE2ME8kFn0cE+9kdk/NKDdj6g+qIghNDPNUoTVSl4iKr9QCJq2jbJgZTkIEoAXBp50Tg4ZOaUe2DxB7E5hEaRwTbpIJBIW9GMiQ2GuoZ/vvheFx++Fbj4uMz5ZJXXpUeU8346CA7O/y11+fnE9HyakbLhkby3Z+hvu4rnvuyo3IoB3PLX60rXDS8UoD9giRv8qdPjN3GcDgdegxFQGASGzXICEETdokfXPCKLuBzYD8bcRNI0cVqfkaYmY0xRl+SpyhAVJSK4NJ0/dNIgzXPJJyWQ8tho7i9ExKXgDPJ0e35g1Wb0z6UpV+dS/mQz8ps/AyEHtUFSTl967RxRIBLSv+KoEWrnqBAqEaTTpqeC+BJXlsR2AZ0C3+7QHhvDj4xSjI2j7Q5+bAK2TcDIKG5khNboGMXEGH58lNboCOXoOMXYKIyOphG6Tge58UY7fprLyt5Q5oL00CHlzJk0JXj6LPWpU+jsHLNnTzF38iTdM6cJM7O4hS5hYRZdmKE3NQ1zC4TpWcoIUvVwMeI04DSmBHRAQqTtC7xzSFSKwiFB0Vgjqvi8WC2lYEM6zMe8U09HIrdo6i3/SwquIorgBtNhzhNjIKCDqTEkJS9rIOapvzzokw+CMrSyL4/p9KcLY0qWZmmQEQe37h9l0z3p0BSVy4lDg4NjM0rWjKIsvtc0/dhMUUp/ynI4VJALfKT704v9hKUmz6w5gOuSy4OAbnhETZYZbTrvfXNJU4ppS3zzHHPweX5I99buf9nfb0Z6Vtqg5V6/FW4euTTOSV6g2UymSoqVYhNs5TEvHUy3XmyETPu3HGxpMzKYgj4dTHEPvbNifq96IQVEIsQQ0z1qGlkbvn0aGR68H1IOWwrQmvdyOjlJX6UMAs5mm4bz5SKDET6fR9eWvt5xaGQ55tE7aKZewTlPVAhEkJSvFgG8I41XJ5UIvRwQhjyaXTuXcvqco5acC+gcvtWC0Q460qEYGcWNjiAjo8TREUJnBJkYp7NzJ+O79zC6YyetbWPIzu2wbRx27Ebee7sdW80lszfNFqevvqLMLRDPnEWnpgknT1OdPM3CmXPUM2eZO/4G1bmz+Pku9dQ0vbPnkKoidOcJ83NQVbRipBXAaaCQQKGRMVfQVqHjCjTW+Wxf8447IjEFS02yuuZ8qZSMnoKNxSNZmnKNSDGOg3Sm3ERPOhw+DB2M8oCYxsF9OckZXU0wlYOrpkLEosTsHCAM3+/ig8vgIxQ1EklTnUA/+Gp+z8nyU4XnH1wHXB6lIN/3StfLBUOxxY8z/FiruTzIT5PzgphLCsiG73gVG3ih3Kzl7n+5RQfpbnXpFRfcDneJu8W4QgS34l9EB69lClaWjhwuXmqw3MKD5V6ywQPnobVm5KqZIh96PJeHtlTi4D0/9Lo0wVvzGR0EWsPv0KHFIEMDz5KncIerpQw+k/lrScWV/jNfZuZ1MHoog+1rtlfTScTgfenSXkKknyYQcz5ilBSIFXmUrxm1a345PU5eCBEjXY30RKlU0rSpCF2EnhdCWVJ7j7RHaI2MUIyO4MdHiJ02xbZttHfuorNnD35yByO79lDs3IXfuRs3OYGMjsFoG7nlJjv+mkXsDbFF6JHXlG4PPLine truncated
</div>
</div>
<div class="pure-u-16-24">
<h4 ><%:Youtube%><br><br><span id="status_youtube" class="red"><em><%:Collecting data...%></em></span></h4>
</div>
</div>
</div>
<div class="pure-u-1-4" >
<div class="block pure-g">
<div class="pure-u-8-24">
<div class="img-con">
<img src="data:image/jpg;base64,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 truncated
</div>
</div>
<div class="pure-u-16-24">
<h4 ><%:GitHub%><br><br><span id="status_github" class="red"><em><%:Collecting data...%></em></span></h4>
</div>
</div>
</div>
</div>
</fieldset>
<% if luci.i18n.context.lang == "zh-cn" then %>
<fieldset class="cbi-section">
<div class="pure-g status">
<div class="siz">
<div class="block pure-g">
<div class="pure-u-8-24">
<div class="img-con">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAACXBIWXMAAC4jAAAuIwF4pT92AAAI/2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wOkNyZWF0ZURhdGU9IjIwMTgtMTAtMDhUMTY6MDg6NDErMDU6MzAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMTgtMTAtMDhUMTY6MDg6NTgrMDU6MzAiIHhtcDpNb2RpZnlEYXRlPSIyMDE4LTEwLTA4VDE2OjA4OjU4KzA1OjMwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowYmFlMDViZS0wMTMxLTM3NGYtOWFhOS03NGEzZTJhOThiMmEiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDplODc0YTI4NS1mNGY5LWQzNGMtYTcyMS1jZmNhNzc4YjVlY2UiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo5ZTc4ZmE3Yy03NTFjLWRiNDktOWZmOC03ZWY0NGFlYzk3NDIiIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjllNzhmYTdjLTc1MWMtZGI0OS05ZmY4LTdlZjQ0YWVjOTc0MiIgc3RFdnQ6d2hlbj0iMjAxOC0xMC0wOFQxNjowODo0MSswNTozMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6N2QxOTYzOTAtMGYzNC00ODQ1LWE1NjYtM2JmNTE1ODFlYzExIiBzdEV2dDp3aGVuPSIyMDE4LTEwLTA4VDE2OjA4OjU4KzA1OjMwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgKFdpbmRvd3MpIiBzdEV2dDpjaGFuZ2VkPSIvIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjb252ZXJ0ZWQiIHN0RXZ0OnBhcmFtZXRlcnM9ImZyb20gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcCB0byBpbWFnZS9wbmciLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249ImRlcml2ZWQiIHN0RXZ0OnBhcmFtZXRlcnM9ImNvbnZlcnRlZCBmcm9tIGFwcGxpY2F0aW9uL3ZuZC5hZG9iZS5waG90b3Nob3AgdG8gaW1hZ2UvcG5nIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDowYmFlMDViZS0wMTMxLTM3NGYtOWFhOS03NGEzZTJhOThiMmEiIHN0RXZ0OndoZW49IjIwMTgtMTAtMDhUMTY6MDg6NTgrMDU6MzAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cykiIHN0RXZ0OmNoYW5nZWQ9Ii8iLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjdkMTk2MzkwLTBmMzQtNDg0NS1hNTY2LTNiZjUxNTgxZWMxMSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo5ZTc4ZmE3Yy03NTFjLWRiNDktOWZmOC03ZWY0NGFlYzk3NDIiIHN0UmVmOm9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo5ZTc4ZmE3Yy03NTFjLWRiNDktOWZmOC03ZWY0NGFlYzk3NDIiLz4gPHBob3Rvc2hvcDpUZXh0TGF5ZXJzPiA8cmRmOkJhZz4gPHJkZjpsaSBwaG90b3Nob3A6TGF5ZXJOYW1lPSJJUCIgcGhvdG9zaG9wOkxheWVyVGV4dD0iSVAiLz4gPC9yZGY6QmFnPiA8L3Bob3Rvc2hvcDpUZXh0TGF5ZXJzPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pv9h0hoAAQYxSURBVHic7P13eBxndqcN3xU6R+RIgASYc5QYlCWSymGUNUGTxzOe5DDO2esN9oZ319/nXdtre732vLbHM/bMeHJWzqQoUaSYSRAgMtC5K9f7R3VDoESJBLrR3QDqvq66AILoqtPo7jq/5zwnCLZt4+Li4uLi4rK4EKttgIuLi4uLi0vlcQWAi4uLi4vLIsQVAC4uLi4uLosQVwC4uLi4uLgsQlwB4OLi4uLisgiR3+0/1m+4s5J2uLgsdARAetshA3XAEqBj2tEGtAJNQDMQqIK9pZIHRgvHYOEYmHacByYBAzDfdrilSS4uZeTw69+65M/fVQC4uLjMCgHw4Hy2PIWjFegBlhWOpcByHMcfKDzm7cd8Jwg0AKsL/7YvcShAH3AKOAucBs4UjiFAA3QckaDjCgMXl7LiCgAXl9kjAV7AVzhacRz7amBV4VgJxAq/vxAc+2y5lLDxAOsKR5Gik08BJ4A3gWOFrydwhIGKIw5UnIiBi4vLLHAFgIvLlSHgrNaLRyewHtgIbCgcDVWzbuFQFAkxYHvhmM4E8HrheA04jLOdoAA5nK0HN1Lg4nIFuALAxeXSeIFQ4agHNvGWQ9rC/NyXXwjUA9cXjiJ54FXg5cJxCBgHsoVDq6yJLi7zA1cAuLg4+IAIEAW6gF3AVYWjvYp2uVyeAM7rtWvazwaBF4AXgedwogRJII2zdeDisuhxBYDLYkXCWU3W4yTj7cFxIHuAcBXtcikPbcC9hQOc7YGngOeBZ3CSDyd4qxLBxWXR4QoAl8VEHGjESdbbCdwE3Aj4q2iTS2UIAvsLBzhRgJ8AP8URBUPAGI4gcHFZFLgCwGUhI+I4+2acZL1bcJx+RzWNcqkJfMBthQOcLYOfAD/ESS4cKfzMqop1Li4VwBUALguNAG811NmFs+K7oZoGucwL2oD3Fw6AJ4HvAc8CF4B+nGRDF5cFgysAXBYCAaAb6MVZ5d/KWw1oXFxmw3WFA+A48F3gx8BJ4BxOToGLy7zGFQAu8xU/jsNfAdwM3I7Tbc/FpdysLBxfwOlY+B3gRziNiU7hRgZc5imuAHCZb6wA1uKs9O/Eaavr4lIplgKfKRx9wLdwxMARnEiB24TIZd7gCgCX+cASHKd/Pc5Kf1N1zXFxAZx+EUUxcBhHDDyJIwbOVdEuF5crwhUALrVKCNgK7MZx+te996+7uFSV9YXj14CngW/jJBAexGk+5OJSc7gCwKXWWIvTbncvThMXtymPy3zjmsKRBb4B/ACnRfEb1TTKxeXtuALApRYI8VbW9R04g3VcXOY7IeCxwvEGb20RPAlkqmiXiwvgCgCX6rICuBZntf8gTnteF5eFSHHs8ZeAr+JEBZ7CSRx0cakKrgBwqQY34ST03QbsqLItLi6VRAQeKhyv4PQX+BlOjwEXl4riCgCXSuEH7sHpvf8A0FBdc1xcqs62wvEZ4Gs4rYi/idtkyKVCuALAZa7pBO7GWfXfX2VbXFxqkXrgE4XjX3GiAd/EGWHs4jJnuALAZa5YC9yH05b3mirb4uIyX7ivcDyKM4vg6zg9Blxcyo4rAFzKzU7ecvwbq2yLi8t8ZU/heBin9fDXgeeqaZDLwsMVAC7l4mbgfTiJfcuqbIuLy0Kh2GDoQZyIwL/gtB52cSkZVwC4lMotOHXOt+KMVHVxcSk/y4BP4zTH+h7wT8D3q2mQy/zHFQAus+VmnNnpruN3cakcbcBHcNpjfx/4Mk5PAReXGeMKAJeZci3wMZyVf0eVbXG5BLZtv+tR+A3sS8ysEwQAofC9UPi38zNRFBFFELine truncated
</div>
</div>
<div class="pure-u-16-24">
<h4><%:Global IP%><br><br><span class="green" id="ip-ipify"><%:Checking...%></span> <span class="green" id="ip-ipify-ipip"></span></h4>
</div>
</div>
</div>
<div class="siz">
<div class="block pure-g">
<div class="pure-u-8-24">
<div class="img-con">
<img src="data:image/png;base64,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 truncated
</div>
</div>
<div class="pure-u-16-24">
<h4 ><%:Domestic IP%><br><br><span id="d-ip" class="green"><%:Checking...%></span><span class="green" id="ipify-ipip"></span></h4>
</div>
</div>
</div>
</div>
</fieldset>
<%end%>
<% if luci.i18n.context.lang == "en" or luci.i18n.context.lang == "auto" then %>
<fieldset class="cbi-section">
<div class="pure-g status">
<div class="siz">
<div class="block pure-g">
<div class="pure-u-8-24">
<div class="img-con">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAACXBIWXMAAC4jAAAuIwF4pT92AAAI/2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wOkNyZWF0ZURhdGU9IjIwMTgtMTAtMDhUMTY6MDg6NDErMDU6MzAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMTgtMTAtMDhUMTY6MDg6NTgrMDU6MzAiIHhtcDpNb2RpZnlEYXRlPSIyMDE4LTEwLTA4VDE2OjA4OjU4KzA1OjMwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowYmFlMDViZS0wMTMxLTM3NGYtOWFhOS03NGEzZTJhOThiMmEiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDplODc0YTI4NS1mNGY5LWQzNGMtYTcyMS1jZmNhNzc4YjVlY2UiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo5ZTc4ZmE3Yy03NTFjLWRiNDktOWZmOC03ZWY0NGFlYzk3NDIiIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjllNzhmYTdjLTc1MWMtZGI0OS05ZmY4LTdlZjQ0YWVjOTc0MiIgc3RFdnQ6d2hlbj0iMjAxOC0xMC0wOFQxNjowODo0MSswNTozMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6N2QxOTYzOTAtMGYzNC00ODQ1LWE1NjYtM2JmNTE1ODFlYzExIiBzdEV2dDp3aGVuPSIyMDE4LTEwLTA4VDE2OjA4OjU4KzA1OjMwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgKFdpbmRvd3MpIiBzdEV2dDpjaGFuZ2VkPSIvIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjb252ZXJ0ZWQiIHN0RXZ0OnBhcmFtZXRlcnM9ImZyb20gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcCB0byBpbWFnZS9wbmciLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249ImRlcml2ZWQiIHN0RXZ0OnBhcmFtZXRlcnM9ImNvbnZlcnRlZCBmcm9tIGFwcGxpY2F0aW9uL3ZuZC5hZG9iZS5waG90b3Nob3AgdG8gaW1hZ2UvcG5nIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDowYmFlMDViZS0wMTMxLTM3NGYtOWFh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 truncated
</div>
</div>
<div class="pure-u-16-24">
<h4><%:Global IP%><br><br><span id="d-ip-g" class="green"><%:Checking...%></span><span class="green" id="ipip-g"></span></h4>
</div>
</div>
</div>
<div class="siz">
<div class="block pure-g">
<div class="pure-u-8-24">
<div class="img-con">
<img src="data:image/png;base64,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 truncated
</div>
</div>
<div class="pure-u-16-24">
<h4 ><%:Domestic IP%><br><br><span id="d-ip" class="green"><%:Checking...%></span><span class="green" id="ipip"></span></h4>
</div>
</div>
</div>
</div>
</fieldset>
<%end%>
<fieldset class="cbi-section">
<table width="100%" cellspacing="10">
<tr><td width="50%"><span><%:Clash Client%></span></td><td id="_clash"><em><%:Collecting data...%></em></td> </tr>
<tr><td width="50%"><span><%:Clash Mode%></span></td><td id="_emode"><em><%:Collecting data...%></em></td> </tr>
<tr><td width="50%"><span><%:Clash Config%></span></td><td id="_conf"><em><%:Collecting data...%></em></td> </tr>
<tr><td width="50%"><span><%:Config Type%></span></td><td id="_conf_path"><em><%:Collecting data...%></em></td> </tr>
<tr><td width="50%"><span><%:Clash Dashboard%></span></td><td id="_web"><em> <%:Collecting data...%> </em></td> </tr>
<tr><td width="50%"><span><%:Yacd Dashboard%></span></td><td id="_webb"><em> <%:Collecting data...%> </em></td> </tr>
</table>
</fieldset>
<fieldset class="cbi-section">
<table width="100%" cellspacing="10">
<tr><td width="50%"> <%:Dashboard Host%></td><td id="_ip"><em><%:Collecting data...%></em></td></tr>
<tr><td width="50%"> <%:Dashboard Port%></td><td id="_port"><em><%:Collecting data...%></em></td></tr>
<tr><td width="50%"> <%:Dashboard Secret%></td> <td id="_secret"><em><%:Collecting data...%></em></td></tr>
</table>
</fieldset>
<script type="text/javascript">//<![CDATA[
<% if luci.i18n.context.lang == "zh-cn" then %>
let random = parseInt(Math.random() * 100000000);
let IP = {
get: (url, type) =>
fetch(url, { method: 'GET' }).then((resp) => {
if (type === 'text')
return Promise.all([resp.ok, resp.status, resp.text(), resp.headers]);
else {
return Promise.all([resp.ok, resp.status, resp.json(), resp.headers]);
}
}).then(([ok, status, data, headers]) => {
if (ok) {
let json = {
ok,
status,
data,
headers
}
return json;
} else {
throw new Error(JSON.stringify(json.error));
}
}).catch(error => {
throw error;
}),
parseIPIpip: (ip, elID) => {
IP.get(`https://geoip.gbxcloud.com/?geoip=${ip}`, 'text')
.then(resp => {
document.getElementById(elID).innerHTML = resp.data;
})
},
getIpipnetIP: () => {
IP.get(`http://myip.ipip.net/?z=${random}`, 'text')
.then((resp) => {
let data = resp.data.replace('当前 IP:', '').split(' 来自于:');
//var u= data[0].indexOf("来自于:")
document.getElementById('d-ip').innerHTML = `${data[0]} - `
return `${data[0]}`
})
.then(ip => {
IP. parseIPIpip(ip, 'ipify-ipip');
})
},
getIpifyIP: () => {
IP.get(`https://ip4.seeip.org/json?z=${random}`, 'json')
.then(resp => {
document.getElementById('ip-ipify').innerHTML = `${resp.data.ip} - `;
return resp.data.ip
})
.then(ip => {
IP. parseIPIpip(ip, 'ip-ipify-ipip');
})
}
}
<%end%>
<% if luci.i18n.context.lang == "en" or luci.i18n.context.lang == "auto" then %>
let random = parseInt(Math.random() * 100000000);
let IP = {
get: (url, type) =>
fetch(url, { method: 'GET' }).then((resp) => {
if (type === 'text')
return Promise.all([resp.ok, resp.status, resp.text(), resp.headers]);
else {
return Promise.all([resp.ok, resp.status, resp.json(), resp.headers]);
}
}).then(([ok, status, data, headers]) => {
if (ok) {
let json = {
ok,
status,
data,
headers
}
return json;
} else {
throw new Error(JSON.stringify(json.error));
}
}).catch(error => {
throw error;
}),
Ipip: (ip, elID) => {
IP.get(`https://api.ip.sb/geoip/${ip}`, 'json')
.then(resp => {
document.getElementById(elID).innerHTML = `${resp.data.country} ${resp.data.region} ${resp.data.city} ${resp.data.isp} ${resp.data.asn_organization}`
})
},
getIpipnetIP: () => {
IP.get(`http://myip.ipip.net/?z=${random}`, 'text')
.then((resp) => {
let data = resp.data.replace('当前 IP:', '').split(' 来自于:');
//var u= data[0].indexOf("来自于:")
document.getElementById('d-ip').innerHTML = `${data[0]} - `
return `${data[0]}`
})
.then(ip => {
IP.Ipip(ip, 'ipip');
})
},
getIpifyIP: () => {
IP.get(`https://ip4.seeip.org/json?z=${random}`, 'json')
.then(resp => {
document.getElementById('d-ip-g').innerHTML = `${resp.data.ip} - `;
return resp.data.ip
})
.then(ip => {
IP.Ipip(ip, 'ipip-g');
})
}
}
<%end%>
var HTTP = {
checker: (domain, cbElID) => {
let img = new Image;
let timeout = setTimeout(() => {
img.onerror = img.onload = null;
img = null;
document.getElementById(cbElID).innerHTML = '<b class="red"><%:NO ACCESS%></b>'
}, 1000);
img.onerror = () => {
clearTimeout(timeout);
document.getElementById(cbElID).innerHTML = '<b class="red"><%:TIMEOUT%></b>'
}
img.onload = () => {
clearTimeout(timeout);
document.getElementById(cbElID).innerHTML = '<b class="green"><%:NORMAL%></b>'
}
img.src = `https://${domain}/favicon.ico?${+(new Date)}`
}
}
var dnew = document.getElementById('_downloadnew');
var web = document.getElementById('_web');
var webb = document.getElementById('_webb');
var clash = document.getElementById('_clash');
var ip = document.getElementById('_ip');
var port = document.getElementById('_port');
var secret = document.getElementById('_secret');
var emode = document.getElementById('_emode');
var logo = document.getElementById('_logo');
var conf = document.getElementById('_conf');
var conf_path = document.getElementById('_conf_path');
XHR.poll(1, '<%=luci.dispatcher.build_url("admin", "services", "clash", "status")%>', null, function(x, status) {
if ( x && x.status == 200 ) {
web.innerHTML = status.clash ? '<a type="button" class="btn" style="background-color:black;padding: 5px;" href="http://'+window.location.hostname+':'+status.dash_port+'/ui" target="_blank"><b><font color="green"><%:DASHBOARD%></font></b></a>' : '<b><font color="red"><%:NOT RUNNING%></font></b>';
webb.innerHTML = status.clash ? '<a type="button" class="btn" style="background-color:black;padding: 5px;" href="http://'+window.location.hostname+status.uhttp_port+'/luci-static/yacd?hostname='+ status.localip + '&port=' + status.dash_port + '&secret=' + status.dash_pass +'" target="_blank"><b><font color="green"><%:DASHBOARD%></font></b></a>' : '<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>';
ip.innerHTML = status.localip ? '<b><font color="green">'+status.localip+'</font> </b>' : '<em><b><font color="red"><%:NOT SET%></font></b></em>';
port.innerHTML = status.dash_port ? '<b><font color="green">'+status.dash_port+'</font> </b>' : '<em><b><font color="red"><%:NOT SET%></font></b></em>';
secret.innerHTML = status.dash_pass ? '<b><font color="green">'+status.dash_pass+'</font> </b>' : '<em><b><font color="red"><%:NOT SET%></font></b></em>';
emode.innerHTML = status.clash ? '<b><font color="green" style="text-transform: uppercase;">'+status.e_mode+'</font> </b>' : '<b><font color="red"><%:NOT RUNNING%></font></b>';
if(status.typeconf != 0 || status.typeconf != ''){
conf.innerHTML = status.typeconf ? '<b><input type="button" class="btn" style="background-color:black;padding: 5px;font-color:green;color:green;font-weight:bold" value="<%:VIEW CONFIG%>" onclick="return view(this)" /></b>' : '<b><font color="red"><%:NOT RUNNING%></font></b>';
}
if(status.typeconf==1){
conf_path.innerHTML = status.clash ? '<b><font color="green"><%:SUBSCRIBE%> </font></b>' : '<b><font color="red"><%:NOT RUNNING%></font></b>';
}
if(status.typeconf==2){
conf_path.innerHTML = status.clash ? '<b><font color="green"><%:UPLOAD%></font></b>' : '<b><font color="red"><%:NOT RUNNING%></font></b>';
}
if(status.typeconf==3){
conf_path.innerHTML = status.clash ? '<b><font color="green"><%:CUSTOM%></font></b>' : '<b><font color="red"><%:NOT RUNNING%></font></b>';
}
if(status.typeconf==0 || status.typeconf==''){
conf_path.innerHTML = status.typeconf ? '<b><font color="red"><%:NOT SELECTED%></font></b>' : '<b><font color="red"><%:NOT RUNNING%></font></b>';
}
if(status.new_version > status.current_version)
{
dnew.innerHTML ='<center><br><a href="https://github.com/frainzy1477/luci-app-clash/releases/download/'+status.new_version+'/luci-app-clash_'+status.new_version+'_all.ipk" class="btn" style="height:20px;font-size:15px;margin-top:-20px;background-color:#568fa1;color:#ffffff;" target="_blank"><%:Download Update%></a></center>';
}
IP.getIpifyIP();
IP.getIpipnetIP();
}
});
XHR.poll(3, '<%=luci.dispatcher.build_url("admin", "services", "clash", "status")%>', null, function(x, status) {
if ( x && x.status == 200 ) {
HTTP.checker('www.baidu.com', 'status_baidu');
HTTP.checker('www.google.com', 'status_google');
HTTP.checker('www.youtube.com', 'status_youtube');
HTTP.checker('github.com', 'status_github');
}
});
IP.getIpifyIP();
IP.getIpipnetIP();
HTTP.checker('www.baidu.com', 'status_baidu');
HTTP.checker('www.google.com', 'status_google');
HTTP.checker('www.youtube.com', 'status_youtube');
HTTP.checker('github.com', 'status_github');
var rtlog = document.getElementById('_realtimelog');
XHR.poll(1, '<%=luci.dispatcher.build_url("admin", "services", "clash", "readlog")%>', status.readlog, function(x, status) {
if ( x && x.status == 200 ) {
if ( status.readlog != "\n" || status.readlog != "" ) {
rtlog.innerHTML = '<b>'+status.readlog+'</b>';
}
}
});
XHR.poll(5,'<%=luci.dispatcher.build_url("admin", "services", "clash", "check_status")%>', null, function(x, status) {});
//]]></script>
<style>
.modals-bg{
position: fixed;
z-index: 90;
width: 100%;
height: 100%;
left: 0;
top: 0;
background: rgba(0,0,0,0.8);
display: none;
}
.modals {
position: fixed;
z-index: 100;
width: 70%;
height: 650px;
background: #FFFFFF;
left: 20%;
top: 15%;
color: #fff;
border-radius: 10px;
padding: 20px;
box-sizing: border-box;
-moz-box-sizing: border-box;
/* Firefox */
-webkit-box-sizing: border-box;
/* Safari */
}
.modals h2 {}
.modals h3 {
font-size: 14px;
color: red;
background: transparent;
margin: 0;
padding: 0;
}
@media screen and (max-width: 1024px) {
.modals {
position: fixed;
z-index: 100;
width: 80%;
height: 550px;
background: #FFFFFF;
left: 10%;
top: 15%;
color: #fff;
border-radius: 10px;
padding: 20px;
}
}
@media screen and (max-width: 700px) {
.modals-bg{
position: fixed;
z-index: 100000;
}
.modals {
width: 100%;
height: 100%;
left: 0;
top: 0;
}
}
.close {
color: #aaaaaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
</style>
<div class="modals-bg">
<div class="modals">
<span><input type="button" class="cbi-button cbi-button-apply" value="<%:Download%>" style=" display:inline;" onclick=" return download_conf()" /></span><br /><span class="close">&times;</span>
<br /><h3 style="margin-left:0;"><%:If config does not show refresh page%></h3><br />
<span><textarea id="cbid.logview.1.conf" style="width:100%;height:80%; font-family:'Lucida Console'; font-size:12px;padding-left:3px;padding-right:22px;" readonly="readonly" wrap="off" rows="25"><%=pcdata(nixio.fs.readfile("/etc/clash/config.yaml"))%></textarea></span>
</div>
</div>
<script>
var btn = document.getElementById("myBtn");
var span = document.getElementsByClassName("close")[0];
var cfg = document.getElementsByClassName("modals-bg")[0];
span.onclick = function() {
cfg.style.display = "none";
}
function view(btn) {
cfg.style.display = "inline";
}
function createAndDownloadFile(fileName, content) {
var aTag = document.createElement('a');
var blob = new Blob([content]);
aTag.download = fileName;
aTag.href = URL.createObjectURL(blob);
aTag.click();
URL.revokeObjectURL(blob);
}
function download_conf(){
var lv = document.getElementById('cbid.logview.1.conf');
var dt = new Date();
createAndDownloadFile("config.yaml",lv.innerHTML)
return
}
</script>
@@ -1,22 +0,0 @@
<%+cbi/valueheader%>
<textarea id="log" class="cbi-input-textarea" style="width: 100%;" data-update="change" rows="29" readonly="readonly" > </textarea>
<script type="text/javascript">//<![CDATA[
var lv = document.getElementById('log');
lv.style.display="inline"
XHR.poll(1, '<%=url([[admin]], [[services]], [[clash]], [[logstatus]])%>', null,
function(x, data) {
var lv = document.getElementById('log');
if (x.responseText && lv) {
lv.innerHTML += x.responseText;
lv.scrollTop = lv.scrollHeight;
}
}
);
//]]>
</script>
<%+cbi/valuefooter%>
@@ -1,6 +0,0 @@
<%+cbi/valueheader%>
<textarea class="cbi-input-textarea" style="width: 100%" rows="30" cols="45" data-update="change" <%= attr("name", cbid) .. attr("id", cbid) %>>
<%-=pcdata(self:cfgvalue(section))-%>
</textarea>
<%+cbi/valuefooter%>
@@ -1,94 +0,0 @@
<fieldset class="cbi-section">
<table width="100%" cellspacing="10">
<thead align="center">
<tr>
<th align="center"><%:App Name%></th>
<th align="center"><%:Installed Version%></th>
<th align="center"><%:New Version%></th>
</tr>
</thead>
<tbody>
<tr>
<td align="center" width="35%">clash</td> <td align="center" width="35%" id="_core"><%:Collecting data...%></td> <td width="35%" align="center" id="_corebutt"><font color="red"><%:Checking...%></font> </td>
</tr>
<tr>
<td align="center" width="35%">clash(ctun)</td> <td align="center" width="35%" id="_coretun"><%:Collecting data...%></td> <td width="35%" align="center" id="_coretunbutt"><font color="red"><%:Checking...%></font> </td>
</tr>
<tr>
<td align="center" width="35%">clash(premium)</td> <td align="center" width="35%" id="_coredtun"><%:Collecting data...%></td> <td width="35%" align="center" id="_coredtunbutt"><font color="red"><%:Checking...%></font> </td>
</tr>
<tr>
<td align="center" width="35%">luci-app-clash</td> <td align="center" width="35%" id="_version"><%:Collecting data...%> </td> <td width="35%" align="center" id="_versionbutt"><font color="red"><%:Checking...%></font> </td>
</tr>
</tbody>
</table>
</fieldset>
<script type="text/javascript">//<![CDATA[
var version = document.getElementById('_version');
var core = document.getElementById('_core');
var coretun = document.getElementById('_coretun');
var version_butt = document.getElementById('_versionbutt');
var core_butt = document.getElementById('_corebutt');
var corer_butt = document.getElementById('_corerbutt');
var coretun_butt = document.getElementById('_coretunbutt');
var coredtun = document.getElementById('_coredtun');
var coredtun_butt = document.getElementById('_coredtunbutt');
XHR.poll(1, '<%=luci.dispatcher.build_url("admin", "services", "clash", "status")%>', null, function(x, status) {
if ( x && x.status == 200 ) {
if(status.clash_core==0){
core.innerHTML = status.clash_core ? '<b><font color="red"><%:Not Installed%></font> </b>' : '<em><b><font color="red"><%:Checking...%></font></b></em>';
}else{
core.innerHTML = status.clash_core ? '<b><font color="green">'+status.clash_core+'</font> </b>' : '<em><b><font color="red"><%:Checking...%></font></b></em>';
}
if(status.clashtun_core==0){
coretun.innerHTML = status.clashtun_core ? '<b><font color="red"><%:Not Installed%></font> </b>' : '<em><b><font color="red"><%:Checking...%></font></b></em>';
}else{
coretun.innerHTML = status.clashtun_core ? '<b><font color="green">'+status.clashtun_core+'</font> </b>' : '<em><b><font color="red"><%:Checking...%></font></b></em>';
}
if(status.dtun_core==0){
coredtun.innerHTML = status.dtun_core ? '<b><font color="red"><%:Not Installed%></font> </b>' : '<em><b><font color="red"><%:Checking...%></font></b></em>';
}else{
coredtun.innerHTML = status.dtun_core ? '<b><font color="green">'+status.dtun_core+'</font> </b>' : '<em><b><font color="red"><%:Checking...%></font></b></em>';
}
version.innerHTML = status.current_version ? '<b><font color="green">'+status.current_version+'</font> </b>' : '<em><b><font color="red"><%:Checking...%></font></b></em>';
}
});
XHR.poll(5,'<%=luci.dispatcher.build_url("admin", "services", "clash", "check_status")%>', null, function(x, status) {});
XHR.poll(1,'<%=luci.dispatcher.build_url("admin", "services", "clash", "status")%>', null, function(x, status) {
if ( x && x.status == 200 ) {
version_butt.innerHTML = status.current_version ? '<b><font color="green">'+status.new_version+'</font> </b>' : '<em><b><font color="red"><%:Checking...%></font></b></em>';
core_butt.innerHTML = status.current_version ? '<b><font color="green">'+status.new_core_version+'</font> </b>' : '<em><b><font color="red"><%:Checking...%></font></b></em>';
coretun_butt.innerHTML = status.current_version ? '<b><font color="green">'+status.new_clashtun_core_version+'</font> </b>' : '<em><b><font color="red"><%:Checking...%></font></b></em>';
coredtun_butt.innerHTML = status.current_version ? '<b><font color="green">'+status.new_dtun_core+'</font> </b>' : '<em><b><font color="red"><%:Checking...%></font></b></em>';
}
});
//]]></script>
@@ -1,11 +0,0 @@
<%+cbi/valueheader%>
<select name="file_type" style="width:20%">&nbsp;&nbsp;&nbsp;
<option value="clash" selected="selected"><%:clash%></option>
<option value="clashctun"><%:clash(ctun)%></option>
<option value="clashdtun"><%:clash(premium)%></option>
</select>
<input class="cbi-input-file" style="width: 60%" type="file" id="ulfile" name="ulfile" />
<input type="submit" style="width: 100%" class="cbi-button cbi-input-apply" name="upload" value="<%:Upload%>" />
<%+cbi/valuefooter%>
File diff suppressed because it is too large. Load diff
-1
View File
@@ -1 +0,0 @@
zh-cn
Binary file not shown.
-116
View File
@@ -1,116 +0,0 @@
config clash 'config'
option redir_port '7892'
option http_port '7890'
option socks_port '7891'
option mixed_port '7893'
option enable_ipv6 'false'
option tun_mode '0'
option enable '0'
option dash_port '9090'
option dash_pass '123456'
option auto_update '0'
option auto_update_time '0'
option level 'info'
option core '1'
option allow_lan 'true'
option bind_addr '*'
option dnsforwader '1'
option subcri 'clash'
option cusrule '0'
option dnscache '0'
option config_type '1'
option p_mode 'rule'
option auto_clear_log '1'
option auto_update '1'
option auto_update_time '12'
option clear_time '12'
option append_rules '0'
option enable_udp '0'
option dnscache '0'
option stack 'system'
option enhanced_mode 'fake-ip'
option fake_ip_range '198.18.0.1/16'
list fake_ip_filter '*.lan'
list fake_ip_filter 'localhost.ptlogin2.qq.com'
list defaul_nameserver '114.114.114.114'
list defaul_nameserver '8.8.8.8'
option listen_port '5300'
option interf '0'
option enable_dns '1'
config dnshijack
option enabled '1'
option ip '8.8.8.8'
option port '53'
option type 'tcp://'
config dnshijack
option enabled '1'
option ip '8.8.8.8'
option port '53'
option type 'udp://'
config hosts
option enabled '0'
option adress '*.clash.dev'
option ip '127.0.0.1'
config hosts
option enabled '0'
option adress 'alpha.clash.dev'
option ip '::1'
config dnsservers
option enabled '1'
option ser_type 'nameserver'
option ser_address '114.114.114.114'
option protocol 'udp://'
config dnsservers
option enabled '1'
option ser_port '853'
option protocol 'tls://'
option ser_type 'nameserver'
option ser_address '47.96.179.163'
config dnsservers
option enabled '1'
option ser_type 'nameserver'
option ser_address '118.89.110.78'
option ser_port '853'
option protocol 'tls://'
config dnsservers
option enabled '1'
option ser_type 'nameserver'
option ser_address '8.8.8.8'
option ser_port '53'
option protocol 'udp://'
config dnsservers
option enabled '1'
option ser_type 'nameserver'
option ser_address '1.1.1.1'
option ser_port '853'
option protocol 'tls://'
config dnsservers
option enabled '1'
option ser_type 'fallback'
option ser_address '114.114.114.114'
option protocol 'udp://'
config dnsservers
option enabled '1'
option ser_type 'fallback'
option ser_address '118.89.110.78'
option ser_port '853'
option protocol 'tls://'
config dnsservers
option enabled '1'
option ser_type 'fallback'
option ser_address '1.1.1.1'
option protocol 'tcp://'
-975
View File
@@ -1,975 +0,0 @@
#!/bin/sh /etc/rc.common
[ ! -f "/usr/share/ucitrack/luci-app-ucitrack.json" ] && {
cat > /usr/share/ucitrack/luci-app-ucitrack.json << EEOF
{
"config": "ucitrack",
"init": "ucitrack"
}
EEOF
}
START=99
STOP=15
CLASH="/etc/clash/clash"
CLASHT="/etc/clash/clashtun/clash"
CLASHD="/etc/clash/dtun/clash"
CLASH_CONFIG="/etc/clash"
CRON_FILE="/etc/crontabs/root"
CONFIG_YAML="/etc/clash/config.yaml"
CONFIG_YAML_PATH=$(uci get clash.config.use_config 2>/dev/null)
CUSLIST="/tmp/dnsmasq.d/custom_list.conf"
CUSLITT="/tmp/dnsmasq.clash"
CUSLISTV="/var/dnsmasq.d/custom_list.conf"
CUSLITTV="/var/dnsmasq.clash"
REAL_LOG="/usr/share/clash/clash_real.txt"
revert_dns() {
#===========================================================================================================================
dns_port=$(grep "^ \{0,\}listen:" $CONFIG_YAML |awk -F ':' '{print $3}' 2>/dev/null)
uci del_list dhcp.@dnsmasq[0].server=127.0.0.1#$dns_port >/dev/null 2>&1
uci set dhcp.@dnsmasq[0].noresolv=0
uci delete dhcp.@dnsmasq[0].cachesize
rm -rf $CUSLIST $CUSLITT $CUSLISTV $CUSLITTV 2>/dev/null
uci commit dhcp
/etc/init.d/dnsmasq restart >/dev/null 2>&1
#===========================================================================================================================
}
add_cron(){
config_type=$(uci get clash.config.config_type 2>/dev/null)
#===========================================================================================================================
[ -z "$(grep -w "/usr/share/clash/clash-watchdog.sh" $CRON_FILE)" ] && echo "*/3 * * * * /usr/share/clash/clash-watchdog.sh" >> $CRON_FILE
[ -z "$(grep -w "/usr/share/clash/kill_watchdog.sh" $CRON_FILE)" ] && echo "*/1 * * * * /usr/share/clash/kill_watchdog.sh" >> $CRON_FILE
clear=$(uci get clash.config.auto_clear_log 2>/dev/null)
if [ "${clear}" -eq 1 ]; then
[ -z "$(grep -w "/usr/share/clash/clash.txt" $CRON_FILE)" ] && echo "0 */$(uci get clash.config.clear_time 2>/dev/null) * * * echo '' >/usr/share/clash/clash.txt" >> $CRON_FILE
fi
auto=$(uci get clash.config.auto_update 2>/dev/null)
if [ "${auto}" -eq 1 ]; then
[ -z "$(grep -w "/usr/share/clash/update_all.sh" $CRON_FILE)" ] && echo "0 */$(uci get clash.config.auto_update_time 2>/dev/null) * * * bash /usr/share/clash/update_all.sh >/usr/share/clash/clash.txt 2>&1 &" >> $CRON_FILE
fi
auto_geoip=$(uci get clash.config.auto_update_geoip 2>/dev/null)
if [ "${auto_geoip}" -eq 1 ]; then
day=$(uci get clash.config.geoip_update_day 2>/dev/null)
week=$(uci get clash.config.geo_update_week 2>/dev/null)
if [ -z $week ];then
update_week="*"
else
update_week=$week
fi
if [ -z $day ];then
update_day="*"
else
update_day=$day
fi
[ -z "$(grep -w "/usr/share/clash/geoip.sh" $CRON_FILE)" ] && echo "0 $(uci get clash.config.auto_update_geoip_time 2>/dev/null) $update_week * $update_day /usr/share/clash/geoip.sh" >> $CRON_FILE
fi
crontab $CRON_FILE
#===========================================================================================================================
}
del_cron(){
#===========================================================================================================================
sed -i '/clash-watchdog.sh/d' $CRON_FILE
sed -i '/update_all.sh/d' $CRON_FILE
sed -i '/clash.txt/d' $CRON_FILE
/etc/init.d/cron restart
#===========================================================================================================================
}
select_config(){
#===========================================================================================================================
config_type=$(uci get clash.config.config_type 2>/dev/null)
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Checking Config file" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "正在检查配置文件" >$REAL_LOG
fi
if [ -f $CONFIG_YAML_PATH ] && [ "$(ls -l $CONFIG_YAML_PATH|awk '{print int($5)}')" -ne 0 ];then
cp $CONFIG_YAML_PATH $CONFIG_YAML 2>/dev/null
elif [ ! -f "$CONFIG_YAML_PATH" ] && [ ! -f "$CONFIG_YAML" ];then
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "No config found" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "找不到配置文章" >$REAL_LOG
fi
sleep 5
echo "Clash for OpenWRT" >$REAL_LOG
exit 0
elif [ "$(ls -l $CONFIG_YAML_PATH|awk '{print int($5)}')" -eq 0 ] && [ "$(ls -l $CONFIG_YAML|awk '{print int($5)}')" -eq 0 ];then
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Your Config File is Empty" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "你的config.yaml有问题还是为了空" >$REAL_LOG
fi
sleep 5
echo "Clash for OpenWRT" >$REAL_LOG
exit 0
fi
#===========================================================================================================================
}
yml_change() {
#===========================================================================================================================
sh /usr/share/clash/yum_change.sh 2>/dev/null
#===========================================================================================================================
}
game_rules() {
#===========================================================================================================================
sh /usr/share/clash/game.sh 2>/dev/null
#===========================================================================================================================
}
ip_rules() {
#===========================================================================================================================
sh /usr/share/clash/iprules.sh 2>/dev/null
#===========================================================================================================================
}
yml_dns_change(){
#===========================================================================================================================
dns_port=$(grep "^ \{0,\}listen:" /etc/clash/config.yaml |awk -F ':' '{print $3}' 2>/dev/null)
dnsforwader=$(uci get clash.config.dnsforwader 2>/dev/null)
dnscache=$(uci get clash.config.dnscache 2>/dev/null)
if [ "${dns_port}" -eq 53 ]; then
sed -i 's/^0.0.0.0:53/0.0.0.0:5300/g' $CONFIG_YAML
fi
if [ "$dnsforwader" -ne 0 ]; then
if [ "${dns_port}" -eq 53 ]; then
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Setting dns forwarder" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "设置dns转发器" >$REAL_LOG
fi
uci del_list dhcp.@dnsmasq[0].server=127.0.0.1#$dns_port >/dev/null 2>&1
uci add_list dhcp.@dnsmasq[0].server=127.0.0.1#5300 >/dev/null 2>&1
uci delete dhcp.@dnsmasq[0].resolvfile
uci set dhcp.@dnsmasq[0].noresolv=1
uci commit dhcp
if [ "$dnscache" -eq 0 ];then
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Disabling dns cache" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "禁用dns缓存" >$REAL_LOG
fi
uci set dhcp.@dnsmasq[0].cachesize=0
uci commit dhcp
fi
else
echo "Setting dns forwarder" >$REAL_LOG
uci del_list dhcp.@dnsmasq[0].server=127.0.0.1#$dns_port >/dev/null 2>&1
uci add_list dhcp.@dnsmasq[0].server=127.0.0.1#$dns_port >/dev/null 2>&1
uci delete dhcp.@dnsmasq[0].resolvfile
uci set dhcp.@dnsmasq[0].noresolv=1
uci commit dhcp
if [ "$dnscache" -eq 0 ];then
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Disabling dns cache" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "禁用dns缓存" >$REAL_LOG
fi
uci set dhcp.@dnsmasq[0].cachesize=0
uci commit dhcp
fi
fi
elif [ "$dnsforwader" -ne 1 ]; then
if [ "$dnscache" -eq 0 ];then
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Disabling dns cache" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "禁用dns缓存" >$REAL_LOG
fi
uci set dhcp.@dnsmasq[0].cachesize=0
uci commit dhcp
fi
fi
#===========================================================================================================================
}
check(){
sed -i 's/^Proxy Group:/proxy-groups:/g' "$CONFIG_YAML"
sed -i 's/^proxy-provider:/proxy-providers:/g' "$CONFIG_YAML"
sed -i 's/^Proxy:/proxies:/g' "$CONFIG_YAML"
sed -i 's/^Rule:/rules:/g' "$CONFIG_YAML"
sed -i 's/^rule-provider:/rule-providers:/g' "$CONFIG_YAML"
}
rules(){
#===========================================================================================================================
dns_port=$(grep listen: $CONFIG_YAML |awk -F ':' '{print $3}' |tr -cd "[0-9]")
redir_port=$(uci get clash.config.redir_port 2>/dev/null)
#fake_ip_range=$(uci get clash.config.fake_ip_range 2>/dev/null)
ipv6=$(uci get clash.config.enable_ipv6 2>/dev/null)
core=$(uci get clash.config.core 2>/dev/null)
tun_mode=$(uci get clash.config.tun_mode 2>/dev/null)
#lan_ip=$(uci get network.lan.ipaddr 2>/dev/null |awk -F '/' '{print $1}' 2>/dev/null)
wan=$(ifconfig | grep 'inet addr' | awk '{print $2}' | cut -d: -f2 2>/dev/null)
ip6=$(ifconfig | grep 'inet6 addr' | awk '{print $3}' 2>/dev/null)
enable_udp=$(uci get clash.config.enable_udp 2>/dev/null)
fake_ip=$(egrep '^ {0,}enhanced-mode' /etc/clash/config.yaml |grep enhanced-mode: |awk -F ': ' '{print $2}')
PROXY_FWMARK="0x162"
PROXY_ROUTE_TABLE="0x162"
PROXY_BYPASS_USER="root"
dnsforwader=$(uci get clash.config.dnsforwader 2>/dev/null)
redir_host=$(egrep '^ {0,}enhanced-mode' /etc/clash/config.yaml |grep enhanced-mode: |awk -F ': ' '{print $2}')
if [ "$redir_host" == "redir-host" ];then
if [ "$(uci get clash.config.access_control 2>/dev/null)" = "1" ] && [ -n "$(uci get clash.config.proxy_lan_ips 2>/dev/null)" ]; then
proxy_ips=$(uci get clash.config.proxy_lan_ips)
ipset -! -R <<-EOF
create proxy_lan hash:net
$(for ip in $proxy_ips; do echo "add proxy_lan $ip"; done)
EOF
elif [ "$(uci get clash.config.access_control 2>/dev/null)" = "2" ] && [ -n "$(uci get clash.config.reject_lan_ips 2>/dev/null)" ]; then
reject_ips=$(uci get clash.config.reject_lan_ips)
ipset -! -R <<-EOF
create reject_lan hash:net
$(for ip in $reject_ips; do echo "add reject_lan $ip"; done)
EOF
fi
fi
ipset create localnetwork hash:net
ipset add localnetwork 127.0.0.0/8
ipset add localnetwork 10.0.0.0/8
ipset add localnetwork 169.254.0.0/16
ipset add localnetwork 192.168.0.0/16
ipset add localnetwork 224.0.0.0/4
ipset add localnetwork 240.0.0.0/4
ipset add localnetwork 172.16.0.0/12
if [ -n "$wan" ]; then
for wan_ip4s in $wan; do
ipset add localnetwork "$wan_ip4s" 2>/dev/null
done
fi
sh /usr/share/clash/chinaipset.sh >/dev/null 2>&1
if [ "$(iptables -t nat -nL PREROUTING --line-number |grep "udp dpt:53" |grep "0.0.0.0/0 \{0,\}0.0.0.0/0" |wc -l)" -gt 1 ] && [ "$dnsforwader" -eq "1" ]; then
pre_lines=$(iptables -nvL PREROUTING -t nat |sed 1,2d |sed -n '/0.0.0.0\/0 \{0,\}0.0.0.0\/0 \{0,\}udp dpt:53/=' 2>/dev/null |sort -rn)
for pre_line in $pre_lines; do
iptables -t nat -D PREROUTING "$pre_line" >/dev/null 2>&1
done
iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 53 >/dev/null 2>&1
sleep 2
fi
if [ -z "$(uci get firewall.clash 2>/dev/null)" ] || [ -z "$(uci get ucitrack.@clash[-1].init 2>/dev/null)" ]; then
uci delete ucitrack.@clash[-1] >/dev/null 2>&1
uci add ucitrack clash >/dev/null 2>&1
uci set ucitrack.@clash[-1].init=clash >/dev/null 2>&1
uci commit ucitrack >/dev/null 2>&1
uci delete firewall.clash >/dev/null 2>&1
uci set firewall.clash=include >/dev/null 2>&1
uci set firewall.clash.type=script >/dev/null 2>&1
uci set firewall.clash.path=/var/etc/clash.include >/dev/null 2>&1
uci set firewall.clash.reload=1 >/dev/null 2>&1
fi
if [ "$(uci get firewall.@defaults[0].forward)" != "ACCEPT" ]; then
uci set firewall.@defaults[0].forward=ACCEPT >/dev/null 2>&1
uci commit firewall >/dev/null 2>&1
/etc/init.d/firewall restart >/dev/null 2>&1
fi
mkdir -p /var/etc
cat > "/var/etc/clash.include" <<-EOF
/etc/init.d/clash reload >/dev/null 2>&1
EOF
if [ "${core}" -eq 1 ] || [ "${core}" -eq 2 ];then
iptables -t nat -N clash
iptables -t nat -F clash
iptables -t nat -A clash -m set --match-set localnetwork dst -j RETURN
iptables -t nat -A clash -m set --match-set reject_lan src -j RETURN
iptables -t nat -A clash -m set ! --match-set proxy_lan src -j RETURN
iptables -t nat -A clash -m set --match-set china dst -j RETURN
iptables -t nat -A clash -p tcp -j REDIRECT --to-ports "${redir_port}"
iptables -t nat -I PREROUTING -p tcp -d 8.8.8.8 -j REDIRECT --to-ports "${redir_port}"
iptables -t nat -I PREROUTING -p tcp -d 8.8.4.4 -j REDIRECT --to-ports "${redir_port}"
iptables -t nat -A PREROUTING -p tcp -j clash
ip rule add fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE"
ip route add local 0.0.0.0/0 dev lo table "$PROXY_ROUTE_TABLE"
iptables -t mangle -N clash
iptables -t mangle -A clash -m set --match-set localnetwork dst -j RETURN
iptables -t mangle -A clash -m set --match-set reject_lan src -j RETURN
iptables -t mangle -A clash -m set ! --match-set proxy_lan src -j RETURN
iptables -t mangle -A clash -m set --match-set china dst -j RETURN
iptables -t mangle -A clash -p udp -j TPROXY --on-port "${redir_port}" --tproxy-mark "$PROXY_FWMARK"
iptables -t mangle -A PREROUTING -p udp -j clash
if [ "${fake_ip}" == "fake-ip" ];then
iptables -t nat -N clash_output
iptables -t nat -F clash_output
iptables -t nat -A clash_output -m set --match-set localnetwork dst -j RETURN
fake_ip_range=$(egrep '^ {0,}fake-ip-range' /etc/clash/config.yaml |grep fake-ip-range: |awk -F ': ' '{print $2}')
if [ ! -z "${fake_ip_range}" ];then
iptables -t nat -A clash_output -p tcp -d $fake_ip_range -j REDIRECT --to-ports "${redir_port}"
else
iptables -t nat -A clash_output -p tcp -d 198.18.0.0/16 -j REDIRECT --to-ports "${redir_port}"
fi
iptables -t nat -A OUTPUT -p tcp -j clash_output
fi
if [ "${ipv6}" == "true" ]; then
ip6tables -t nat -N clash
if [ -n "${ip6}" ]; then
for lan_ip6s in $ip6; do
ip6tables -t nat -A clash -d "$lan_ip6s" -j RETURN 2>/dev/null
done
fi
ip6tables -t nat -A clash -p tcp -j REDIRECT --to-ports "$proxy_port"
ip6tables -t nat -A PREROUTING -p tcp -j clash
fi
elif [ "${core}" -eq 3 ] || [ "${core}" -eq 4 ];then
natr=$(iptables -nvL PREROUTING -t nat | sed 1,2d | sed -n '/tcp dpt:53/=' | sort -r)
for natx in $natr; do
iptables -t nat -D PREROUTING $natx >/dev/null 2>&1
done
TUN_DEVICE=$(egrep '^ {0,}device-url:' /etc/clash/config.yaml |grep device-url: |awk -F '//' '{print $2}')
if [ -z $TUN_DEVICE ];then
TUN_DEVICE_NAME="clash0"
else
TUN_DEVICE_NAME=$TUN_DEVICE
fi
if [ "${core}" -eq 3 ];then
ip tuntap add user root mode tun $TUN_DEVICE_NAME
ip link set $TUN_DEVICE_NAME up
ip route replace default dev $TUN_DEVICE_NAME table "$PROXY_ROUTE_TABLE"
elif [ "${core}" -eq 4 ];then
TUN_WAIT=0
while ( [ -n "$(pidof clash)" ] && [ -z "$(ip route list |grep utun)" ] && [ "$TUN_WAIT" -le 3 ] )
do
TUN_WAIT=$(expr "$TUN_WAIT" + 1)
sleep 2
done
ip route replace default dev utun table "$PROXY_ROUTE_TABLE"
fi
ip rule add fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE"
iptables -t mangle -N clash
iptables -t mangle -F clash
iptables -t mangle -A clash -m set --match-set localnetwork dst -j RETURN
iptables -t mangle -A clash -m set --match-set china dst -j RETURN
if [ "${fake_ip}" == "fake-ip" ];then
iptables -t mangle -A clash -d 198.18.0.0/16 -j MARK --set-mark "$PROXY_FWMARK"
fi
iptables -t mangle -I OUTPUT -j clash
#iptables -t mangle -I PREROUTING -m set ! --match-set localnetwork dst -j MARK --set-mark "$PROXY_FWMARK"
#iptables -t mangle -I PREROUTING -m set ! --match-set china dst -j MARK --set-mark "$PROXY_FWMARK"
iptables -t mangle -I PREROUTING -m set ! --match-set localnetwork dst -m set ! --match-set china dst -j MARK --set-mark "$PROXY_FWMARK"
iptables -t mangle -I PREROUTING -m set --match-set reject_lan src -j RETURN >/dev/null 2>&1
iptables -t mangle -I PREROUTING -m set ! --match-set proxy_lan src -j RETURN >/dev/null 2>&1
iptables -t nat -I PREROUTING -p tcp --dport 53 -j ACCEPT
if [ "${fake_ip}" == "fake-ip" ];then
fake_ip_range=$(egrep '^ {0,}fake-ip-range' /etc/clash/config.yaml |grep fake-ip-range: |awk -F ': ' '{print $2}')
if [ ! -z "${fake_ip_range}" ];then
iptables -t nat -A OUTPUT -p tcp -d $fake_ip_range -j REDIRECT --to-ports "${redir_port}"
else
iptables -t nat -A OUTPUT -p tcp -d 198.18.0.1/16 -j REDIRECT --to-ports "${redir_port}"
fi
fi
fi
#===========================================================================================================================
}
custom_list() {
sh /usr/share/clash/list.sh >/dev/null 2>&1
}
restore() {
sh /usr/share/clash/restore.sh >/dev/null 2>&1
}
start(){
#===========================================================================================================================
lang=$(uci get luci.main.lang 2>/dev/null)
enable=$(uci get clash.config.enable 2>/dev/null)
core=$(uci get clash.config.core 2>/dev/null)
mode=$(uci get clash.config.mode 2>/dev/null)
tun_mode=$(uci get clash.config.tun_mode 2>/dev/null)
if [ -f /etc/clash/config.yaml ];then
rm -rf /etc/clash/config.yaml >/dev/null 2>&1
fi
if [ "${enable}" -eq 1 ]; then
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Starting Client" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "启动客户端" >$REAL_LOG
fi
sleep 1
select_config >/dev/null 2>&1
sleep 1
if [ "${core}" -eq 1 ] && [ ! -f /etc/clash/clash ]; then
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo " $(date "+%Y-%m-%d %H:%M:%S") - clash core not found, download and install clash from update page " >> /usr/share/clash/clash.txt
echo "clash core not found, download and install clash from update page" >> $REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo " $(date "+%Y-%m-%d %H:%M:%S") - 找不到/etc/clash/clash,请从更新页下载clash内核" >> /usr/share/clash/clash.txt
echo "找不到/etc/clash/clash,请从更新页下载clash内核" >> $REAL_LOG
fi
echo "Clash for OpenWRT" >$REAL_LOG
exit 0
elif [ "${core}" -eq 3 ] && [ ! -f /etc/clash/clashtun/clash ]; then
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo " $(date "+%Y-%m-%d %H:%M:%S") - clash Tun core not found in /etc/clash/clashtun/clash " >> /usr/share/clash/clash.txt
echo "clash Tun core not found in /etc/clash/clashtun/clash" >> $REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo " $(date "+%Y-%m-%d %H:%M:%S") - 找不到/etc/clash/clashtun/clash, clash Tun内核" >> /usr/share/clash/clash.txt
echo "找不到/etc/clash/clashtun/clash, clash Tun内核" >> $REAL_LOG
fi
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
exit 0
elif [ "${core}" -eq 4 ] && [ ! -f /etc/clash/dtun/clash ]; then
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo " $(date "+%Y-%m-%d %H:%M:%S") - clash Tun core not found in /etc/clash/dtun/clash " >> /usr/share/clash/clash.txt
echo "clash Tun core not found in /etc/clash/dtun/clash" >> $REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo " $(date "+%Y-%m-%d %H:%M:%S") - 找不到/usr/bin/clash clash Tun" >> /usr/share/clash/clash.txt
echo "找不到/etc/clash/dtun/clash,clash Tun" >> $REAL_LOG
fi
echo "Clash for OpenWRT" >$REAL_LOG
exit 0
else
if [ -f $CONFIG_YAML ] && [ "$(ls -l $CONFIG_YAML|awk '{print int($5)}')" -ne 0 ] ; then
check >/dev/null 2>&1
custom_list >/dev/null 2>&1
if [ "$core" -eq 4 ] || [ "$core" -eq 3 ];then
if [ $tun_mode -eq 0 ];then
uci set clash.config.tun_mode="1" && uci set clash.config.stack="system" && uci commit clash
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Enabling TUN" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "启用TUN" >$REAL_LOG
fi
fi
fi
sleep 1
enable_dns=$(uci get clash.config.enable_dns 2>/dev/null)
if [ -z "$(grep "^ {0,}listen:" /etc/clash/config.yaml)" ] || [ -z "$(grep "^ {0,}enhanced-mode:" /etc/clash/config.yaml)" ] || [ -z "$(grep "^ {0,}dns:" /etc/clash/config.yaml)" ];then
if [ $enable_dns -eq 0 ];then
uci set clash.config.enable_dns="1" && uci commit clash
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Enabling Custom Dns" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "启用自定义DNS" >$REAL_LOG
fi
fi
fi
if [ ! -z "$(egrep '^ {0,}rule-providers:' "/etc/clash/config.yaml")" ] && [ "$(uci get clash.config.core)" -ne 4 ];then
if [ -f /etc/clash/dtun/clash ];then
uci set clash.config.core="4" && uci commit clash
sleep 1
else
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Your Current Config only support Clash Core(dtun)" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "你在使用配置不支持Clash内核,仅支持Clash(dtun)h内核" >$REAL_LOG
fi
remove_mark >/dev/null 2>&1
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
exit 0
fi
fi
if [ ! -z "$(egrep '^ {0,}script:' "/etc/clash/config.yaml")" ] && [ "$(uci get clash.config.core)" -ne 4 ];then
if [ -f /etc/clash/dtun/clash ];then
uci set clash.config.core="4" && uci commit clash
sleep 1
else
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Your Current Config only support Clash Core(dtun)" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "你在使用配置不支持Clash内核,仅支持Clash(dtun)h内核" >$REAL_LOG
fi
remove_mark >/dev/null 2>&1
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
exit 0
fi
fi
if [ ! -z "$(egrep '^ {0,}script:' "/etc/clash/config.yaml")" ] && [ "$(uci get clash.config.p_mode 2>/dev/null)" != "Script" ];then
uci set clash.config.p_mode="Script"&& uci commit clash
elif [ "$(uci get clash.config.p_mode)" == "Script" ] && [ -z "$(egrep '^ {0,}script:' "/etc/clash/config.yaml")" ];then
uci set clash.config.p_mode="rule" && uci commit clash
fi
sleep 1
yml_change >/dev/null 2>&1
if [ ! -f /etc/clash/Country.mmdb ];then
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Cannot find Country.mmdb" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "找不到Country.mmdb" >$REAL_LOG
fi
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
exit 0
fi
if [ ! -f /etc/clash/config.yaml ];then
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Cannot find config.yaml" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "找不到config.yaml" >$REAL_LOG
fi
remove_mark >/dev/null 2>&1
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
exit 0
fi
yml_dns_change >/dev/null 2>&1
game_rules >/dev/null 2>&1
ip_rules >/dev/null 2>&1
if [ "$(uci get clash.config.core)" -eq 1 ];then
nohup $CLASH -d "$CLASH_CONFIG" > /usr/share/clash/clash.txt 2>&1 &
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Clash Core Started Successfully " >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "Clash 计划任务,启动进程守护程序..." >$REAL_LOG
fi
elif [ "$(uci get clash.config.core)" -eq 3 ];then
nohup $CLASHT -d "$CLASH_CONFIG" > /usr/share/clash/clash.txt 2>&1 &
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Clash Core Started Successfully " >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "Clash 计划任务,启动进程守护程序..." >$REAL_LOG
fi
elif [ "$(uci get clash.config.core)" -eq 4 ];then
nohup $CLASHD -d "$CLASH_CONFIG" > /usr/share/clash/clash.txt 2>&1 &
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Clash Core Started Successfully " >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "Clash 计划任务,启动进程守护程序..." >$REAL_LOG
fi
fi
ln -s /usr/share/clash/yacd /www/luci-static/yacd 2>/dev/null
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Setting up clash iptables rules" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "设置 Clash iptables" >$REAL_LOG
fi
rules >/dev/null 2>&1
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Restarting Dnsmasq " >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "重启 Dnsmasq 程序" >$REAL_LOG
fi
/etc/init.d/dnsmasq restart >/dev/null 2>&1
restore >/dev/null 2>&1
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Setting Cron Job" >$REAL_LOG
add_cron
elif [ "${lang}" == "zh_cn" ];then
echo "设置Cron" >$REAL_LOG
add_cron
fi
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Clash Started Successfully " >$REAL_LOG
sleep 1
echo "Clash is Running " >$REAL_LOG
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "Clash 启动成功,请等待服务器上线!" >$REAL_LOG
sleep 1
echo "Clash运行中" >$REAL_LOG
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
fi
if ! pidof clash >/dev/null; then
remove_mark 2>/dev/null
kill -9 `pidof clash|sed "s/$//g"` 2>/dev/null
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
fi
else
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo " $(date "+%Y-%m-%d %H:%M:%S") - problem with config.yaml, config.yaml is either empty or not found " >> /usr/share/clash/clash.txt
echo " problem with config file " >$REAL_LOG
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo " $(date "+%Y-%m-%d %H:%M:%S") - 你的config.yaml有问题还是为了空 0kb " >> /usr/share/clash/clash.txt
echo " 你的config.yaml有问题还是为了空 0kb " >$REAL_LOG
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
fi
fi
fi
else
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Enable Client and Start Client Again" >$REAL_LOG
echo " $(date "+%Y-%m-%d %H:%M:%S") - Enable Client and Start Client Again" >>/usr/share/clash/clash.txt
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "启用客户端并重新启动客户端" >$REAL_LOG
echo " $(date "+%Y-%m-%d %H:%M:%S") - 启用客户端并重新启动客户端" >>/usr/share/clash/clash.txt
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
fi
fi
#===========================================================================================================================
}
remove_mark(){
rm -rf /var/etc/clash.include 2>/dev/null
core=$(uci get clash.config.core 2>/dev/null)
ipv6=$(uci get clash.config.enable_ipv6 2>/dev/null)
dns_port=$(grep "^ \{0,\}listen:" $CONFIG_YAML |awk -F ':' '{print $3}' 2>/dev/null)
PROXY_FWMARK="0x162" 2>/dev/null
PROXY_ROUTE_TABLE="0x162" 2>/dev/null
ip rule del fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
ip route del local 0.0.0.0/0 dev lo table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
TUN_DEVICE=$(egrep '^ {0,}device-url:' /etc/clash/config.yaml |grep device-url: |awk -F '//' '{print $2}')
if [ -z $TUN_DEVICE ];then
TUN_DEVICE_NAME="clash0"
else
TUN_DEVICE_NAME=$TUN_DEVICE
fi
if [ "${core}" -eq 3 ];then
ip link set dev $TUN_DEVICE_NAME down 2>/dev/null
ip tuntap del $TUN_DEVICE_NAME mode tun 2>/dev/null
ip route del default dev $TUN_DEVICE_NAME table "$PROXY_ROUTE_TABLE" 2>/dev/null
fi
ip route del default dev utun table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
#ip rule del fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE" 2>/dev/null
ip rule del fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
mangle=$(iptables -nvL OUTPUT -t mangle | sed 1,2d | sed -n '/clash/=' | sort -r)
for mangles in $mangle; do
iptables -t mangle -D OUTPUT $mangles 2>/dev/null
done
pre=$(iptables -nvL PREROUTING -t mangle | sed 1,2d | sed -n '/! match-set localnetwork dst MARK set 0x162/=' | sort -r)
for prer in $pre; do
iptables -t mangle -D PREROUTING $prer 2>/dev/null
done
pre1=$(iptables -nvL PREROUTING -t mangle | sed 1,2d | sed -n '/! match-set china dst MARK set 0x162/=' | sort -r)
for prer in $pre1; do
iptables -t mangle -D PREROUTING $prer 2>/dev/null
done
pre_lines=$(iptables -nvL PREROUTING -t nat |sed 1,2d |sed -n '/8\.8\./=' 2>/dev/null |sort -rn)
for pre_line in $pre_lines; do
iptables -t nat -D PREROUTING "$pre_line" >/dev/null 2>&1
done
iptables -t nat -D PREROUTING -p tcp --dport 53 -j ACCEPT >/dev/null 2>&1
iptables -t nat -D PREROUTING -p udp --dport 53 -j DNAT --to "127.0.0.1:$dns_port"
if [ "${ipv6}" == "true" ]; then
ip6tables -t mangle -D PREROUTING -j MARK --set-mark "$PROXY_FWMARK" 2>/dev/null
fi
iptables -t mangle -F clash 2>/dev/null
iptables -t mangle -X clash 2>/dev/null
iptables -t nat -F clash_output >/dev/null 2>&1
iptables -t nat -X clash_output >/dev/null 2>&1
ipset -! flush proxy_lan >/dev/null 2>&1
ipset -! flush reject_lan >/dev/null 2>&1
ipset destroy reject_lan >/dev/null 2>&1
ipset destroy proxy_lan >/dev/null 2>&1
ipset -! flush china >/dev/null 2>&1
ipset destroy china >/dev/null 2>&1
proxy_lan=$(iptables -nvL PREROUTING -t mangle | sed 1,2d | sed -n '/! match-set proxy_lan src/=' | sort -r)
for natx in $proxy_lan; do
iptables -t mangle -D PREROUTING $natx >/dev/null 2>&1
done
reject_lan=$(iptables -nvL PREROUTING -t mangle | sed 1,2d | sed -n '/match-set reject_lan src/=' | sort -r)
for natx in $reject_lan; do
iptables -t mangle -D PREROUTING $natx >/dev/null 2>&1
done
proxy_lann=$(iptables -nvL clash -t nat | sed 1,2d | sed -n '/! match-set proxy_lan src/=' | sort -r)
for natx in $proxy_lann; do
iptables -t nat -D PREROUTING $natx >/dev/null 2>&1
done
reject_lann=$(iptables -nvL clash -t nat | sed 1,2d | sed -n '/match-set reject_lan src/=' | sort -r)
for natx in $reject_lann; do
iptables -t nat -D PREROUTING $natx >/dev/null 2>&1
done
proxy_lannn=$(iptables -nvL clash -t nat | sed 1,2d | sed -n '/! match-set proxy_lan src/=' | sort -r)
for natx in $proxy_lannn; do
iptables -t mangle -D PREROUTING $natx >/dev/null 2>&1
done
reject_lannn=$(iptables -nvL clash -t nat | sed 1,2d | sed -n '/match-set reject_lan src/=' | sort -r)
for natx in $reject_lannn; do
iptables -t mangle -D PREROUTING $natx >/dev/null 2>&1
done
iptables -t nat -D OUTPUT -p tcp -j clash_output >/dev/null 2>&1
china_lan2=$(iptables -nvL PREROUTING -t nat | sed 1,2d | sed -n '/match-set china/=' | sort -r)
for natx in $china_lan2; do
iptables -t mangle -D PREROUTING $natx >/dev/null 2>&1
done
china_lan3$(iptables -nvL PREROUTING -t mangle | sed 1,2d | sed -n '/match-set china/=' | sort -r)
for natx in $china_lan3; do
iptables -t mangle -D PREROUTING $natx >/dev/null 2>&1
done
ipset destroy localnetwork 2>/dev/null
nat_indexs=$(iptables -nvL PREROUTING -t nat | sed 1,2d | sed -n '/clash/=' | sort -r)
for nat_index in $nat_indexs; do
iptables -t nat -D PREROUTING $nat_index >/dev/null 2>&1
iptables -t nat -F clash >/dev/null 2>&1
iptables -t nat -X clash >/dev/null 2>&1
iptables -t mangle -F clash >/dev/null 2>&1
iptables -t mangle -D PREROUTING -p udp -j clash >/dev/null 2>&1
iptables -t mangle -X clash >/dev/null 2>&1
done
nat=$(iptables -nvL PREROUTING -t nat | sed 1,2d | sed -n '/tcp dpt:53/=' | sort -r)
for natx in $nat; do
iptables -t nat -D PREROUTING $natx >/dev/null 2>&1
done
ip6tables -t mangle -F clash >/dev/null 2>&1
ip6tables -t mangle -D PREROUTING -p udp -j clash >/dev/null 2>&1
ip6tables -t mangle -X clash >/dev/null 2>&1
out_linese=$(iptables -nvL OUTPUT -t mangle |sed 1,2d |sed -n '/198.18.0.1\/16/=' 2>/dev/null |sort -rn)
for out_linee in $out_linese; do
iptables -t mangle -D OUTPUT "$out_linee" >/dev/null 2>&1
done
out_linesee=$(iptables -nvL OUTPUT -t mangle |sed 1,2d |sed -n '/198.18.0.0\/16/=' 2>/dev/null |sort -rn)
for out_linees in $out_linesee; do
iptables -t mangle -D OUTPUT "$out_linees" >/dev/null 2>&1
done
nat_indexs=$(iptables -nvL PREROUTING -t nat | sed 1,2d | sed -n '/clash/=' | sort -r)
for nat_index in $nat_indexs; do
iptables -t nat -D PREROUTING $nat_index >/dev/null 2>&1
done
fake=$(iptables -nvL OUTPUT -t nat |sed 1,2d |sed -n '/198.18.0.0\/16/=' |sort -r)
for fake in $fake; do
iptables -t nat -D OUTPUT $fake >/dev/null 2>&1
done
fake2=$(iptables -nvL OUTPUT -t nat |sed 1,2d |sed -n '/198.18.0.1\/16/=' |sort -r)
for fake2 in $fake2; do
iptables -t nat -D OUTPUT $fake2 >/dev/null 2>&1
done
iptables -t nat -I PREROUTING -p tcp --dport 53 -j ACCEPT
revert_dns >/dev/null 2>&1
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Restarting Dnsmasq " >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "重启 Dnsmasq 程序" >$REAL_LOG
fi
}
stop(){
#===========================================================================================================================
lang=$(uci get luci.main.lang 2>/dev/null)
tun_mode=$(uci get clash.config.tun_mode 2>/dev/null)
#ipv6=$(uci get clash.config.enable_ipv6 2>/dev/null)
core=$(uci get clash.config.core 2>/dev/null)
LIST="/usr/share/clash/server.list"
sed -i '/#START/,/#END/d' "$LIST" 2>/dev/null
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Stopping Client..." >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "正在停止客户端..." >$REAL_LOG
fi
sleep 1
remove_mark >/dev/null 2>&1
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Removing clash iptables rules" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "删除clash iptables规则" >$REAL_LOG
fi
bash /usr/share/clash/backup.sh >/dev/null 2>&1
kill -9 `pidof clash|sed "s/$//g"` 2>/dev/null
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Clash Core Stoped Successfully " >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "Clash 停止进程守护程序" >$REAL_LOG
fi
rm -rf /www/luci-static/yacd 2>/dev/null
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Deleting Cron Job" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "删除Cron" >$REAL_LOG
fi
del_cron >/dev/null 2>&1
sleep 1
echo "" >/usr/share/clash/clash.txt >/dev/null 2>&1
echo "0" > /usr/share/clash/logstatus_check >/dev/null 2>&1
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo " $(date "+%Y-%m-%d %H:%M:%S") - CLIENT IS DISABLED " >> /usr/share/clash/clash.txt
echo "Client is Disabled " >$REAL_LOG
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo " $(date "+%Y-%m-%d %H:%M:%S") - 客户端被禁用 " >> /usr/share/clash/clash.txt
echo "客户端被禁用 " >$REAL_LOG
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
fi
if pidof clash >/dev/null; then
kill $(pidof clash) >/dev/null 2>&1 || kill -9 $(ps | grep clash | grep -v grep | awk '{print $1}') >/dev/null 2>&1
fi
#===========================================================================================================================
}
restart(){
#===========================================================================================================================
if pidof clash >/dev/null; then
stop >/dev/null 2>&1
start >/dev/null 2>&1
echo "Clash Successfully Restarted"
else
start >/dev/null 2>&1
echo "Clash Successfully Started"
fi
#===========================================================================================================================
}
reload()
{
if pidof clash >/dev/null; then
remove_mark 2>/dev/null
yml_dns_change 2>/dev/null
rules 2>/dev/null
echo "Clash Reload Completed"
fi
}
@@ -1,21 +0,0 @@
#!/bin/sh
. /lib/functions.sh
CURL_GROUP_CACHE="/usr/share/clashbackup/clash_gorup.json"
CURL_NOW_CACHE="/usr/share/clashbackup/clash_now.json"
CURL_CACHE="/usr/share/clashbackup/clash_curl.json"
HISTORY_PATH="/usr/share/clashbackup/history"
SECRET=$(uci get clash.config.dash_pass 2>/dev/null)
LAN_IP=$(uci get network.lan.ipaddr 2>/dev/null |awk -F '/' '{print $1}' 2>/dev/null)
PORT=$(uci get clash.config.dash_port 2>/dev/null)
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
if [ "$(sed -n '$p' "$CURL_CACHE" 2>/dev/null)" = "200" ]; then
if [ ! -d /usr/share/clashbackup ];then
mkdir -p /usr/share/clashbackup 2>/dev/null
fi
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
fi
rm -rf /usr/share/clashbackup/clash_*.json 2>/dev/null
@@ -1,13 +0,0 @@
#!/bin/sh
new_clashtun_core_version=`curl -sL "https://github.com/frainzy1477/clashtun/tags"| grep "/frainzy1477/clashtun/releases/"| head -n 1| awk -F "/tag/" '{print $2}'| sed 's/\">//'`
if [ "$?" -eq "0" ]; then
rm -rf /usr/share/clash/new_clashtun_core_version
if [ $new_clashtun_core_version ]; then
echo $new_clashtun_core_version > /usr/share/clash/new_clashtun_core_version 2>&1 & >/dev/null
elif [ $new_clashtun_core_version =="" ]; then
echo 0 > /usr/share/clash/new_clashtun_core_version 2>&1 & >/dev/null
fi
fi
@@ -1,12 +0,0 @@
#!/bin/sh
new_core_version=`curl -sL "https://github.com/frainzy1477/clash_dev/tags"| grep "/frainzy1477/clash_dev/releases/"| head -n 1| awk -F "/tag/" '{print $2}'| sed 's/\">//'`
if [ "$?" -eq "0" ]; then
rm -rf /usr/share/clash/new_core_version
if [ $new_core_version ]; then
echo $new_core_version > /usr/share/clash/new_core_version 2>&1 & >/dev/null
elif [ $new_core_version =="" ]; then
echo 0 > /usr/share/clash/new_core_version 2>&1 & >/dev/null
fi
fi
@@ -1,12 +0,0 @@
#!/bin/sh
new_clashdtun_core_version=`curl -sL "https://github.com/frainzy1477/clashdtun/tags"| grep "/frainzy1477/clashdtun/releases/"| head -n 1| awk -F "/tag/" '{print $2}'| sed 's/\">//'`
sleep 2
if [ "$?" -eq "0" ]; then
rm -rf /usr/share/clash/new_clashdtun_core_version
if [ $new_clashdtun_core_version ]; then
echo $new_clashdtun_core_version > /usr/share/clash/new_clashdtun_core_version 2>&1 & >/dev/null
elif [ $new_clashdtun_core_version =="" ]; then
echo 0 > /usr/share/clash/new_clashdtun_core_version 2>&1 & >/dev/null
fi
fi
@@ -1,12 +0,0 @@
#!/bin/sh
new_version=`curl -sL "https://github.com/frainzy1477/luci-app-clash/tags"| grep "/frainzy1477/luci-app-clash/releases/"| head -n 1| awk -F "/tag/" '{print $2}'| sed 's/\">//'`
if [ "$?" -eq "0" ]; then
rm -rf /usr/share/clash/new_luci_version
if [ $new_version ]; then
echo $new_version > /usr/share/clash/new_luci_version 2>&1 & >/dev/null
elif [ $new_version =="" ]; then
echo 0 > /usr/share/clash/new_luci_version 2>&1 & >/dev/null
fi
fi
File diff suppressed because it is too large. Load diff
@@ -1,6 +0,0 @@
echo "create china hash:net family inet hashsize 1024 maxelem 65536" > /tmp/china.ipset
awk '!/^$/&&!/^#/{printf("add china %s'" "'\n",$0)}' /usr/share/clash/china_ip.txt >> /tmp/china.ipset
ipset -! flush china
ipset -! restore < /tmp/china.ipset 2>/dev/null
rm -f /tmp/china.ipset
@@ -1,13 +0,0 @@
#!/bin/sh
enable=$(uci get clash.config.enable 2>/dev/null)
if [ "${enable}" -eq 1 ];then
if ! pidof clash>/dev/null; then
/etc/init.d/clash restart 2>&1 &
fi
fi
@@ -1,125 +0,0 @@
#!/bin/bash /etc/rc.common
clash_url=$(uci get clash.config.clash_url 2>/dev/null)
ssr_url=$(uci get clash.config.ssr_url 2>/dev/null)
v2_url=$(uci get clash.config.v2_url 2>/dev/null)
config_name=$(uci get clash.config.config_name 2>/dev/null)
subtype=$(uci get clash.config.subcri 2>/dev/null)
REAL_LOG="/usr/share/clash/clash_real.txt"
lang=$(uci get luci.main.lang 2>/dev/null)
CONFIG_YAML="/usr/share/clash/config/sub/${config_name}.yaml"
if [ $config_name == "" ] || [ -z $config_name ];then
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Tag Your Config" >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "标记您的配置" >$REAL_LOG
fi
sleep 5
echo "Clash for OpenWRT" >$REAL_LOG
exit 0
fi
if [ ! -f "/usr/share/clashbackup/confit_list.conf" ];then
touch /usr/share/clashbackup/confit_list.conf
fi
check_name=$(grep -F "${config_name}.yaml" "/usr/share/clashbackup/confit_list.conf")
if [ ! -z $check_name ];then
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Config with same name exist, please rename and download again" >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "已存在同名配置,请重命名名配置重新下载" >$REAL_LOG
fi
sleep 5
echo "Clash for OpenWRT" >$REAL_LOG
exit 0
else
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Downloading Configuration..." >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "开始下载配置" >$REAL_LOG
fi
sleep 1
if [ "$subtype" = "clash" ];then
wget -c4 --no-check-certificate --user-agent="Clash/OpenWRT" "$clash_url" -O 2>&1 >1 $CONFIG_YAML
if [ "$?" -eq "0" ]; then
echo "${config_name}.yaml#$clash_url#$subtype" >>/usr/share/clashbackup/confit_list.conf
fi
fi
if [ "$subtype" = "ssr2clash" ];then
wget -c4 --no-check-certificate --user-agent="Clash/OpenWRT" "https://gfwsb.114514.best/sub?target=clashr&url=$ssr_url" -O 2>&1 >1 $CONFIG_YAML
if [ "$?" -eq "0" ]; then
echo "${config_name}.yaml#$ssr_url#$subtype" >>/usr/share/clashbackup/confit_list.conf
CONFIG_YAMLL="/tmp/conf"
da_password=$(uci get clash.config.dash_pass 2>/dev/null)
redir_port=$(uci get clash.config.redir_port 2>/dev/null)
http_port=$(uci get clash.config.http_port 2>/dev/null)
socks_port=$(uci get clash.config.socks_port 2>/dev/null)
dash_port=$(uci get clash.config.dash_port 2>/dev/null)
bind_addr=$(uci get clash.config.bind_addr 2>/dev/null)
allow_lan=$(uci get clash.config.allow_lan 2>/dev/null)
log_level=$(uci get clash.config.level 2>/dev/null)
p_mode=$(uci get clash.config.p_mode 2>/dev/null)
sed -i "/^Proxy:/i\#clash-openwrt" $CONFIG_YAML 2>/dev/null
sed -i '1,/#clash-openwrt/d' $CONFIG_YAML 2>/dev/null
cat /usr/share/clash/dns.yaml $CONFIG_YAML > $CONFIG_YAMLL 2>/dev/null
mv $CONFIG_YAMLL $CONFIG_YAML 2>/dev/null
sed -i "1i\#****CLASH-CONFIG-START****#" $CONFIG_YAML 2>/dev/null
sed -i "2i\port: ${http_port}" $CONFIG_YAML 2>/dev/null
sed -i "/port: ${http_port}/a\socks-port: ${socks_port}" $CONFIG_YAML 2>/dev/null
sed -i "/socks-port: ${socks_port}/a\redir-port: ${redir_port}" $CONFIG_YAML 2>/dev/null
sed -i "/redir-port: ${redir_port}/a\allow-lan: ${allow_lan}" $CONFIG_YAML 2>/dev/null
if [ $allow_lan == "true" ]; then
sed -i "/allow-lan: ${allow_lan}/a\bind-address: \"${bind_addr}\"" $CONFIG_YAML 2>/dev/null
sed -i "/bind-address: \"${bind_addr}\"/a\mode: ${p_mode}" $CONFIG_YAML 2>/dev/null
sed -i "/mode: ${p_mode}/a\log-level: ${log_level}" $CONFIG_YAML 2>/dev/null
sed -i "/log-level: ${log_level}/a\external-controller: 0.0.0.0:${dash_port}" $CONFIG_YAML 2>/dev/null
sed -i "/external-controller: 0.0.0.0:${dash_port}/a\secret: \"${da_password}\"" $CONFIG_YAML 2>/dev/null
sed -i "/secret: \"${da_password}\"/a\external-ui: \"/usr/share/clash/dashboard\"" $CONFIG_YAML 2>/dev/null
else
sed -i "/allow-lan: ${allow_lan}/a\mode: Rule" $CONFIG_YAML 2>/dev/null
sed -i "/mode: Rule/a\log-level: ${log_level}" $CONFIG_YAML 2>/dev/null
sed -i "/log-level: ${log_level}/a\external-controller: 0.0.0.0:${dash_port}" $CONFIG_YAML 2>/dev/null
sed -i "/external-controller: 0.0.0.0:${dash_port}/a\secret: \"${da_password}\"" $CONFIG_YAML 2>/dev/null
sed -i "/secret: \"${da_password}\"/a\external-ui: \"/usr/share/clash/dashboard\"" $CONFIG_YAML 2>/dev/null
fi
sleep 1
fi
fi
if [ "$subtype" = "v2clash" ];then
wget -c4 --no-check-certificate --user-agent="Clash/OpenWRT" "https://tgbot.lbyczf.com/v2rayn2clash?url=$v2_url" -O 2>&1 >1 $CONFIG_YAML
if [ "$?" -eq "0" ]; then
echo "${config_name}.yaml#$v2_url#$subtype" >>/usr/share/clashbackup/confit_list.conf
fi
fi
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Downloading Configuration Completed" >$REAL_LOG
sleep 2
echo "Clash for OpenWRT" >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "下载配置完成" >$REAL_LOG
sleep 2
echo "Clash for OpenWRT" >$REAL_LOG
fi
fi
@@ -1 +0,0 @@
@@ -1,78 +0,0 @@
#!/bin/bash /etc/rc.common
. /lib/functions.sh
RULE_FILE_NAME="$1"
RULE_FILE_ENNAME=$(grep -F $RULE_FILE_NAME /usr/share/clash/rules/rules.list |awk -F ',' '{print $3}' 2>/dev/null)
if [ ! -z "$RULE_FILE_ENNAME" ]; then
DOWNLOAD_PATH=$(grep -F $RULE_FILE_NAME /usr/share/clash/rules/rules.list |awk -F ',' '{print $2}' 2>/dev/null)
else
DOWNLOAD_PATH=$RULE_FILE_NAME
fi
RULE_FILE_DIR="/usr/share/clash/rules/g_rules/$RULE_FILE_NAME"
TMP_RULE_DIR="/tmp/$RULE_FILE_NAME"
LOG_FILE="/usr/share/clash/clash.txt"
REAL_LOG="/usr/share/clash/clash_real.txt"
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Updating 【$RULE_FILE_NAME】 Rule..." >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "开始下载【$RULE_FILE_NAME】规则..." >$REAL_LOG
fi
wget --no-check-certificate -c4 https://raw.githubusercontent.com/FQrabbit/SSTap-Rule/master/rules/"$DOWNLOAD_PATH" -O 2>&1 >1 "$TMP_RULE_DIR"
if [ "$?" -eq "0" ] && [ "$(ls -l $TMP_RULE_DIR |awk '{print $5}')" -ne 0 ]; then
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "【$RULE_FILE_NAME】 Downloaded successfully. Checking whether the rule version is updated.." >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "【$RULE_FILE_NAME】规则下载成功,检查规则版本是否更新..." >$REAL_LOG
fi
cmp -s $TMP_RULE_DIR $RULE_FILE_DIR
if [ "$?" -ne "0" ]; then
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Rule version has been updated. Start to replace the old rule version.." >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "规则版本有更新,开始替换旧规则版本..." >$REAL_LOG
fi
mv $TMP_RULE_DIR $RULE_FILE_DIR >/dev/null 2>&1
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Delete download cache" >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "删除下载缓存..." >$REAL_LOG
fi
rm -rf $TMP_RULE_DIR >/dev/null 2>&1
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Rule File【$RULE_FILE_NAME】 Download Successful" >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "【$RULE_FILE_NAME】规则更新成功!" >$REAL_LOG
fi
sleep 2
echo "Clash for OpenWRT" >$REAL_LOG
else
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Updated Rule File【$RULE_FILE_NAME】 No Change, Do Nothing" >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "【$RULE_FILE_NAME】规则版本没有更新,停止继续操作..." >$REAL_LOG
fi
rm -rf $TMP_RULE_DIR >/dev/null 2>&1
sleep 2
echo "Clash for OpenWRT" >$REAL_LOG
fi
else
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Rule File【$RULE_FILE_NAME】 Download Error" >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "【$RULE_FILE_NAME】规则下载失败,请检查网络或稍后再试!" >$REAL_LOG
fi
rm -rf $TMP_RULE_DIR >/dev/null 2>&1
sleep 2
echo "Clash for OpenWRT" >$REAL_LOG
fi
@@ -1 +0,0 @@
Clash for OpenWRT
@@ -1,175 +0,0 @@
#!/bin/sh
LOGTIME=$(date "+%Y-%m-%d %H:%M:%S")
LOG_FILE="/tmp/clash_update.txt"
MODELTYPE=$(uci get clash.config.download_core 2>/dev/null)
CORETYPE=$(uci get clash.config.dcore 2>/dev/null)
CORE=$(uci get clash.config.core 2>/dev/null)
lang=$(uci get luci.main.lang 2>/dev/null)
if [ -f /tmp/clash.tar.gz ];then
rm -rf /tmp/clash.tar.gz >/dev/null 2>&1
fi
echo '' >/tmp/clash_update.txt 2>/dev/null
if [ -f /usr/share/clash/core_down_complete ];then
rm -rf /usr/share/clash/core_down_complete 2>/dev/null
fi
if [ $CORETYPE -eq 4 ];then
if [ -f /usr/share/clash/download_dtun_version ];then
rm -rf /usr/share/clash/download_dtun_version
fi
if [ $lang == "zh_cn" ];then
echo " ${LOGTIME} - 正在检查最新版本。。" >$LOG_FILE
elif [ $lang == "en" ] || [ $lang == "auto" ];then
echo " ${LOGTIME} - Checking latest version.." >$LOG_FILE
fi
new_clashdtun_core_version=`wget -qO- "https://github.com/frainzy1477/clashdtun/tags"| grep "/frainzy1477/clashdtun/releases/"| head -n 1| awk -F "/tag/" '{print $2}'| sed 's/\">//'`
if [ $new_clashdtun_core_version ]; then
echo $new_clashdtun_core_version > /usr/share/clash/download_dtun_version 2>&1 & >/dev/null
elif [ $new_clashdtun_core_version =="" ]; then
echo 0 > /usr/share/clash/download_dtun_version 2>&1 & >/dev/null
fi
sleep 5
if [ -f /usr/share/clash/download_dtun_version ];then
CLASHDTUNC=$(sed -n 1p /usr/share/clash/download_dtun_version 2>/dev/null)
fi
fi
if [ $CORETYPE -eq 3 ];then
if [ -f /usr/share/clash/download_tun_version ];then
rm -rf /usr/share/clash/download_tun_version
fi
if [ $lang == "zh_cn" ];then
echo " ${LOGTIME} - 正在检查最新版本。。" >$LOG_FILE
elif [ $lang == "en" ] || [ $lang == "auto" ];then
echo " ${LOGTIME} - Checking latest version.." >$LOG_FILE
fi
new_clashtun_core_version=`wget -qO- "https://github.com/frainzy1477/clashtun/tags"| grep "/frainzy1477/clashtun/releases/"| head -n 1| awk -F "/tag/" '{print $2}'| sed 's/\">//'`
if [ $new_clashtun_core_version ]; then
echo $new_clashtun_core_version > /usr/share/clash/download_tun_version 2>&1 & >/dev/null
elif [ $new_clashtun_core_version =="" ]; then
echo 0 > /usr/share/clash/download_tun_version 2>&1 & >/dev/null
fi
sleep 5
if [ -f /usr/share/clash/download_tun_version ];then
CLASHTUN=$(sed -n 1p /usr/share/clash/download_tun_version 2>/dev/null)
fi
fi
if [ $CORETYPE -eq 1 ];then
if [ -f /usr/share/clash/download_core_version ];then
rm -rf /usr/share/clash/download_core_version
fi
if [ $lang == "zh_cn" ];then
echo " ${LOGTIME} - 正在检查最新版本。。" >$LOG_FILE
elif [ $lang == "en" ] || [ $lang == "auto" ];then
echo " ${LOGTIME} - Checking latest version.." >$LOG_FILE
fi
new_clashr_core_version=`wget -qO- "https://github.com/frainzy1477/clash_dev/tags"| grep "/frainzy1477/clash_dev/releases/"| head -n 1| awk -F "/tag/" '{print $2}'| sed 's/\">//'`
if [ $new_clashr_core_version ]; then
echo $new_clashr_core_version > /usr/share/clash/download_core_version 2>&1 & >/dev/null
elif [ $new_clashr_core_version =="" ]; then
echo 0 > /usr/share/clash/download_core_version 2>&1 & >/dev/null
fi
sleep 5
if [ -f /usr/share/clash/download_core_version ];then
CLASHVER=$(sed -n 1p /usr/share/clash/download_core_version 2>/dev/null)
fi
fi
sleep 2
update(){
if [ -f /tmp/clash.gz ];then
rm -rf /tmp/clash.gz >/dev/null 2>&1
fi
if [ $lang == "zh_cn" ];then
echo " ${LOGTIME} - 开始下载 Clash 内核..." >$LOG_FILE
elif [ $lang == "en" ] || [ $lang == "auto" ];then
echo " ${LOGTIME} - Starting Clash Core download" >$LOG_FILE
fi
if [ $CORETYPE -eq 1 ];then
wget --no-check-certificate https://github.com/frainzy1477/clash_dev/releases/download/"$CLASHVER"/clash-"$MODELTYPE".gz -O 2>&1 >1 /tmp/clash.gz
elif [ $CORETYPE -eq 3 ];then
wget --no-check-certificate https://github.com/frainzy1477/clashtun/releases/download/"$CLASHTUN"/clash-"$MODELTYPE".gz -O 2>&1 >1 /tmp/clash.gz
elif [ $CORETYPE -eq 4 ];then
wget --no-check-certificate https://github.com/frainzy1477/clashdtun/releases/download/"$CLASHDTUNC"/clash-"$MODELTYPE".gz -O 2>&1 >1 /tmp/clash.gz
fi
if [ "$?" -eq "0" ] && [ "$(ls -l /tmp/clash.gz |awk '{print int($5)}')" -ne 0 ]; then
if [ $lang == "zh_cn" ];then
echo " ${LOGTIME} - 开始解压缩文件" >$LOG_FILE
elif [ $lang == "en" ] || [ $lang == "auto" ];then
echo " ${LOGTIME} - Beginning to unzip file" >$LOG_FILE
fi
gunzip /tmp/clash.gz >/dev/null 2>&1\
&& rm -rf /tmp/clash.gz >/dev/null 2>&1\
&& chmod 755 /tmp/clash\
&& chown root:root /tmp/clash
if [ $lang == "zh_cn" ];then
echo " ${LOGTIME} - 完成下载内核,正在更新..." >$LOG_FILE
elif [ $lang == "en" ] || [ $lang == "auto" ];then
echo " ${LOGTIME} - Successfully downloaded core, updating now..." >$LOG_FILE
fi
if [ $CORETYPE -eq 1 ];then
rm -rf /etc/clash/clash >/dev/null 2>&1
mv /tmp/clash /etc/clash/clash >/dev/null 2>&1
rm -rf /usr/share/clash/core_version >/dev/null 2>&1
mv /usr/share/clash/download_core_version /usr/share/clash/core_version >/dev/null 2>&1
if [ $lang == "zh_cn" ];then
echo " ${LOGTIME} - Clash内核更新成功!" >$LOG_FILE
elif [ $lang == "en" ] || [ $lang == "auto" ];then
echo " ${LOGTIME} - Clash Core Update Successful" >$LOG_FILE
fi
elif [ $CORETYPE -eq 3 ];then
rm -rf /etc/clash/clashtun/clash >/dev/null 2>&1
mv /tmp/clash /etc/clash/clashtun/clash >/dev/null 2>&1
rm -rf /usr/share/clash/tun_version >/dev/null 2>&1
mv /usr/share/clash/download_tun_version /usr/share/clash/tun_version >/dev/null 2>&1
tun=$(sed -n 1p /usr/share/clash/tun_version 2>/dev/null)
sed -i "s/${tun}/v${tun}/g" /usr/share/clash/tun_version 2>&1
if [ $lang == "zh_cn" ];then
echo " ${LOGTIME} - ClashTun内核更新成功!" >$LOG_FILE
elif [ $lang == "en" ] || [ $lang == "auto" ];then
echo " ${LOGTIME} - ClashTun Core Update Successful" >>$LOG_FILE
fi
fi
sleep 2
touch /usr/share/clash/core_down_complete >/dev/null 2>&1
sleep 2
rm -rf /var/run/core_update >/dev/null 2>&1
echo "" > /tmp/clash_update.txt >/dev/null 2>&1
else
if [ $lang == "zh_cn" ];then
echo " ${LOGTIME} - 核心程序下载失败,请检查网络或稍后再试!" >$LOG_FILE
elif [ $lang == "en" ] || [ $lang == "auto" ];then
echo " ${LOGTIME} - Core Update Error" >$LOG_FILE
fi
rm -rf /tmp/clash.tar.gz >/dev/null 2>&1
echo "" > /tmp/clash_update.txt >/dev/null 2>&1
fi
if pidof clash >/dev/null; then
if [ $CORETYPE == $CORE ];then
/etc/init.d/clash restart >/dev/null
fi
fi
}
if [ $CORETYPE -eq 1 ] || [ $CORETYPE -eq 3 ] || [ $CORETYPE -eq 4 ]; then
update
fi
@@ -1,48 +0,0 @@
#!/bin/sh
RULE_FILE_NAME="$1"
if [ -z "$(grep ",$RULE_FILE_NAME" /usr/share/clash/create/rule_provider.list 2>/dev/null)" ]; then
DOWNLOAD_PATH=$(grep -F "$RULE_FILE_NAME" /usr/share/clash/create/rule_provider.list |awk -F ',' '{print $3$4}' 2>/dev/null)
else
DOWNLOAD_PATH=$(grep -F ",$RULE_FILE_NAME" /usr/share/clash/create/rule_provider.list |awk -F ',' '{print $3$4}' 2>/dev/null)
fi
RULE_FILE_DIR="/etc/clash/ruleprovider/$RULE_FILE_NAME"
TMP_RULE_DIR="/tmp/$RULE_FILE_NAME"
LOG_FILE="/usr/share/clash/clash.txt"
REAL_LOG="/usr/share/clash/clash_real.txt"
url="https://cdn.jsdelivr.net/gh/$DOWNLOAD_PATH"
behavior=$(grep -F $RULE_FILE_NAME /usr/share/clash/create/rule_provider.list |awk -F ',' '{print $2}' 2>/dev/null)
namee=$(grep -F ",$RULE_FILE_NAME" /usr/share/clash/create/rule_provider.list |awk -F ',' '{print $4}' | awk -F '.' '{print $1}' 2>/dev/null)
path="./ruleprovider/"$RULE_FILE_NAME""
curl -sL --connect-timeout 5 --retry 2 https://cdn.jsdelivr.net/gh/"$DOWNLOAD_PATH" -o "$TMP_RULE_DIR" >/dev/null 2>&1
if [ "$?" -eq "0" ] && [ -s "$TMP_RULE_DIR" ] && [ -z "$(grep "404: Not Found" "$TMP_RULE_DIR")" ]; then
cmp -s $TMP_RULE_DIR $RULE_FILE_DIR
if [ "$?" -ne "0" ]; then
mv $TMP_RULE_DIR $RULE_FILE_DIR >/dev/null 2>&1\
&& rm -rf $TMP_RULE_DIR >/dev/null 2>&1
name=clash
uci_name_tmp=$(uci add $name ruleprovider)
uci_set="uci -q set $name.$uci_name_tmp."
uci_add="uci -q add_list $name.$uci_name_tmp."
${uci_set}type="http"
${uci_set}name="$namee"
${uci_set}path="$path"
${uci_set}behavior="$behavior"
${uci_set}url="$url"
${uci_set}interval="86400"
uci commit clash
return 1
else
rm -rf $TMP_RULE_DIR >/dev/null 2>&1
return 2
fi
else
rm -rf $TMP_RULE_DIR >/dev/null 2>&1
return 0
fi
File diff suppressed because it is too large. Load diff
@@ -1,46 +0,0 @@
#!/bin/sh /etc/rc.common
. /lib/functions.sh
cfg_groups_set()
{
CFG_FILE="/etc/config/clash"
local section="$1"
config_get "name" "$section" "name" ""
config_get "old_name_cfg" "$section" "old_name_cfg" ""
config_get "old_name" "$section" "old_name" ""
if [ -z "$name" ]; then
return
fi
if [ -z "$old_name_cfg" ]; then
uci set clash."$section".old_name_cfg="$name"
uci commit clash
fi
if [ -z "$old_name" ]; then
uci set clash."$section".old_name="$name"
uci commit clash
fi
if [ "$name" != "$old_name_cfg" ] && [ ! -z "$old_name_cfg" ]; then
sed -i "s/old_name_cfg \'${old_name_cfg}\'/old_name_cfg \'${name}\'/g" $CFG_FILE 2>/dev/null
sed -i "s/groups \'${old_name_cfg}/groups \'${name}/g" $CFG_FILE 2>/dev/null
sed -i "s/other_group \'${old_name_cfg}/other_group \'${name}/g" $CFG_FILE 2>/dev/null
sed -i "s/new_servers_group \'${old_name_cfg}/new_servers_group \'${name}/g" $CFG_FILE 2>/dev/null
sed -i "s/relay_groups \'${old_name_cfg}/relay_groups \'${name}/g" $CFG_FILE 2>/dev/null
config_load "clash"
fi
}
start(){
status=$(ps|grep -c /usr/share/clash/create/pgroups.sh)
[ "$status" -gt "3" ] && exit 0
config_load "clash"
config_foreach cfg_groups_set "pgroups"
}
start
@@ -1,76 +0,0 @@
All-4,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,All-4.yaml
BBC-iPlayer,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,BBC-iPlayer.yaml
Bahamut,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,Bahamut.yaml
DAZN,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,DAZN.yaml
DisneyPlus,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,DisneyPlus.yaml
FOX,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,FOX.yaml
HBO-GO-HKG,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,HBO-GO-HKG.yaml
HBO,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,HBO.yaml
HWTV,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,HWTV.yaml
Hulu-JPN,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,Hulu-JPN.yaml
Hulu,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,Hulu.yaml
ITV,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,ITV.yaml
KKTV,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,KKTV.yaml
LINE-TV,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,LINE-TV.yaml
LiTV,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,LiTV.yaml
My5,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,My5.yaml
Netflix,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,Netflix.yaml
Now-E,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,Now-E.yaml
PBS,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,PBS.yaml
Pornhub,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,Pornhub.yaml
Prime-Video,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,Prime-Video.yaml
TaiwanGood,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,TaiwanGood.yaml
TikTok,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,TikTok.yaml
ViuTV,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,ViuTV.yaml
YouTube,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,YouTube.yaml
encoreTVB,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,encoreTVB.yaml
myTV-SUPER,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,myTV-SUPER.yaml
niconico,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Video/,niconico.yaml
Himalaya,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Podcast/,Himalaya.yaml
Deezer,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Music/,Deezer.yaml
Instagram,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Music/,Instagram.yaml
JOOX,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Music/,JOOX.yaml
KKBOX,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Music/,KKBOX.yaml
Pandora,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Music/,Pandora.yaml
SoundCloud,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Music/,SoundCloud.yaml
Spotify,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Music/,Spotify.yaml
TIDAL,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Music/,TIDAL.yaml
Twitch,classical,frainzy1477/clashrules@master/Clash/RuleSet/StreamingMedia/Live/,Twitch.yaml
Advertising,classical,frainzy1477/clashrules@master/Clash/RuleSet/Guard/,Advertising.yaml
Hijacking,classical,frainzy1477/clashrules@master/Clash/RuleSet/Guard/,Hijacking.yaml
Privacy,classical,frainzy1477/clashrules@master/Clash/RuleSet/Guard/,Privacy.yaml
ChinaIP,ipcidr,frainzy1477/clashrules@master/Clash/RuleSet/Extra/,ChinaIP.yaml
IPBlackhole,ipcidr,frainzy1477/clashrules@master/Clash/RuleSet/Extra/,IP-Blackhole.yaml
PayPal,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/,PayPal.yaml
Scholar,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/,Scholar.yaml
AppStore,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Apple/,AppStore.yaml
Apple,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Apple/,Apple.yaml
AppStoreConnect,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Apple/,AppStoreConnect.yaml
Apple-FindMy,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Apple/,FindMy.yaml
Apple-Mail,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Apple/,Mail.yaml
Apple-Music,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Apple/,Music.yaml
Apple-News,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Apple/,News.yaml
Apple-Siri,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Apple/,Siri.yaml
Apple-SoftwareUpdate,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Apple/,SoftwareUpdate.yaml
Apple-TV,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Apple/,TV.yaml
Apple-TestFlight,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Apple/,TestFlight.yaml
Apple-iCloud,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Apple/,iCloud.yaml
Steam,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Game/,Steam.yaml
Blizzard,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Game/,Blizzard.yaml
GoogleDrive,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Google/,GoogleDrive.yaml
GoogleSearch,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Google/,GoogleSearch.yaml
OneDrive,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Microsoft/,OneDrive.yaml
Telegram,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Telegram/,Telegram.yaml
TelegramNL,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Telegram/,TelegramNL.yaml
TelegramSG,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Telegram/,TelegramSG.yaml
TelegramUS,classical,frainzy1477/clashrules@master/Clash/RuleSet/Extra/Telegram/,TelegramUS.yaml
广告(IP合集,ipcidr,frainzy1477/Clash-Ruleset@master/,Reject_IP.yaml
广告(域名合集,domain,frainzy1477/Clash-Ruleset@master/,Reject_Domain.yaml
网易云音乐域名,domain,frainzy1477/Clash-Ruleset@master/,Netease_Music_Domains.yaml
苹果服务合集,domain,frainzy1477/Clash-Ruleset@master/,Apple_Domain.yaml
国外流媒体(IP合集,ipcidr,frainzy1477/Clash-Ruleset@master/,Stream_IP.yaml
国外流媒体(域名合集,domain,frainzy1477/Clash-Ruleset@master/,Stream_Domain.yaml
国外IP代理合集,ipcidr,frainzy1477/Clash-Ruleset@master/,Global_IP.yaml
国外域名代理合集,domain,frainzy1477/Clash-Ruleset@master/,Global_Domain.yaml
国内IP合集,ipcidr,frainzy1477/Clash-Ruleset@master/,Domestic_IP.yaml
国内常用域名,domain,frainzy1477/Clash-Ruleset@master/,Domestic_Domain.yaml
@@ -1,30 +0,0 @@
#!/bin/sh /etc/rc.common
. /lib/functions.sh
rules_set()
{
CFG_FILE="/etc/config/clash"
local section="$1"
config_get "type" "$section" "type" ""
config_get "rulename" "$section" "rulename" ""
config_get "rulenamee" "$section" "rulenamee" ""
if [ -z "$type" ]; then
return
fi
if [ -z "$rulename" ]; then
uci set clash."$section".rulename="$rulenamee"
uci commit clash
fi
}
start(){
config_load "clash"
config_foreach rules_set "rules"
}
start
@@ -1,12 +0,0 @@
script:
code: |
def main(ctx, metadata):
ip = metadata["dst_ip"] = ctx.resolve_ip(metadata["host"])
if ip == "":
return "DIRECT"
code = ctx.geoip(ip)
if code == "LAN" or code == "CN":
return "DIRECT"
return "Proxy" # default policy for requests which are not matched by any other script
@@ -1,11 +0,0 @@
#!/bin/bash /etc/rc.common
. /lib/functions.sh
name=$(uci get clash.config.config_cus_remove 2>/dev/null)
check_match_name=$(grep -F "$name" "/usr/share/clashbackup/create_list.conf")
line_no=$(grep -n "$check_match_name" /usr/share/clashbackup/create_list.conf |awk -F ':' '{print $1}')
if [ ! -z $check_match_name ];then
sed -i "${line_no}d" /usr/share/clashbackup/create_list.conf
rm -rf /usr/share/clash/config/custom/${name}
sed -i '/^$/d' /usr/share/clashbackup/create_list.conf
fi
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

@@ -1 +0,0 @@
<!doctype html><html lang="en" dir="ltr"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><link rel="icon" type="image/x-icon" href="https://cdn.jsdelivr.net/gh/Dreamacro/clash/docs/logo.png"/><title>Clash Dashboard</title><link href="main.658aa6a6e3feec8f168b.css" rel="stylesheet"></head><body><div id="root"></div><script src="js/1.bundle.658aa6a6e3feec8f168b.min.js"></script><script src="js/bundle.658aa6a6e3feec8f168b.min.js"></script></body></html>
@@ -1,2 +0,0 @@
/*! For license information please see 1.bundle.658aa6a6e3feec8f168b.min.js.LICENSE.txt */
(window.webpackJsonp=window.webpackJsonp||[]).push([[1],[function(e,t,n){"use strict";e.exports=n(54)},function(e,t,n){var r;!function(){"use strict";var n={}.hasOwnProperty;function o(){for(var e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var i=typeof r;if("string"===i||"number"===i)e.push(r);else if(Array.isArray(r)&&r.length){var a=o.apply(null,r);a&&e.push(a)}else if("object"===i)for(var u in r)n.call(r,u)&&r[u]&&e.push(u)}}return e.join(" ")}e.exports?(o.default=o,e.exports=o):void 0===(r=function(){return o}.apply(t,[]))||(e.exports=r)}()},function(e,t,n){"use strict";function r(){return(r=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}n.d(t,"a",(function(){return r}))},function(e,t,n){"use strict";function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}n.d(t,"a",(function(){return r}))},,,,function(e,t,n){"use strict";var r=n(40),o=Object.prototype.toString;function i(e){return"[object Array]"===o.call(e)}function a(e){return void 0===e}function u(e){return null!==e&&"object"==typeof e}function l(e){return"[object Function]"===o.call(e)}function s(e,t){if(null!=e)if("object"!=typeof e&&(e=[e]),i(e))for(var n=0,r=e.length;n<r;n++)t.call(null,e[n],n,e);else for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.call(null,e[o],o,e)}e.exports={isArray:i,isArrayBuffer:function(e){return"[object ArrayBuffer]"===o.call(e)},isBuffer:function(e){return null!==e&&!a(e)&&null!==e.constructor&&!a(e.constructor)&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)},isFormData:function(e){return"undefined"!=typeof FormData&&e instanceof FormData},isArrayBufferView:function(e){return"undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&e.buffer instanceof ArrayBuffer},isString:function(e){return"string"==typeof e},isNumber:function(e){return"number"==typeof e},isObject:u,isUndefined:a,isDate:function(e){return"[object Date]"===o.call(e)},isFile:function(e){return"[object File]"===o.call(e)},isBlob:function(e){return"[object Blob]"===o.call(e)},isFunction:l,isStream:function(e){return u(e)&&l(e.pipe)},isURLSearchParams:function(e){return"undefined"!=typeof URLSearchParams&&e instanceof URLSearchParams},isStandardBrowserEnv:function(){return("undefined"==typeof navigator||"ReactNative"!==navigator.product&&"NativeScript"!==navigator.product&&"NS"!==navigator.product)&&("undefined"!=typeof window&&"undefined"!=typeof document)},forEach:s,merge:function e(){var t={};function n(n,r){"object"==typeof t[r]&&"object"==typeof n?t[r]=e(t[r],n):t[r]=n}for(var r=0,o=arguments.length;r<o;r++)s(arguments[r],n);return t},deepMerge:function e(){var t={};function n(n,r){"object"==typeof t[r]&&"object"==typeof n?t[r]=e(t[r],n):t[r]="object"==typeof n?e({},n):n}for(var r=0,o=arguments.length;r<o;r++)s(arguments[r],n);return t},extend:function(e,t,n){return s(t,(function(t,o){e[o]=n&&"function"==typeof t?r(t,n):t})),e},trim:function(e){return e.replace(/^\s*/,"").replace(/\s*$/,"")}}},function(e,t,n){"use strict";function r(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}n.d(t,"a",(function(){return r}))},,,,function(e,t,n){"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(55)},function(e,t){e.exports=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}},function(e,t,n){e.exports=n(58)()},function(e,t,n){"use strict";e.exports=n(62)},function(e,t,n){var r=n(38),o=n(88);e.exports=function(e){return"symbol"==typeof e||o(e)&&"[object Symbol]"==r(e)}},function(e,t,n){var r=n(85),o="object"==typeof self&&self&&self.Object===Object&&self,i=r||o||Function("return this")();e.exports=i},function(e,t,n){var r=n(39)(Object,"create");e.exports=r},function(e,t,n){var r=n(109);e.exports=function(e,t){for(var n=e.length;n--;)if(r(e[n][0],t))return n;return-1}},function(e,t,n){var r=n(115);e.exports=function(e,t){var n=e.__data__;return r(t)?n["string"==typeof t?"string":"hash"]:n.map}},function(e,t,n){"use strict";function r(e){for(var t=arguments.length,n=Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];throw Error("[Immer] minified error nr: "+e+(n.length?" "+n.join(","):"")+". Find the full error at: https://bit.ly/3cXEKWf")}function o(e){return!!e&&!!e[Z]}function i(e){return!!e&&(function(e){if(!e||"object"!=typeof e)return!1;var t=Object.getPrototypeOf(e);return!t||t===Object.prototype}(e)||Array.isArray(e)||!!e[J]||!!e.constructor[J]||p(e)||h(e))}function a(e){return o(e)||r(23,e),e[Z].t}function u(e,t,n){void 0===n&&(n=!1),0===l(e)?(n?Object.keys:te)(e).forEach((function(r){n&&"symbol"==typeof r||t(r,e[r],e)})):e.forEach((functionLine truncated
@@ -1 +0,0 @@
!function(e){function t(t){for(var r,i,u=t[0],l=t[1],s=t[2],f=0,d=[];f<u.length;f++)i=u[f],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&d.push(o[i][0]),o[i]=0;for(r in l)Object.prototype.hasOwnProperty.call(l,r)&&(e[r]=l[r]);for(c&&c(t);d.length;)d.shift()();return a.push.apply(a,s||[]),n()}function n(){for(var e,t=0;t<a.length;t++){for(var n=a[t],r=!0,u=1;u<n.length;u++){var l=n[u];0!==o[l]&&(r=!1)}r&&(a.splice(t--,1),e=i(i.s=n[0]))}return e}var r={},o={0:0},a=[];function i(t){if(r[t])return r[t].exports;var n=r[t]={i:t,l:!1,exports:{}};return e[t].call(n.exports,n,n.exports,i),n.l=!0,n.exports}i.m=e,i.c=r,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)i.d(n,r,function(t){return e[t]}.bind(null,r));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="";var u=window.webpackJsonp=window.webpackJsonp||[],l=u.push.bind(u);u.push=t,u=u.slice();for(var s=0;s<u.length;s++)t(u[s]);var c=l;a.push([52,1]),n()}([,,,,function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){function o(e){return e instanceof n?e:new n((function(t){t(e)}))}return new(n||(n=Promise))((function(n,a){function i(e){try{l(r.next(e))}catch(e){a(e)}}function u(e){try{l(r.throw(e))}catch(e){a(e)}}function l(e){e.done?n(e.value):o(e.value).then(i,u)}l((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){function n(e){return function(t){return r([e,t])}}function r(n){if(o)throw new TypeError("Generator is already executing.");for(;l;)try{if(o=1,a&&(i=2&n[0]?a.return:n[0]?a.throw||((i=a.return)&&i.call(a),0):a.next)&&!(i=i.call(a,n[1])).done)return i;switch(a=0,i&&(n=[2&n[0],i.value]),n[0]){case 0:case 1:i=n;break;case 4:return l.label++,{value:n[1],done:!1};case 5:l.label++,a=n[1],n=[0];continue;case 7:n=l.ops.pop(),l.trys.pop();continue;default:if(!(i=l.trys,(i=0<i.length&&i[i.length-1])||6!==n[0]&&2!==n[0])){l=0;continue}if(3===n[0]&&(!i||n[1]>i[0]&&n[1]<i[3])){l.label=n[1];break}if(6===n[0]&&l.label<i[1]){l.label=i[1],i=n;break}if(i&&l.label<i[2]){l.label=i[2],l.ops.push(n);break}i[2]&&l.ops.pop(),l.trys.pop();continue}n=t.call(e,l)}catch(e){n=[6,e],a=0}finally{o=i=0}if(5&n[0])throw n[1];return{value:n[0]?n[1]:void 0,done:!0}}var o,a,i,u,l={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return u={next:n(0),throw:n(1),return:n(2)},"function"==typeof Symbol&&(u[Symbol.iterator]=function(){return this}),u},a=this&&this.__values||function(e){var t="function"==typeof Symbol&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")};Object.defineProperty(t,"__esModule",{value:!0}),t.partition=t.to=t.noop=t.removeLocalStorageItem=t.setLocalStorageItem=t.getLocalStorageItem=void 0,t.getLocalStorageItem=function(e,t){return void 0===t&&(t=""),window.localStorage.getItem(e)||t},t.setLocalStorageItem=function(e,t){return window.localStorage.setItem(e,t)},t.removeLocalStorageItem=function(e){return window.localStorage.removeItem(e)},t.noop=function(){},t.to=function(e){return r(this,void 0,void 0,(function(){return o(this,(function(t){switch(t.label){case 0:return t.trys.push([0,2,,3]),[4,e];case 1:return[2,[t.sent(),null]];case 2:return[2,[null,t.sent()]];case 3:return[2]}}))}))},t.partition=function(e,t){var n,r,o=[],i=[];try{for(var u,l=a(e),s=l.next();!s.done;s=l.next())t(u=s.value)?o.push(u):i.push(u)}catch(e){n={error:e}}finally{try{s&&!s.done&&(r=l.return)&&r.call(l)}finally{if(n)throw n.error}}return[o,i]}},function(e,t,n){"use strict";var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),o=this&&this.__exportStar||function(e,t){for(var n in e)"default"==n||t.hasOwnProperty(n)||r(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),o(n(67),t),o(n(69),t),o(n(70),t),o(n(72),t),o(n(74),t),o(n(76),t),o(n(77),t),o(n(79),t),o(n(151),t),o(n(153),t),o(n(155),t),o(n(157),t),o(n(159),t),o(n(161),t),o(n(163),t),o(n(165),t),o(n(167),t)},function(e,t,n){"use strict";var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),o=this&&tLine truncated
@@ -1,28 +0,0 @@
@font-face{font-family:"clash-iconfont";src:url("//at.alicdn.com/t/font_841708_ok9czskbhel.ttf?t=1576162884356") format("truetype")}.clash-iconfont{font-family:"clash-iconfont" !important;font-size:14px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:#2c8af8}.icon-update::before{content:""}.icon-healthcheck::before{content:""}.icon-speed::before{content:""}.icon-close::before{content:""}.icon-drag::before{content:""}.icon-down-arrow-o::before{content:""}.icon-check::before{content:""}.icon-plus::before{content:""}.icon-triangle-up::before{content:""}.icon-triangle-down::before{content:""}.icon-up-arrow-o::before{content:""}.icon-info::before{content:""}.icon-info-o::before{content:""}.icon-setting::before{content:""}.icon-show::before{content:""}.icon-hide::before{content:""}.icon-sort::before{content:""}.icon-sort-descending::before{content:""}.icon-sort-ascending::before{content:""}.icon-close-all::before{content:""}html{box-sizing:border-box;background:rgba(255,255,255,.8)}*,*::before,*::after{margin:0;padding:0;box-sizing:inherit}body{margin:0;padding:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"}body ::-webkit-scrollbar{z-index:11;background:transparent}body ::-webkit-scrollbar-thumb{border-radius:5px;background:#2c8af8}body ::-webkit-scrollbar:vertical{width:6px}body ::-webkit-scrollbar:horizontal{height:6px}.app{min-height:100vh;padding-left:150px}.app.not-clashx{background:#f4f5f6}.page-container{width:100%;height:100vh;padding-left:10px;overflow-y:scroll}.page{padding:20px 35px 30px 20px;width:100%;min-height:100vh;margin:0 auto;display:flex;flex-direction:column}.container{margin:20px 0}input{-webkit-appearance:none}@media(max-width: 768px){.app{padding-left:0;padding-top:60px}.page-container{width:100%;padding:0 10px;height:calc(100vh - 60px);-webkit-overflow-scrolling:touch}.page-container::-webkit-scrollbar{display:none}.page{padding:0 0 20px;height:100%}}
.header{margin:10px 0;width:100%;display:flex;flex-direction:row;align-items:center;justify-content:space-between;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.header>h1{flex-shrink:0;font-size:24px;color:#2c8af8;font-weight:500;text-shadow:0 2px 6px rgba(44,138,248,.4);line-height:32px}.operations{display:flex;flex:1;align-items:center;justify-content:flex-end}@media(max-width: 768px){.header>h1{font-size:20px}}
.switch{display:inline-block;width:32px;height:16px;border-radius:8px;background-color:#d8dee2;transition:background-color .3s ease;position:relative;cursor:pointer}.switch.checked{background-color:#57befc}.switch.checked::after{transform:translateX(16px)}.switch.disabled{cursor:not-allowed;background-color:#b7c5d6}.switch.disabled::after{background-color:#e4eaef;box-shadow:0 0 8px rgba(144,147,153,.5)}.switch.checked.disabled{background-color:#e4eaef}.switch::after{content:"";position:absolute;top:-1px;height:18px;width:18px;border-radius:9px;background-color:#fff;box-shadow:0 0 8px rgba(44,138,248,.4);transition:transform .3s ease;transform:translateX(-2px)}.switch-icon{position:absolute;transform:translateX(-1px) scale(0.4);color:#fff;line-height:16px}
.card{padding:15px;box-shadow:2px 5px 20px -3px rgba(44,138,248,.18);background-color:#fff;border-radius:4px}
.row{width:100%;display:flex;flex-direction:row}.row-gutter-1{padding:12px 6px}.row-gutter-1 .column{padding:0 6px;display:flex;flex-shrink:0}.row-gutter-1 .column-span-1{width:100%}.row-gutter-1 .column-offset-1{margin-left:100%}.row-gutter-1 .column-span-2{width:200%}.row-gutter-1 .column-offset-2{margin-left:200%}.row-gutter-1 .column-span-3{width:300%}.row-gutter-1 .column-offset-3{margin-left:300%}.row-gutter-1 .column-span-4{width:400%}.row-gutter-1 .column-offset-4{margin-left:400%}.row-gutter-1 .column-span-5{width:500%}.row-gutter-1 .column-offset-5{margin-left:500%}.row-gutter-1 .column-span-6{width:600%}.row-gutter-1 .column-offset-6{margin-left:600%}.row-gutter-1 .column-span-7{width:700%}.row-gutter-1 .column-offset-7{margin-left:700%}.row-gutter-1 .column-span-8{width:800%}.row-gutter-1 .column-offset-8{margin-left:800%}.row-gutter-1 .column-span-9{width:900%}.row-gutter-1 .column-offset-9{margin-left:900%}.row-gutter-1 .column-span-10{width:1000%}.row-gutter-1 .column-offset-10{margin-left:1000%}.row-gutter-1 .column-span-11{width:1100%}.row-gutter-1 .column-offset-11{margin-left:1100%}.row-gutter-1 .column-span-12{width:1200%}.row-gutter-1 .column-offset-12{margin-left:1200%}.row-gutter-1 .column-span-13{width:1300%}.row-gutter-1 .column-offset-13{margin-left:1300%}.row-gutter-1 .column-span-14{width:1400%}.row-gutter-1 .column-offset-14{margin-left:1400%}.row-gutter-1 .column-span-15{width:1500%}.row-gutter-1 .column-offset-15{margin-left:1500%}.row-gutter-1 .column-span-16{width:1600%}.row-gutter-1 .column-offset-16{margin-left:1600%}.row-gutter-1 .column-span-17{width:1700%}.row-gutter-1 .column-offset-17{margin-left:1700%}.row-gutter-1 .column-span-18{width:1800%}.row-gutter-1 .column-offset-18{margin-left:1800%}.row-gutter-1 .column-span-19{width:1900%}.row-gutter-1 .column-offset-19{margin-left:1900%}.row-gutter-1 .column-span-20{width:2000%}.row-gutter-1 .column-offset-20{margin-left:2000%}.row-gutter-1 .column-span-21{width:2100%}.row-gutter-1 .column-offset-21{margin-left:2100%}.row-gutter-1 .column-span-22{width:2200%}.row-gutter-1 .column-offset-22{margin-left:2200%}.row-gutter-1 .column-span-23{width:2300%}.row-gutter-1 .column-offset-23{margin-left:2300%}.row-gutter-1 .column-span-24{width:2400%}.row-gutter-1 .column-offset-24{margin-left:2400%}.row-gutter-2{padding:12px 6px}.row-gutter-2 .column{padding:0 6px;display:flex;flex-shrink:0}.row-gutter-2 .column-span-1{width:50%}.row-gutter-2 .column-offset-1{margin-left:50%}.row-gutter-2 .column-span-2{width:100%}.row-gutter-2 .column-offset-2{margin-left:100%}.row-gutter-2 .column-span-3{width:150%}.row-gutter-2 .column-offset-3{margin-left:150%}.row-gutter-2 .column-span-4{width:200%}.row-gutter-2 .column-offset-4{margin-left:200%}.row-gutter-2 .column-span-5{width:250%}.row-gutter-2 .column-offset-5{margin-left:250%}.row-gutter-2 .column-span-6{width:300%}.row-gutter-2 .column-offset-6{margin-left:300%}.row-gutter-2 .column-span-7{width:350%}.row-gutter-2 .column-offset-7{margin-left:350%}.row-gutter-2 .column-span-8{width:400%}.row-gutter-2 .column-offset-8{margin-left:400%}.row-gutter-2 .column-span-9{width:450%}.row-gutter-2 .column-offset-9{margin-left:450%}.row-gutter-2 .column-span-10{width:500%}.row-gutter-2 .column-offset-10{margin-left:500%}.row-gutter-2 .column-span-11{width:550%}.row-gutter-2 .column-offset-11{margin-left:550%}.row-gutter-2 .column-span-12{width:600%}.row-gutter-2 .column-offset-12{margin-left:600%}.row-gutter-2 .column-span-13{width:650%}.row-gutter-2 .column-offset-13{margin-left:650%}.row-gutter-2 .column-span-14{width:700%}.row-gutter-2 .column-offset-14{margin-left:700%}.row-gutter-2 .column-span-15{width:750%}.row-gutter-2 .column-offset-15{margin-left:750%}.row-gutter-2 .column-span-16{width:800%}.row-gutter-2 .column-offset-16{margin-left:800%}.row-gutter-2 .column-span-17{width:850%}.row-gutter-2 .column-offset-17{margin-left:850%}.row-gutter-2 .column-span-18{width:900%}.row-gutter-2 .column-offset-18{margin-left:900%}.row-gutter-2 .column-span-19{width:950%}.row-gutter-2 .column-offset-19{margin-left:950%}.row-gutter-2 .column-span-20{width:1000%}.row-gutter-2 .column-offset-20{margin-left:1000%}.row-gutter-2 .column-span-21{width:1050%}.row-gutter-2 .column-offset-21{margin-left:1050%}.row-gutter-2 .column-span-22{width:1100%}.row-gutter-2 .column-offset-22{margin-left:1100%}.row-gutter-2 .column-span-23{width:1150%}.row-gutter-2 .column-offset-23{margin-left:1150%}.row-gutter-2 .column-span-24{width:1200%}.row-gutter-2 .column-offset-24{margin-left:1200%}.row-gutter-3{padding:12px 6px}.row-gutter-3 .column{padding:0 6px;display:flex;flex-shrink:0}.row-gutter-3 .column-span-1{width:33.3333333333%}.row-gutter-3 .column-offset-1{margin-left:33.3333333333%}.row-gutter-3 .column-span-2{width:66.6666666667%}.row-gutter-3 .column-offset-2{margin-left:66.6666666667%}.row-gutter-3 .column-span-3{width:100%}.row-gutter-3 .column-offset-3{margin-left:100%}.row-gutter-3 .column-span-4{width:133.3333Line truncated
.button-select{display:flex;flex-direction:row}.button-select .button-select-options{height:30px;padding:0 15px;color:#54759a;font-size:12px;line-height:30px;background:#fff;border:1px solid #e4eaef;border-right:none;transition:all 300ms ease;cursor:pointer;outline:0;display:block}.button-select .button-select-options:first-child{border-radius:3px 0 0 3px}.button-select .button-select-options:last-child{border-radius:0 3px 3px 0;border-right:1px solid #e4eaef}.button-select .button-select-options.actived{background:#57befc;color:#fff;border-color:#57befc;box-shadow:0 2px 5px rgba(87,190,252,.5)}.button-select .button-select-options.actived:active{box-shadow:none}
.tags-container{display:flex;align-items:flex-start;overflow-y:hidden}.tags{display:flex;flex:1;align-items:center;list-style:none;flex-wrap:wrap;box-sizing:content-box}.tags li{position:relative;display:flex;align-items:center;justify-content:center;border:1px solid #2c8af8;color:#54759a;height:22px;border-radius:11px;padding:0 6px;margin:3px 4px;font-size:10px;cursor:default}.tags li.can-click{cursor:pointer}.tags li.error{color:#fff;background-color:#f56c6c;border-color:#f56c6c}.tags li.tags-selected.error{background:linear-gradient(135deg, #2c8af8, #f56c6c);border:none;height:24px;padding:0 7px}.tags .tags-selected{background-color:#2c8af8;color:#fff}.tags-expand{height:30px;line-height:30px;padding:0 20px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer}
.input{display:inline-block;height:30px;width:100%;padding:0 10px;font-size:14px;color:#54759a;border-radius:3px;border:1px solid #e4eaef;transition:all .3s;transition-property:border-color,color,box-shadow}.input:focus{outline:0;border-color:#57befc;color:#2c8af8;box-shadow:0 2px 5px rgba(87,190,252,.5)}.input-align-left{text-align:left}.input-align-center{text-align:center}.input-align-right{text-align:right}.input-inside:focus{box-shadow:none}
.select{cursor:pointer;font-size:14px;line-height:30px;color:#54759a;display:flex;overflow:hidden}.select>i{margin-left:5px;color:#54759a}.select-list{position:absolute;max-width:170px;border-radius:4px;overflow:hidden;box-shadow:0 2px 5px rgba(183,197,214,.5);opacity:.8;pointer-events:none;transform:scaleY(0);transform-origin:top;transition:all 200ms linear}.select-list .list{max-height:300px;overflow:auto;background:#fff;padding:5px 0;transform:scaleY(2);transform-origin:top;transition:all 200ms linear}.select-list .list>.option{color:#54759a;padding:10px 15px;font-size:14px;list-style:none;cursor:pointer}.select-list .list>.option:hover{background:rgba(228,234,239,.5)}.select-list .list>.selected{background:rgba(228,234,239,.5)}.select-list-show{opacity:1;pointer-events:visible;transform:scaleY(1)}.select-list-show .list{transform:scaleY(1)}
.modal-mask{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.15);opacity:0;pointer-events:none;transition:all 500ms ease;display:flex;justify-content:center;align-items:center;z-index:11}.modal-mask .modal{margin-top:-50px;padding:20px 30px;background:#fff;box-shadow:0 2px 16px rgba(84,117,154,.2);border-radius:4px;display:flex;flex-direction:column;transform:scale(0);transition:all 300ms cubic-bezier(0.32, 0.26, 0.71, 1.29)}.modal-mask .modal .modal-title{margin:5px 0;width:100%;display:flex;align-items:center;justify-content:space-between;font-weight:bold;font-size:18px;color:#2c8af8;text-shadow:0 2px 6px rgba(44,138,248,.4)}.modal-mask .modal .modal-body{margin:10px 0;font-size:14px;color:#54759a}.modal-mask .modal .footer{width:100%;margin:5px 0;display:flex;align-items:center;justify-content:flex-end}.modal-mask .modal .footer .button{margin-left:10px}.modal-mask .modal-small{width:400px}.modal-mask .modal-big{width:600px}.modal-show{opacity:1;pointer-events:visible}.modal-show .modal{transform:scale(1)}@media(max-width: 768px){.modal-mask .modal{margin-top:0;padding:18px 20px}.modal-mask .modal-small{width:280px}.modal-mask .modal-big{width:480px}}
.alert{padding:15px;background:#fff;border-radius:4px;box-shadow:0 2px 8px rgba(44,138,248,.3);font-size:13px;line-height:1.6;text-align:justify;display:flex}.alert .alert-icon{margin-right:10px;width:20px;height:20px;border-radius:50%;flex-shrink:0;display:flex;justify-content:center;align-items:center;background:#fff}.alert .alert-icon>i{transform:scale(0.5);font-weight:bold}.alert .alert-message{width:100%;color:#fff}.alert-box-success{background:linear-gradient(135deg, #5dae34, #67c23a);box-shadow:0 2px 8px rgba(93,174,52,.3)}.alert-box-success .alert-icon>i{color:#67c23a}.alert-box-info{background:linear-gradient(135deg, #3eb4fc, #57befc);box-shadow:0 2px 8px rgba(62,180,252,.3)}.alert-box-info .alert-icon>i{color:#57befc}.alert-box-warning{background:linear-gradient(135deg, #e39725, #e6a23c);box-shadow:0 2px 8px rgba(227,151,37,.3)}.alert-box-warning .alert-icon>i{color:#e6a23c}.alert-box-error{background:linear-gradient(135deg, #f35454, #f56c6c);box-shadow:0 2px 8px rgba(243,84,84,.3)}.alert-box-error .alert-icon>i{color:#f56c6c}.alert-note-success{background:rgba(103,194,58,.05);border-radius:1px 4px 4px 1px;border-left:2px solid #67c23a;box-shadow:0 2px 8px rgba(93,174,52,.3)}.alert-note-success .alert-icon{background:#67c23a}.alert-note-success .alert-icon>i{color:#fff}.alert-note-success .alert-message{color:#3d7323}.alert-note-info{background:rgba(87,190,252,.05);border-radius:1px 4px 4px 1px;border-left:2px solid #57befc;box-shadow:0 2px 8px rgba(62,180,252,.3)}.alert-note-info .alert-icon{background:#57befc}.alert-note-info .alert-icon>i{color:#fff}.alert-note-info .alert-message{color:#0493e9}.alert-note-warning{background:rgba(230,162,60,.05);border-radius:1px 4px 4px 1px;border-left:2px solid #e6a23c;box-shadow:0 2px 8px rgba(227,151,37,.3)}.alert-note-warning .alert-icon{background:#e6a23c}.alert-note-warning .alert-icon>i{color:#fff}.alert-note-warning .alert-message{color:#a76d15}.alert-note-error{background:rgba(245,108,108,.05);border-radius:1px 4px 4px 1px;border-left:2px solid #f56c6c;box-shadow:0 2px 8px rgba(243,84,84,.3)}.alert-note-error .alert-icon{background:#f56c6c}.alert-note-error .alert-icon>i{color:#fff}.alert-note-error .alert-message{color:#eb1010}
.button{outline:0;padding:0 15px;height:32px;line-height:32px;border-radius:16px;font-size:14px;cursor:pointer;transition:all 150ms ease}.button-primary{color:#fff;border:none;background:linear-gradient(135deg, #57befc, #2c8af8);box-shadow:0 2px 8px rgba(44,138,248,.5)}.button-primary:hover{border:none}.button-primary:active{box-shadow:0 0 2px rgba(44,138,248,.5)}.button-normal{color:#909399;background:#fff;border:1px solid rgba(0,0,0,.1)}.button-normal:hover{border-color:#b7c5d6;color:#54759a}.button-normal:active{background:#fafafa;color:#54759a}.button-danger{color:#fff;border:none;background:linear-gradient(135deg, #f56c6c, #f23c3c);box-shadow:0 2px 8px rgba(242,60,60,.5)}.button-danger:hover{border:none}.button-danger:active{box-shadow:0 0 2px rgba(242,60,60,.5)}.button-success{color:#fff;border:none;background:linear-gradient(135deg, #67c23a, #5dae34);box-shadow:0 2px 8px rgba(93,174,52,.5)}.button-success:hover{border:none}.button-success:active{box-shadow:0 0 2px rgba(93,174,52,.5)}.button-warning{color:#fff;border:none;background:linear-gradient(135deg, #e6a23c, #e39725);box-shadow:0 2px 8px rgba(227,151,37,.5)}.button-warning:hover{border:none}.button-warning:active{box-shadow:0 0 2px rgba(227,151,37,.5)}
.message{position:fixed;top:20px;right:20px;border-radius:4px;opacity:0;background:#fff;display:flex;box-shadow:0 0 20px rgba(44,138,248,.2);transition:all 200ms ease;transform:translateX(100%)}.message .message-icon{width:36px;flex:1;border-radius:4px 0 0 4px;display:flex;justify-content:center;align-items:center}.message .message-icon>i{color:#fff}.message .message-content{padding:10px 15px;font-size:13px;color:#54759a}.message-info .message-icon{background:linear-gradient(135deg, #57befc, #2c8af8)}.message-success .message-icon{background:linear-gradient(135deg, #67c23a, #5dae34)}.message-warning .message-icon{background:linear-gradient(135deg, #e6a23c, #e39725)}.message-error .message-icon{background:linear-gradient(135deg, #f56c6c, #f23c3c)}.message-show{opacity:1;transition:all 200ms ease;transform:translateX(0)}
.checkbox{display:flex;position:relative;padding-left:26px;cursor:pointer;line-height:18px}.checkbox::before{content:"";display:inline-block;position:absolute;left:0;top:50%;width:18px;height:18px;border-radius:3px;transition:background-color .3s ease;transform:translateY(-9px);background-color:#fff;border:1px solid #e4eaef}.checkbox.checked::before{background-color:#57befc}.checkbox-icon{position:absolute;left:0;top:50%;color:#fff;line-height:18px;transform:translateY(-9px) scale(0.6);text-shadow:none;font-weight:bold}
.tag{display:flex;align-items:center;justify-content:center;height:24px;font-size:12px;padding:0 12px;text-align:center;background-color:#fff;border:2px solid #2c8af8;color:#2c8af8;border-radius:12px}
.spinner{position:relative;width:80px;height:80px;border-radius:100%;-webkit-animation:spinner 5s infinite linear;animation:spinner 5s infinite linear}.spinner-circle{position:absolute;width:100%;height:100%;transform-origin:48% 48%}.spinner-inner{width:100%;height:100%;border-radius:100%;border:5px solid rgba(44,138,248,.7);border-right:none;border-top:none;background-clip:padding-box;box-shadow:inset 0 0 10px rgba(44,138,248,.15)}@-webkit-keyframes spinner{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}@keyframes spinner{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}.spinner-circle:nth-of-type(0){transform:rotate(0deg)}.spinner-circle:nth-of-type(0) .spinner-inner{-webkit-animation:spinner 2s infinite linear;animation:spinner 2s infinite linear}.spinner-circle:nth-of-type(1){transform:rotate(70deg)}.spinner-circle:nth-of-type(1) .spinner-inner{-webkit-animation:spinner 2s infinite linear;animation:spinner 2s infinite linear}.spinner-circle:nth-of-type(2){transform:rotate(140deg)}.spinner-circle:nth-of-type(2) .spinner-inner{-webkit-animation:spinner 2s infinite linear;animation:spinner 2s infinite linear}
.loading{position:absolute;display:flex;align-items:center;justify-content:center;top:0;left:0;bottom:0;right:0;background-color:rgba(255,255,255,.9);box-shadow:inset 0 0 80px rgba(0,0,0,.1);z-index:1000}
.proxy-item{position:relative;width:100%;height:110px;padding:10px;border-radius:4px;background:#fff;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default;box-shadow:2px 5px 20px -3px rgba(44,138,248,.2);transition:all 300ms ease}.proxy-item .proxy-type{padding:2px 5px;font-size:10px;color:#fff;border-radius:2px}.proxy-item .proxy-name{display:-webkit-box;margin-top:10px;color:#54759a;font-size:10px;overflow:hidden;word-break:break-word;-webkit-line-clamp:2;-webkit-box-orient:vertical}.proxy-item .proxy-delay{position:absolute;left:10px;bottom:13px;font-size:10px;color:rgba(84,117,154,.8)}.proxy-item .proxy-editor{position:absolute;right:10px;bottom:10px;cursor:pointer;color:rgba(84,117,154,.8);opacity:0;pointer-events:none;transition:all 300ms ease}.proxy-item:hover{box-shadow:0 14px 20px -4px rgba(84,117,154,.4)}.proxy-item:hover .proxy-editor{opacity:1;pointer-events:visible}.proxy-error{opacity:.5}.proxy-error .proxy-type{background-color:#909399}@media(max-width: 768px){.proxy-item{height:70px}.proxy-item .proxy-delay{left:unset;bottom:unset;top:0;right:20px;height:70px;line-height:70px}}
.proxy-group{display:flex;align-items:flex-start;font-size:14px;color:#546b87}.proxy-group-part{display:flex;align-items:center;height:60px}.proxy-group-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:0 20px;width:120px;height:18px}.proxies-group-card{padding:0}.proxies-group-item{border-bottom:1px solid #d8dee2}.proxies-group-item:last-child{border-bottom:none}.proxy-group-tags-container{padding:15px 0}.proxy-group-tags{flex:1;margin-left:30px}@media(max-width: 768px){.proxy-group{flex-direction:column}.proxy-group-name{width:140px}.proxy-group-part{width:100%;height:42px;margin-top:6px;justify-content:space-between}.proxy-group-type{margin-right:20px}.proxy-group-tags-container{padding:5px 0 10px}.proxy-group-tags{margin-left:20px}}
.proxy-provider{position:relative;display:flex;flex-direction:column;font-size:16px;padding:20px;color:#546b87}.proxy-provider-header{display:flex;align-items:center;justify-content:space-between}.proxy-provider-header-part{display:flex;align-items:center}.proxy-provider-name{margin-right:24px}.proxy-provider-proxies{list-style:none}.proxy-provider-item{box-shadow:0 0 24px 0 rgba(44,138,248,.2)}.proxy-provider-item:hover{box-shadow:0 0 24px 0 rgba(84,117,154,.4)}.proxy-provider-update{line-height:14px;font-size:14px}.proxy-provider-icon{margin-left:20px;cursor:pointer}.proxy-provider-icon.healthcheck{color:#f56c6c}@media(max-width: 768px){.proxy-provider-header{flex-direction:column;align-items:flex-start}.proxy-provider-header-part{margin:6px 0}}
.proxies-list{--item-width: calc(100% / (var(--columns) + 1));--gap: calc(var(--item-width) / var(--columns));display:flex;margin-right:calc(-1 * var(--gap));margin-top:20px;flex-wrap:wrap;align-content:flex-start;list-style:none}@media(min-width: 2001px){.proxies-list{--columns: 12}}@media(max-width: 2000px){.proxies-list{--columns: 10}}@media(max-width: 1600px){.proxies-list{--columns: 8}}@media(max-width: 1340px){.proxies-list{--columns: 7}}@media(max-width: 960px){.proxies-list{--columns: 6}}@media(max-width: 860px){.proxies-list{--columns: 5}}@media(max-width: 760px){.proxies-list{--columns: 3}}.proxies-list>li{display:inline-block;width:var(--item-width);margin-right:var(--gap);flex-shrink:0;margin-bottom:10px}.proxies-group-list{list-style:none}.proxies-group-card{margin:20px 0}.proxies-container .proxies-action-icon{margin-left:10px}.proxies-speed-test{line-height:32px;margin:0 2px 0 6px;color:#2c8af8;text-shadow:0 2px 6px rgba(44,138,248,.4);cursor:pointer}.proxies-providers-item{margin:20px 0}.proxies-providers-list{list-style:none}@media(max-width: 768px){.proxies-group-card{margin:12px 0}.proxies-list{margin-right:0;padding-bottom:20px;flex-wrap:unset;flex-direction:column}.proxies-list>li{width:100%;margin-right:0;margin-bottom:10px}}
.logs-card{display:flex;flex-direction:column;flex:1;margin-top:10px}.logs-panel{display:flex;flex-direction:column;flex-grow:1;flex-basis:0;list-style:none;padding:10px;border-radius:2px;background-color:#f3f6f9;font-size:12px;color:#73808f;overflow-y:auto;font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace}.logs-panel li{line-height:20px;display:inline-block}.logs-panel-time{margin-right:10px;color:#adb7c3}
.rule-provider{position:relative;display:flex;flex-direction:column;font-size:16px;padding:20px;color:#546b87}.rule-provider-header{display:flex;align-items:center;justify-content:space-between}.rule-provider-header-part{display:flex;align-items:center}.rule-provider-name{width:120px;margin-right:6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rule-provider-behavior{width:80px;margin:0 20px 0 12px;background-color:#2c8af8;color:#fff}.rule-provider-spinner{transform:scale(0.4)}.rule-provider-proxies{list-style:none}.rule-provider-item{box-shadow:0 0 24px 0 rgba(44,138,248,.2)}.rule-provider-item:hover{box-shadow:0 0 24px 0 rgba(84,117,154,.4)}.rule-provider-update{line-height:14px;font-size:14px}.rule-provider-icon{display:block;margin-left:20px;cursor:pointer}.rule-provider-icon.rule-provider-loading::before{color:#909399;cursor:not-allowed;-webkit-animation:spinner 2s infinite linear;animation:spinner 2s infinite linear}@media(max-width: 768px){.rule-provider-header{flex-direction:column;align-items:flex-start}.rule-provider-header-part{margin:6px 0}}
.rules-card{display:flex;flex-direction:column;flex:1;min-height:700px;margin-top:10px;padding:0}.rules-card:focus{outline:none}.rules-card .rules{flex:1 0 auto}.rule-item{line-height:30px;padding:5px 0;height:50px;overflow:hidden;list-style:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-bottom:1px solid rgba(228,234,239,.5)}.rule-item .rule-item-row{padding:5px 0}.rule-item .drag-handler{cursor:row-resize;margin:0 10px;display:flex;justify-content:center}.rule-item .drag-handler>i{font-weight:bold;color:#b7c5d6}.rule-item .rule-type{font-size:14px;color:#54759a}.rule-item .rule-type>i{margin-left:5px;color:#54759a}.rule-item .payload{font-size:14px;color:#54759a;cursor:pointer}.rule-item .rule-proxy{font-size:14px;color:#54759a}.rule-item .delete-btn{opacity:0;transition:all 300ms ease}.rule-item .delete-btn span{font-size:14px;color:#f56c6c;cursor:pointer}.rule-item:last-child{border-bottom:none}.rule-item:hover .delete-btn{opacity:1}.rule-proxy-option{display:flex;align-items:center;overflow:hidden}.rule-proxy-option .label{margin-right:5px;height:20px;line-height:20px;padding:0 8px;font-size:10px;border-radius:10px;color:#fff;background:#b7c5d6}.rule-proxy-option .value{line-height:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.settings-card{margin-top:10px;padding:20px 0}.settings-card .column{font-weight:bold;align-items:center}.settings-card .value-column{justify-content:flex-end}.settings-card .label{font-size:14px;color:#54759a}.settings-card .external-controller{font-size:14px;color:#54759a;display:flex;justify-content:flex-end;font-weight:normal;line-height:17px}.settings-card .external-controller .modify-btn{color:#2c8af8;cursor:pointer}.clash-version{position:relative;margin-top:10px;padding:20px 45px;display:flex}.clash-version .check-icon{width:24px;height:24px;border-radius:50%;background:linear-gradient(135deg, #57befc, #2c8af8);display:flex;justify-content:center;align-items:center}.clash-version .check-icon>i{transform:scale(0.5);color:#fff;font-weight:bold}.clash-version .version-info{margin-left:10px;font-size:14px;line-height:24px;color:#54759a}.clash-version .check-update-btn{position:absolute;right:45px;font-size:14px;line-height:24px;color:#b7c5d6;cursor:pointer;transition:all 150ms ease}.clash-version .check-update-btn:hover{color:#54759a}@media(max-width: 768px){.settings-card .row{flex-direction:column;padding-top:0;padding-bottom:0}.settings-card .row>.column{width:100%;margin:10px 0}}
.sidebar{position:fixed;top:0;bottom:0;left:0;display:flex;flex-direction:column;align-items:center;flex-shrink:0;width:160px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.sidebar-logo{margin-top:50px;width:60px;height:60px}.sidebar-menu{display:flex;flex-direction:column;flex:1;margin-top:12px}.sidebar-menu .item{display:block;margin-top:18px}.sidebar-menu .item>a{display:block;width:120px;height:36px;line-height:36px;font-size:14px;border-radius:18px;text-align:center}.sidebar-menu .item>a,.sidebar-menu .item a:active,.sidebar-menu .item a:visited{color:#909399;text-decoration:none}.sidebar-menu .item>a.active{background:linear-gradient(135deg, #57befc, #2c8af8);color:#fff;box-shadow:0 2px 8px rgba(44,138,248,.5)}.sidebar-version{display:flex;flex-direction:column;align-items:center;padding-bottom:20px}.sidebar-version-label{font-size:14px;color:#2c8af8;text-shadow:0 2px 6px rgba(44,138,248,.4)}.sidebar-version-text{text-align:center;font-size:14px;margin:8px 0;padding:0 10px;color:#54759a}@media(max-width: 768px){.sidebar{width:100%;height:60px;flex-direction:row;background:#f4f5f6;z-index:10}.sidebar-logo{margin:0 15px;width:36px;height:36px}.sidebar-menu{flex:1;flex-direction:row;justify-content:center;margin-top:0;overflow-x:scroll;padding:10px}.sidebar-menu::-webkit-scrollbar{display:none}.sidebar-menu .item{margin:0 3px}.sidebar-menu .item>a{width:80px;height:32px;line-height:32px}.sidebar-menu .item.no-mobile{display:none}.sidebar-version{display:none}}
.connections-card{display:flex;flex-direction:column;flex:1;margin-top:10px;padding:0;overflow:hidden}.connections-card .connections{display:flex;flex-direction:column;width:100%;flex-grow:1;flex-basis:0;overflow:auto}.connections-card .connections-body{flex:1 0 auto}.connections-card .connections-th{position:relative;text-align:center;color:#909399;background:#f3f6f9;height:30px;line-height:30px;font-weight:500;font-size:14px;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.connections-card .connections-resizer{position:absolute;opacity:0;right:-10px;top:8px;bottom:8px;width:20px;transition:opacity .3s ease;z-index:10;font-size:14px;font-weight:300}.connections-card .connections-resizer::before{content:"";display:block;position:absolute;left:10px;transform:translateX(-2px);width:2px;height:100%;background-color:rgba(144,147,153,.6)}.connections-card .connections-header{position:-webkit-sticky;position:sticky;top:0;white-space:nowrap}.connections-card .connections-header:hover .connections-resizer{opacity:1}.connections-card .connetions-item{height:36px}.connections-card .connections-block{display:flex;align-items:center;font-size:14px;line-height:36px;padding:0 10px;color:#54759a;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.connections-card .connections-block.center{text-align:center}.connections-card .connections-block.completed{background-color:#e9eef4;color:rgba(84,117,154,.5)}.connections-filter{color:#2c8af8;font-size:14px;line-height:20px;margin-left:15px;text-shadow:0 0 6px rgba(44,138,248,.4);cursor:pointer}.connections-filter.dangerous{color:#f56c6c;text-shadow:0 0 6px rgba(87,190,252,.2)}.connections-filter.total{flex:1;cursor:unset}
.external-controller .row{padding:0}.external-controller .alert{margin:10px 0}.external-controller .title,.external-controller .form{margin:15px 0}.external-controller .title{margin-top:15px;font-size:14px;font-weight:bold}@media(max-width: 768px){.external-controller .row{flex-direction:column;align-items:flex-start}.external-controller .title{margin:5px 0}.external-controller .form{margin:5px 0}.external-controller .column{width:100%}.external-controller .alert{display:none}}
@@ -1,31 +0,0 @@
#!/bin/sh /etc/rc.common
. /lib/functions.sh
cfg_groups_set()
{
CFG_FILE="/etc/config/clash"
local section="$1"
config_get "name" "$section" "name" ""
config_get "old_name_cfg" "$section" "old_name_cfg" ""
config_get "old_name" "$section" "old_name" ""
if [ -z "$name" ]; then
return
fi
if [ "$name" != "$old_name_cfg" ]; then
sed -i "s/\'${old_name_cfg}\'/\'${name}\'/g" $CFG_FILE 2>/dev/null
sed -i "s/old_name \'${name}\'/old_name \'${old_name}\'/g" $CFG_FILE 2>/dev/null
config_load "clash"
fi
}
start(){
status=$(ps|grep -c /usr/share/clash/game-groups.sh)
[ "$status" -gt "3" ] && exit 0
config_load "clash"
config_foreach cfg_groups_set "conf_groups"
}
-103
View File
@@ -1,103 +0,0 @@
#!/bin/bash /etc/rc.common
. /lib/functions.sh
GROUP_FILE="/tmp/yaml_group.yaml"
GAME_RULE_FILE="/tmp/yaml_game_rule_group.yaml"
game_rules=$(uci get clash.config.g_rules 2>/dev/null)
CUSTOM_RULE_FILE="/tmp/ipadd.conf"
RULE="/tmp/rules_conf.yaml"
CLASH="/tmp/conf.yaml"
CONFIG_YAML="/etc/clash/config.yaml"
CLASH_CONFIG="/tmp/config.yaml"
if [ "${game_rules}" -eq 1 ];then
if [ -f $CLASH_CONFIG ];then
rm -rf $CLASH_CONFIG 2>/dev/null
fi
cp $CONFIG_YAML $CLASH_CONFIG 2>/dev/null
if [ ! -z "$(grep "^Rule:" "$CLASH_CONFIG")" ]; then
sed -i "/^Rule:/i\#RULESTART#" $CLASH_CONFIG 2>/dev/null
elif [ ! -z "$(grep "^rules:" "$CLASH_CONFIG")" ]; then
sed -i "/^rules:/i\#RULESTART#" $CLASH_CONFIG 2>/dev/null
fi
sed -i -e "\$a#RULEEND#" $CLASH_CONFIG 2>/dev/null
awk '/#RULESTART#/,/#RULEEND#/{print}' "$CLASH_CONFIG" 2>/dev/null |sed "s/\'//g" 2>/dev/null |sed 's/\"//g' 2>/dev/null |sed 's/\t/ /g' 2>/dev/null |grep - |awk -F '- ' '{print "- "$2}' | sed 's/^ \{0,\}//' 2>/dev/null |sed 's/ \{0,\}$//' 2>/dev/null >$RULE 2>&1
sed -i '/#RULESTART#/,/#RULEEND#/d' "$CLASH_CONFIG" 2>/dev/null
sed -i -e "\$a " $CLASH_CONFIG 2>/dev/null
sed -i "1i\rules:" $RULE 2>/dev/null
cat $CLASH_CONFIG $RULE >$CLASH 2>/dev/null
mv $CLASH $CLASH_CONFIG 2>/dev/null
rm -rf $RULE 2>/dev/null
get_rule_file()
{
if [ -z "$1" ]; then
return
fi
GAME_RULE_FILE_NAME=$(grep -F $1 /usr/share/clash/rules/rules.list |awk -F ',' '{print $3}' 2>/dev/null)
if [ -z "$GAME_RULE_FILE_NAME" ]; then
GAME_RULE_FILE_NAME=$(grep -F $1 /usr/share/clash/rules/rules.list |awk -F ',' '{print $2}' 2>/dev/null)
fi
GAME_RULE_PATH="/usr/share/clash/rules/g_rules/$GAME_RULE_FILE_NAME"
sed '/^#/d' $GAME_RULE_PATH 2>/dev/null |sed '/^ *$/d' |awk '{print "- IP-CIDR,"$0}' |awk -v tag="$2" '{print $0","'tag'""}' >> $GAME_RULE_FILE 2>/dev/null
set_rule_file=1
}
yml_game_rule_get()
{
local section="$1"
config_get "group" "$section" "group" ""
if [ -f $GAME_RULE_FILE ];then
rm -rf $GAME_RULE_FILE 2>/dev/null
fi
if [ -z "$group" ]; then
return
fi
config_list_foreach "$section" "rule_name" get_rule_file "$group"
}
config_load "clash"
config_foreach yml_game_rule_get "game"
if [ -f $GAME_RULE_FILE ];then
sed -i -e "\$a#GAMERULEEND#" $GAME_RULE_FILE 2>/dev/null
sed -i '/#GAMERULESTART#/,/#GAMERULEEND#/d' "$CLASH_CONFIG" 2>/dev/null
if [ ! -z "$(grep "^ \{0,\}- GEOIP" "$CLASH_CONFIG")" ]; then
sed -i '1,/^ \{0,\}- GEOIP,/{/^ \{0,\}- GEOIP,/s/^ \{0,\}- GEOIP,/#GAMERULESTART#\n&/}' "$CLASH_CONFIG" 2>/dev/null
elif [ ! -z "$(grep "^ \{0,\}- MATCH," "$CLASH_CONFIG")" ]; then
sed -i '1,/^ \{0,\}- MATCH,/{/^ \{0,\}- MATCH,/s/^ \{0,\}- MATCH,/#GAMERULESTART#\n&/}' "$CLASH_CONFIG" 2>/dev/null
else
echo "#GAMERULESTART#" >> "$CLASH_CONFIG" 2>/dev/null
fi
sed -i '/GAMERULESTART/r/tmp/yaml_game_rule_group.yaml' "$CLASH_CONFIG" 2>/dev/null
mv $CLASH_CONFIG $CONFIG_YAML 2>/dev/null
fi
rm -rf $GAME_RULE_FILE 2>/dev/null
else
sed -i '/#GAMERULESTART#/,/#GAMERULEEND#/d' "$CONFIG_YAML" 2>/dev/null
rm -rf $GAME_RULE_FILE 2>/dev/null
fi
@@ -1,33 +0,0 @@
#!/bin/sh
Key=$(uci get clash.config.license_key 2>/dev/null)
geoip_source=$(uci get clash.config.geoip_source 2>/dev/null)
if [ -f /var/run/geoip_down_complete ];then
rm -rf /var/run/geoip_down_complete 2>/dev/null
fi
echo '' >/tmp/geoip_update.txt 2>/dev/null
if [ $geoip_source == 1 ];then
wget -c4 --no-check-certificate --timeout=300 --user-agent="Mozilla" "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country&license_key="$Key"&suffix=tar.gz" -O /tmp/ipdb.tar.gz
if [ "$?" -eq "0" ]; then
tar zxvf /tmp/ipdb.tar.gz -C /tmp\
&& rm -rf /tmp/ipdb.tar.gz >/dev/null 2>&1\
&& mv /tmp/GeoLite2-Country_*/GeoLite2-Country.mmdb /etc/clash/Country.mmdb\
&& rm -rf /tmp/GeoLite2-Country_* >/dev/null 2>&1
fi
else
wget -c4 --no-check-certificate --timeout=300 --user-agent="Mozilla" https://raw.githubusercontent.com/alecthw/mmdb_china_ip_list/release/Country.mmdb -O /etc/clash/Country.mmdb
fi
sleep 2
touch /var/run/geoip_down_complete >/dev/null 2>&1
sleep 2
rm -rf /var/run/geoip_update >/dev/null 2>&1
echo "" > /tmp/geoip_update.txt >/dev/null 2>&1
if pidof clash >/dev/null; then
/etc/init.d/clash restart 2>/dev/null
fi
@@ -1,45 +0,0 @@
#!/bin/sh /etc/rc.common
. /lib/functions.sh
cfg_groups_set()
{
CFG_FILE="/etc/config/clash"
local section="$1"
config_get "name" "$section" "name" ""
config_get "old_name_cfg" "$section" "old_name_cfg" ""
config_get "old_name" "$section" "old_name" ""
if [ -z "$name" ]; then
return
fi
if [ -z "$old_name_cfg" ]; then
uci set clash."$section".old_name_cfg="$name"
uci commit clash
fi
if [ -z "$old_name" ]; then
uci set clash."$section".old_name="$name"
uci commit clash
fi
if [ "$name" != "$old_name_cfg" ] && [ ! -z "$old_name_cfg" ]; then
sed -i "s/old_name_cfg \'${old_name_cfg}\'/old_name_cfg \'${name}\'/g" $CFG_FILE 2>/dev/null
sed -i "s/groups \'${old_name_cfg}/groups \'${name}/g" $CFG_FILE 2>/dev/null
sed -i "s/other_group \'${old_name_cfg}/other_group \'${name}/g" $CFG_FILE 2>/dev/null
sed -i "s/new_servers_group \'${old_name_cfg}/new_servers_group \'${name}/g" $CFG_FILE 2>/dev/null
sed -i "s/relay_groups \'${old_name_cfg}/relay_groups \'${name}/g" $CFG_FILE 2>/dev/null
config_load "clash"
fi
}
start(){
status=$(ps|grep -c /usr/share/clash/groups.sh)
[ "$status" -gt "3" ] && exit 0
config_load "clash"
config_foreach cfg_groups_set "groups"
}
@@ -1,93 +0,0 @@
#!/bin/bash /etc/rc.common
. /lib/functions.sh
CUSTOM_RULE_FILE="/tmp/ipadd.conf"
RULE="/tmp/rules_conf.yaml"
CLASH="/tmp/conf.yaml"
CONFIG_YAML="/etc/clash/config.yaml"
CLASH_CONFIG="/tmp/config.yaml"
append=$(uci get clash.config.append_rules 2>/dev/null)
if [ "${append}" -eq 1 ];then
if [ -f $CLASH_CONFIG ];then
rm -rf $CLASH_CONFIG 2>/dev/null
fi
cp $CONFIG_YAML $CLASH_CONFIG 2>/dev/null
if [ ! -z "$(grep "^Rule:" "$CLASH_CONFIG")" ]; then
sed -i "/^Rule:/i\#RULESTART#" $CLASH_CONFIG 2>/dev/null
elif [ ! -z "$(grep "^rules:" "$CLASH_CONFIG")" ]; then
sed -i "/^rules:/i\#RULESTART#" $CLASH_CONFIG 2>/dev/null
fi
sed -i -e "\$a#RULEEND#" $CLASH_CONFIG 2>/dev/null
awk '/#RULESTART#/,/#RULEEND#/{print}' "$CLASH_CONFIG" 2>/dev/null |sed "s/\'//g" 2>/dev/null |sed 's/\"//g' 2>/dev/null |sed 's/\t/ /g' 2>/dev/null |grep '^ \{0,\}- '|awk -F '- ' '{print "- "$2}' | sed 's/^ \{0,\}//' 2>/dev/null |sed 's/ \{0,\}$//' 2>/dev/null >$RULE 2>&1
sed -i '/#RULESTART#/,/#RULEEND#/d' "$CLASH_CONFIG" 2>/dev/null
sed -i -e "\$a " $CLASH_CONFIG 2>/dev/null
sed -i "1i\rules:" $RULE 2>/dev/null
cat $CLASH_CONFIG $RULE >$CLASH 2>/dev/null
mv $CLASH $CLASH_CONFIG 2>/dev/null
rm -rf $RULE 2>/dev/null
if [ -f $CUSTOM_RULE_FILE ];then
rm -rf $CUSTOM_RULE_FILE 2>/dev/null
fi
ipadd()
{
local section="$1"
config_get "pgroup" "$section" "pgroup" ""
config_get "ipaaddr" "$section" "ipaaddr" ""
config_get "type" "$section" "type" ""
config_get "res" "$section" "res" ""
if [ -z "$type" ]; then
return
fi
if [ -z "$pgroup" ]; then
return
fi
if [ "${res}" -eq 1 ];then
echo "- $type,$ipaaddr,$pgroup,no-resolve">>/tmp/ipadd.conf
else
echo "- $type,$ipaaddr,$pgroup">>/tmp/ipadd.conf
fi
}
config_load clash
config_foreach ipadd "addtype"
if [ -f $CUSTOM_RULE_FILE ];then
sed -i -e "\$a#CUSTOMRULEEND#" $CUSTOM_RULE_FILE 2>/dev/null
sed -i '/#CUSTOMRULESTART#/,/#CUSTOMRULEEND#/d' "$CLASH_CONFIG" 2>/dev/null
if [ ! -z "$(grep "^ \{0,\}rules:" "$CLASH_CONFIG")" ]; then
sed -i '/rules:/a\#CUSTOMRULESTART#' "$CLASH_CONFIG" 2>/dev/null
else
echo "#CUSTOMRULESTART#" >> "$CLASH_CONFIG" 2>/dev/null
fi
sed -i '/CUSTOMRULESTART/r/tmp/ipadd.conf' "$CLASH_CONFIG" 2>/dev/null
mv $CLASH_CONFIG $CONFIG_YAML 2>/dev/null
fi
else
sed -i '/#CUSTOMRULESTART#/,/#CUSTOMRULEEND#/d' "$CONFIG_YAML" 2>/dev/null
fi
@@ -1,19 +0,0 @@
#!/bin/sh
enable=$(uci get clash.config.enable 2>/dev/null)
if [ "${enable}" -eq 0 ];then
if [ -f /tmp/watchlist ];then
rm -rf /tmp/watchlist
fi
line=$(ps | grep -n 'clash-watchdog.sh'|awk -F ':' '{print $2}' |awk -F ' ' '{print $1}'>/tmp/watchlist)
line_no=$(grep -n '' /tmp/watchlist|awk -F ':' '{print $1}')
num=$(grep -c '' /tmp/watchlist| awk '{print $1}')
nums=1
while [[ $nums -le $num ]]
do
kill -9 $(sed -n "$nums"p /tmp/watchlist| awk '{print $1}') >/dev/null 2>&1
nums=$(( $nums + 1))
done
fi
@@ -1,156 +0,0 @@
#!/bin/bash /etc/rc.common
. /lib/functions.sh
lang=$(uci get luci.main.lang 2>/dev/null)
load="/tmp/config.yaml"
CONFIG_YAML_PATH=$(uci get clash.config.use_config 2>/dev/null)
if [ -f $CONFIG_YAML_PATH ] && [ "$(ls -l $CONFIG_YAML_PATH|awk '{print int($5)}')" -ne 0 ];then
cp $CONFIG_YAML_PATH $load 2>/dev/null
fi
if [ ! -f $load ] || [ "$(ls -l $load|awk '{print int($5)}')" -eq 0 ]; then
exit 0
fi
CFG_FILE="/etc/config/clash"
REAL_LOG="/usr/share/clash/clash_real.txt"
rm -rf /tmp/Proxy_Group /tmp/group_*.yaml /tmp/yaml_group.yaml 2>/dev/null
if [ $lang == "zh_cn" ];then
echo "开始更新策略组配置..." >$REAL_LOG
elif [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Start updating policy group config" >$REAL_LOG
fi
sed -i 's/^Proxy Group:/proxy-groups:/g' "$load"
sed -i 's/^proxy-provider:/proxy-providers:/g' "$load"
sed -i 's/^Proxy:/proxies:/g' "$load"
sed -i 's/^Rule:/rules:/g' "$load"
sed -i 's/^rule-provider:/rule-providers:/g' "$load"
group_len=$(sed -n '/^ \{0,\}proxy-groups:/=' "$load" 2>/dev/null)
provider_len=$(sed -n '/^ \{0,\}proxy-providers:/=' "$load" 2>/dev/null)
if [ "$provider_len" -ge "$group_len" ]; then
awk '/proxies:/,/proxy-providers:/{print}' "$load" 2>/dev/null |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
sed -i "s/proxy-providers://g" /tmp/Proxy_Group 2>&1
else
awk '/proxies:/,/rules:/{print}' "$load" 2>/dev/null |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
fi
if [ "$?" -eq "0" ]; then
echo 'DIRECT' >>/tmp/Proxy_Group
echo 'REJECT' >>/tmp/Proxy_Group
else
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Read error, configuration file exception!" >/tmp/Proxy_Group
elif [ $lang == "zh_cn" ];then
echo '读取错误,配置文件异常!' >/tmp/Proxy_Group
fi
fi
group_len=$(sed -n '/^ \{0,\}proxy-groups:/=' "$load" 2>/dev/null)
provider_len=$(sed -n '/^ \{0,\}proxy-providers:/=' "$load" 2>/dev/null)
ruleprovider_len=$(sed -n '/^ \{0,\}rule-providers:/=' "$load" 2>/dev/null)
if [ "$provider_len" -ge "$group_len" ]; then
awk '/proxy-groups:/,/proxy-providers:/{print}' "$load" 2>/dev/null |sed 's/\"//g' 2>/dev/null |sed "s/\'//g" 2>/dev/null |sed 's/\t/ /g' 2>/dev/null >/tmp/yaml_group.yaml 2>&1
sed -i "s/proxy-providers://g" /tmp/yaml_group.yaml 2>&1
elif [ "$ruleprovider_len" -ge "$group_len" ]; then
awk '/proxy-groups:/,/rule-providers:/{print}' "$load" 2>/dev/null |sed 's/\"//g' 2>/dev/null |sed "s/\'//g" 2>/dev/null |sed 's/\t/ /g' 2>/dev/null >/tmp/yaml_group.yaml 2>&1
sed -i "s/rule-providers://g" /tmp/yaml_group.yaml 2>&1
else
awk '/proxy-groups:/,/Rule:/{print}' "$load" 2>/dev/null |sed 's/\"//g' 2>/dev/null |sed "s/\'//g" 2>/dev/null |sed 's/\t/ /g' 2>/dev/null >/tmp/yaml_group.yaml 2>&1
fi
#######READ GROUPS START
if [ -f /tmp/yaml_group.yaml ];then
while [[ "$( grep -c "config conf_groups" $CFG_FILE )" -ne 0 ]]
do
uci delete clash.@conf_groups[0] && uci commit clash >/dev/null 2>&1
done
count=1
file_count=1
match_group_file="/tmp/Proxy_Group"
group_file="/tmp/yaml_group.yaml"
line=$(sed -n '/name:/=' $group_file)
num=$(grep -c "name:" $group_file)
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/^ \{0,\}//g' 2>/dev/null |sed 's/ \{0,\}$//g' 2>/dev/null |sed 's/ \{0,\}\}\{0,\}$//g' 2>/dev/null)"
}
for n in $line
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")"
#name
group_name="$(cfg_get "name:" "$single_group")"
#test_url
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Now Reading 【$group_type】-【$group_name】 Policy Group..." >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "正在读取【$group_type】-【$group_name】策略组配置..." >$REAL_LOG
fi
name=clash
uci_name_tmp=$(uci add $name conf_groups)
uci_set="uci -q set $name.$uci_name_tmp."
uci_add="uci -q add_list $name.$uci_name_tmp."
${uci_set}name="$group_name"
${uci_set}type="$group_type"
file_count=$(( $file_count + 1))
done
uci commit clash
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Reading Policy Group Completed" >$REAL_LOG
sleep 2
echo "Clash for OpenWRT" >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "读取策略组配置完成" >$REAL_LOG
sleep 2
echo "Clash for OpenWRT" >$REAL_LOG
fi
rm -rf /tmp/Proxy_Group /tmp/group_*.yaml /tmp/yaml_group.yaml $load 2>/dev/null
fi
#######READ GROUPS END
@@ -1 +0,0 @@
0
@@ -1 +0,0 @@
v1.8.0
@@ -1,31 +0,0 @@
#!/bin/sh /etc/rc.common
if [ -f /usr/share/clashbackup/history ];then
HISTORY_PATH="/usr/share/clashbackup/history"
SECRET=$(uci get clash.config.dash_pass 2>/dev/null)
LAN_IP=$(uci get network.lan.ipaddr 2>/dev/null |awk -F '/' '{print $1}' 2>/dev/null)
PORT=$(uci get clash.config.dash_port 2>/dev/null)
urlencode() {
local data
if [ "$#" != 1 ]; then
return 1
fi
data=$(curl -s -o /dev/null -w %{url_effective} --get --data-urlencode "$1" "")
if [ ! -z "$data" ]; then
echo "${data##/?}"
fi
return 0
}
cat $HISTORY_PATH |while read line
do
if [ -z "$(echo $line |grep "#*#")" ]; then
continue
else
GORUP_NAME=$(urlencode "$(echo $line |awk -F '#*#' '{print $1}')")
NOW_NAME=$(echo $line |awk -F '#*#' '{print $3}')
curl -H "Authorization: Bearer ${SECRET}" -H "Content-Type:application/json" -X PUT -d '{"name":"'"$NOW_NAME"'"}' http://"$LAN_IP":"$PORT"/proxies/"$GORUP_NAME" >/dev/null 2>&1
fi
done >/dev/null 2>&1
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
fi
@@ -1,13 +0,0 @@
#!/bin/bash /etc/rc.common
. /lib/functions.sh
name=$(uci get clash.config.config_name_remove 2>/dev/null)
check_match_name=$(grep -F "$name" "/usr/share/clashbackup/confit_list.conf")
line_no=$(grep -n "$check_match_name" /usr/share/clashbackup/confit_list.conf |awk -F ':' '{print $1}')
if [ ! -z $check_match_name ];then
sed -i "${line_no}d" /usr/share/clashbackup/confit_list.conf
rm -rf /usr/share/clash/config/sub/${name}
sed -i '/^$/d' /usr/share/clashbackup/confit_list.conf
rm -rf /usr/share/clash/config/sub/${name}
fi
@@ -1,23 +0,0 @@
#!/bin/bash
rule=$(uci get clash.config.rule_url 2>/dev/null)
RULE_YAML="/tmp/Rule"
wget -c4 --no-check-certificate --user-agent="Clash/OpenWRT" "$rule" -O 2>&1 >1 $RULE_YAML
if [ -f "$RULE_YAML" ]; then
status=$(egrep '^ {0,}Rule:' /tmp/Rule)
if [ $status ];then
sed -i "/Rule:/i\===" $RULE_YAML
sed -i "1i\ " $RULE_YAML
mv $RULE_YAML /tmp/test
sed -i '1,/===/d' /tmp/test
mv /tmp/test /usr/share/clash/rule.yaml
else
sed -i "1i\Rule:" $RULE_YAML
mv $RULE_YAML /tmp/test
sed -i "1i\ " /tmp/test
mv /tmp/test /usr/share/clash/rule.yaml
fi
fi
File diff suppressed because it is too large. Load diff
@@ -1,949 +0,0 @@
#Steam,Steam-社区(Beta),0,0,1,0,0,0,By-FQrabbit
2.16.4.0/24
2.16.10.0/24
2.16.17.0/24
2.16.21.0/24
2.16.39.0/24
2.16.59.0/24
2.16.82.0/24
2.16.95.0/24
2.16.104.0/23
2.16.111.0/24
2.17.55.0/24
2.17.98.0/24
2.17.191.0/24
2.18.119.0/24
2.18.152.0/24
2.18.199.0/24
2.19.131.0/24
2.19.147.0/24
2.19.225.0/24
2.20.57.0/24
2.20.166.0/24
2.20.177.0/24
2.20.200.0/24
2.20.214.0/24
2.21.31.0/24
2.21.46.0/24
2.21.75.0/24
2.21.131.0/24
2.21.145.0/24
2.21.150.0/24
2.21.195.0/24
2.21.205.0/24
2.21.248.0/24
2.22.13.0/24
2.22.15.0/24
2.22.36.0/24
2.22.69.0/24
2.22.73.0/24
2.22.74.0/23
2.22.146.0/24
2.23.151.0/24
2.23.181.0/24
8.7.198.0/24
14.21.78.0/24
23.0.7.0/24
23.0.21.0/24
23.0.83.0/24
23.0.146.0/24
23.0.168.0/24
23.0.178.0/24
23.0.232.0/24
23.0.252.0/24
23.1.15.0/24
23.1.26.0/24
23.1.45.0/24
23.1.227.0/24
23.2.8.0/24
23.2.11.0/24
23.2.16.0/24
23.2.18.0/24
23.2.29.0/24
23.2.42.0/24
23.2.59.0/24
23.2.92.0/24
23.2.204.0/24
23.2.206.0/24
23.3.244.0/24
23.4.168.0/24
23.4.251.0/24
23.5.114.0/24
23.5.117.0/24
23.5.156.0/24
23.5.170.0/24
23.5.241.0/24
23.5.242.0/24
23.7.39.0/24
23.7.80.0/24
23.7.128.0/24
23.7.199.0/24
23.7.246.0/24
23.8.12.0/24
23.8.117.0/24
23.8.229.0/24
23.9.9.0/24
23.9.154.0/24
23.10.0.0/16
23.11.202.0/24
23.11.204.0/24
23.11.225.0/24
23.11.236.0/24
23.12.34.0/24
23.12.109.0/24
23.12.227.0/24
23.12.229.0/24
23.13.147.0/24
23.14.6.0/24
23.14.10.0/24
23.14.68.0/24
23.14.77.0/24
23.14.85.0/24
23.14.222.0/24
23.14.229.0/24
23.15.4.0/24
23.15.81.0/24
23.15.91.0/24
23.15.94.0/24
23.15.98.0/23
23.15.184.0/24
23.15.187.0/24
23.15.224.0/24
23.32.17.0/24
23.32.86.0/24
23.32.113.0/24
23.32.131.0/24
23.32.163.0/24
23.32.215.0/24
23.32.216.0/24
23.32.248.0/24
23.32.254.0/24
23.33.75.0/24
23.33.88.0/24
23.33.112.0/24
23.33.168.0/24
23.33.255.0/24
23.34.60.0/24
23.34.65.0/24
23.34.75.0/24
23.35.225.0/24
23.35.230.0/24
23.36.26.0/24
23.36.105.0/24
23.36.141.0/24
23.36.148.0/24
23.36.165.0/24
23.36.216.0/24
23.36.220.0/24
23.36.230.0/23
23.37.53.0/24
23.37.58.0/24
23.37.67.0/24
23.37.147.0/24
23.37.148.0/24
23.37.237.0/24
23.37.239.0/24
23.37.242.0/23
23.37.249.0/24
23.37.250.0/24
23.38.3.0/24
23.38.77.0/24
23.38.109.0/24
23.38.153.0/24
23.38.155.0/24
23.38.166.0/24
23.39.136.0/24
23.40.1.0/24
23.40.4.0/24
23.40.31.0/24
23.40.247.0/24
23.41.5.0/24
23.41.59.0/24
23.41.102.0/24
23.41.132.0/24
23.41.149.0/24
23.41.165.0/24
23.41.243.0/24
23.42.6.0/24
23.42.69.0/24
23.42.83.0/24
23.42.165.0/24
23.42.212.0/24
23.42.232.0/24
23.42.248.0/24
23.43.0.0/16
23.44.193.0/24
23.45.96.0/24
23.45.201.0/24
23.46.18.0/24
23.46.24.0/24
23.46.104.0/24
23.46.241.0/24
23.47.0.0/16
23.48.4.0/24
23.48.219.0/24
23.49.4.0/24
23.49.119.0/24
23.49.135.0/24
23.49.148.0/24
23.49.224.0/24
23.50.18.0/24
23.50.37.0/24
23.50.43.0/24
23.50.69.0/24
23.50.168.0/24
23.51.39.0/24
23.51.122.0/24
23.51.131.0/24
23.51.134.0/23
23.51.154.0/24
23.51.240.0/24
23.51.246.0/24
23.52.37.0/24
23.52.51.0/24
23.52.74.0/24
23.52.82.0/24
23.52.86.0/24
23.53.33.0/24
23.53.73.0/24
23.53.195.0/24
23.54.176.0/24
23.54.179.0/24
23.54.199.0/24
23.54.247.0/24
23.54.248.0/24
23.54.250.0/24
23.55.48.0/24
23.55.53.0/24
23.55.60.0/24
23.55.139.0/24
23.55.235.0/24
23.56.115.0/24
23.56.208.0/24
23.57.32.0/24
23.57.64.0/23
23.57.230.0/24
23.57.251.0/24
23.58.0.0/24
23.58.27.0/24
23.58.36.0/24
23.58.41.0/24
23.58.75.0/24
23.58.80.0/24
23.58.154.0/24
23.59.57.0/24
23.59.96.0/24
23.59.117.0/24
23.60.41.0/24
23.60.48.0/24
23.60.123.0/24
23.60.131.0/24
23.61.10.0/24
23.61.74.0/24
23.61.161.0/24
23.62.53.0/24
23.62.102.0/24
23.62.109.0/24
23.62.145.0/24
23.62.152.0/24
23.63.11.0/24
23.63.22.0/24
23.63.32.0/24
23.63.219.0/24
23.63.228.0/24
23.64.22.0/24
23.64.34.0/24
23.64.37.0/24
23.64.38.0/24
23.64.127.0/24
23.64.158.0/24
23.64.178.0/24
23.65.80.0/24
23.65.190.0/24
23.65.225.0/24
23.66.0.0/16
23.67.65.0/24
23.67.67.0/24
23.67.69.0/24
23.67.72.0/24
23.67.76.0/24
23.67.130.0/24
23.67.161.0/24
23.67.200.0/24
23.67.204.0/24
23.67.217.0/24
23.72.20.0/24
23.72.36.0/24
23.72.58.0/24
23.72.80.0/24
23.72.92.0/24
23.72.138.0/24
23.72.156.0/24
23.72.226.0/24
23.72.250.0/24
23.73.29.0/24
23.73.77.0/24
23.73.85.0/24
23.73.137.0/24
23.73.139.0/24
23.73.144.0/24
23.73.153.0/24
23.73.168.0/24
23.73.170.0/24
23.73.199.0/24
23.73.206.0/24
23.74.15.0/24
23.74.17.0/24
23.74.57.0/24
23.74.60.0/24
23.74.138.0/24
23.74.162.0/24
23.74.170.0/24
23.74.237.0/24
23.75.12.0/24
23.75.14.0/24
23.75.30.0/24
23.75.186.0/24
23.75.210.0/24
23.75.212.0/24
23.75.216.0/23
23.76.253.0/24
23.77.32.0/24
23.77.202.0/24
23.77.208.0/24
23.77.214.0/24
23.78.23.0/24
23.78.39.0/24
23.78.54.0/24
23.78.86.0/24
23.78.117.0/24
23.78.168.0/24
23.79.15.0/24
23.79.19.0/24
23.79.68.0/24
23.192.26.0/24
23.192.38.0/24
23.192.114.0/24
23.192.116.0/24
23.192.126.0/24
23.192.168.0/24
23.192.245.0/24
23.193.64.0/24
23.193.162.0/24
23.193.168.0/24
23.193.171.0/24
23.193.175.0/24
23.194.66.0/24
23.194.88.0/24
23.194.212.0/24
23.194.216.0/24
23.196.4.0/24
23.196.56.0/24
23.196.199.0/24
23.196.214.0/24
23.196.244.0/24
23.197.49.0/24
23.198.97.0/24
23.198.108.0/24
23.198.121.0/24
23.198.213.0/24
23.198.214.0/24
23.199.7.0/24
23.199.10.0/24
23.199.67.0/24
23.199.134.0/24
23.199.138.0/24
23.199.149.0/24
23.199.152.0/24
23.199.154.0/24
23.199.207.0/24
23.199.232.0/24
23.199.234.0/24
23.199.242.0/24
23.199.248.0/24
23.200.18.0/24
23.200.26.0/24
23.200.94.0/24
23.200.103.0/24
23.200.140.0/24
23.201.23.0/24
23.201.41.0/24
23.201.103.0/24
23.201.254.0/24
23.202.39.0/24
23.202.69.0/24
23.202.70.0/24
23.202.83.0/24
23.202.117.0/24
23.202.124.0/24
23.202.128.0/24
23.202.139.0/24
23.202.143.0/24
23.203.26.0/23
23.203.50.0/24
23.203.52.0/24
23.203.62.0/24
23.203.84.0/24
23.203.132.0/24
23.203.255.0/24
23.204.36.0/24
23.204.104.0/23
23.204.148.0/24
23.204.239.0/24
23.205.26.0/24
23.205.35.0/24
23.205.132.0/24
23.205.140.0/24
23.205.226.0/24
23.206.10.0/24
23.206.13.0/24
23.206.35.0/24
23.206.51.0/24
23.206.66.0/24
23.206.90.0/24
23.206.95.0/24
23.206.112.0/24
23.206.126.0/24
23.206.169.0/24
23.206.192.0/24
23.206.197.0/24
23.206.198.0/24
23.206.211.0/24
23.206.239.0/24
23.206.246.0/24
23.207.179.0/24
23.208.28.0/24
23.208.34.0/24
23.208.36.0/24
23.208.102.0/24
23.208.123.0/24
23.208.136.0/24
23.208.138.0/24
23.208.215.0/24
23.208.228.0/24
23.208.235.0/24
23.209.75.0/24
23.209.184.0/24
23.210.0.0/24
23.210.3.0/24
23.210.203.0/24
23.211.16.0/24
23.211.40.0/24
23.211.56.0/24
23.211.106.0/24
23.211.140.0/24
23.211.150.0/24
23.211.152.0/24
23.212.53.0/24
23.212.110.0/24
23.212.141.0/24
23.212.171.0/24
23.213.53.0/24
23.213.55.0/24
23.213.138.0/24
23.213.158.0/24
23.213.176.0/24
23.214.27.0/24
23.214.43.0/24
23.214.51.0/24
23.214.66.0/24
23.214.74.0/24
23.214.102.0/23
23.214.116.0/24
23.214.165.0/24
23.214.172.0/24
23.215.0.0/24
23.215.52.0/24
23.215.57.0/24
23.215.105.0/24
23.215.130.0/24
23.216.8.0/24
23.216.202.0/24
23.217.43.0/24
23.217.106.0/24
23.217.143.0/24
23.217.226.0/24
23.218.40.0/24
23.218.144.0/24
23.218.158.0/24
23.218.215.0/24
23.219.212.0/24
23.220.38.0/24
23.220.46.0/24
23.220.181.0/24
23.220.195.0/24
23.220.206.0/24
23.221.3.0/24
23.221.17.0/24
23.221.45.0/24
23.221.46.0/24
23.221.66.0/24
23.221.154.0/24
23.222.27.0/24
23.222.61.0/24
23.222.132.0/24
23.222.161.0/24
23.222.172.0/24
23.222.195.0/24
23.223.65.0/24
23.223.75.0/24
23.223.99.0/24
31.13.0.0/16
37.10.124.0/24
45.121.186.0/24
46.82.0.0/16
59.24.0.0/16
60.254.131.0/24
60.254.171.0/24
61.213.168.0/24
63.146.69.0/24
63.219.254.0/24
63.243.244.0/24
64.13.0.0/16
65.158.114.0/24
66.220.0.0/16
67.15.0.0/16
67.131.44.0/24
67.228.0.0/16
69.16.175.0/24
69.63.0.0/16
69.171.0.0/16
69.192.12.0/24
69.192.44.0/24
72.165.61.0/24
72.246.62.0/24
72.246.91.0/24
72.246.106.0/24
72.246.167.0/24
72.246.169.0/24
72.246.174.0/24
72.246.189.0/24
72.246.190.0/24
72.246.224.0/24
72.247.90.0/24
72.247.192.0/23
72.247.198.0/24
74.86.0.0/16
74.201.99.0/24
75.126.0.0/16
78.16.49.0/24
84.53.134.0/24
85.190.158.0/24
88.191.0.0/16
88.221.34.0/24
88.221.37.0/24
88.221.71.0/24
88.221.99.0/24
88.221.172.0/24
88.221.175.0/24
88.221.195.0/24
88.221.198.0/23
92.122.5.0/24
92.122.254.0/24
92.123.123.0/24
92.123.176.0/24
92.123.208.0/24
95.100.3.0/24
95.100.60.0/24
95.100.97.0/24
95.100.142.0/24
95.101.30.0/24
95.101.51.0/24
95.101.166.0/24
95.101.199.0/24
95.101.241.0/24
95.101.247.0/24
96.6.89.0/24
96.6.161.0/24
96.7.0.0/16
96.16.160.0/24
96.16.184.0/24
96.16.186.0/24
96.16.221.0/24
96.17.38.0/24
96.17.109.0/24
96.17.210.0/24
103.28.54.0/24
103.74.6.0/24
104.65.15.0/24
104.66.5.0/24
104.66.7.0/24
104.66.36.0/24
104.66.44.0/24
104.66.140.0/24
104.67.26.0/24
104.67.37.0/24
104.67.57.0/24
104.67.152.0/24
104.68.176.0/24
104.68.183.0/24
104.68.189.0/24
104.69.0.0/16
104.70.69.0/24
104.70.154.0/24
104.70.200.0/24
104.70.204.0/24
104.70.207.0/24
104.71.138.0/24
104.71.152.0/24
104.71.213.0/24
104.72.60.0/24
104.72.63.0/24
104.72.154.0/24
104.72.156.0/24
104.73.12.0/24
104.74.0.0/16
104.75.37.0/24
104.75.57.0/24
104.75.65.0/24
104.75.228.0/24
104.76.18.0/24
104.76.58.0/24
104.76.65.0/24
104.76.88.0/24
104.76.111.0/24
104.76.114.0/24
104.76.133.0/24
104.77.22.0/24
104.78.0.0/16
104.79.88.0/24
104.79.128.0/24
104.79.153.0/24
104.80.3.0/24
104.80.29.0/24
104.80.37.0/24
104.80.53.0/24
104.80.59.0/24
104.80.64.0/24
104.80.66.0/24
104.80.88.0/24
104.81.11.0/24
104.81.23.0/24
104.81.120.0/24
104.81.126.0/24
104.81.137.0/24
104.81.141.0/24
104.81.244.0/23
104.82.83.0/24
104.82.89.0/24
104.82.180.0/23
104.82.245.0/24
104.82.247.0/24
104.83.70.0/24
104.83.83.0/24
104.83.89.0/24
104.83.100.0/24
104.83.102.0/24
104.84.154.0/24
104.84.169.0/24
104.84.187.0/24
104.85.41.0/24
104.85.50.0/24
104.85.52.0/23
104.85.172.0/24
104.85.174.0/24
104.86.44.0/23
104.86.110.0/24
104.86.250.0/24
104.87.39.0/24
104.87.102.0/24
104.87.227.0/24
104.87.228.0/24
104.88.0.0/16
104.89.8.0/24
104.89.18.0/24
104.89.38.0/23
104.89.40.0/24
104.89.143.0/24
104.90.20.0/24
104.90.24.0/24
104.90.44.0/24
104.90.49.0/24
104.90.96.0/24
104.90.100.0/24
104.90.104.0/24
104.90.140.0/24
104.90.143.0/24
104.90.180.0/24
104.91.170.0/24
104.91.217.0/24
104.91.233.0/24
104.92.6.0/24
104.92.80.0/24
104.92.90.0/24
104.92.102.0/24
104.92.123.0/24
104.92.136.0/24
104.92.153.0/24
104.93.0.0/16
104.94.2.0/24
104.94.8.0/24
104.94.18.0/24
104.94.110.0/24
104.94.173.0/24
104.94.204.0/24
104.95.20.0/24
104.95.24.0/24
104.95.59.0/24
104.95.98.0/24
104.95.110.0/24
104.95.119.0/24
104.95.197.0/24
104.95.227.0/24
104.96.0.0/16
104.97.66.0/24
104.97.113.0/24
104.97.226.0/24
104.97.228.0/24
104.98.0.0/15
104.100.51.0/24
104.100.52.0/24
104.100.187.0/24
104.101.203.0/24
104.102.10.0/24
104.102.56.0/24
104.103.52.0/24
104.103.58.0/24
104.103.70.0/24
104.103.106.0/24
104.103.157.0/24
104.104.162.0/24
104.104.187.0/24
104.105.7.0/24
104.105.10.0/24
104.105.28.0/24
104.105.58.0/24
104.105.148.0/24
104.105.153.0/24
104.106.200.0/24
104.106.236.0/24
104.107.7.0/24
104.107.52.0/23
104.107.108.0/24
104.107.168.0/23
104.107.248.0/24
104.108.46.0/24
104.108.52.0/24
104.108.69.0/24
104.109.55.0/24
104.109.66.0/24
104.109.82.0/24
104.109.130.0/24
104.109.139.0/24
104.109.142.0/24
104.109.160.0/24
104.109.208.0/24
104.109.235.0/24
104.110.104.0/24
104.111.200.0/24
104.111.247.0/24
104.112.150.0/24
104.112.238.0/24
104.113.52.0/24
104.113.62.0/24
104.113.115.0/24
104.115.83.0/24
104.115.92.0/24
104.115.97.0/24
104.115.118.0/24
104.115.125.0/24
104.115.175.0/24
104.115.209.0/24
104.115.227.0/24
104.115.233.0/24
104.115.253.0/24
104.116.0.0/24
104.116.18.0/24
104.116.70.0/24
104.116.130.0/24
104.116.145.0/24
104.116.217.0/24
104.116.243.0/24
104.116.246.0/24
104.116.251.0/24
104.117.0.0/24
104.117.65.0/24
104.117.95.0/24
104.117.105.0/24
104.117.140.0/24
104.118.6.0/24
104.118.28.0/24
104.118.96.0/24
104.118.103.0/24
104.118.112.0/24
104.119.40.0/24
104.119.181.0/24
104.120.78.0/24
104.120.86.0/24
104.120.92.0/24
104.120.143.0/24
104.120.178.0/24
104.120.219.0/24
104.121.21.0/24
104.121.70.0/24
104.121.122.0/24
104.121.226.0/24
104.121.232.0/24
104.121.249.0/24
104.122.2.0/24
104.122.10.0/24
104.122.102.0/24
104.122.198.0/24
104.122.203.0/24
104.122.220.0/24
104.122.255.0/24
104.123.122.0/24
104.124.27.0/24
104.124.49.0/24
104.124.119.0/24
104.124.134.0/24
104.124.139.0/24
104.124.182.0/24
104.124.211.0/24
104.124.228.0/24
104.125.0.0/16
104.126.21.0/24
104.126.83.0/24
104.127.43.0/24
104.127.62.0/24
104.127.119.0/24
104.127.221.0/24
106.15.109.0/24
110.45.200.0/24
115.223.23.0/24
117.103.182.0/24
118.155.230.0/24
118.214.82.0/24
118.214.249.0/24
118.215.92.0/24
118.215.97.0/24
118.215.176.0/24
121.156.60.0/24
122.252.43.0/24
125.56.227.0/24
125.252.235.0/24
128.241.91.0/24
139.175.87.0/24
141.0.168.0/24
146.66.152.0/24
152.199.38.0/24
153.254.86.0/24
155.133.227.0/24
155.133.229.0/24
155.133.230.0/24
155.133.238.0/24
155.133.242.0/24
155.133.254.0/24
162.254.193.0/24
162.254.195.0/24
162.254.196.0/23
165.254.12.0/24
165.254.105.0/24
165.254.134.0/24
172.16.0.0/16
172.19.83.0/24
172.224.1.0/24
172.224.11.0/24
172.226.72.0/24
172.226.220.0/24
172.227.13.0/24
172.227.150.0/24
172.227.171.0/24
172.228.232.0/24
172.229.58.0/24
172.230.102.0/24
172.230.106.0/24
172.230.108.0/24
172.230.172.0/24
172.231.9.0/24
173.197.192.0/24
173.205.6.0/24
173.222.1.0/24
173.222.43.0/24
173.222.193.0/24
173.222.225.0/24
173.222.237.0/24
173.223.81.0/24
173.223.87.0/24
173.223.164.0/24
173.252.0.0/16
174.36.0.0/15
175.99.100.0/24
175.99.115.0/24
175.139.142.0/24
182.162.106.0/24
184.24.26.0/24
184.24.104.0/24
184.24.110.0/24
184.24.155.0/24
184.24.195.0/24
184.24.223.0/24
184.25.19.0/24
184.25.56.0/24
184.25.61.0/24
184.25.91.0/24
184.25.146.0/24
184.25.158.0/24
184.25.205.0/24
184.25.221.0/24
184.25.243.0/24
184.25.248.0/24
184.25.252.0/23
184.26.22.0/24
184.26.84.0/24
184.26.114.0/24
184.26.120.0/24
184.26.140.0/23
184.26.221.0/24
184.27.0.0/16
184.28.0.0/16
184.29.37.0/24
184.29.59.0/24
184.29.108.0/24
184.29.150.0/24
184.30.6.0/24
184.30.19.0/24
184.30.20.0/24
184.30.226.0/24
184.31.201.0/24
184.50.2.0/24
184.50.87.0/24
184.50.163.0/24
184.51.0.0/24
184.51.15.0/24
184.51.17.0/24
184.51.56.0/24
184.51.141.0/24
184.84.56.0/24
184.84.168.0/24
184.85.67.0/24
184.85.120.0/24
184.85.244.0/24
184.86.0.0/16
184.87.14.0/24
184.87.121.0/24
184.87.197.0/24
185.25.180.0/24
185.27.16.0/24
185.88.181.0/24
192.81.222.0/24
198.172.88.0/24
199.16.0.0/16
199.59.0.0/16
199.239.182.0/24
203.69.81.0/24
205.186.152.0/24
208.43.0.0/16
208.64.201.0/24
208.78.164.0/24
208.101.0.0/16
209.170.97.0/24
210.61.248.0/24
210.201.31.0/24
216.3.133.0/24
216.156.211.0/24
223.119.157.0/24
223.119.206.0/24
223.119.217.0/24
224.0.0.0/4
243.185.187.0/24
@@ -1,140 +0,0 @@
300英雄,300hero-cn.rules
永恒之塔-台服,Aion-TW.rules
美国卡车模拟国际服,American-Truck-Simulator.rules
圣歌,Anthem.rules
Apex-uu,Apex-uu.rules
Apex英雄,Apex.rules
方舟:生存进化,ARK--Survival-Evolved.rules
刺客信条:奥德赛,Assassin's-Creed-Odyssey.rules,Assassins-Creed-Odyssey.rules
刺客信条:起源,Assassin's-Creed-Origins.rules,Assassins-Creed-Origins.rules
Atlas-全区,Atlas.rules
战地1,Battlefield-1.rules
战地4,BattleField-4.rules
战地5,Battlefield-Ⅴ.rules,Battlefield-5.rules
黑色沙漠-steam,BlackDesert-steam.rules
黑色幸存者,BlackSurvivor.rules
剑灵台服,Blade%26Soul%20TW.rules
剑灵-日服,Blade-%26-Soul-jp.rules
剑灵-国服全部区服(UU规则),Blood-%26-Soul-CN-TestServer-NantianGuo-Alpha.rules
剑灵-国服-南天国(测试版),Blood-%26-Soul-CN.rules
无主之地3,Borderlands3-asia.rules
使命召唤4:现代战争重置版,Call-Of-Duty-4-Modern-Warfare.rules
使命召唤15亚服,Call-Of-Duty15-Asia.rules
英雄连2,Company-Of-Heroes-2.rules
反恐精英:全球攻势,CS-GO.rules
反恐精英:全球攻势-港服(tx),CSGO-HKtx.rules
反恐精英:全球攻势-日服(tx),CSGO-JPtx.rules
反恐精英:全球攻势-美服(tx),CSGO-UStx.rules
黑暗之魂3,Dark-Souls-3.rules
不屈不挠,Dauntless.rules
DayZ-steam,DayZ.rules
黎明杀机,Dead-by-Daylight.rules
命运2-全服(tx),Destiny2-Alltx.rules
命运2-全服(uu),Destiny2-Alluu.rules
天命2-亚服/命运2-亚服,Destiny2-Asia.rules
天命2-欧服/命运2-欧服,Destiny2-EU.rules
命运2-steam,Destiny2-steam.rules
天命2-美服/命运2-美服,Destiny2-US.rules
暗黑破坏神3-亚服,Diablo3-Asia.rules
暗黑破坏神3-美服,Diablo3-US.rules
脏弹-Steam,Dirty-Bomb.rules
Discord,Discord-All.rules
饥荒-steam,Don't-Starve-steam.rules,Dont-Starve-steam.rules
刀塔霸业,Dota-Underlords.rules
DOTA2-日服,Dota2-jp.rules
逃离塔科夫,Escape-from-Tarkov.rules
欧卡2所有分区-UU,Euro-Truck-Simulator-2.rules
Eve-online欧服,Eve-online.rules
FIFA19,FiFa19-INT.rules
FIFA20,FIFA20.rules
最终幻想14国服,FINAL-FANTASY-XIV-cn.rules
最终幻想14,Final-Fantasy-XIV.rules
荣耀战魂,For-Honour.rules
堡垒之夜-亚服,Fortnite-AS.rules
堡垒之夜-国服,Fortnite-cn.rules
极限竞速地平线4,Forza-Horizon-4.rules
极限竞速7,Forza-Motorsport-7.rules
基佬大乱斗Gang-Beasts,Gang-Beasts.rules
GTA5,GTA-5.rules
激战2,Guild-Wars-2.rules
巫师昆特牌国际服,Gwent_The-Witcher-Card-game.rules
杀手2外服,HITMAN2.rules
荒野行动PC版-国服,HuangYeXingDong-cn.rules
叛乱:沙漠风暴,Insurgency-Sandstorm.rules
Jump大乱斗,Jump-Force.rules
跑跑卡丁车(韩服),KartRider.rules
Kurtzpel,Kurtzpel.rules
求生之路2-Test,L4D2-Test.rules
英雄联盟-日服,League-of-Legends-jp.rules
英雄联盟-韩服,League-of-Legends-kr.rules
英雄联盟PBE,League-of-Legends-PBE.rules
英雄联盟-台服,League-of-Legends-tw+Garena(2018-12-19).rules
英雄联盟-台服+Garena平台(2018-12-19更新),League-of-Legends-tw.rules
英雄联盟-美服,League-of-Legends-us.rules
失落的方舟韩服,Lost-Ark.rules
失落的方舟俄服,Lostark-RU.rules
冒险岛,Maplestory-us.rules
怪兽世界猎人steam版,Monster-Hunter-World.rules
奇迹传奇MU2,MU2.rules
NBA-2K19,NBA-2K19.rules
NBA2K20,NBA2K20.rules
仁王,NIOH.rules
橘子客户端-UU,Origin.rules
Osu!,Osu!.rules
守望先锋-亚服,Overwatch-Asia.rules
守望先锋-美服,Overwatch-US.rules
流亡黯道-国际服,Path%20Of%20Exile.rules
流放之路,PathOfexile.rules
梦幻之星2-日服(tx),PHANTASY%20STAR%20ONLINE2-JPtx.rules
行星边际2,PlanetSide-2.rules
绝地求生大逃杀,PlayerUnknown's-Battlegrounds-update.rules,PlayerUnknowns-Battlegrounds-update.rules
实况足球-2018,Pro-Evolution-Soccer-2018.rules
实况足球-2019,Pro-Evolution-Soccer-2019.rules
绝地求生亚服-东南亚服,PUBG-Asia%26-Southeast-Asia.rules
绝地求生国际服,PUBG-INT.rules
绝地求生韩服,PUBG-kakao.rules
绝地求生低配版-Garena,PUBGLite-Garena.rules
绝地求生轻量版-WEB客户端,PUBGLITE-WEB.rules
R2竞技场服,R2Arena.rules
R2俄服官服,R2RU.rules
R2美服,R2US.rules
仙境传说OL台湾,RagnarokOnlineTW.rules
荒野大镖客2,Red-dead-redemption2.rules
无限法则,Ring-of-Elysium-asia.rules
Roblox,Roblox.rules
影之诗,Shadowverse.rules
灵魂行者-台服,Soul-Worker.rules
星际公民,Star-Citizen.rules
星球大战2前线,Star-Wars-BattlefrontII.rules
StarCraft-亚服,StarCraft-2-asia.rules
星际争霸2-国服,StarCraftⅡ-cn.rules,StarCraft2-cn.rules
Steam-社区(Beta),Steam.rules
极限巅峰,Steep.rules
街头霸王5,Street-Fighter-V.rules
神谕之战,TERA.rules
飙酷车神,The-Crew.rules
飙酷车神2,The-Crew2.rules
上古卷轴OL,The-Elder-Scrolls-Online.rules
天涯明月刀-台服,TianYaMingYueDao-tw.rules
泰坦陨落2,TiTanFall2.rules
新枫之谷,TMS.rules
幽灵行动:荒野,Tom-Clancy's-Ghost-Recon-Wildlands.rules,Tom-Clancys-Ghost-Recon-Wildlands.rules
彩虹六号-围攻-全部,Tom-Clancy's-Rainbow-Six-Siege-all.rules,Tom-Clancys-Rainbow-Six-Siege-all.rules
彩虹六号-围攻-EAS,Tom-Clancy's-Rainbow-Six-Siege-EAS.rules,Tom-Clancys-Rainbow-Six-Siege-EAS.rules
全境封锁,Tom-clancy's-The-Division-2.rules,Tom-clancys-The-Division-2.rules
全境封锁2,Tom-clancy's-The-Division.rules,Tom-clancys-The-Division.rules
未转变者Unturned,Unturned.rules
战争前线,War-thunder-steam.rules
战争雷霆-steam,Warface.rules
看门狗,Watch-Dogs.rules
看门狗2,Watch-Dogs2.rules
求生意志OL,Will-To-Live-Online.rules
坦克世界-亚服,World-of-Tanks-Asia.rules
坦克世界-国服,World-of-Tanks-cn.rules
魔兽世界台服,World-of-warcraft-tw.rules
战舰世界-亚服,World-of-Warships-US.rules
战舰世界-美服,World-of-Warships.rules
僵尸世界大战,Worldwar-Z.rules
魔兽世界-欧服,WoW-EU.rules
游戏王决斗链接,YO-GI-HO%20delulinks.rules
游侠对战平台,YouXiaDuiZhanPingTai.rules
@@ -1,81 +0,0 @@
time.windows.com
time.nist.gov
time.apple.com
time.asia.apple.com
cn.ntp.org.cn
edu.ntp.org.cn
hk.ntp.org.cn
tw.ntp.org.cn
us.ntp.org.cn
sgp.ntp.org.cn
kr.ntp.org.cn
jp.ntp.org.cn
de.ntp.org.cn
ina.ntp.org.cn
0.openwrt.pool.ntp.org
1.openwrt.pool.ntp.org
2.openwrt.pool.ntp.org
3.openwrt.pool.ntp.org
ntp.aliyun.com
ntp1.aliyun.com
ntp2.aliyun.com
ntp3.aliyun.com
ntp4.aliyun.com
ntp5.aliyun.com
ntp6.aliyun.com
ntp7.aliyun.com
time1.aliyun.com
time2.aliyun.com
time3.aliyun.com
time4.aliyun.com
time5.aliyun.com
time6.aliyun.com
time7.aliyun.com
s1c.time.edu.cn
s2m.time.edu.cn
s1b.time.edu.cn
s1e.time.edu.cn
s2a.time.edu.cn
s2b.time.edu.cn
time1.apple.com
time2.apple.com
time3.apple.com
time4.apple.com
time5.apple.com
time6.apple.com
time7.apple.com
time1.google.com
time2.google.com
time3.google.com
time4.google.com
.music.163.com
.music.126.net
p1.music.126.net
p2.music.126.net
p3.music.126.net
p4.music.126.net
p5.music.126.net
p1c.music.126.net
p2c.music.126.net
p3c.music.126.net
p4c.music.126.net
p5c.music.126.net
interface.music.163.com
interface1.music.163.com
interface2.music.163.com
interface3.music.163.com
interface4.music.163.com
interface5.music.163.com
apm.music.163.com
apm3.music.163.com
man.netease.com
api.iplay.163.com
ac.dun.163yun.com
mr.da.netease.com
crash.163.com
imap.163.com
music.126.net
music.163.com
msftconnecttest.com
msftncsi.com
qq.com
@@ -1,142 +0,0 @@
#!/bin/bash /etc/rc.common
. /lib/functions.sh
config_name=$(uci get clash.config.config_update_name 2>/dev/null)
CONFIG_YAML="/usr/share/clash/config/sub/${config_name}"
url=$(grep -F "${config_name}" "/usr/share/clashbackup/confit_list.conf" | awk -F '#' '{print $2}')
lang=$(uci get luci.main.lang 2>/dev/null)
REAL_LOG="/usr/share/clash/clash_real.txt"
c_type=$(uci get clash.config.config_type 2>/dev/null)
path=$(uci get clash.config.use_config 2>/dev/null)
type=$(grep -F "${config_name}" "/usr/share/clashbackup/confit_list.conf" | awk -F '#' '{print $3}')
if [ $type == "clash" ] && [ ! -z $url ];then
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Updating Configuration..." >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "开始更新配置" >$REAL_LOG
fi
wget --no-check-certificate --user-agent="Clash/OpenWRT" $url -O 2>&1 >1 $CONFIG_YAML
if [ "$?" -eq "0" ]; then
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Updating Configuration Completed" >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "更新配置完成" >$REAL_LOG
fi
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
sleep 2
use_config=$(uci get clash.config.use_config 2>/dev/null)
if [ "$c_type" -eq 1 ] && [ "$CONFIG_YAML" = "$use_config" ];then
if pidof clash >/dev/null; then
/etc/init.d/clash restart 2>/dev/null
fi
fi
fi
fi
if [ $type == "ssr2clash" ] && [ ! -z $url ];then
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Updating Configuration..." >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "开始更新配置" >$REAL_LOG
fi
wget --no-check-certificate --user-agent="Clash/OpenWRT" "https://ssrsub2clashr.herokuapp.com/ssrsub2clash?sub=$url" -O 2>&1 >1 $CONFIG_YAML
if [ "$?" -eq "0" ]; then
CONFIG_YAMLL="/tmp/conf"
da_password=$(uci get clash.config.dash_pass 2>/dev/null)
redir_port=$(uci get clash.config.redir_port 2>/dev/null)
http_port=$(uci get clash.config.http_port 2>/dev/null)
socks_port=$(uci get clash.config.socks_port 2>/dev/null)
dash_port=$(uci get clash.config.dash_port 2>/dev/null)
bind_addr=$(uci get clash.config.bind_addr 2>/dev/null)
allow_lan=$(uci get clash.config.allow_lan 2>/dev/null)
log_level=$(uci get clash.config.level 2>/dev/null)
p_mode=$(uci get clash.config.p_mode 2>/dev/null)
sed -i "/^Proxy:/i\#clash-openwrt" $CONFIG_YAML 2>/dev/null
sed -i '1,/#clash-openwrt/d' $CONFIG_YAML 2>/dev/null
cat /usr/share/clash/dns.yaml $CONFIG_YAML > $CONFIG_YAMLL 2>/dev/null
mv $CONFIG_YAMLL $CONFIG_YAML 2>/dev/null
sed -i "1i\#****CLASH-CONFIG-START****#" $CONFIG_YAML 2>/dev/null
sed -i "2i\port: ${http_port}" $CONFIG_YAML 2>/dev/null
sed -i "/port: ${http_port}/a\socks-port: ${socks_port}" $CONFIG_YAML 2>/dev/null
sed -i "/socks-port: ${socks_port}/a\redir-port: ${redir_port}" $CONFIG_YAML 2>/dev/null
sed -i "/redir-port: ${redir_port}/a\allow-lan: ${allow_lan}" $CONFIG_YAML 2>/dev/null
if [ $allow_lan == "true" ]; then
sed -i "/allow-lan: ${allow_lan}/a\bind-address: \"${bind_addr}\"" $CONFIG_YAML 2>/dev/null
sed -i "/bind-address: \"${bind_addr}\"/a\mode: ${p_mode}" $CONFIG_YAML 2>/dev/null
sed -i "/mode: ${p_mode}/a\log-level: ${log_level}" $CONFIG_YAML 2>/dev/null
sed -i "/log-level: ${log_level}/a\external-controller: 0.0.0.0:${dash_port}" $CONFIG_YAML 2>/dev/null
sed -i "/external-controller: 0.0.0.0:${dash_port}/a\secret: \"${da_password}\"" $CONFIG_YAML 2>/dev/null
sed -i "/secret: \"${da_password}\"/a\external-ui: \"/usr/share/clash/dashboard\"" $CONFIG_YAML 2>/dev/null
else
sed -i "/allow-lan: ${allow_lan}/a\mode: Rule" $CONFIG_YAML 2>/dev/null
sed -i "/mode: Rule/a\log-level: ${log_level}" $CONFIG_YAML 2>/dev/null
sed -i "/log-level: ${log_level}/a\external-controller: 0.0.0.0:${dash_port}" $CONFIG_YAML 2>/dev/null
sed -i "/external-controller: 0.0.0.0:${dash_port}/a\secret: \"${da_password}\"" $CONFIG_YAML 2>/dev/null
sed -i "/secret: \"${da_password}\"/a\external-ui: \"/usr/share/clash/dashboard\"" $CONFIG_YAML 2>/dev/null
fi
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Updating Configuration Completed" >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "更新配置完成" >$REAL_LOG
fi
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
sleep 2
use_config=$(uci get clash.config.use_config 2>/dev/null)
if [ "$c_type" -eq 1 ] && [ "$CONFIG_YAML" = "$use_config" ];then
if pidof clash >/dev/null; then
/etc/init.d/clash restart 2>/dev/null
fi
fi
fi
fi
if [ $type == "v2clash" ] && [ ! -z $url ];then
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Updating Configuration..." >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "开始更新配置" >$REAL_LOG
fi
wget --no-check-certificate --user-agent="Clash/OpenWRT" "https://tgbot.lbyczf.com/v2rayn2clash?url=$url" -O 2>&1 >1 $CONFIG_YAML
if [ "$?" -eq "0" ]; then
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Updating Configuration Completed" >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "更新配置完成" >$REAL_LOG
fi
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
sleep 2
use_config=$(uci get clash.config.use_config 2>/dev/null)
if [ "$c_type" -eq 1 ] && [ "$CONFIG_YAML" = "$use_config" ];then
if pidof clash >/dev/null; then
/etc/init.d/clash restart 2>/dev/null
fi
fi
fi
fi
@@ -1,146 +0,0 @@
#!/bin/bash /etc/rc.common
. /lib/functions.sh
c_type=$(uci get clash.config.config_type 2>/dev/null)
countt=$(grep -c '' /usr/share/clashbackup/confit_list.conf)
count_nums=1
while [[ $count_nums -le $countt ]]
do
config_name=$(sed -n "$count_nums"p /usr/share/clashbackup/confit_list.conf| awk -F '#' '{print $1}')
CONFIG_YAML="/usr/share/clash/config/sub/${config_name}"
url=$(grep -F "${config_name}" "/usr/share/clashbackup/confit_list.conf" | awk -F '#' '{print $2}')
lang=$(uci get luci.main.lang 2>/dev/null)
REAL_LOG="/usr/share/clash/update_clash_real.txt"
type=$(grep -F "${config_name}" "/usr/share/clashbackup/confit_list.conf" | awk -F '#' '{print $3}')
if [ $type == "clash" ] && [ ! -z $url ];then
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Updating Configuration..." >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "开始更新配置" >$REAL_LOG
fi
wget --no-check-certificate --user-agent="Clash/OpenWRT" $url -O 2>&1 >1 $CONFIG_YAML
sleep 3
if [ "$?" -eq "0" ]; then
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Updating Configuration Completed" >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "更新配置完成" >$REAL_LOG
fi
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
fi
fi
if [ $type == "ssr2clash" ] && [ ! -z $url ];then
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Updating Configuration..." >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "开始更新配置" >$REAL_LOG
fi
wget --no-check-certificate --user-agent="Clash/OpenWRT" "https://ssrsub2clashr.herokuapp.com/ssrsub2clash?sub=$url" -O 2>&1 >1 $CONFIG_YAML
sleep 3
if [ "$?" -eq "0" ]; then
CONFIG_YAMLL="/tmp/conf"
da_password=$(uci get clash.config.dash_pass 2>/dev/null)
redir_port=$(uci get clash.config.redir_port 2>/dev/null)
http_port=$(uci get clash.config.http_port 2>/dev/null)
socks_port=$(uci get clash.config.socks_port 2>/dev/null)
dash_port=$(uci get clash.config.dash_port 2>/dev/null)
bind_addr=$(uci get clash.config.bind_addr 2>/dev/null)
allow_lan=$(uci get clash.config.allow_lan 2>/dev/null)
log_level=$(uci get clash.config.level 2>/dev/null)
p_mode=$(uci get clash.config.p_mode 2>/dev/null)
sed -i "/^Proxy:/i\#clash-openwrt" $CONFIG_YAML 2>/dev/null
sed -i '1,/#clash-openwrt/d' $CONFIG_YAML 2>/dev/null
cat /usr/share/clash/dns.yaml $CONFIG_YAML > $CONFIG_YAMLL 2>/dev/null
mv $CONFIG_YAMLL $CONFIG_YAML 2>/dev/null
sed -i "1i\#****CLASH-CONFIG-START****#" $CONFIG_YAML 2>/dev/null
sed -i "2i\port: ${http_port}" $CONFIG_YAML 2>/dev/null
sed -i "/port: ${http_port}/a\socks-port: ${socks_port}" $CONFIG_YAML 2>/dev/null
sed -i "/socks-port: ${socks_port}/a\redir-port: ${redir_port}" $CONFIG_YAML 2>/dev/null
sed -i "/redir-port: ${redir_port}/a\allow-lan: ${allow_lan}" $CONFIG_YAML 2>/dev/null
if [ $allow_lan == "true" ]; then
sed -i "/allow-lan: ${allow_lan}/a\bind-address: \"${bind_addr}\"" $CONFIG_YAML 2>/dev/null
sed -i "/bind-address: \"${bind_addr}\"/a\mode: ${p_mode}" $CONFIG_YAML 2>/dev/null
sed -i "/mode: ${p_mode}/a\log-level: ${log_level}" $CONFIG_YAML 2>/dev/null
sed -i "/log-level: ${log_level}/a\external-controller: 0.0.0.0:${dash_port}" $CONFIG_YAML 2>/dev/null
sed -i "/external-controller: 0.0.0.0:${dash_port}/a\secret: \"${da_password}\"" $CONFIG_YAML 2>/dev/null
sed -i "/secret: \"${da_password}\"/a\external-ui: \"/usr/share/clash/dashboard\"" $CONFIG_YAML 2>/dev/null
else
sed -i "/allow-lan: ${allow_lan}/a\mode: Rule" $CONFIG_YAML 2>/dev/null
sed -i "/mode: Rule/a\log-level: ${log_level}" $CONFIG_YAML 2>/dev/null
sed -i "/log-level: ${log_level}/a\external-controller: 0.0.0.0:${dash_port}" $CONFIG_YAML 2>/dev/null
sed -i "/external-controller: 0.0.0.0:${dash_port}/a\secret: \"${da_password}\"" $CONFIG_YAML 2>/dev/null
sed -i "/secret: \"${da_password}\"/a\external-ui: \"/usr/share/clash/dashboard\"" $CONFIG_YAML 2>/dev/null
fi
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Updating Configuration Completed" >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "更新配置完成" >$REAL_LOG
fi
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
fi
fi
if [ $type == "v2clash" ] && [ ! -z $url ];then
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Updating Configuration..." >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "开始更新配置" >$REAL_LOG
fi
wget --no-check-certificate --user-agent="Clash/OpenWRT" "https://tgbot.lbyczf.com/v2rayn2clash?url=$url" -O 2>&1 >1 $CONFIG_YAML
sleep 3
if [ "$?" -eq "0" ]; then
if [ $lang == "en" ] || [ $lang == "auto" ];then
echo "Updating Configuration Completed" >$REAL_LOG
elif [ $lang == "zh_cn" ];then
echo "更新配置完成" >$REAL_LOG
fi
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
fi
fi
count_nums=$(( $count_nums + 1))
done
sleep 2
use=$(uci get clash.config.use_config 2>/dev/null)
if [ "$c_type" -eq 1 ] && [ "$(ls -l $use|awk '{print int($5)}')" -ne 0 ];then
if pidof clash >/dev/null; then
/etc/init.d/clash restart 2>/dev/null
fi
fi
@@ -1,7 +0,0 @@
#!/bin/bash /etc/rc.common
. /lib/functions.sh
name=$(uci get clash.config.config_up_remove 2>/dev/null)
if [ ! -z $name ];then
rm -rf /usr/share/clash/config/upload/${name}
fi
@@ -1 +0,0 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[14],{"+924":function(t,e,n){"use strict";n.d(e,"d",(function(){return o})),n.d(e,"c",(function(){return i})),n.d(e,"b",(function(){return a})),n.d(e,"a",(function(){return s}));var r=n("9AQC");function o(t,e){return void 0===e&&(e=0),"string"!=typeof t||0===e||t.length<=e?t:t.substr(0,e)+"..."}function i(t,e){var n=t,r=n.length;if(r<=150)return n;e>r&&(e=r);var o=Math.max(e-60,0);o<5&&(o=0);var i=Math.min(o+140,r);return i>r-5&&(i=r),i===r&&(o=Math.max(i-140,0)),n=n.slice(o,i),o>0&&(n="'{snip} "+n),i<r&&(n+=" {snip}"),n}function a(t,e){if(!Array.isArray(t))return"";for(var n=[],r=0;r<t.length;r++){var o=t[r];try{n.push(String(o))}catch(t){n.push("[value cannot be serialized]")}}return n.join(e)}function s(t,e){return!!Object(r.k)(t)&&(Object(r.j)(e)?e.test(t):"string"==typeof e&&-1!==t.indexOf(e))}},"3UD+":function(t,e){t.exports=function(t){if(!t.webpackPolyfill){var e=Object.create(t);e.children||(e.children=[]),Object.defineProperty(e,"loaded",{enumerable:!0,get:function(){return e.l}}),Object.defineProperty(e,"id",{enumerable:!0,get:function(){return e.i}}),Object.defineProperty(e,"exports",{enumerable:!0}),e.webpackPolyfill=1}return e}},"6PXS":function(t,e,n){"use strict";(function(t){n.d(e,"b",(function(){return s})),n.d(e,"e",(function(){return c})),n.d(e,"d",(function(){return l})),n.d(e,"c",(function(){return d})),n.d(e,"a",(function(){return v}));n("mrSG");var r=n("9AQC"),o=n("wCA9"),i=n("9/Zf"),a=n("+924");function s(t,e,n){if(e in t){var r=t[e],o=n(r);if("function"==typeof o)try{o.prototype=o.prototype||{},Object.defineProperties(o,{__sentry_original__:{enumerable:!1,value:r}})}catch(t){}t[e]=o}}function c(t){return Object.keys(t).map((function(e){return encodeURIComponent(e)+"="+encodeURIComponent(t[e])})).join("&")}function u(t){if(Object(r.d)(t)){var e=t,n={message:e.message,name:e.name,stack:e.stack};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&(n[o]=e[o]);return n}if(Object(r.f)(t)){var a=t,s={};s.type=a.type;try{s.target=Object(r.c)(a.target)?Object(i.h)(a.target):Object.prototype.toString.call(a.target)}catch(t){s.target="<unknown>"}try{s.currentTarget=Object(r.c)(a.currentTarget)?Object(i.h)(a.currentTarget):Object.prototype.toString.call(a.currentTarget)}catch(t){s.currentTarget="<unknown>"}for(var o in"undefined"!=typeof CustomEvent&&Object(r.g)(t,CustomEvent)&&(s.detail=a.detail),a)Object.prototype.hasOwnProperty.call(a,o)&&(s[o]=a);return s}return t}function p(t){return function(t){return~-encodeURI(t).split(/%..|./).length}(JSON.stringify(t))}function l(t,e,n){void 0===e&&(e=3),void 0===n&&(n=102400);var r=d(t,e);return p(r)>n?l(t,e-1,n):r}function f(e,n){return"domain"===n&&e&&"object"==typeof e&&e._events?"[Domain]":"domainEmitter"===n?"[DomainEmitter]":void 0!==t&&e===t?"[Global]":"undefined"!=typeof window&&e===window?"[Window]":"undefined"!=typeof document&&e===document?"[Document]":Object(r.l)(e)?"[SyntheticEvent]":"number"==typeof e&&e!=e?"[NaN]":void 0===e?"[undefined]":"function"==typeof e?"[Function: "+Object(i.e)(e)+"]":e}function h(t,e,n,i){if(void 0===n&&(n=1/0),void 0===i&&(i=new o.a),0===n)return function(t){var e=Object.prototype.toString.call(t);if("string"==typeof t)return t;if("[object Object]"===e)return"[Object]";if("[object Array]"===e)return"[Array]";var n=f(t);return Object(r.i)(n)?n:e}(e);if(null!=e&&"function"==typeof e.toJSON)return e.toJSON();var a=f(e,t);if(Object(r.i)(a))return a;var s=u(e),c=Array.isArray(e)?[]:{};if(i.memoize(e))return"[Circular ~]";for(var p in s)Object.prototype.hasOwnProperty.call(s,p)&&(c[p]=h(p,s[p],n-1,i));return i.unmemoize(e),c}function d(t,e){try{return JSON.parse(JSON.stringify(t,(function(t,n){return h(t,n,e)})))}catch(t){return"**non-serializable**"}}function v(t,e){void 0===e&&(e=40);var n=Object.keys(u(t));if(n.sort(),!n.length)return"[object has no keys]";if(n[0].length>=e)return Object(a.d)(n[0],e);for(var r=n.length;r>0;r--){var o=n.slice(0,r).join(", ");if(!(o.length>e))return r===n.length?o:Object(a.d)(o,e)}return""}}).call(this,n("yLpj"))},"8oxB":function(t,e){var n,r,o=t.exports={};function i(){throw new Error("setTimeout has not been defined")}function a(){throw new Error("clearTimeout has not been defined")}function s(t){if(n===setTimeout)return setTimeout(t,0);if((n===i||!n)&&setTimeout)return n=setTimeout,setTimeout(t,0);try{return n(t,0)}catch(e){try{return n.call(null,t,0)}catch(e){return n.call(this,t,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:i}catch(t){n=i}try{r="function"==typeof clearTimeout?clearTimeout:a}catch(t){r=a}}();var c,u=[],p=!1,l=-1;function f(){p&&c&&(p=!1,c.length?u=c.concat(u):l=-1,u.length&&h())}function h(){if(!p){var t=s(f);p=!0;for(var e=u.length;e;){for(c=u,u=[];++l<e;)c&&c[l].run();l=-1,e=u.length}c=null,p=!1,function(t){if(r===clearTimeout)return clearTimeout(t);if((r===a||!r)&&clearTimeout)return r=clearTimeout,clearTimeout(t);try{r(t)}catch(e){try{return r.call(null,t)}catch(e){return r.call(thLine truncated
@@ -1 +0,0 @@
yacd.haishan.me
@@ -1,12 +0,0 @@
# for netlify hosting
# https://docs.netlify.com/routing/headers/#syntax-for-the-headers-file
/*
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
/*.css
Cache-Control: public, max-age=31536000, immutable
/*.js
Cache-Control: public, max-age=31536000, immutable
@@ -1,20 +0,0 @@
/*! modern-normalize v0.7.0 | MIT License | https://github.com/sindresorhus/modern-normalize */*,:after,:before{box-sizing:border-box}:root{-moz-tab-size:4;tab-size:4}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0;font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji}hr{height:0}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}legend{padding:0}progress{vertical-align:initial}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}
@font-face{font-family:Roboto Mono;font-style:normal;font-display:swap;font-weight:400;src:local("Roboto Mono Regular "),local("Roboto Mono-Regular"),url(roboto-mono-latin-400.woff2) format("woff2")}@font-face{font-family:Open Sans;font-style:normal;font-display:swap;font-weight:400;src:local("Open Sans Regular "),local("Open Sans-Regular"),url(open-sans-latin-400.woff2) format("woff2")}@font-face{font-family:Open Sans;font-style:normal;font-display:swap;font-weight:700;src:local("Open Sans Bold "),local("Open Sans-Bold"),url(open-sans-latin-700.woff2) format("woff2")}.border-bottom,.border-left,.border-top,.relative{position:relative}.border-top:before{top:0}.border-bottom:after,.border-top:before{position:absolute;content:"";height:1px;width:100%;transform:scaleY(.5) translateZ(0);left:0;right:0;background:#555}.border-bottom:after{bottom:0}.border-left:before{position:absolute;content:"";height:100%;width:1px;transform:scaleX(.5) translateZ(0);top:0;bottom:0;background:#555;left:0}*,:after,:before{box-sizing:border-box}:root{--font-mono:"Roboto Mono",Menlo,monospace;--font-normal:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,"PingFang SC","Microsoft YaHei","微软雅黑",Arial,sans-serif;--color-focus-blue:#1a73e8}body{font-family:Open Sans,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,PingFang SC,Microsoft YaHei,微软雅黑;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-text-size-adjust:100%;-webkit-font-smoothing:antialiased;margin:0;padding:0}body,body.dark{--color-background:#202020;--color-text:#ddd;--color-text-secondary:#ccc;--color-text-highlight:#fff;--color-bg-sidebar:#2d2d30;--color-sb-active-row-bg:#494b4e;--color-input-bg:#2d2d30;--color-input-border:#3f3f3f;--color-toggle-bg:#353535;--color-toggle-selected:#181818;--color-icon:#c7c7c7;--color-separator:#333;--color-btn-bg:#232323;--color-btn-fg:#bebebe;--color-bg-proxy:#303030;--color-row-odd:#282828;--bg-modal:#1f1f20;--bg-near-transparent:hsla(0,0%,100%,0.1);--select-border-color:#040404;--select-bg-hover:url("data:image/svg+xml;charset=utf-8,%3Csvg width='8' height='24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4 7l3 4H1l3-4zM4 17l-3-4h6l-3 4z' fill='%23fff'/%3E%3C/svg%3E")}body.light{--color-background:#fbfbfb;--color-text:#222;--color-text-secondary:#646464;--color-text-highlight:#040404;--color-bg-sidebar:#e7e7e7;--color-sb-active-row-bg:#d0d0d0;--color-input-bg:#fff;--color-input-border:silver;--color-toggle-bg:#fff;--color-toggle-selected:#d7d7d7;--color-icon:#5b5b5b;--color-separator:#ccc;--color-btn-bg:#f4f4f4;--color-btn-fg:#101010;--color-bg-proxy:#e7e7e7;--color-row-odd:#f5f5f5;--bg-modal:#fbfbfb;--bg-near-transparent:rgba(0,0,0,0.1);--select-border-color:#999;--select-bg-hover:url("data:image/svg+xml;charset=utf-8,%3Csvg width='8' height='24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4 7l3 4H1l3-4zM4 17l-3-4h6l-3 4z' fill='%23222'/%3E%3C/svg%3E")}.flexCenter{display:flex;align-items:center;justify-content:center}.fabgrp{position:fixed;z-index:3;right:20px;bottom:20px}
._24ddJm1Q5s{height:76px;display:flex;align-items:center}.B4QNkMu-0t{padding:0 15px;font-size:1.7em;text-align:left;margin:0}@media screen and (min-width:30em){.B4QNkMu-0t{padding:0 40px;font-size:2em}}
.cHbZy_rAHf{padding:6px 15px}@media screen and (min-width:30em){.cHbZy_rAHf{padding:10px 40px}}._2SNe_x81Ib{font-family:var(--font-mono)}.LUI6m76ply{color:var(--color-text-secondary);display:inline-flex}.LUI6m76ply:hover{color:var(--color-text-highlight)}
._2-70itbuF1:focus{outline:none}.JKE-0c5hxF{display:flex;justify-content:center;align-items:center}.JKE-0c5hxF .o2VhY_cs6Z{color:#2d2d30;opacity:.4;transition:opacity .4s}.JKE-0c5hxF .o2VhY_cs6Z:hover{opacity:.7}._3QDGxJ_pWs{padding:30px 0 10px}.tTZzzcEsTA{display:flex}.tTZzzcEsTA div{flex:1 1 auto}.tTZzzcEsTA div:nth-child(2){flex-grow:0;flex-basis:120px;margin-left:10px}._3OT00Mqmrw{padding:30px 0 10px;display:flex;justify-content:flex-end;align-items:center}
._796AqwOFs_{-webkit-appearance:none;outline:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;position:relative;display:inline-flex;align-items:center;justify-content:center;color:var(--color-btn-fg);background:var(--color-btn-bg);border:1px solid #555;border-radius:100px}._796AqwOFs_:focus{border-color:var(--color-focus-blue)}._796AqwOFs_:hover{background:#387cec;border:1px solid #387cec;color:#fff}._796AqwOFs_:active{transform:scale(.97)}._796AqwOFs_{font-size:.85em;padding:4px 7px}@media screen and (min-width:30em){._796AqwOFs_{font-size:1em;padding:6px 12px}}._796AqwOFs_._1bLZvI40oA{border-color:transparent;background:none}._796AqwOFs_._1bLZvI40oA:focus{border-color:var(--color-focus-blue)}._796AqwOFs_._1bLZvI40oA:hover{color:#fff;background:#387cec;border:1px solid #387cec}._796AqwOFs_:disabled{opacity:.5}._1SrCTG7yDt{margin-right:5px;display:inline-flex;align-items:center;justify-content:center}._39VuJRXAmL{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);display:inline-flex}
h2.Q-CsP5Y3FT{margin:0;font-size:1.3em}@media screen and (min-width:30em){h2.Q-CsP5Y3FT{font-size:1.5em}}h2.Q-CsP5Y3FT span:nth-child(2){font-size:12px;color:#777;font-weight:400;margin:0 .3em}body.light{--loading-dot-1-1:rgba(0,0,0,0.1);--loading-dot-1-2:rgba(0,0,0,0.5);--loading-dot-1-3:rgba(0,0,0,0.3);--loading-dot-2-1:rgba(0,0,0,0.3);--loading-dot-2-2:rgba(0,0,0,0.1);--loading-dot-2-3:rgba(0,0,0,0.5);--loading-dot-3-1:rgba(0,0,0,0.5);--loading-dot-3-2:rgba(0,0,0,0.3);--loading-dot-3-3:rgba(0,0,0,0.1)}body.dark{--loading-dot-1-1:hsla(0,0%,100%,0.5);--loading-dot-1-2:hsla(0,0%,100%,0.1);--loading-dot-1-3:hsla(0,0%,100%,0.3);--loading-dot-2-1:hsla(0,0%,100%,0.3);--loading-dot-2-2:hsla(0,0%,100%,0.5);--loading-dot-2-3:hsla(0,0%,100%,0.1);--loading-dot-3-1:hsla(0,0%,100%,0.1);--loading-dot-3-2:hsla(0,0%,100%,0.3);--loading-dot-3-3:hsla(0,0%,100%,0.5)}._3GL3LmFL_E,._3GL3LmFL_E:after,._3GL3LmFL_E:before{display:inline-block;vertical-align:middle;width:6px;height:6px;border-radius:50%;font-size:0}._3GL3LmFL_E{position:relative;background-color:var(--loading-dot-2-1);animation:uZWMZR9nBW 1s step-start infinite}._3GL3LmFL_E:before{content:"";position:absolute;left:-12px;background-color:var(--loading-dot-1-1);animation:saNygeIhRC 1s step-start infinite}._3GL3LmFL_E:after{content:"";position:absolute;right:-12px;background-color:var(--loading-dot-3-1);animation:_3RtxWfV4g4 1s step-start infinite}@keyframes saNygeIhRC{0%,to{background-color:var(--loading-dot-1-1)}33%{background-color:var(--loading-dot-1-2)}66%{background-color:var(--loading-dot-1-3)}}@keyframes uZWMZR9nBW{0%,to{background-color:var(--loading-dot-2-1)}33%{background-color:var(--loading-dot-2-2)}66%{background-color:var(--loading-dot-2-3)}}@keyframes _3RtxWfV4g4{0%,to{background-color:var(--loading-dot-3-1)}33%{background-color:var(--loading-dot-3-2)}66%{background-color:var(--loading-dot-3-3)}}
._2uN43zExEi{position:relative;padding:10px 0}._2uN43zExEi input{-webkit-appearance:none;background-color:initial;background-image:none;border:none;border-radius:0;border-bottom:1px solid var(--color-input-border);box-sizing:border-box;color:#c1c1c1;display:inline-block;font-size:inherit;height:40px;outline:none;padding:0 8px;transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}._2uN43zExEi input:focus{border-color:var(--color-focus-blue)}._2uN43zExEi label{position:absolute;left:8px;bottom:22px;transition:transform .15s ease-in-out;transform-origin:0 0}._2uN43zExEi input:focus+label,._2uN43zExEi label._2gQ0j5OHC8{transform:scale(.75) translateY(-25px)}._2uN43zExEi input:focus+label{color:var(--color-focus-blue)}
._3MvgliBN_D{stroke-dasharray:890;stroke-dashoffset:890;animation:_2C1TpO8LMn 3s ease-in-out infinite normal forwards}@keyframes _2C1TpO8LMn{0%{stroke-dashoffset:890}to{stroke-dashoffset:0}}
._2vs8ks4GvR._2vs8ks4GvR{background:none;position:fixed;top:0;bottom:0;left:0;right:0;transform:none;padding:0;border-radius:0;display:flex;justify-content:center}.Z8vSJz0PbL{position:relative;top:10%;margin-left:20px;margin-right:20px}.EWfRQXOK8M.EWfRQXOK8M{background:#222}
._2ueF0jmjym{position:fixed;top:0;right:0;left:0;bottom:0;background:#444;z-index:1024}.UZ5fqyDCOb{outline:none;position:relative;color:#ddd;top:50%;left:50%;transform:translate(-50%,-50%);background:#444;padding:20px;border-radius:10px}
._113JVByWGF{position:fixed;top:0;bottom:0;left:0;right:0;overflow:hidden;padding:20px;background:var(--color-background);color:var(--color-text);text-align:center}._1m2ZsnzFvt{color:#2a477a;opacity:.6;display:flex;justify-content:center;padding:40px}._3TKFOM4Tgj,._1m2ZsnzFvt{align-items:center}._3TKFOM4Tgj{display:inline-flex;color:var(--color-text-secondary)}._3TKFOM4Tgj:active,._3TKFOM4Tgj:hover{color:#387cec}._3TKFOM4Tgj svg{margin-right:5px}
._2kr0S-YLqE{padding:6px 15px}@media screen and (min-width:30em){._2kr0S-YLqE{padding:10px 40px}}
._12V5kDiPEH{width:100%;height:100%;display:flex;justify-content:center;align-items:center}._2FcudZSVil{--color1:#ddd;--size:40px;width:var(--size);height:var(--size);margin:10px;background-color:var(--color1);border-radius:100%;animation:_3gvFm3l86P 1s ease-in-out infinite}@keyframes _3gvFm3l86P{0%{transform:scale(0)}to{transform:scale(1);opacity:0}}
._2n4kL7wLDR{color:var(--color-text);display:flex;align-items:center;flex-wrap:wrap}._2n4kL7wLDR .sec{padding:10px;width:180px}._2n4kL7wLDR .sec div:first-child{color:var(--color-text-secondary);font-size:.7em}._2n4kL7wLDR .sec div:nth-child(2){padding:10px 0 0;font-size:1.8em}
._2fg1R7Zu62{opacity:.5;width:100%;height:100%;display:flex;justify-content:center;align-items:center}
._1X99PPGcn7{display:flex;background:var(--color-background);color:var(--color-text);min-height:300px;height:100vh}@media (max-width:768px){._1X99PPGcn7{flex-direction:column}}._2oV8uPP0dj{flex-grow:1;overflow:auto}
._3sTuXodYya{background:var(--color-bg-sidebar);position:relative}._1WdrygzFVZ{height:15px}@media (max-width:768px){._1WdrygzFVZ{display:none}}@media (max-width:768px){.q9nBJwAvlz{display:flex;justify-content:space-between;overflow:scroll}}._3yqSXpep4D{color:var(--color-text);text-decoration:none;display:flex;align-items:center;padding:6px 16px}@media screen and (min-width:30em){._3yqSXpep4D{padding:8px 20px}}@media (max-width:768px){._3yqSXpep4D{flex-direction:column}}._3yqSXpep4D svg{color:var(--color-icon);width:22px;height:22px}@media screen and (min-width:30em){._3yqSXpep4D svg{width:24px;height:24px}}._3wqPc_btNi{background:var(--color-sb-active-row-bg)}@media (max-width:768px){._3wqPc_btNi{background:none;border-bottom:2px solid #387cec}}._2sd59kze-t{padding-left:14px;font-size:.75em}@media (max-width:768px){._2sd59kze-t{padding-left:0;padding-top:5px}}@media screen and (min-width:30em){._2sd59kze-t{font-size:1em}}._2o6aUGu--S{position:absolute;bottom:10px;left:50%;transform:translateX(-50%)}@media (max-width:768px){._2o6aUGu--S{display:none}}._11NITPe4W7{--sz:40px;width:var(--sz);height:var(--sz);display:flex;justify-content:center;align-items:center;outline:none;padding:5px;color:var(--color-text);border-radius:100%;border:1px solid transparent}._11NITPe4W7:hover{opacity:.6}._11NITPe4W7:focus{border-color:var(--color-focus-blue)}._1kzEILbWHq{-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;background:none;cursor:pointer}
._2DECxrOsTa{-webkit-appearance:none;background-color:var(--color-input-bg);background-image:none;border-radius:4px;border:1px solid var(--color-input-border);box-sizing:border-box;color:#c1c1c1;display:inline-block;font-size:inherit;height:40px;outline:none;padding:0 15px;transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}._2DECxrOsTa:focus{border-color:var(--color-focus-blue)}input::-webkit-inner-spin-button,input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}
._2IgDTE__bQ{-webkit-user-select:none;-ms-user-select:none;user-select:none;border:1px solid #525252;color:var(--color-text);background:var(--color-toggle-bg);display:flex;position:relative;outline:none}._2IgDTE__bQ:focus{border-color:var(--color-focus-blue)}._2IgDTE__bQ input{position:absolute;left:0;opacity:0}._2IgDTE__bQ label{z-index:2;display:flex;align-items:center;justify-content:center;padding:10px 0;cursor:pointer}._2IfOm9qQ_4{z-index:1;position:absolute;display:block;left:0;height:100%;transition:left .2s ease-out;background:var(--color-toggle-selected)}
@@ -1,2 +0,0 @@
/*! For license information please see app.8bd641dadb8c0be21576.js.LICENSE.txt */
(window.webpackJsonp=window.webpackJsonp||[]).push([[2],{"+FPD":function(t,e,n){"use strict";n.d(e,"c",(function(){return c})),n.d(e,"b",(function(){return l})),n.d(e,"e",(function(){return f})),n.d(e,"a",(function(){return p})),n.d(e,"d",(function(){return d}));n("TeQF"),n("yXV3");function r(t,e){return t===e}function o(t,e,n){if(null===e||null===n||e.length!==n.length)return!1;for(var r=e.length,o=0;o<r;o++)if(!t(e[o],n[o]))return!1;return!0}function i(t){var e=Array.isArray(t[0])?t[0]:t;if(!e.every((function(t){return"function"==typeof t}))){var n=e.map((function(t){return typeof t})).join(", ");throw new Error("Selector creators expect all input-selectors to be functions, instead received the following types: ["+n+"]")}return e}var a=function(t){for(var e=arguments.length,n=Array(e>1?e-1:0),r=1;r<e;r++)n[r-1]=arguments[r];return function(){for(var e=arguments.length,r=Array(e),o=0;o<e;o++)r[o]=arguments[o];var a=0,s=r.pop(),u=i(r),c=t.apply(void 0,[function(){return a++,s.apply(null,arguments)}].concat(n)),l=t((function(){for(var t=[],e=u.length,n=0;n<e;n++)t.push(u[n].apply(null,arguments));return c.apply(null,t)}));return l.resultFunc=s,l.dependencies=u,l.recomputations=function(){return a},l.resetRecomputations=function(){return a=0},l}}((function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:r,n=null,i=null;return function(){return o(e,n,arguments)||(i=t.apply(null,arguments)),n=arguments,i}}));var s=function(t){return t.logs.logs},u=function(t){return t.logs.tail},c=function(t){return t.logs.searchText},l=a(s,u,c,(function(t,e,n){for(var r=[],o=e;o>=0;o--)r.push(t[o]);if(300===t.length)for(var i=299;i>e;i--)r.push(t[i]);return""===n?r:r.filter((function(t){return t.payload.toLowerCase().indexOf(n)>=0}))}));function f(t){return function(e){e("logsUpdateSearchText",(function(e){e.logs.searchText=t.toLowerCase()}))}}function p(t){return function(e,n){var r=n(),o=s(r),i=u(r),a=i>=299?0:i+1;o[a]=t,e("logsAppendLog",(function(t){t.logs.tail=a}))}}var d={searchText:"",logs:[],tail:-1}},"+wdc":function(t,e,n){"use strict";var r,o,i,a,s;if(Object.defineProperty(e,"__esModule",{value:!0}),"undefined"==typeof window||"function"!=typeof MessageChannel){var u=null,c=null,l=function(){if(null!==u)try{var t=e.unstable_now();u(!0,t),u=null}catch(t){throw setTimeout(l,0),t}},f=Date.now();e.unstable_now=function(){return Date.now()-f},r=function(t){null!==u?setTimeout(r,0,t):(u=t,setTimeout(l,0))},o=function(t,e){c=setTimeout(t,e)},i=function(){clearTimeout(c)},a=function(){return!1},s=e.unstable_forceFrameRate=function(){}}else{var p=window.performance,d=window.Date,h=window.setTimeout,v=window.clearTimeout;if("undefined"!=typeof console){var m=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof m&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")}if("object"==typeof p&&"function"==typeof p.now)e.unstable_now=function(){return p.now()};else{var y=d.now();e.unstable_now=function(){return d.now()-y}}var g=!1,b=null,w=-1,O=5,x=0;a=function(){return e.unstable_now()>=x},s=function(){},e.unstable_forceFrameRate=function(t){0>t||125<t?console.error("forceFrameRate takes a positive int between 0 and 125, forcing framerates higher than 125 fps is not unsupported"):O=0<t?Math.floor(1e3/t):5};var E=new MessageChannel,S=E.port2;E.port1.onmessage=function(){if(null!==b){var t=e.unstable_now();x=t+O;try{b(!0,t)?S.postMessage(null):(g=!1,b=null)}catch(t){throw S.postMessage(null),t}}else g=!1},r=function(t){b=t,g||(g=!0,S.postMessage(null))},o=function(t,n){w=h((function(){t(e.unstable_now())}),n)},i=function(){v(w),w=-1}}function j(t,e){var n=t.length;t.push(e);t:for(;;){var r=n-1>>>1,o=t[r];if(!(void 0!==o&&0<k(o,e)))break t;t[r]=e,t[n]=o,n=r}}function C(t){return void 0===(t=t[0])?null:t}function P(t){var e=t[0];if(void 0!==e){var n=t.pop();if(n!==e){t[0]=n;t:for(var r=0,o=t.length;r<o;){var i=2*(r+1)-1,a=t[i],s=i+1,u=t[s];if(void 0!==a&&0>k(a,n))void 0!==u&&0>k(u,a)?(t[r]=u,t[s]=n,r=s):(t[r]=a,t[i]=n,r=i);else{if(!(void 0!==u&&0>k(u,n)))break t;t[r]=u,t[s]=n,r=s}}}return e}return null}function k(t,e){var n=t.sortIndex-e.sortIndex;return 0!==n?n:t.id-e.id}var T=[],A=[],R=1,L=null,M=3,_=!1,D=!1,N=!1;function V(t){for(var e=C(A);null!==e;){if(null===e.callback)P(A);else{if(!(e.startTime<=t))break;P(A),e.sortIndex=e.expirationTime,j(T,e)}e=C(A)}}function F(t){if(N=!1,V(t),!D)if(null!==C(T))D=!0,r(B);else{var e=C(A);null!==e&&o(F,e.startTime-t)}}function B(t,n){D=!1,N&&(N=!1,i()),_=!0;var r=M;try{for(V(n),L=C(T);null!==L&&(!(L.expirationTime>n)||t&&!a());){var s=L.callback;if(null!==s){L.callback=null,M=L.priorityLevel;var u=s(L.expirationTime<=n);n=e.unstable_now(),"function"==typeof u?L.callback=u:L===C(T)&&P(T),V(nLine truncated
@@ -1,56 +0,0 @@
/*
object-assign
(c) Sindre Sorhus
@license MIT
*/
/*!
Copyright (c) 2015 Jed Watson.
Based on code that is Copyright 2013-2015, Facebook, Inc.
All rights reserved.
*/
/*!
* Adapted from jQuery UI core
*
* http://jqueryui.com
*
* Copyright 2014 jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*
* http://api.jqueryui.com/category/ui-core/
*/
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/** @license React v0.0.0-experimental-241c4467e
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v16.6.1
* react-cache.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
@@ -1 +0,0 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[3],{EeQf:function(e,t,a){"use strict";a.r(t);a("pNMO"),a("TeQF"),a("QWBl"),a("2B1R"),a("+2oP"),a("27RR"),a("FZtP");var n=a("rePB"),r=a("ODXe"),l=a("17x9"),c=a.n(l),o=a("q1tI"),i=a.n(o),s=a("OADI"),u=a("vJea"),p=a("n57c"),b=a("S7Mu"),d=a.n(b),m=a("DKqX"),f=a("/P0+"),v=a("iuhU"),O=a("uLK7"),y=a.n(O);function g(e){var t=e.OptionComponent,a=e.optionPropsList,n=e.selectedIndex,r=e.onChange;return i.a.createElement("div",{className:y.a.root},a.map((function(e,a){var l=Object(v.a)(y.a.item,{[y.a.itemActive]:a===n}),c=function(e){e.preventDefault(),a!==n&&r(a)};return i.a.createElement("div",{key:a,className:l,tabIndex:0,role:"menuitem",onKeyDown:c,onClick:c},i.a.createElement(t,e))})))}g.propTypes={OptionComponent:l.func,optionPropsList:l.array,selectedIndex:l.number,onChange:l.func};var j=a("WfPo"),E=a("hkBY"),w=a("Utih"),h=a("aK+U"),P=a("zouR");function k(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function C(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?k(Object(a),!0).forEach((function(t){Object(n.a)(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):k(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}var x={legend:{display:!1},scales:{xAxes:[{display:!1}],yAxes:[{display:!1}]}},D=[23e3,35e3,46e3,33e3,9e4,68e3,23e3,45e3],N=[184e3,183e3,196e3,182e3,19e4,186e3,182e3,189e3],I=D;function S(e){var t=e.id,a=P.a.read(),n=Object(o.useMemo)((function(){return{labels:I,datasets:[C(C(C({},P.d),P.b[t].up),{},{data:D}),C(C(C({},P.d),P.b[t].down),{},{data:N})]}}),[t]),r="chart-"+t;return Object(h.a)(a,r,n,null,x),i.a.createElement("div",{style:{width:130,padding:5}},i.a.createElement("canvas",{id:r}))}function L(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function A(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?L(Object(a),!0).forEach((function(t){Object(n.a)(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):L(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}var R=i.a.useEffect,T=i.a.useState,U=i.a.useCallback,M=i.a.useRef,K=i.a.useMemo,_=[{id:0},{id:1},{id:2},{id:3}],B=[{label:"Global",value:"Global"},{label:"Rule",value:"Rule"},{label:"Direct",value:"Direct"}],W=[{label:"info",value:"info"},{label:"warning",value:"warning"},{label:"error",value:"error"},{label:"debug",value:"debug"},{label:"silent",value:"silent"}],Q=[{key:"port",label:"HTTP Proxy Port"},{key:"socks-port",label:"SOCKS5 Proxy Port"},{key:"mixed-port",label:"Mixed Port"},{key:"redir-port",label:"Redir Port"}],q=Object(j.a)((function(e){return{selectedChartStyleIndex:Object(s.h)(e),latencyTestUrl:Object(s.f)(e),apiConfig:Object(s.c)(e)}}))((function(e){var t=e.dispatch,a=e.configs,n=e.selectedChartStyleIndex,l=e.latencyTestUrl,c=e.apiConfig,o=T(a),b=Object(r.a)(o,2),v=b[0],O=b[1],y=M(a);R((function(){y.current!==a&&O(a),y.current=a}),[a]);var h=U((function(e,t){O(A(A({},v),{},{[e]:t}))}),[v]),P=U((function(e){var a=e;h("allow-lan",a),t(Object(u.e)(c,{"allow-lan":a}))}),[c,t,h]),k=U((function(e){var a=e.target,n=a.name,r=a.value;switch(a.name){case"mode":case"log-level":h(n,r),t(Object(u.e)(c,{[n]:r}));break;case"redir-port":case"socks-port":case"mixed-port":case"port":if(""!==a.value){var l=parseInt(a.value,10);if(l<0||l>65535)return}h(n,r);break;default:return}}),[c,t,h]),C=Object(j.c)(),x=C.selectChartStyleIndex,D=C.updateAppConfig,N=U((function(e){var a=e.target,n=a.name,r=a.value;switch(n){case"port":case"socks-port":case"mixed-port":case"redir-port":var l=parseInt(r,10);if(l<0||l>65535)return;t(Object(u.e)(c,{[n]:l}));break;case"latencyTestUrl":D(n,r);break;default:throw new Error("unknown input name "+n)}}),[c,t,D]),I=K((function(){var e=v.mode;return"string"==typeof e&&e[0].toUpperCase()+e.slice(1)}),[v.mode]);return i.a.createElement("div",null,i.a.createElement(m.a,{title:"Config"}),i.a.createElement("div",{className:d.a.root},Q.map((function(e){return void 0!==v[e.key]?i.a.createElement("div",{key:e.key},i.a.createElement("div",{className:d.a.label},e.label),i.a.createElement(f.b,{name:e.key,value:v[e.key],onChange:k,onBlur:N})):null})),i.a.createElement("div",null,i.a.createElement("div",{className:d.a.label},"Allow LAN"),i.a.createElement(E.a,{name:"allow-lan",checked:v["allow-lan"],onChange:P})),i.a.createElement("div",null,i.a.createElement("div",{className:d.a.label},"Mode"),i.a.createElement(w.a,{options:B,name:"mode",value:I,onChange:k})),i.a.createElement(Line truncated
@@ -1,2 +0,0 @@
._2drigWG08z>div{min-width:345px}@media screen and (min-width:30em){._2drigWG08z>div{width:360px}}._2drigWG08z,._3qy5-MPwaw{padding:6px 15px 15px}@media screen and (min-width:30em){._2drigWG08z,._3qy5-MPwaw{padding:10px 40px 40px}}._1sbDIR8sCY{padding:0 15px}@media screen and (min-width:30em){._1sbDIR8sCY{padding:0 40px}}._1sbDIR8sCY>div{border-top:1px dashed #373737}._1Hvw0QbyvH{padding:16px 0}
._3uy3l7xDdI{display:flex;flex-wrap:wrap}._2hwDLKbh5f{flex-grow:0;margin-right:10px;margin-bottom:10px;cursor:pointer;border:2px solid transparent}._1OeAkW2Cff{border-color:#387cec}
Loaded 100 of 149 files, more files were not shown because too many files have changed in this diff. Show more