瀏覽代碼

Preview in development

# Important improvement
Rewrite startup code to speed up startup
Same as global server, no need to start multiple processes
Use unified path and configuration

# Changes
Add Reset default settings
Optimize the use of shadowsocks plugin
Remove the sh script used in update and modify the UI usage
Remove Easylist China from adblock and add NEO DEV HOST
Adjust the parameters used by wget to ensure compatibility

# Fixes
Fix the issue of starting twice after apply in the server node list
Fix the problem that dnsmasq fails to start when the access control list contains wrong entries
Mattraks 4 年之前
父節點
當前提交
703bcc9763
共有 48 個文件被更改,包括 1657 次插入1449 次删除
  1. 4 16
      luci-app-ssr-plus/Makefile
  2. 26 66
      luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua
  3. 17 11
      luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua
  4. 210 165
      luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua
  5. 16 13
      luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua
  6. 8 8
      luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua
  7. 3 3
      luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua
  8. 36 37
      luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua
  9. 35 36
      luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua
  10. 16 23
      luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua
  11. 75 68
      luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua
  12. 0 1
      luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm
  13. 1 12
      luci-app-ssr-plus/luasrc/view/shadowsocksr/checkport.htm
  14. 8 6
      luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm
  15. 25 0
      luci-app-ssr-plus/luasrc/view/shadowsocksr/reset.htm
  16. 1 19
      luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm
  17. 0 8
      luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm
  18. 54 0
      luci-app-ssr-plus/po/zh-cn/ssr-plus.po
  19. 0 42
      luci-app-ssr-plus/root/etc/config/shadowsocksr
  20. 486 376
      luci-app-ssr-plus/root/etc/init.d/shadowsocksr
  21. 0 0
      luci-app-ssr-plus/root/etc/ssrplus/ad.conf
  22. 0 0
      luci-app-ssr-plus/root/etc/ssrplus/black.list
  23. 2 0
      luci-app-ssr-plus/root/etc/ssrplus/china_ssr.txt
  24. 0 0
      luci-app-ssr-plus/root/etc/ssrplus/deny.list
  25. 0 0
      luci-app-ssr-plus/root/etc/ssrplus/gfw_base.conf
  26. 10 0
      luci-app-ssr-plus/root/etc/ssrplus/gfw_list.conf
  27. 0 0
      luci-app-ssr-plus/root/etc/ssrplus/netflix.list
  28. 0 0
      luci-app-ssr-plus/root/etc/ssrplus/netflixip.list
  29. 0 0
      luci-app-ssr-plus/root/etc/ssrplus/oversea_list.conf
  30. 0 0
      luci-app-ssr-plus/root/etc/ssrplus/white.list
  31. 13 14
      luci-app-ssr-plus/root/etc/uci-defaults/luci-ssr-plus
  32. 0 10
      luci-app-ssr-plus/root/usr/bin/ssr-ad
  33. 0 27
      luci-app-ssr-plus/root/usr/bin/ssr-gfw
  34. 21 61
      luci-app-ssr-plus/root/usr/bin/ssr-monitor
  35. 72 72
      luci-app-ssr-plus/root/usr/bin/ssr-rules
  36. 15 26
      luci-app-ssr-plus/root/usr/bin/ssr-switch
  37. 6 6
      luci-app-ssr-plus/root/usr/share/rpcd/acl.d/luci-app-ssr-plus.json
  38. 1 1
      luci-app-ssr-plus/root/usr/share/shadowsocksr/chinaipset.sh
  39. 171 0
      luci-app-ssr-plus/root/usr/share/shadowsocksr/gen_config.lua
  40. 85 62
      luci-app-ssr-plus/root/usr/share/shadowsocksr/genred2config.sh
  41. 0 40
      luci-app-ssr-plus/root/usr/share/shadowsocksr/gentrojanconfig.lua
  42. 0 117
      luci-app-ssr-plus/root/usr/share/shadowsocksr/genv2config.lua
  43. 38 50
      luci-app-ssr-plus/root/usr/share/shadowsocksr/gfw2ipset.sh
  44. 1 1
      luci-app-ssr-plus/root/usr/share/shadowsocksr/ssrplusupdate.sh
  45. 19 30
      luci-app-ssr-plus/root/usr/share/shadowsocksr/subscribe.lua
  46. 166 19
      luci-app-ssr-plus/root/usr/share/shadowsocksr/update.lua
  47. 3 3
      tcping/Makefile
  48. 13 0
      tcping/patches/0001-Remove-strip.patch

+ 4 - 16
luci-app-ssr-plus/Makefile

@@ -1,14 +1,12 @@
 include $(TOPDIR)/rules.mk
 include $(TOPDIR)/rules.mk
 
 
 PKG_NAME:=luci-app-ssr-plus
 PKG_NAME:=luci-app-ssr-plus
-PKG_VERSION:=181
-PKG_RELEASE:=4
-
-include $(INCLUDE_DIR)/package.mk
+PKG_VERSION:=182
+PKG_RELEASE:=1
 
 
 define Package/$(PKG_NAME)/conffiles
 define Package/$(PKG_NAME)/conffiles
 /etc/config/shadowsocksr
 /etc/config/shadowsocksr
-/etc/ssr/
+/etc/ssrplus/
 endef
 endef
 
 
 define Package/$(PKG_NAME)/config
 define Package/$(PKG_NAME)/config
@@ -46,17 +44,7 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server
 	default y if i386||x86_64||arm||aarch64
 	default y if i386||x86_64||arm||aarch64
 endef
 endef
 
 
-PKG_CONFIG_DEPENDS:= \
-	CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_plugin \
-	CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \
-	CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Xray \
-	CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Trojan \
-	CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy \
-	CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Redsocks2 \
-	CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun \
-	CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server
-
-LUCI_TITLE:=SS/SSR/V2Ray/Xray/Trojan/NaiveProxy/Socks5/Tun LuCI interface
+LUCI_TITLE:=SS/SSR/V2Ray/Trojan/NaiveProxy/Socks5/Tun LuCI interface
 LUCI_PKGARCH:=all
 LUCI_PKGARCH:=all
 LUCI_DEPENDS:=+shadowsocksr-libev-alt +ipset +ip-full +iptables-mod-tproxy +dnsmasq-full +coreutils +coreutils-base64 +pdnsd-alt +wget +lua +libuci-lua \
 LUCI_DEPENDS:=+shadowsocksr-libev-alt +ipset +ip-full +iptables-mod-tproxy +dnsmasq-full +coreutils +coreutils-base64 +pdnsd-alt +wget +lua +libuci-lua \
 	+microsocks +dns2socks +shadowsocks-libev-ss-local +shadowsocksr-libev-ssr-local +shadowsocks-libev-ss-redir +simple-obfs +tcping +resolveip\
 	+microsocks +dns2socks +shadowsocks-libev-ss-local +shadowsocksr-libev-ssr-local +shadowsocks-libev-ss-redir +simple-obfs +tcping +resolveip\

+ 26 - 66
luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua

@@ -1,30 +1,30 @@
 -- Copyright (C) 2017 yushi studio <[email protected]>
 -- Copyright (C) 2017 yushi studio <[email protected]>
 -- Licensed to the public under the GNU General Public License v3.
 -- Licensed to the public under the GNU General Public License v3.
-
 module("luci.controller.shadowsocksr", package.seeall)
 module("luci.controller.shadowsocksr", package.seeall)
 
 
 function index()
 function index()
 	if not nixio.fs.access("/etc/config/shadowsocksr") then
 	if not nixio.fs.access("/etc/config/shadowsocksr") then
 		return
 		return
 	end
 	end
-	entry({"admin", "services", "shadowsocksr"}, alias("admin", "services", "shadowsocksr", "client"),_("ShadowSocksR Plus+"), 10).dependent = true
-	entry({"admin", "services", "shadowsocksr", "client"}, cbi("shadowsocksr/client"),_("SSR Client"), 10).leaf = true
-	entry({"admin", "services", "shadowsocksr", "servers"}, arcombine(cbi("shadowsocksr/servers", {autoapply = true}), cbi("shadowsocksr/client-config")),_("Severs Nodes"), 20).leaf = true
-	entry({"admin", "services", "shadowsocksr", "control"},cbi("shadowsocksr/control"), _("Access Control"), 30).leaf = true
-	entry({"admin", "services", "shadowsocksr", "advanced"},cbi("shadowsocksr/advanced"),_("Advanced Settings"), 50).leaf = true
-	entry({"admin", "services", "shadowsocksr", "server"},arcombine(cbi("shadowsocksr/server"), cbi("shadowsocksr/server-config")),_("SSR Server"), 60).leaf = true
-	entry({"admin", "services", "shadowsocksr", "status"},form("shadowsocksr/status"),_("Status"), 70).leaf = true
+	entry({"admin", "services", "shadowsocksr"}, alias("admin", "services", "shadowsocksr", "client"), _("ShadowSocksR Plus+"), 10).dependent = true
+	entry({"admin", "services", "shadowsocksr", "client"}, cbi("shadowsocksr/client"), _("SSR Client"), 10).leaf = true
+	entry({"admin", "services", "shadowsocksr", "servers"}, arcombine(cbi("shadowsocksr/servers", {autoapply = true}), cbi("shadowsocksr/client-config")), _("Severs Nodes"), 20).leaf = true
+	entry({"admin", "services", "shadowsocksr", "control"}, cbi("shadowsocksr/control"), _("Access Control"), 30).leaf = true
+	entry({"admin", "services", "shadowsocksr", "advanced"}, cbi("shadowsocksr/advanced"), _("Advanced Settings"), 50).leaf = true
+	entry({"admin", "services", "shadowsocksr", "server"}, arcombine(cbi("shadowsocksr/server"), cbi("shadowsocksr/server-config")), _("SSR Server"), 60).leaf = true
+	entry({"admin", "services", "shadowsocksr", "status"}, form("shadowsocksr/status"), _("Status"), 70).leaf = true
 	entry({"admin", "services", "shadowsocksr", "check"}, call("check_status"))
 	entry({"admin", "services", "shadowsocksr", "check"}, call("check_status"))
 	entry({"admin", "services", "shadowsocksr", "refresh"}, call("refresh_data"))
 	entry({"admin", "services", "shadowsocksr", "refresh"}, call("refresh_data"))
 	entry({"admin", "services", "shadowsocksr", "subscribe"}, call("subscribe"))
 	entry({"admin", "services", "shadowsocksr", "subscribe"}, call("subscribe"))
 	entry({"admin", "services", "shadowsocksr", "checkport"}, call("check_port"))
 	entry({"admin", "services", "shadowsocksr", "checkport"}, call("check_port"))
-	entry({"admin", "services", "shadowsocksr", "log"},form("shadowsocksr/log"),_("Log"), 80).leaf = true
-	entry({"admin", "services", "shadowsocksr","run"},call("act_status")).leaf = true
+	entry({"admin", "services", "shadowsocksr", "log"}, form("shadowsocksr/log"), _("Log"), 80).leaf = true
+	entry({"admin", "services", "shadowsocksr", "run"}, call("act_status")).leaf = true
 	entry({"admin", "services", "shadowsocksr", "ping"}, call("act_ping")).leaf = true
 	entry({"admin", "services", "shadowsocksr", "ping"}, call("act_ping")).leaf = true
+	entry({"admin", "services", "shadowsocksr", "reset"}, call("act_reset"))
 end
 end
 
 
 function subscribe()
 function subscribe()
-	luci.sys.call("/usr/bin/lua /usr/share/shadowsocksr/subscribe.lua >> /tmp/ssrplus.log 2>&1")
+	luci.sys.call("/usr/bin/lua /usr/share/shadowsocksr/subscribe.lua >>/var/log/ssrplus.log")
 	luci.http.prepare_content("application/json")
 	luci.http.prepare_content("application/json")
 	luci.http.write_json({ret = 1})
 	luci.http.write_json({ret = 1})
 end
 end
@@ -41,16 +41,16 @@ function act_ping()
 	local domain = luci.http.formvalue("domain")
 	local domain = luci.http.formvalue("domain")
 	local port = luci.http.formvalue("port")
 	local port = luci.http.formvalue("port")
 	e.index = luci.http.formvalue("index")
 	e.index = luci.http.formvalue("index")
-	local iret = luci.sys.call(" ipset add ss_spec_wan_ac " .. domain .. " 2>/dev/null")
+	local iret = luci.sys.call("ipset add ss_spec_wan_ac " .. domain .. " 2>/dev/null")
 	local socket = nixio.socket("inet", "stream")
 	local socket = nixio.socket("inet", "stream")
 	socket:setopt("socket", "rcvtimeo", 3)
 	socket:setopt("socket", "rcvtimeo", 3)
 	socket:setopt("socket", "sndtimeo", 3)
 	socket:setopt("socket", "sndtimeo", 3)
 	e.socket = socket:connect(domain, port)
 	e.socket = socket:connect(domain, port)
 	socket:close()
 	socket:close()
--- 	e.ping = luci.sys.exec("ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*.[0-9]' | awk -F '=' '{print$2}'" % domain)
--- 	if (e.ping == "") then
-		e.ping = luci.sys.exec(string.format("echo -n $(tcping -q -c 1 -i 1 -t 2 -p %s %s 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}') 2>/dev/null",port, domain))
--- 	end
+	-- 	e.ping = luci.sys.exec("ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*.[0-9]' | awk -F '=' '{print$2}'" % domain)
+	-- 	if (e.ping == "") then
+	e.ping = luci.sys.exec(string.format("echo -n $(tcping -q -c 1 -i 1 -t 2 -p %s %s 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}') 2>/dev/null", port, domain))
+	-- 	end
 	if (iret == 0) then
 	if (iret == 0) then
 		luci.sys.call(" ipset del ss_spec_wan_ac " .. domain)
 		luci.sys.call(" ipset del ss_spec_wan_ac " .. domain)
 	end
 	end
@@ -72,55 +72,9 @@ end
 
 
 function refresh_data()
 function refresh_data()
 	local set = luci.http.formvalue("set")
 	local set = luci.http.formvalue("set")
-	local uci = luci.model.uci.cursor()
-	local icount = 0
-	local retstring = 0
-	local function update(url, file, type, file2)
-		local Num = 1
-		refresh_cmd = "wget-ssl --no-check-certificate -t 3 -T 10 -O- " .. url .. " > /tmp/ssr-update." .. type
-		sret = luci.sys.call(refresh_cmd .. " 2>/dev/null")
-		if sret == 0 then
-			if type == "gfw_data" then
-				luci.sys.call("/usr/bin/ssr-gfw " .. type)
-				Num = 2
-			end
-			if type == "ad_data" then
-				luci.sys.call("/usr/bin/ssr-ad " .. type)
-			end
-			local new_md5 = luci.sys.exec("echo -n $([ -f '/tmp/ssr-update." .. type .. "' ] && md5sum /tmp/ssr-update." .. type .. " | awk '{print $1}')")
-			local old_md5 = luci.sys.exec("echo -n $([ -f '" .. file .. "' ] && md5sum " .. file .. " | awk '{print $1}')")
-			if new_md5 == old_md5 then
-				retstring = "0"
-			else
-				icount = luci.sys.exec("cat /tmp/ssr-update." .. type .. " | wc -l")
-				luci.sys.exec("cp -f /tmp/ssr-update." .. type .. " " .. file)
-				if file2 then luci.sys.exec("cp -f /tmp/ssr-update." .. type .. " " .. file2) end
-				retstring = tostring(tonumber(icount)/Num)
-				if type == "gfw_data" or type == "ad_data" then
-					luci.sys.exec("/usr/share/shadowsocksr/gfw2ipset.sh")
-				else
-					luci.sys.exec("/usr/share/shadowsocksr/chinaipset.sh /tmp/etc/china_ssr.txt")
-				end
-			end
-		else
-			retstring = "-1"
-		end
-		luci.sys.exec("rm -f /tmp/ssr-update." .. type)
-	end
-	if set == "gfw_data" then
-		update(uci:get_first("shadowsocksr", "global", "gfwlist_url", "https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt"), "/etc/ssr/gfw_list.conf", set, "/tmp/dnsmasq.ssr/gfw_list.conf")
-	end
-	if set == "ip_data" then
-		update(uci:get_first("shadowsocksr", "global", "chnroute_url","https://ispip.clang.cn/all_cn.txt"), "/etc/ssr/china_ssr.txt", set, "/tmp/etc/china_ssr.txt")
-	end
-	if set == "ad_data" then
-		update(uci:get_first("shadowsocksr", "global", "adblock_url","https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt"), "/etc/ssr/ad.conf", set, "/tmp/dnsmasq.ssr/ad.conf")
-	end
-	if set == "nfip_data" then
-		update(uci:get_first("shadowsocksr", "global", "nfip_url","https://raw.githubusercontent.com/QiuSimons/Netflix_IP/master/NF_only.txt"), "/etc/ssr/netflixip.list", set)
-	end
+	local retstring = luci.sys.exec("/usr/bin/lua /usr/share/shadowsocksr/update.lua " .. set)
 	luci.http.prepare_content("application/json")
 	luci.http.prepare_content("application/json")
-	luci.http.write_json({ret = retstring,retcount = icount})
+	luci.http.write_json({ret = tonumber(retstring)})
 end
 end
 
 
 function check_port()
 function check_port()
@@ -134,13 +88,13 @@ function check_port()
 		if s.alias then
 		if s.alias then
 			server_name = s.alias
 			server_name = s.alias
 		elseif s.server and s.server_port then
 		elseif s.server and s.server_port then
-			server_name = "%s:%s" %{s.server, s.server_port}
+			server_name = "%s:%s" % {s.server, s.server_port}
 		end
 		end
 		iret = luci.sys.call("ipset add ss_spec_wan_ac " .. s.server .. " 2>/dev/null")
 		iret = luci.sys.call("ipset add ss_spec_wan_ac " .. s.server .. " 2>/dev/null")
 		socket = nixio.socket("inet", "stream")
 		socket = nixio.socket("inet", "stream")
 		socket:setopt("socket", "rcvtimeo", 3)
 		socket:setopt("socket", "rcvtimeo", 3)
 		socket:setopt("socket", "sndtimeo", 3)
 		socket:setopt("socket", "sndtimeo", 3)
-		ret = socket:connect(s.server,s.server_port)
+		ret = socket:connect(s.server, s.server_port)
 		if tostring(ret) == "true" then
 		if tostring(ret) == "true" then
 			socket:close()
 			socket:close()
 			retstring = retstring .. "<font color = 'green'>[" .. server_name .. "] OK.</font><br />"
 			retstring = retstring .. "<font color = 'green'>[" .. server_name .. "] OK.</font><br />"
@@ -154,3 +108,9 @@ function check_port()
 	luci.http.prepare_content("application/json")
 	luci.http.prepare_content("application/json")
 	luci.http.write_json({ret = retstring})
 	luci.http.write_json({ret = retstring})
 end
 end
+
+function act_reset()
+	nixio.exec("/etc/init.d/shadowsocksr", "reset")
+	http.redirect(luci.dispatcher.build_url('admin/services/shadowsocksr'))
+	return
+end

+ 17 - 11
luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua

@@ -1,19 +1,18 @@
-local shadowsocksr = "shadowsocksr"
 local uci = luci.model.uci.cursor()
 local uci = luci.model.uci.cursor()
 local server_table = {}
 local server_table = {}
 
 
-uci:foreach(shadowsocksr, "servers", function(s)
+uci:foreach("shadowsocksr", "servers", function(s)
 	if s.alias then
 	if s.alias then
-		server_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias}
+		server_table[s[".name"]] = "[%s]:%s" % {string.upper(s.type), s.alias}
 	elseif s.server and s.server_port then
 	elseif s.server and s.server_port then
-		server_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port}
+		server_table[s[".name"]] = "[%s]:%s:%s" % {string.upper(s.type), s.server, s.server_port}
 	end
 	end
 end)
 end)
 
 
-local key_table = {}   
-for key,_ in pairs(server_table) do  
-    table.insert(key_table,key)  
-end 
+local key_table = {}
+for key, _ in pairs(server_table) do
+	table.insert(key_table, key)
+end
 
 
 table.sort(key_table)
 table.sort(key_table)
 
 
@@ -49,9 +48,10 @@ o = s:option(Flag, "adblock", translate("Enable adblock"))
 o.rmempty = false
 o.rmempty = false
 
 
 o = s:option(Value, "adblock_url", translate("adblock_url"))
 o = s:option(Value, "adblock_url", translate("adblock_url"))
+o:value("https://neodev.team/lite_host_dnsmasq.conf", translate("NEO DEV HOST Lite"))
+o:value("https://neodev.team/host_dnsmasq.conf", translate("NEO DEV HOST Full"))
 o:value("https://anti-ad.net/anti-ad-for-dnsmasq.conf", translate("anti-AD"))
 o:value("https://anti-ad.net/anti-ad-for-dnsmasq.conf", translate("anti-AD"))
-o:value("https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt", translate("Easylist China"))
-o.default = "https://anti-ad.net/anti-ad-for-dnsmasq.conf"
+o.default = "https://neodev.team/lite_host_dnsmasq.conf"
 o:depends("adblock", "1")
 o:depends("adblock", "1")
 o.description = translate("Support AdGuardHome and DNSMASQ format list")
 o.description = translate("Support AdGuardHome and DNSMASQ format list")
 
 
@@ -73,6 +73,10 @@ o:value("https://cdn.jsdelivr.net/gh/QiuSimons/Netflix_IP/getflix.txt", translat
 o.default = "https://cdn.jsdelivr.net/gh/QiuSimons/Netflix_IP/NF_only.txt"
 o.default = "https://cdn.jsdelivr.net/gh/QiuSimons/Netflix_IP/NF_only.txt"
 o.description = translate("Customize Netflix IP Url")
 o.description = translate("Customize Netflix IP Url")
 
 
+o = s:option(Button, "reset", translate("Reset to defaults"))
+o.rawhtml = true
+o.template = "shadowsocksr/reset"
+
 -- [[ SOCKS5 Proxy ]]--
 -- [[ SOCKS5 Proxy ]]--
 s = m:section(TypedSection, "socks5_proxy", translate("Global SOCKS5 Proxy Server"))
 s = m:section(TypedSection, "socks5_proxy", translate("Global SOCKS5 Proxy Server"))
 s.anonymous = true
 s.anonymous = true
@@ -80,7 +84,9 @@ s.anonymous = true
 o = s:option(ListValue, "server", translate("Server"))
 o = s:option(ListValue, "server", translate("Server"))
 o:value("nil", translate("Disable"))
 o:value("nil", translate("Disable"))
 o:value("same", translate("Same as Global Server"))
 o:value("same", translate("Same as Global Server"))
-for _,key in pairs(key_table) do o:value(key,server_table[key]) end
+for _, key in pairs(key_table) do
+	o:value(key, server_table[key])
+end
 o.default = "nil"
 o.default = "nil"
 o.rmempty = false
 o.rmempty = false
 
 

+ 210 - 165
luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua

@@ -1,118 +1,121 @@
 -- Copyright (C) 2017 yushi studio <[email protected]> github.com/ywb94
 -- Copyright (C) 2017 yushi studio <[email protected]> github.com/ywb94
 -- Licensed to the public under the GNU General Public License v3.
 -- Licensed to the public under the GNU General Public License v3.
-
 require "nixio.fs"
 require "nixio.fs"
 require "luci.sys"
 require "luci.sys"
 require "luci.http"
 require "luci.http"
 local m, s, o, kcp_enable
 local m, s, o, kcp_enable
-local shadowsocksr = "shadowsocksr"
 local sid = arg[1]
 local sid = arg[1]
 local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid")
 local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid")
 
 
 local function isKcptun(file)
 local function isKcptun(file)
-if not nixio.fs.access(file, "rwx", "rx", "rx") then
-nixio.fs.chmod(file, 755)
-end
-local str = luci.sys.exec(file .. " -v | awk '{printf $1}'")
-return (str:lower() == "kcptun")
+	if not nixio.fs.access(file, "rwx", "rx", "rx") then
+		nixio.fs.chmod(file, 755)
+	end
+	local str = luci.sys.exec(file .. " -v | awk '{printf $1}'")
+	return (str:lower() == "kcptun")
 end
 end
 
 
 local server_table = {}
 local server_table = {}
 local encrypt_methods = {
 local encrypt_methods = {
-"none",
-"table",
-"rc4",
-"rc4-md5-6",
-"rc4-md5",
-"aes-128-cfb",
-"aes-192-cfb",
-"aes-256-cfb",
-"aes-128-ctr",
-"aes-192-ctr",
-"aes-256-ctr",
-"bf-cfb",
-"camellia-128-cfb",
-"camellia-192-cfb",
-"camellia-256-cfb",
-"cast5-cfb",
-"des-cfb",
-"idea-cfb",
-"rc2-cfb",
-"seed-cfb",
-"salsa20",
-"chacha20",
-"chacha20-ietf",
+	-- ssr
+	"none",
+	"table",
+	"rc4",
+	"rc4-md5-6",
+	"rc4-md5",
+	"aes-128-cfb",
+	"aes-192-cfb",
+	"aes-256-cfb",
+	"aes-128-ctr",
+	"aes-192-ctr",
+	"aes-256-ctr",
+	"bf-cfb",
+	"camellia-128-cfb",
+	"camellia-192-cfb",
+	"camellia-256-cfb",
+	"cast5-cfb",
+	"des-cfb",
+	"idea-cfb",
+	"rc2-cfb",
+	"seed-cfb",
+	"salsa20",
+	"chacha20",
+	"chacha20-ietf"
 }
 }
 
 
 local encrypt_methods_ss = {
 local encrypt_methods_ss = {
--- aead
-"aes-128-gcm",
-"aes-192-gcm",
-"aes-256-gcm",
-"chacha20-ietf-poly1305",
-"xchacha20-ietf-poly1305",
--- stream
-"table",
-"rc4",
-"rc4-md5",
-"aes-128-cfb",
-"aes-192-cfb",
-"aes-256-cfb",
-"aes-128-ctr",
-"aes-192-ctr",
-"aes-256-ctr",
-"bf-cfb",
-"camellia-128-cfb",
-"camellia-192-cfb",
-"camellia-256-cfb",
-"salsa20",
-"chacha20",
-"chacha20-ietf",
+	-- aead
+	"aes-128-gcm",
+	"aes-192-gcm",
+	"aes-256-gcm",
+	"chacha20-ietf-poly1305",
+	"xchacha20-ietf-poly1305",
+	-- stream
+	"table",
+	"rc4",
+	"rc4-md5",
+	"aes-128-cfb",
+	"aes-192-cfb",
+	"aes-256-cfb",
+	"aes-128-ctr",
+	"aes-192-ctr",
+	"aes-256-ctr",
+	"bf-cfb",
+	"camellia-128-cfb",
+	"camellia-192-cfb",
+	"camellia-256-cfb",
+	"salsa20",
+	"chacha20",
+	"chacha20-ietf"
 }
 }
 
 
 local protocol = {
 local protocol = {
-"origin",
-"verify_deflate",
-"auth_sha1_v4",
-"auth_aes128_sha1",
-"auth_aes128_md5",
-"auth_chain_a",
-"auth_chain_b",
-"auth_chain_c",
-"auth_chain_d",
-"auth_chain_e",
-"auth_chain_f",
+	-- ssr
+	"origin",
+	"verify_deflate",
+	"auth_sha1_v4",
+	"auth_aes128_sha1",
+	"auth_aes128_md5",
+	"auth_chain_a",
+	"auth_chain_b",
+	"auth_chain_c",
+	"auth_chain_d",
+	"auth_chain_e",
+	"auth_chain_f"
 }
 }
 
 
 obfs = {
 obfs = {
-"plain",
-"http_simple",
-"http_post",
-"random_head",
-"tls1.2_ticket_auth",
+	-- ssr
+	"plain",
+	"http_simple",
+	"http_post",
+	"random_head",
+	"tls1.2_ticket_auth"
 }
 }
 
 
 local securitys = {
 local securitys = {
-"auto",
-"none",
-"aes-128-gcm",
-"chacha20-poly1305"
+	-- vmess
+	"auto",
+	"none",
+	"aes-128-gcm",
+	"chacha20-poly1305"
 }
 }
 
 
 local flows = {
 local flows = {
-"xtls-rprx-origin",
-"xtls-rprx-origin-udp443",
-"xtls-rprx-direct",
-"xtls-rprx-direct-udp443",
-"xtls-rprx-splice",
-"xtls-rprx-splice-udp443"
+	-- xlts
+	"xtls-rprx-origin",
+	"xtls-rprx-origin-udp443",
+	"xtls-rprx-direct",
+	"xtls-rprx-direct-udp443",
+	"xtls-rprx-splice",
+	"xtls-rprx-splice-udp443"
 }
 }
 
 
-m = Map(shadowsocksr, translate("Edit ShadowSocksR Server"))
+m = Map("shadowsocksr", translate("Edit ShadowSocksR Server"))
 m.redirect = luci.dispatcher.build_url("admin/services/shadowsocksr/servers")
 m.redirect = luci.dispatcher.build_url("admin/services/shadowsocksr/servers")
-if m.uci:get(shadowsocksr, sid) ~= "servers" then
-luci.http.redirect(m.redirect)
-return
+if m.uci:get("shadowsocksr", sid) ~= "servers" then
+	luci.http.redirect(m.redirect)
+	return
 end
 end
 
 
 -- [[ Servers Setting ]]--
 -- [[ Servers Setting ]]--
@@ -126,30 +129,36 @@ o.template = "shadowsocksr/ssrurl"
 o.value = sid
 o.value = sid
 
 
 o = s:option(ListValue, "type", translate("Server Node Type"))
 o = s:option(ListValue, "type", translate("Server Node Type"))
-o:value("ssr", translate("ShadowsocksR"))
+if nixio.fs.access("/usr/bin/ssr-redir") then
+	o:value("ssr", translate("ShadowsocksR"))
+end
 if nixio.fs.access("/usr/bin/ss-redir") then
 if nixio.fs.access("/usr/bin/ss-redir") then
-o:value("ss", translate("Shadowsocks New Version"))
+	o:value("ss", translate("Shadowsocks New Version"))
 end
 end
-if nixio.fs.access("/usr/bin/xray") or nixio.fs.access("/usr/bin/xray/xray") or nixio.fs.access("/usr/bin/v2ray/v2ray") or nixio.fs.access("/usr/bin/v2ray") then
-o:value("vmess", translate("Vmess"))
-o:value("vless", translate("VLESS"))
+if nixio.fs.access("/usr/bin/xray") or nixio.fs.access("/usr/bin/v2ray") then
+	o:value("vmess", translate("Vmess"))
+	o:value("vless", translate("VLESS"))
 end
 end
 if nixio.fs.access("/usr/sbin/trojan") then
 if nixio.fs.access("/usr/sbin/trojan") then
-o:value("trojan", translate("Trojan"))
+	o:value("trojan", translate("Trojan"))
 end
 end
 if nixio.fs.access("/usr/bin/naive") then
 if nixio.fs.access("/usr/bin/naive") then
-o:value("naiveproxy", translate("NaiveProxy"))
+	o:value("naiveproxy", translate("NaiveProxy"))
 end
 end
 if nixio.fs.access("/usr/sbin/redsocks2") then
 if nixio.fs.access("/usr/sbin/redsocks2") then
-o:value("socks5", translate("Socks5"))
-o:value("tun", translate("Network Tunnel"))
+	o:value("socks5", translate("Socks5"))
+	o:value("tun", translate("Network Tunnel"))
 end
 end
 o.description = translate("Using incorrect encryption mothod may causes service fail to start")
 o.description = translate("Using incorrect encryption mothod may causes service fail to start")
 
 
 o = s:option(Value, "alias", translate("Alias(optional)"))
 o = s:option(Value, "alias", translate("Alias(optional)"))
 
 
 o = s:option(ListValue, "iface", translate("Network interface to use"))
 o = s:option(ListValue, "iface", translate("Network interface to use"))
-for _, e in ipairs(luci.sys.net.devices()) do if e ~= "lo" then o:value(e) end end
+for _, e in ipairs(luci.sys.net.devices()) do
+	if e ~= "lo" then
+		o:value(e)
+	end
+end
 o:depends("type", "tun")
 o:depends("type", "tun")
 o.description = translate("Redirect traffic to this network interface")
 o.description = translate("Redirect traffic to this network interface")
 
 
@@ -195,26 +204,54 @@ o:depends("type", "naiveproxy")
 o:depends({type = "socks5", auth_enable = true})
 o:depends({type = "socks5", auth_enable = true})
 
 
 o = s:option(ListValue, "encrypt_method", translate("Encrypt Method"))
 o = s:option(ListValue, "encrypt_method", translate("Encrypt Method"))
-for _, v in ipairs(encrypt_methods) do o:value(v) end
+for _, v in ipairs(encrypt_methods) do
+	o:value(v)
+end
 o.rmempty = true
 o.rmempty = true
 o:depends("type", "ssr")
 o:depends("type", "ssr")
 
 
 o = s:option(ListValue, "encrypt_method_ss", translate("Encrypt Method"))
 o = s:option(ListValue, "encrypt_method_ss", translate("Encrypt Method"))
-for _, v in ipairs(encrypt_methods_ss) do o:value(v) end
+for _, v in ipairs(encrypt_methods_ss) do
+	o:value(v)
+end
 o.rmempty = true
 o.rmempty = true
 o:depends("type", "ss")
 o:depends("type", "ss")
 
 
 -- Shadowsocks Plugin
 -- Shadowsocks Plugin
-o = s:option(Value, "plugin", translate("Plugin"))
+o = s:option(ListValue, "plugin", translate("Obfs"))
+o:value("", translate("None"))
+if nixio.fs.access("/usr/bin/obfs-local") then
+	o:value("obfs-local", translate("simple-obfs"))
+end
+if nixio.fs.access("/usr/bin/v2ray-plugin") then
+	o:value("v2ray-plugin", translate("v2ray-plugin"))
+end
 o.rmempty = true
 o.rmempty = true
 o:depends("type", "ss")
 o:depends("type", "ss")
 
 
-o = s:option(Value, "plugin_opts", translate("Plugin Opts"))
+o = s:option(ListValue, "simple_obfs", translate("Plugin Opts"))
+o:value("obfs=tls;obfs-host=", translate("TLS"))
+o:value("obfs=http;obfs-host=", translate("HTTP"))
+o:depends("plugin", "obfs-local")
+o.rmempty = true
+
+o = s:option(ListValue, "v2ray_plugin", translate("Plugin Opts"))
+o:value("tls;host=", translate("TLS"))
+o:value("mode=quic;host=", translate("QUIC"))
+o:value("none", translate("HTTP"))
+o:depends("plugin", "v2ray-plugin")
 o.rmempty = true
 o.rmempty = true
-o:depends("type", "ss")
+
+o = s:option(Value, "plugin_opts", translate("Plugin Opts"), translate("Please fill in the Host, for example: www.baidu.com"))
+o.rmempty = true
+o:depends({type = "ss", plugin = "obfs-local"})
+o:depends({type = "ss", v2ray_plugin = "tls;host="})
+o:depends({type = "ss", v2ray_plugin = "mode=quic;host="})
 
 
 o = s:option(ListValue, "protocol", translate("Protocol"))
 o = s:option(ListValue, "protocol", translate("Protocol"))
-for _, v in ipairs(protocol) do o:value(v) end
+for _, v in ipairs(protocol) do
+	o:value(v)
+end
 o.rmempty = true
 o.rmempty = true
 o:depends("type", "ssr")
 o:depends("type", "ssr")
 
 
@@ -222,7 +259,9 @@ o = s:option(Value, "protocol_param", translate("Protocol param(optional)"))
 o:depends("type", "ssr")
 o:depends("type", "ssr")
 
 
 o = s:option(ListValue, "obfs", translate("Obfs"))
 o = s:option(ListValue, "obfs", translate("Obfs"))
-for _, v in ipairs(obfs) do o:value(v) end
+for _, v in ipairs(obfs) do
+	o:value(v)
+end
 o.rmempty = true
 o.rmempty = true
 o:depends("type", "ssr")
 o:depends("type", "ssr")
 
 
@@ -251,7 +290,9 @@ o:depends("type", "vless")
 
 
 -- 加密方式
 -- 加密方式
 o = s:option(ListValue, "security", translate("Encrypt Method"))
 o = s:option(ListValue, "security", translate("Encrypt Method"))
-for _, v in ipairs(securitys) do o:value(v, v:upper()) end
+for _, v in ipairs(securitys) do
+	o:value(v, v:upper())
+end
 o.rmempty = true
 o.rmempty = true
 o:depends("type", "vmess")
 o:depends("type", "vmess")
 
 
@@ -267,7 +308,6 @@ o:depends("type", "vmess")
 o:depends("type", "vless")
 o:depends("type", "vless")
 
 
 -- [[ TCP部分 ]]--
 -- [[ TCP部分 ]]--
-
 -- TCP伪装
 -- TCP伪装
 o = s:option(ListValue, "tcp_guise", translate("Camouflage Type"))
 o = s:option(ListValue, "tcp_guise", translate("Camouflage Type"))
 o:depends("transport", "tcp")
 o:depends("transport", "tcp")
@@ -286,7 +326,6 @@ o:depends("tcp_guise", "http")
 o.rmempty = true
 o.rmempty = true
 
 
 -- [[ WS部分 ]]--
 -- [[ WS部分 ]]--
-
 -- WS域名
 -- WS域名
 o = s:option(Value, "ws_host", translate("WebSocket Host"))
 o = s:option(Value, "ws_host", translate("WebSocket Host"))
 o:depends({transport = "ws", tls = false})
 o:depends({transport = "ws", tls = false})
@@ -310,7 +349,6 @@ o:depends("transport", "h2")
 o.rmempty = true
 o.rmempty = true
 
 
 -- [[ QUIC部分 ]]--
 -- [[ QUIC部分 ]]--
-
 o = s:option(ListValue, "quic_security", translate("QUIC Security"))
 o = s:option(ListValue, "quic_security", translate("QUIC Security"))
 o:depends("transport", "quic")
 o:depends("transport", "quic")
 o:value("none", translate("None"))
 o:value("none", translate("None"))
@@ -329,19 +367,18 @@ o:value("none", translate("None"))
 o:value("srtp", translate("VideoCall (SRTP)"))
 o:value("srtp", translate("VideoCall (SRTP)"))
 o:value("utp", translate("BitTorrent (uTP)"))
 o:value("utp", translate("BitTorrent (uTP)"))
 o:value("wechat-video", translate("WechatVideo"))
 o:value("wechat-video", translate("WechatVideo"))
-o:value("dtls", "DTLS 1.2")
-o:value("wireguard", "WireGuard")
+o:value("dtls", translate("DTLS 1.2"))
+o:value("wireguard", translate("WireGuard"))
 
 
 -- [[ mKCP部分 ]]--
 -- [[ mKCP部分 ]]--
-
 o = s:option(ListValue, "kcp_guise", translate("Camouflage Type"))
 o = s:option(ListValue, "kcp_guise", translate("Camouflage Type"))
 o:depends("transport", "kcp")
 o:depends("transport", "kcp")
 o:value("none", translate("None"))
 o:value("none", translate("None"))
 o:value("srtp", translate("VideoCall (SRTP)"))
 o:value("srtp", translate("VideoCall (SRTP)"))
 o:value("utp", translate("BitTorrent (uTP)"))
 o:value("utp", translate("BitTorrent (uTP)"))
 o:value("wechat-video", translate("WechatVideo"))
 o:value("wechat-video", translate("WechatVideo"))
-o:value("dtls", "DTLS 1.2")
-o:value("wireguard", "WireGuard")
+o:value("dtls", translate("DTLS 1.2"))
+o:value("wireguard", translate("WireGuard"))
 o.rmempty = true
 o.rmempty = true
 
 
 o = s:option(Value, "mtu", translate("MTU"))
 o = s:option(Value, "mtu", translate("MTU"))
@@ -397,16 +434,18 @@ o:depends({type = "vless", xtls = false})
 o:depends("type", "trojan")
 o:depends("type", "trojan")
 
 
 -- XTLS
 -- XTLS
-if nixio.fs.access("/usr/bin/xray") or nixio.fs.access("/usr/bin/xray/xray") then
-o = s:option(Flag, "xtls", translate("XTLS"))
-o.rmempty = true
-o.default = "0"
-o:depends({type = "vless", transport = "tcp", tls = false})
+if nixio.fs.access("/usr/bin/xray") then
+	o = s:option(Flag, "xtls", translate("XTLS"))
+	o.rmempty = true
+	o.default = "0"
+	o:depends({type = "vless", transport = "tcp", tls = false})
 end
 end
 
 
 -- Flow
 -- Flow
 o = s:option(Value, "vless_flow", translate("Flow"))
 o = s:option(Value, "vless_flow", translate("Flow"))
-for _, v in ipairs(flows) do o:value(v, v) end
+for _, v in ipairs(flows) do
+	o:value(v, v)
+end
 o.rmempty = true
 o.rmempty = true
 o.default = "xtls-rprx-splice"
 o.default = "xtls-rprx-splice"
 o:depends("xtls", true)
 o:depends("xtls", true)
@@ -453,24 +492,30 @@ cert_dir = "/etc/ssl/private/"
 local path
 local path
 
 
 luci.http.setfilehandler(function(meta, chunk, eof)
 luci.http.setfilehandler(function(meta, chunk, eof)
-if not fd then
-if (not meta) or (not meta.name) or (not meta.file) then return end
-fd = nixio.open(cert_dir .. meta.file, "w")
-if not fd then
-path = translate("Create upload file error.")
-return
-end
-end
-if chunk and fd then fd:write(chunk) end
-if eof and fd then
-fd:close()
-fd = nil
-path = '/etc/ssl/private/' .. meta.file .. ''
-end
+	if not fd then
+		if (not meta) or (not meta.name) or (not meta.file) then
+			return
+		end
+		fd = nixio.open(cert_dir .. meta.file, "w")
+		if not fd then
+			path = translate("Create upload file error.")
+			return
+		end
+	end
+	if chunk and fd then
+		fd:write(chunk)
+	end
+	if eof and fd then
+		fd:close()
+		fd = nil
+		path = '/etc/ssl/private/' .. meta.file .. ''
+	end
 end)
 end)
 if luci.http.formvalue("upload") then
 if luci.http.formvalue("upload") then
-local f = luci.http.formvalue("ulfile")
-if #f <= 0 then path = translate("No specify upload file.") end
+	local f = luci.http.formvalue("ulfile")
+	if #f <= 0 then
+		path = translate("No specify upload file.")
+	end
 end
 end
 
 
 o = s:option(Value, "certpath", translate("Current Certificate Path"))
 o = s:option(Value, "certpath", translate("Current Certificate Path"))
@@ -496,40 +541,40 @@ o.default = 1234
 o.rmempty = false
 o.rmempty = false
 
 
 if nixio.fs.access("/usr/bin/kcptun-client") then
 if nixio.fs.access("/usr/bin/kcptun-client") then
-kcp_enable = s:option(Flag, "kcp_enable", translate("KcpTun Enable"), translate("bin:/usr/bin/kcptun-client"))
-kcp_enable.rmempty = true
-kcp_enable.default = "0"
-kcp_enable:depends("type", "ssr")
-kcp_enable:depends("type", "ss")
-
-o = s:option(Value, "kcp_port", translate("KcpTun Port"))
-o.datatype = "port"
-o.default = 4000
-function o.validate(self, value, section)
-local kcp_file = "/usr/bin/kcptun-client"
-local enable = kcp_enable:formvalue(section) or kcp_enable.disabled
-if enable == kcp_enable.enabled then
-if not nixio.fs.access(kcp_file) then
-return nil, translate("Haven't a Kcptun executable file")
-elseif not isKcptun(kcp_file) then
-return nil, translate("Not a Kcptun executable file")
-end
-end
-
-return value
-end
-o:depends("type", "ssr")
-o:depends("type", "ss")
-
-o = s:option(Value, "kcp_password", translate("KcpTun Password"))
-o.password = true
-o:depends("type", "ssr")
-o:depends("type", "ss")
-
-o = s:option(Value, "kcp_param", translate("KcpTun Param"))
-o.default = "--nocomp"
-o:depends("type", "ssr")
-o:depends("type", "ss")
+	kcp_enable = s:option(Flag, "kcp_enable", translate("KcpTun Enable"), translate("bin:/usr/bin/kcptun-client"))
+	kcp_enable.rmempty = true
+	kcp_enable.default = "0"
+	kcp_enable:depends("type", "ssr")
+	kcp_enable:depends("type", "ss")
+
+	o = s:option(Value, "kcp_port", translate("KcpTun Port"))
+	o.datatype = "port"
+	o.default = 4000
+	function o.validate(self, value, section)
+		local kcp_file = "/usr/bin/kcptun-client"
+		local enable = kcp_enable:formvalue(section) or kcp_enable.disabled
+		if enable == kcp_enable.enabled then
+			if not nixio.fs.access(kcp_file) then
+				return nil, translate("Haven't a Kcptun executable file")
+			elseif not isKcptun(kcp_file) then
+				return nil, translate("Not a Kcptun executable file")
+			end
+		end
+
+		return value
+	end
+	o:depends("type", "ssr")
+	o:depends("type", "ss")
+
+	o = s:option(Value, "kcp_password", translate("KcpTun Password"))
+	o.password = true
+	o:depends("type", "ssr")
+	o:depends("type", "ss")
+
+	o = s:option(Value, "kcp_param", translate("KcpTun Param"))
+	o.default = "--nocomp"
+	o:depends("type", "ssr")
+	o:depends("type", "ss")
 end
 end
 
 
 return m
 return m

+ 16 - 13
luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua

@@ -1,27 +1,24 @@
 -- Copyright (C) 2017 yushi studio <[email protected]> github.com/ywb94
 -- Copyright (C) 2017 yushi studio <[email protected]> github.com/ywb94
 -- Copyright (C) 2018 lean <[email protected]> github.com/coolsnowwolf
 -- Copyright (C) 2018 lean <[email protected]> github.com/coolsnowwolf
 -- Licensed to the public under the GNU General Public License v3.
 -- Licensed to the public under the GNU General Public License v3.
-
 local m, s, sec, o, kcp_enable
 local m, s, sec, o, kcp_enable
-local shadowsocksr = "shadowsocksr"
 local uci = luci.model.uci.cursor()
 local uci = luci.model.uci.cursor()
-m = Map(shadowsocksr, translate("ShadowSocksR Plus+ Settings"),
-	translate("<h3>Support SS/SSR/V2RAY/TROJAN/NAIVEPROXY/SOCKS5/TUN etc.</h3>"))
+m = Map("shadowsocksr", translate("ShadowSocksR Plus+ Settings"), translate("<h3>Support SS/SSR/V2RAY/TROJAN/NAIVEPROXY/SOCKS5/TUN etc.</h3>"))
 
 
 m:section(SimpleSection).template = "shadowsocksr/status"
 m:section(SimpleSection).template = "shadowsocksr/status"
 
 
 local server_table = {}
 local server_table = {}
-uci:foreach(shadowsocksr, "servers", function(s)
+uci:foreach("shadowsocksr", "servers", function(s)
 	if s.alias then
 	if s.alias then
-		server_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias}
+		server_table[s[".name"]] = "[%s]:%s" % {string.upper(s.type), s.alias}
 	elseif s.server and s.server_port then
 	elseif s.server and s.server_port then
-		server_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port}
+		server_table[s[".name"]] = "[%s]:%s:%s" % {string.upper(s.type), s.server, s.server_port}
 	end
 	end
 end)
 end)
 
 
 local key_table = {}
 local key_table = {}
-for key,_ in pairs(server_table) do
-	table.insert(key_table,key)
+for key, _ in pairs(server_table) do
+	table.insert(key_table, key)
 end
 end
 
 
 table.sort(key_table)
 table.sort(key_table)
@@ -32,26 +29,32 @@ s.anonymous = true
 
 
 o = s:option(ListValue, "global_server", translate("Main Server"))
 o = s:option(ListValue, "global_server", translate("Main Server"))
 o:value("nil", translate("Disable"))
 o:value("nil", translate("Disable"))
-for _,key in pairs(key_table) do o:value(key,server_table[key]) end
+for _, key in pairs(key_table) do
+	o:value(key, server_table[key])
+end
 o.default = "nil"
 o.default = "nil"
 o.rmempty = false
 o.rmempty = false
 
 
 o = s:option(ListValue, "udp_relay_server", translate("Game Mode UDP Server"))
 o = s:option(ListValue, "udp_relay_server", translate("Game Mode UDP Server"))
 o:value("", translate("Disable"))
 o:value("", translate("Disable"))
 o:value("same", translate("Same as Global Server"))
 o:value("same", translate("Same as Global Server"))
-for _,key in pairs(key_table) do o:value(key,server_table[key]) end
+for _, key in pairs(key_table) do
+	o:value(key, server_table[key])
+end
 
 
 o = s:option(ListValue, "netflix_server", translate("Netflix Node"))
 o = s:option(ListValue, "netflix_server", translate("Netflix Node"))
 o:value("nil", translate("Disable"))
 o:value("nil", translate("Disable"))
 o:value("same", translate("Same as Global Server"))
 o:value("same", translate("Same as Global Server"))
-for _,key in pairs(key_table) do o:value(key,server_table[key]) end
+for _, key in pairs(key_table) do
+	o:value(key, server_table[key])
+end
 o.default = "nil"
 o.default = "nil"
 o.rmempty = false
 o.rmempty = false
 
 
 o = s:option(Flag, "netflix_proxy", translate("External Proxy Mode"))
 o = s:option(Flag, "netflix_proxy", translate("External Proxy Mode"))
 o.rmempty = false
 o.rmempty = false
 o.description = translate("Forward Netflix Proxy through Main Proxy")
 o.description = translate("Forward Netflix Proxy through Main Proxy")
-o.default="0"
+o.default = "0"
 
 
 o = s:option(ListValue, "threads", translate("Multi Threads Option"))
 o = s:option(ListValue, "threads", translate("Multi Threads Option"))
 o:value("0", translate("Auto Threads"))
 o:value("0", translate("Auto Threads"))

+ 8 - 8
luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua

@@ -36,7 +36,7 @@ o.rmempty = false
 
 
 o = s:taboption("lan_ac", DynamicList, "lan_ac_ips", translate("LAN Host List"))
 o = s:taboption("lan_ac", DynamicList, "lan_ac_ips", translate("LAN Host List"))
 o.datatype = "ipaddr"
 o.datatype = "ipaddr"
-luci.ip.neighbors({ family = 4 }, function(entry)
+luci.ip.neighbors({family = 4}, function(entry)
 	if entry.reachable then
 	if entry.reachable then
 		o:value(entry.dest:string())
 		o:value(entry.dest:string())
 	end
 	end
@@ -46,7 +46,7 @@ o:depends("lan_ac_mode", "b")
 
 
 o = s:taboption("lan_ac", DynamicList, "lan_bp_ips", translate("LAN Bypassed Host List"))
 o = s:taboption("lan_ac", DynamicList, "lan_bp_ips", translate("LAN Bypassed Host List"))
 o.datatype = "ipaddr"
 o.datatype = "ipaddr"
-luci.ip.neighbors({ family = 4 }, function(entry)
+luci.ip.neighbors({family = 4}, function(entry)
 	if entry.reachable then
 	if entry.reachable then
 		o:value(entry.dest:string())
 		o:value(entry.dest:string())
 	end
 	end
@@ -54,7 +54,7 @@ end)
 
 
 o = s:taboption("lan_ac", DynamicList, "lan_fp_ips", translate("LAN Force Proxy Host List"))
 o = s:taboption("lan_ac", DynamicList, "lan_fp_ips", translate("LAN Force Proxy Host List"))
 o.datatype = "ipaddr"
 o.datatype = "ipaddr"
-luci.ip.neighbors({ family = 4 }, function(entry)
+luci.ip.neighbors({family = 4}, function(entry)
 	if entry.reachable then
 	if entry.reachable then
 		o:value(entry.dest:string())
 		o:value(entry.dest:string())
 	end
 	end
@@ -62,7 +62,7 @@ end)
 
 
 o = s:taboption("lan_ac", DynamicList, "lan_gm_ips", translate("Game Mode Host List"))
 o = s:taboption("lan_ac", DynamicList, "lan_gm_ips", translate("Game Mode Host List"))
 o.datatype = "ipaddr"
 o.datatype = "ipaddr"
-luci.ip.neighbors({ family = 4 }, function(entry)
+luci.ip.neighbors({family = 4}, function(entry)
 	if entry.reachable then
 	if entry.reachable then
 		o:value(entry.dest:string())
 		o:value(entry.dest:string())
 	end
 	end
@@ -77,7 +77,7 @@ end)
 -- o.rmempty = false
 -- o.rmempty = false
 
 
 s:tab("esc", translate("Bypass Domain List"))
 s:tab("esc", translate("Bypass Domain List"))
-local escconf = "/etc/ssr/white.list"
+local escconf = "/etc/ssrplus/white.list"
 o = s:taboption("esc", TextValue, "escconf")
 o = s:taboption("esc", TextValue, "escconf")
 o.rows = 13
 o.rows = 13
 o.wrap = "off"
 o.wrap = "off"
@@ -93,7 +93,7 @@ o.remove = function(self, section, value)
 end
 end
 
 
 s:tab("block", translate("Black Domain List"))
 s:tab("block", translate("Black Domain List"))
-local blockconf = "/etc/ssr/black.list"
+local blockconf = "/etc/ssrplus/black.list"
 o = s:taboption("block", TextValue, "blockconf")
 o = s:taboption("block", TextValue, "blockconf")
 o.rows = 13
 o.rows = 13
 o.wrap = "off"
 o.wrap = "off"
@@ -109,7 +109,7 @@ o.remove = function(self, section, value)
 end
 end
 
 
 s:tab("denydomain", translate("Deny Domain List"))
 s:tab("denydomain", translate("Deny Domain List"))
-local denydomainconf = "/etc/ssr/deny.list"
+local denydomainconf = "/etc/ssrplus/deny.list"
 o = s:taboption("denydomain", TextValue, "denydomainconf")
 o = s:taboption("denydomain", TextValue, "denydomainconf")
 o.rows = 13
 o.rows = 13
 o.wrap = "off"
 o.wrap = "off"
@@ -125,7 +125,7 @@ o.remove = function(self, section, value)
 end
 end
 
 
 s:tab("netflix", translate("Netflix Domain List"))
 s:tab("netflix", translate("Netflix Domain List"))
-local netflixconf = "/etc/ssr/netflix.list"
+local netflixconf = "/etc/ssrplus/netflix.list"
 o = s:taboption("netflix", TextValue, "netflixconf")
 o = s:taboption("netflix", TextValue, "netflixconf")
 o.rows = 13
 o.rows = 13
 o.wrap = "off"
 o.wrap = "off"

+ 3 - 3
luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua

@@ -7,8 +7,8 @@ t = f:field(TextValue, "conf")
 t.rmempty = true
 t.rmempty = true
 t.rows = 20
 t.rows = 20
 function t.cfgvalue()
 function t.cfgvalue()
-	if nixio.fs.access("/tmp/ssrplus.log") then
-		local logs = luci.util.execi("cat /tmp/ssrplus.log")
+	if nixio.fs.access("/var/log/ssrplus.log") then
+		local logs = luci.util.execi("cat /var/log/ssrplus.log")
 		local s = ""
 		local s = ""
 		for line in logs do
 		for line in logs do
 			s = line .. "\n" .. s
 			s = line .. "\n" .. s
@@ -16,5 +16,5 @@ function t.cfgvalue()
 		return s
 		return s
 	end
 	end
 end
 end
-t.readonly="readonly"
+t.readonly = "readonly"
 return f
 return f

+ 36 - 37
luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua

@@ -5,48 +5,41 @@ require "luci.dispatcher"
 require "nixio.fs"
 require "nixio.fs"
 
 
 local m, s, o
 local m, s, o
-local shadowsocksr = "shadowsocksr"
 local sid = arg[1]
 local sid = arg[1]
 
 
 local encrypt_methods = {
 local encrypt_methods = {
-"rc4-md5",
-"rc4-md5-6",
-"rc4",
-"table",
-"aes-128-cfb",
-"aes-192-cfb",
-"aes-256-cfb",
-"aes-128-ctr",
-"aes-192-ctr",
-"aes-256-ctr",
-"bf-cfb",
-"camellia-128-cfb",
-"camellia-192-cfb",
-"camellia-256-cfb",
-"cast5-cfb",
-"des-cfb",
-"idea-cfb",
-"rc2-cfb",
-"seed-cfb",
-"salsa20",
-"chacha20",
-"chacha20-ietf",
+	"rc4-md5",
+	"rc4-md5-6",
+	"rc4",
+	"table",
+	"aes-128-cfb",
+	"aes-192-cfb",
+	"aes-256-cfb",
+	"aes-128-ctr",
+	"aes-192-ctr",
+	"aes-256-ctr",
+	"bf-cfb",
+	"camellia-128-cfb",
+	"camellia-192-cfb",
+	"camellia-256-cfb",
+	"cast5-cfb",
+	"des-cfb",
+	"idea-cfb",
+	"rc2-cfb",
+	"seed-cfb",
+	"salsa20",
+	"chacha20",
+	"chacha20-ietf"
 }
 }
 
 
-local protocol = {
-"origin",
-}
+local protocol = {"origin"}
 
 
-obfs = {
-"plain",
-"http_simple",
-"http_post",
-}
+obfs = {"plain", "http_simple", "http_post"}
 
 
-m = Map(shadowsocksr, translate("Edit ShadowSocksR Server"))
+m = Map("shadowsocksr", translate("Edit ShadowSocksR Server"))
 
 
 m.redirect = luci.dispatcher.build_url("admin/services/shadowsocksr/server")
 m.redirect = luci.dispatcher.build_url("admin/services/shadowsocksr/server")
-if m.uci:get(shadowsocksr, sid) ~= "server_config" then
+if m.uci:get("shadowsocksr", sid) ~= "server_config" then
 	luci.http.redirect(m.redirect)
 	luci.http.redirect(m.redirect)
 	return
 	return
 end
 end
@@ -70,7 +63,7 @@ o.default = "socks5"
 o = s:option(Value, "server_port", translate("Server Port"))
 o = s:option(Value, "server_port", translate("Server Port"))
 o.datatype = "port"
 o.datatype = "port"
 math.randomseed(tostring(os.time()):reverse():sub(1, 7))
 math.randomseed(tostring(os.time()):reverse():sub(1, 7))
-o.default = math.random(10240,20480)
+o.default = math.random(10240, 20480)
 o.rmempty = false
 o.rmempty = false
 o.description = translate("warning! Please do not reuse the port!")
 o.description = translate("warning! Please do not reuse the port!")
 
 
@@ -89,17 +82,23 @@ o.password = true
 o.rmempty = false
 o.rmempty = false
 
 
 o = s:option(ListValue, "encrypt_method", translate("Encrypt Method"))
 o = s:option(ListValue, "encrypt_method", translate("Encrypt Method"))
-for _, v in ipairs(encrypt_methods) do o:value(v) end
+for _, v in ipairs(encrypt_methods) do
+	o:value(v)
+end
 o.rmempty = false
 o.rmempty = false
 o:depends("type", "ssr")
 o:depends("type", "ssr")
 
 
 o = s:option(ListValue, "protocol", translate("Protocol"))
 o = s:option(ListValue, "protocol", translate("Protocol"))
-for _, v in ipairs(protocol) do o:value(v) end
+for _, v in ipairs(protocol) do
+	o:value(v)
+end
 o.rmempty = false
 o.rmempty = false
 o:depends("type", "ssr")
 o:depends("type", "ssr")
 
 
 o = s:option(ListValue, "obfs", translate("Obfs"))
 o = s:option(ListValue, "obfs", translate("Obfs"))
-for _, v in ipairs(obfs) do o:value(v) end
+for _, v in ipairs(obfs) do
+	o:value(v)
+end
 o.rmempty = false
 o.rmempty = false
 o:depends("type", "ssr")
 o:depends("type", "ssr")
 
 

+ 35 - 36
luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua

@@ -3,51 +3,50 @@
 require "luci.http"
 require "luci.http"
 require "luci.dispatcher"
 require "luci.dispatcher"
 local m, sec, o
 local m, sec, o
-local shadowsocksr = "shadowsocksr"
 local encrypt_methods = {
 local encrypt_methods = {
-"table",
-"rc4",
-"rc4-md5",
-"rc4-md5-6",
-"aes-128-cfb",
-"aes-192-cfb",
-"aes-256-cfb",
-"aes-128-ctr",
-"aes-192-ctr",
-"aes-256-ctr",
-"bf-cfb",
-"camellia-128-cfb",
-"camellia-192-cfb",
-"camellia-256-cfb",
-"cast5-cfb",
-"des-cfb",
-"idea-cfb",
-"rc2-cfb",
-"seed-cfb",
-"salsa20",
-"chacha20",
-"chacha20-ietf",
+	"table",
+	"rc4",
+	"rc4-md5",
+	"rc4-md5-6",
+	"aes-128-cfb",
+	"aes-192-cfb",
+	"aes-256-cfb",
+	"aes-128-ctr",
+	"aes-192-ctr",
+	"aes-256-ctr",
+	"bf-cfb",
+	"camellia-128-cfb",
+	"camellia-192-cfb",
+	"camellia-256-cfb",
+	"cast5-cfb",
+	"des-cfb",
+	"idea-cfb",
+	"rc2-cfb",
+	"seed-cfb",
+	"salsa20",
+	"chacha20",
+	"chacha20-ietf"
 }
 }
 
 
 local protocol = {
 local protocol = {
-"origin",
-"verify_deflate",
-"auth_sha1_v4",
-"auth_aes128_sha1",
-"auth_aes128_md5",
-"auth_chain_a",
+	"origin",
+	"verify_deflate",
+	"auth_sha1_v4",
+	"auth_aes128_sha1",
+	"auth_aes128_md5",
+	"auth_chain_a"
 }
 }
 
 
 obfs = {
 obfs = {
-"plain",
-"http_simple",
-"http_post",
-"random_head",
-"tls1.2_ticket_auth",
-"tls1.2_ticket_fastauth",
+	"plain",
+	"http_simple",
+	"http_post",
+	"random_head",
+	"tls1.2_ticket_auth",
+	"tls1.2_ticket_fastauth"
 }
 }
 
 
-m = Map(shadowsocksr)
+m = Map("shadowsocksr")
 -- [[ Global Setting ]]--
 -- [[ Global Setting ]]--
 sec = m:section(TypedSection, "server_global", translate("Global Setting"))
 sec = m:section(TypedSection, "server_global", translate("Global Setting"))
 sec.anonymous = true
 sec.anonymous = true

+ 16 - 23
luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua

@@ -3,17 +3,15 @@ require "luci.http"
 require "luci.dispatcher"
 require "luci.dispatcher"
 require "luci.model.uci"
 require "luci.model.uci"
 local m, s, o
 local m, s, o
-local shadowsocksr = "shadowsocksr"
 local uci = luci.model.uci.cursor()
 local uci = luci.model.uci.cursor()
 local server_count = 0
 local server_count = 0
 uci:foreach("shadowsocksr", "servers", function(s)
 uci:foreach("shadowsocksr", "servers", function(s)
 	server_count = server_count + 1
 	server_count = server_count + 1
 end)
 end)
 
 
-m = Map(shadowsocksr, translate("Servers subscription and manage"))
+m = Map("shadowsocksr", translate("Servers subscription and manage"))
 
 
 -- Server Subscribe
 -- Server Subscribe
-
 s = m:section(TypedSection, "server_subscribe")
 s = m:section(TypedSection, "server_subscribe")
 s.anonymous = true
 s.anonymous = true
 
 
@@ -21,12 +19,11 @@ o = s:option(Flag, "auto_update", translate("Auto Update"))
 o.rmempty = false
 o.rmempty = false
 o.description = translate("Auto Update Server subscription, GFW list and CHN route")
 o.description = translate("Auto Update Server subscription, GFW list and CHN route")
 
 
-
 o = s:option(ListValue, "auto_update_time", translate("Update time (every day)"))
 o = s:option(ListValue, "auto_update_time", translate("Update time (every day)"))
-for t = 0,23 do
-	o:value(t, t..":00")
+for t = 0, 23 do
+	o:value(t, t .. ":00")
 end
 end
-o.default=2
+o.default = 2
 o.rmempty = false
 o.rmempty = false
 
 
 o = s:option(DynamicList, "subscribe_url", translate("Subscribe URL"))
 o = s:option(DynamicList, "subscribe_url", translate("Subscribe URL"))
@@ -36,28 +33,28 @@ o = s:option(Value, "filter_words", translate("Subscribe Filter Words"))
 o.rmempty = true
 o.rmempty = true
 o.description = translate("Filter Words splited by /")
 o.description = translate("Filter Words splited by /")
 
 
-o = s:option(Button,"update_Sub",translate("Update Subscribe List"))
+o = s:option(Button, "update_Sub", translate("Update Subscribe List"))
 o.inputstyle = "reload"
 o.inputstyle = "reload"
 o.description = translate("Update subscribe url list first")
 o.description = translate("Update subscribe url list first")
 o.write = function()
 o.write = function()
+	uci:commit("shadowsocksr")
 	luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers"))
 	luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers"))
 end
 end
 
 
 o = s:option(Flag, "switch", translate("Subscribe Default Auto-Switch"))
 o = s:option(Flag, "switch", translate("Subscribe Default Auto-Switch"))
 o.rmempty = false
 o.rmempty = false
 o.description = translate("Subscribe new add server default Auto-Switch on")
 o.description = translate("Subscribe new add server default Auto-Switch on")
-o.default="1"
+o.default = "1"
 
 
 o = s:option(Flag, "proxy", translate("Through proxy update"))
 o = s:option(Flag, "proxy", translate("Through proxy update"))
 o.rmempty = false
 o.rmempty = false
 o.description = translate("Through proxy update list, Not Recommended ")
 o.description = translate("Through proxy update list, Not Recommended ")
 
 
-
-o = s:option(Button,"subscribe", translate("Update All Subscribe Severs"))
+o = s:option(Button, "subscribe", translate("Update All Subscribe Severs"))
 o.rawhtml = true
 o.rawhtml = true
 o.template = "shadowsocksr/subscribe"
 o.template = "shadowsocksr/subscribe"
 
 
-o = s:option(Button,"delete",translate("Delete All Subscribe Severs"))
+o = s:option(Button, "delete", translate("Delete All Subscribe Severs"))
 o.inputstyle = "reset"
 o.inputstyle = "reset"
 o.description = string.format(translate("Server Count") .. ": %d", server_count)
 o.description = string.format(translate("Server Count") .. ": %d", server_count)
 o.write = function()
 o.write = function()
@@ -69,9 +66,7 @@ o.write = function()
 		end
 		end
 	end)
 	end)
 	uci:save("shadowsocksr")
 	uci:save("shadowsocksr")
-	uci:commit("shadowsocksr")
-	luci.sys.exec("/etc/init.d/shadowsocksr restart &")
-	luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers"))
+	m.uci:commit("shadowsocksr")
 	return
 	return
 end
 end
 
 
@@ -106,21 +101,19 @@ function o.cfgvalue(...)
 end
 end
 
 
 o = s:option(DummyValue, "server_port", translate("Socket Connected"))
 o = s:option(DummyValue, "server_port", translate("Socket Connected"))
-o.template="shadowsocksr/socket"
-o.width="10%"
+o.template = "shadowsocksr/socket"
+o.width = "10%"
 
 
 o = s:option(DummyValue, "server", translate("Ping Latency"))
 o = s:option(DummyValue, "server", translate("Ping Latency"))
-o.template="shadowsocksr/ping"
-o.width="10%"
+o.template = "shadowsocksr/ping"
+o.width = "10%"
 
 
-node = s:option(Button,"apply_node",translate("Apply"))
+node = s:option(Button, "apply_node", translate("Apply"))
 node.inputstyle = "apply"
 node.inputstyle = "apply"
 node.write = function(self, section)
 node.write = function(self, section)
 	uci:set("shadowsocksr", '@global[0]', 'global_server', section)
 	uci:set("shadowsocksr", '@global[0]', 'global_server', section)
 	uci:save("shadowsocksr")
 	uci:save("shadowsocksr")
-	uci:commit("shadowsocksr")
-	luci.sys.exec("/etc/init.d/shadowsocksr restart &")
-	luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "client"))
+	m.uci:commit("shadowsocksr")
 end
 end
 
 
 o = s:option(Flag, "switch_enable", translate("Auto Switch"))
 o = s:option(Flag, "switch_enable", translate("Auto Switch"))

+ 75 - 68
luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua

@@ -4,177 +4,184 @@ require "nixio.fs"
 require "luci.sys"
 require "luci.sys"
 require "luci.model.uci"
 require "luci.model.uci"
 local m, s, o
 local m, s, o
-local redir_run=0
-local reudp_run=0
-local sock5_run=0
-local server_run=0
-local kcptun_run=0
-local tunnel_run=0
-local gfw_count=0
-local ad_count=0
-local ip_count=0
-local nfip_count=0
+local redir_run = 0
+local reudp_run = 0
+local sock5_run = 0
+local server_run = 0
+local kcptun_run = 0
+local tunnel_run = 0
+local gfw_count = 0
+local ad_count = 0
+local ip_count = 0
+local nfip_count = 0
+local Process_list = luci.sys.exec("busybox ps -w")
 local uci = luci.model.uci.cursor()
 local uci = luci.model.uci.cursor()
-local shadowsocksr = "shadowsocksr"
 -- html constants
 -- html constants
 font_blue = [[<font color="green">]]
 font_blue = [[<font color="green">]]
 font_off = [[</font>]]
 font_off = [[</font>]]
 bold_on = [[<strong>]]
 bold_on = [[<strong>]]
 bold_off = [[</strong>]]
 bold_off = [[</strong>]]
-local kcptun_version=translate("Unknown")
-local kcp_file="/usr/bin/kcptun-client"
+local kcptun_version = translate("Unknown")
+local kcp_file = "/usr/bin/kcptun-client"
 if not nixio.fs.access(kcp_file) then
 if not nixio.fs.access(kcp_file) then
-	kcptun_version=translate("Not exist")
+	kcptun_version = translate("Not exist")
 else
 else
 	if not nixio.fs.access(kcp_file, "rwx", "rx", "rx") then
 	if not nixio.fs.access(kcp_file, "rwx", "rx", "rx") then
 		nixio.fs.chmod(kcp_file, 755)
 		nixio.fs.chmod(kcp_file, 755)
 	end
 	end
-	kcptun_version=luci.sys.exec(kcp_file .. " -v | awk '{printf $3}'")
+	kcptun_version = luci.sys.exec(kcp_file .. " -v | awk '{printf $3}'")
 	if not kcptun_version or kcptun_version == "" then
 	if not kcptun_version or kcptun_version == "" then
 		kcptun_version = translate("Unknown")
 		kcptun_version = translate("Unknown")
 	end
 	end
 end
 end
 
 
-if nixio.fs.access("/etc/ssr/gfw_list.conf") then
-	gfw_count = tonumber(luci.sys.exec("cat /etc/ssr/gfw_list.conf | wc -l"))/2
+if nixio.fs.access("/etc/ssrplus/gfw_list.conf") then
+	gfw_count = tonumber(luci.sys.exec("cat /etc/ssrplus/gfw_list.conf | wc -l")) / 2
 end
 end
 
 
-if nixio.fs.access("/etc/ssr/ad.conf") then
-	ad_count = tonumber(luci.sys.exec("cat /etc/ssr/ad.conf | wc -l"))
+if nixio.fs.access("/etc/ssrplus/ad.conf") then
+	ad_count = tonumber(luci.sys.exec("cat /etc/ssrplus/ad.conf | wc -l"))
 end
 end
 
 
-if nixio.fs.access("/etc/ssr/china_ssr.txt") then
-	ip_count = tonumber(luci.sys.exec("cat /etc/ssr/china_ssr.txt | wc -l"))
+if nixio.fs.access("/etc/ssrplus/china_ssr.txt") then
+	ip_count = tonumber(luci.sys.exec("cat /etc/ssrplus/china_ssr.txt | wc -l"))
 end
 end
 
 
-if nixio.fs.access("/etc/ssr/netflixip.list") then
-	nfip_count = tonumber(luci.sys.exec("cat /etc/ssr/netflixip.list | wc -l"))
+if nixio.fs.access("/etc/ssrplus/netflixip.list") then
+	nfip_count = tonumber(luci.sys.exec("cat /etc/ssrplus/netflixip.list | wc -l"))
 end
 end
 
 
-local icount=luci.sys.exec("busybox ps -w | grep ssr-reudp |grep -v grep| wc -l")
-if tonumber(icount)>0 then
-	reudp_run=1
-else
-	icount=luci.sys.exec("busybox ps -w | grep ssr-retcp |grep \"\\-u\"|grep -v grep| wc -l")
-	if tonumber(icount)>0 then
-		reudp_run=1
-	end
+if Process_list:find("udp.only.ssr.reudp") then
+	reudp_run = 1
 end
 end
 
 
-if luci.sys.call("busybox ps -w | grep ssr-retcp | grep -v grep >/dev/null") == 0 then
-	redir_run=1
+if Process_list:find("tcp.only.ssr.retcp") then
+	redir_run = 1
 end
 end
 
 
-if luci.sys.call("busybox ps -w | grep ssr-local | grep -v ssr-socksdns |grep -v grep >/dev/null") == 0 then
-	sock5_run=1
+if Process_list:find("tcp.udp.ssr.local") then
+	sock5_run = 1
 end
 end
 
 
-if luci.sys.call("pidof kcptun-client >/dev/null") == 0 then
-	kcptun_run=1
+if Process_list:find("tcp.udp.ssr.retcp") then
+	redir_run = 1
+	reudp_run = 1
 end
 end
 
 
-if luci.sys.call("busybox ps -w | grep ssr-server | grep -v grep >/dev/null") == 0 then
-	server_run=1
+if Process_list:find("local.ssr.retcp") then
+	redir_run = 1
+	sock5_run = 1
 end
 end
 
 
--- if luci.sys.call("busybox ps -w | grep ssr-tunnel |grep -v grep >/dev/null") == 0 then
--- tunnel_run=1
--- end
-if luci.sys.call("pidof pdnsd >/dev/null") == 0 or (luci.sys.call("busybox ps -w | grep ssr-dns |grep -v grep >/dev/null") == 0 and luci.sys.call("pidof dns2socks >/dev/null") == 0)then
-	pdnsd_run=1
+if Process_list:find("local.udp.ssr.retcp") then
+	reudp_run = 1
+	redir_run = 1
+	sock5_run = 1
+end
+
+if Process_list:find("kcptun.client") then
+	kcptun_run = 1
+end
+
+if Process_list:find("ssr.server") then
+	server_run = 1
+end
+
+if Process_list:find("ssrplus/bin/pdnsd") or (Process_list:find("ssrplus.dns") and Process_list:find("dns2socks 127.0.0.1:.*127.0.0.1:5335")) then
+	pdnsd_run = 1
 end
 end
 
 
 m = SimpleForm("Version")
 m = SimpleForm("Version")
 m.reset = false
 m.reset = false
 m.submit = false
 m.submit = false
 
 
-s=m:field(DummyValue,"redir_run",translate("Global Client"))
+s = m:field(DummyValue, "redir_run", translate("Global Client"))
 s.rawhtml = true
 s.rawhtml = true
 if redir_run == 1 then
 if redir_run == 1 then
-	s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
+	s.value = font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
 else
 else
 	s.value = translate("Not Running")
 	s.value = translate("Not Running")
 end
 end
 
 
-s=m:field(DummyValue,"reudp_run",translate("Game Mode UDP Relay"))
+s = m:field(DummyValue, "reudp_run", translate("Game Mode UDP Relay"))
 s.rawhtml = true
 s.rawhtml = true
 if reudp_run == 1 then
 if reudp_run == 1 then
-	s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
+	s.value = font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
 else
 else
 	s.value = translate("Not Running")
 	s.value = translate("Not Running")
 end
 end
 
 
-if uci:get_first(shadowsocksr, 'global', 'pdnsd_enable', '0') ~= '0' then
-	s=m:field(DummyValue,"pdnsd_run",translate("DNS Anti-pollution"))
+if uci:get_first("shadowsocksr", 'global', 'pdnsd_enable', '0') ~= '0' then
+	s = m:field(DummyValue, "pdnsd_run", translate("DNS Anti-pollution"))
 	s.rawhtml = true
 	s.rawhtml = true
 	if pdnsd_run == 1 then
 	if pdnsd_run == 1 then
-		s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
+		s.value = font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
 	else
 	else
 		s.value = translate("Not Running")
 		s.value = translate("Not Running")
 	end
 	end
 end
 end
 
 
-s=m:field(DummyValue,"sock5_run",translate("Global SOCKS5 Proxy Server"))
+s = m:field(DummyValue, "sock5_run", translate("Global SOCKS5 Proxy Server"))
 s.rawhtml = true
 s.rawhtml = true
 if sock5_run == 1 then
 if sock5_run == 1 then
-	s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
+	s.value = font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
 else
 else
 	s.value = translate("Not Running")
 	s.value = translate("Not Running")
 end
 end
 
 
-s=m:field(DummyValue,"server_run",translate("Local Servers"))
+s = m:field(DummyValue, "server_run", translate("Local Servers"))
 s.rawhtml = true
 s.rawhtml = true
 if server_run == 1 then
 if server_run == 1 then
-	s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
+	s.value = font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
 else
 else
 	s.value = translate("Not Running")
 	s.value = translate("Not Running")
 end
 end
 
 
 if nixio.fs.access("/usr/bin/kcptun-client") then
 if nixio.fs.access("/usr/bin/kcptun-client") then
-	s=m:field(DummyValue,"kcp_version",translate("KcpTun Version"))
+	s = m:field(DummyValue, "kcp_version", translate("KcpTun Version"))
 	s.rawhtml = true
 	s.rawhtml = true
-	s.value =kcptun_version
-	s=m:field(DummyValue,"kcptun_run",translate("KcpTun"))
+	s.value = kcptun_version
+	s = m:field(DummyValue, "kcptun_run", translate("KcpTun"))
 	s.rawhtml = true
 	s.rawhtml = true
 	if kcptun_run == 1 then
 	if kcptun_run == 1 then
-		s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
+		s.value = font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
 	else
 	else
 		s.value = translate("Not Running")
 		s.value = translate("Not Running")
 	end
 	end
 end
 end
 
 
-s=m:field(DummyValue,"google",translate("Google Connectivity"))
+s = m:field(DummyValue, "google", translate("Google Connectivity"))
 s.value = translate("No Check")
 s.value = translate("No Check")
 s.template = "shadowsocksr/check"
 s.template = "shadowsocksr/check"
 
 
-s=m:field(DummyValue,"baidu",translate("Baidu Connectivity"))
+s = m:field(DummyValue, "baidu", translate("Baidu Connectivity"))
 s.value = translate("No Check")
 s.value = translate("No Check")
 s.template = "shadowsocksr/check"
 s.template = "shadowsocksr/check"
 
 
-s=m:field(DummyValue,"gfw_data",translate("GFW List Data"))
+s = m:field(DummyValue, "gfw_data", translate("GFW List Data"))
 s.rawhtml = true
 s.rawhtml = true
 s.template = "shadowsocksr/refresh"
 s.template = "shadowsocksr/refresh"
 s.value = gfw_count .. " " .. translate("Records")
 s.value = gfw_count .. " " .. translate("Records")
 
 
-s=m:field(DummyValue,"ip_data",translate("China IP Data"))
+s = m:field(DummyValue, "ip_data", translate("China IP Data"))
 s.rawhtml = true
 s.rawhtml = true
 s.template = "shadowsocksr/refresh"
 s.template = "shadowsocksr/refresh"
 s.value = ip_count .. " " .. translate("Records")
 s.value = ip_count .. " " .. translate("Records")
 
 
-s=m:field(DummyValue,"nfip_data",translate("Netflix IP Data"))
+s = m:field(DummyValue, "nfip_data", translate("Netflix IP Data"))
 s.rawhtml = true
 s.rawhtml = true
 s.template = "shadowsocksr/refresh"
 s.template = "shadowsocksr/refresh"
 s.value = nfip_count .. " " .. translate("Records")
 s.value = nfip_count .. " " .. translate("Records")
 
 
-if uci:get_first(shadowsocksr, 'global', 'adblock', '0') == '1' then
-	s=m:field(DummyValue,"ad_data",translate("Advertising Data"))
+if uci:get_first("shadowsocksr", 'global', 'adblock', '0') == '1' then
+	s = m:field(DummyValue, "ad_data", translate("Advertising Data"))
 	s.rawhtml = true
 	s.rawhtml = true
 	s.template = "shadowsocksr/refresh"
 	s.template = "shadowsocksr/refresh"
 	s.value = ad_count .. " " .. translate("Records")
 	s.value = ad_count .. " " .. translate("Records")
 end
 end
 
 
-s=m:field(DummyValue,"check_port",translate("Check Server Port"))
+s = m:field(DummyValue, "check_port", translate("Check Server Port"))
 s.template = "shadowsocksr/checkport"
 s.template = "shadowsocksr/checkport"
-s.value =translate("No Check")
+s.value = translate("No Check")
 
 
 return m
 return m

+ 0 - 1
luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm

@@ -26,5 +26,4 @@
 //]]></script>
 //]]></script>
 <input type="button" class="cbi-button cbi-button-apply" value="<%:Check Connect%>" onclick="return check_connect(this,'<%=self.option%>')" />
 <input type="button" class="cbi-button cbi-button-apply" value="<%:Check Connect%>" onclick="return check_connect(this,'<%=self.option%>')" />
 <span id="<%=self.option%>-status"><em><%=self.value%></em></span>
 <span id="<%=self.option%>-status"><em><%=self.value%></em></span>
-
 <%+cbi/valuefooter%>
 <%+cbi/valuefooter%>

+ 1 - 12
luci-app-ssr-plus/luasrc/view/shadowsocksr/checkport.htm

@@ -1,7 +1,5 @@
 <%+cbi/valueheader%>
 <%+cbi/valueheader%>
-
 <script type="text/javascript">//<![CDATA[
 <script type="text/javascript">//<![CDATA[
-
 	function check_port(btn)
 	function check_port(btn)
 	{
 	{
 		btn.disabled = true;
 		btn.disabled = true;
@@ -13,24 +11,15 @@
 			var s = document.getElementById('<%=self.option%>-status');
 			var s = document.getElementById('<%=self.option%>-status');
 			if (s)
 			if (s)
 			{
 			{
-
 				s.innerHTML =rv.ret;
 				s.innerHTML =rv.ret;
-
-
-
 			}
 			}
-
 				btn.disabled = false;
 				btn.disabled = false;
 				btn.value    = '<%:Check Server%>';
 				btn.value    = '<%:Check Server%>';
 			}
 			}
 		);
 		);
-
 		return false;
 		return false;
 	}
 	}
 //]]></script>
 //]]></script>
 <input type="button" class="cbi-button cbi-button-apply" value="<%:Check Server%>" onclick="return check_port(this)" />
 <input type="button" class="cbi-button cbi-button-apply" value="<%:Check Server%>" onclick="return check_port(this)" />
 <span id="<%=self.option%>-status"><em><%=self.value%></em></span>
 <span id="<%=self.option%>-status"><em><%=self.value%></em></span>
-
-
-
-<%+cbi/valuefooter%>
+<%+cbi/valuefooter%>

+ 8 - 6
luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm

@@ -12,16 +12,18 @@
 			var s = document.getElementById(dataname+'-status');
 			var s = document.getElementById(dataname+'-status');
 			if (s)
 			if (s)
 			{
 			{
-				if (rv.ret=="0")
-				s.innerHTML ="<font color='green'>"+"<%:No new data!%> "+"</font>";
-				else if(rv.ret=="-1")
+				if(rv.ret=="-1")
 				{
 				{
 					s.innerHTML ="<font color='red'>"+"<%:Refresh Error!%> "+"</font>";
 					s.innerHTML ="<font color='red'>"+"<%:Refresh Error!%> "+"</font>";
 				}
 				}
+				if (rv.ret=="0")
+				{
+					s.innerHTML ="<font color='green'>"+"<%:No new data!%> "+"</font>";
+				}
 				else
 				else
-					{
-				s.innerHTML ="<font color='green'>"+"<%:Refresh OK!%> "+"<%:Total Records:%>"+rv.ret+"</font>";
-			}
+				{
+					s.innerHTML ="<font color='green'>"+"<%:Refresh OK!%> "+"<%:Total Records:%>"+rv.ret+"</font>";
+				}
 			}
 			}
 				btn.disabled = false;
 				btn.disabled = false;
 				btn.value    = '<%:Refresh Data %>';
 				btn.value    = '<%:Refresh Data %>';

+ 25 - 0
luci-app-ssr-plus/luasrc/view/shadowsocksr/reset.htm

@@ -0,0 +1,25 @@
+<%+cbi/valueheader%>
+<script type="text/javascript">//<![CDATA[
+	function subscribe(btn,dataname) {
+		var s = document.getElementById(dataname + '-status');
+		var reset = prompt('<%:Really reset all changes?%><%:Please fill in reset%>',"")
+		if (reset == null || reset == "") {
+			return false;
+		}
+		if (reset != "reset") {
+			s.innerHTML = "<font color='red'><%:The content entered is incorrect!%></font>";
+			return false;
+		}
+		btn.disabled = true;
+		btn.value    = '<%:Perform reset%>';
+		murl=dataname;
+		XHR.get('<%=luci.dispatcher.build_url("admin", "services", "shadowsocksr","reset")%>', { set:murl }, function(x,rv) {
+			btn.value    = '<%:Reset complete%>';
+			s.innerHTML = "<font color='green'><%:Reset complete%></font>";
+		});
+		return false;
+	}
+//]]></script>
+<input type="button" class="cbi-button cbi-button-reset" value="<%:Perform reset%> " onclick="return subscribe(this,'<%=self.option%>')" />
+<span id="<%=self.option%>-status"></span>
+<%+cbi/valuefooter%>

+ 1 - 19
luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm

@@ -2,9 +2,6 @@
  Copyright 2018-2019 Lienol <[email protected]>
  Copyright 2018-2019 Lienol <[email protected]>
  Licensed to the public under the Apache License 2.0.
  Licensed to the public under the Apache License 2.0.
 -%>
 -%>
-<%
-local dsp = require "luci.dispatcher"
--%>
 <script type="text/javascript">
 <script type="text/javascript">
 	//<![CDATA[
 	//<![CDATA[
 	const doms = document.getElementsByClassName('pingtime');
 	const doms = document.getElementsByClassName('pingtime');
@@ -15,8 +12,7 @@ local dsp = require "luci.dispatcher"
 			const port = ports[index];
 			const port = ports[index];
 			if (!dom) res()
 			if (!dom) res()
 			port.innerHTML = '<font color="#0072c3">connect</font>';
 			port.innerHTML = '<font color="#0072c3">connect</font>';
-
-			XHR.get('<%=dsp.build_url("admin/services/shadowsocksr/ping")%>', {
+			XHR.get('<%=luci.dispatcher.build_url("admin/services/shadowsocksr/ping")%>', {
 				index,
 				index,
 				domain: dom.getAttribute("hint"),
 				domain: dom.getAttribute("hint"),
 				port: port.getAttribute("hint")
 				port: port.getAttribute("hint")
@@ -48,7 +44,6 @@ local dsp = require "luci.dispatcher"
 	for (let i = 0; i < 20; i++) {
 	for (let i = 0; i < 20; i++) {
 		thread()
 		thread()
 	}
 	}
-	
 	function cbi_row_drop(fromId, toId, store, isToBottom) {
 	function cbi_row_drop(fromId, toId, store, isToBottom) {
 		var fromNode = document.getElementById(fromId);
 		var fromNode = document.getElementById(fromId);
 		var toNode = document.getElementById(toId);
 		var toNode = document.getElementById(toId);
@@ -65,7 +60,6 @@ local dsp = require "luci.dispatcher"
 		} else {
 		} else {
 			fromNode.parentNode.insertBefore(fromNode, toNode);
 			fromNode.parentNode.insertBefore(fromNode, toNode);
 		}
 		}
-
 		for (var idx = 2; idx < table.rows.length; idx++) {
 		for (var idx = 2; idx < table.rows.length; idx++) {
 			table.rows[idx].className = table.rows[idx].className.replace(
 			table.rows[idx].className = table.rows[idx].className.replace(
 				/cbi-rowstyle-[12]/,
 				/cbi-rowstyle-[12]/,
@@ -75,53 +69,43 @@ local dsp = require "luci.dispatcher"
 			if (table.rows[idx].id && table.rows[idx].id.match(/-([^\-]+)$/))
 			if (table.rows[idx].id && table.rows[idx].id.match(/-([^\-]+)$/))
 				ids.push(RegExp.$1);
 				ids.push(RegExp.$1);
 		}
 		}
-
 		var input = document.getElementById(store);
 		var input = document.getElementById(store);
 		if (input) input.value = ids.join(" ");
 		if (input) input.value = ids.join(" ");
-
 		return false;
 		return false;
 	}
 	}
-
 	// set tr draggable
 	// set tr draggable
 	function enableDragForTable(table_selecter, store) {
 	function enableDragForTable(table_selecter, store) {
 		var trs = document.querySelectorAll(table_selecter + " tr");
 		var trs = document.querySelectorAll(table_selecter + " tr");
 		if (!trs || trs.length.length < 3) {
 		if (!trs || trs.length.length < 3) {
 			return;
 			return;
 		}
 		}
-
 		function ondragstart(ev) {
 		function ondragstart(ev) {
 			ev.dataTransfer.setData("Text", ev.target.id);
 			ev.dataTransfer.setData("Text", ev.target.id);
 		}
 		}
-
 		function ondrop(ev) {
 		function ondrop(ev) {
 			var from = ev.dataTransfer.getData("Text");
 			var from = ev.dataTransfer.getData("Text");
 			cbi_row_drop(from, this.id, store);
 			cbi_row_drop(from, this.id, store);
 		}
 		}
-
 		function ondragover(ev) {
 		function ondragover(ev) {
 			ev.preventDefault();
 			ev.preventDefault();
 			ev.dataTransfer.dropEffect = "move";
 			ev.dataTransfer.dropEffect = "move";
 		}
 		}
-
 		function moveToTop(id) {
 		function moveToTop(id) {
 			var top = document.querySelectorAll(table_selecter + " tr")[2];
 			var top = document.querySelectorAll(table_selecter + " tr")[2];
 			cbi_row_drop(id, top.id, store);
 			cbi_row_drop(id, top.id, store);
 		}
 		}
-
 		function moveToBottom(id) {
 		function moveToBottom(id) {
 			console.log('moveToBottom:', id);
 			console.log('moveToBottom:', id);
 			var trList = document.querySelectorAll(table_selecter + " tr");
 			var trList = document.querySelectorAll(table_selecter + " tr");
 			var bottom = trList[trList.length - 1];
 			var bottom = trList[trList.length - 1];
 			cbi_row_drop(id, bottom.id, store, true);
 			cbi_row_drop(id, bottom.id, store, true);
 		}
 		}
-
 		for (let index = 2; index < trs.length; index++) {
 		for (let index = 2; index < trs.length; index++) {
 			const el = trs[index];
 			const el = trs[index];
 			el.setAttribute("draggable", true);
 			el.setAttribute("draggable", true);
 			el.ondragstart = ondragstart;
 			el.ondragstart = ondragstart;
 			el.ondrop = ondrop;
 			el.ondrop = ondrop;
 			el.ondragover = ondragover;
 			el.ondragover = ondragover;
-
 			// reset the behaviors of the btns
 			// reset the behaviors of the btns
 			var upBtns = el.querySelectorAll(".cbi-button.cbi-button-up");
 			var upBtns = el.querySelectorAll(".cbi-button.cbi-button-up");
 			if (upBtns && upBtns.length > 0) {
 			if (upBtns && upBtns.length > 0) {
@@ -131,7 +115,6 @@ local dsp = require "luci.dispatcher"
 					};
 					};
 				});
 				});
 			}
 			}
-
 			var downBtns = el.querySelectorAll(".cbi-button.cbi-button-down");
 			var downBtns = el.querySelectorAll(".cbi-button.cbi-button-down");
 			if (downBtns && downBtns.length > 0) {
 			if (downBtns && downBtns.length > 0) {
 				downBtns.forEach(function (_el) {
 				downBtns.forEach(function (_el) {
@@ -142,7 +125,6 @@ local dsp = require "luci.dispatcher"
 			}
 			}
 		}
 		}
 	}
 	}
-
 	// enable
 	// enable
 	enableDragForTable(
 	enableDragForTable(
 		"#cbi-shadowsocksr-servers table",
 		"#cbi-shadowsocksr-servers table",

+ 0 - 8
luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm

@@ -80,7 +80,6 @@
 		}
 		}
 		return false;
 		return false;
 	}
 	}
-
 	function import_ssr_url(btn, urlname, sid) {
 	function import_ssr_url(btn, urlname, sid) {
 		var s = document.getElementById(urlname + '-status');
 		var s = document.getElementById(urlname + '-status');
 		if (!s)
 		if (!s)
@@ -98,7 +97,6 @@
 			s.innerHTML = "<font color='red'>无效格式</font>";
 			s.innerHTML = "<font color='red'>无效格式</font>";
 			return false;
 			return false;
 		}
 		}
-
 		var event = document.createEvent("HTMLEvents");
 		var event = document.createEvent("HTMLEvents");
 		event.initEvent("change", true, true);
 		event.initEvent("change", true, true);
 		if (ssu[0] == "ssr") {
 		if (ssu[0] == "ssr") {
@@ -137,7 +135,6 @@
 			s.innerHTML = "<font color='green'>导入ShadowsocksR配置信息成功</font>";
 			s.innerHTML = "<font color='green'>导入ShadowsocksR配置信息成功</font>";
 			return false;
 			return false;
 		} else if (ssu[0] == "ss") {
 		} else if (ssu[0] == "ss") {
-
 			var url0, param = "";
 			var url0, param = "";
 			var sipIndex = ssu[1].indexOf("@");
 			var sipIndex = ssu[1].indexOf("@");
 			var ploc = ssu[1].indexOf("#");
 			var ploc = ssu[1].indexOf("#");
@@ -147,7 +144,6 @@
 			} else {
 			} else {
 				url0 = ssu[1];
 				url0 = ssu[1];
 			}
 			}
-
 			if (sipIndex != -1) {
 			if (sipIndex != -1) {
 				// SIP002
 				// SIP002
 				var userInfo = b64decsafe(url0.substr(0, sipIndex));
 				var userInfo = b64decsafe(url0.substr(0, sipIndex));
@@ -163,7 +159,6 @@
 					plugin = pluginNameInfo.substr(pluginNameInfo.indexOf("=") + 1)
 					plugin = pluginNameInfo.substr(pluginNameInfo.indexOf("=") + 1)
 					pluginOpts = pluginInfo.substr(pluginIndex + 1);
 					pluginOpts = pluginInfo.substr(pluginIndex + 1);
 				}
 				}
-
 				var userInfoSplitIndex = userInfo.indexOf(":");
 				var userInfoSplitIndex = userInfo.indexOf(":");
 				if (userInfoSplitIndex != -1) {
 				if (userInfoSplitIndex != -1) {
 					method = userInfo.substr(0, userInfoSplitIndex);
 					method = userInfo.substr(0, userInfoSplitIndex);
@@ -177,7 +172,6 @@
 				document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method_ss')[0].value = method || "";
 				document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method_ss')[0].value = method || "";
 				document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin')[0].value = plugin || "";
 				document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin')[0].value = plugin || "";
 				document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin_opts')[0].value = pluginOpts || "";
 				document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin_opts')[0].value = pluginOpts || "";
-
 				if (param != undefined) {
 				if (param != undefined) {
 					document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param);
 					document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param);
 				}
 				}
@@ -212,7 +206,6 @@
 				url0 = ssu[1]
 				url0 = ssu[1]
 			}
 			}
 			var sstr = url0;
 			var sstr = url0;
-
 			document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = "trojan";
 			document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = "trojan";
 			document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
 			document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
 			var team = sstr.split('@');
 			var team = sstr.split('@');
@@ -229,7 +222,6 @@
 					queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || '');
 					queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || '');
 				}
 				}
 			}
 			}
-			
 			document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = serverPart[0];
 			document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = serverPart[0];
 			document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = port;
 			document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = port;
 			document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = password;
 			document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = password;

+ 54 - 0
luci-app-ssr-plus/po/zh-cn/ssr-plus.po

@@ -690,3 +690,57 @@ msgstr "混淆密码(可选)"
 
 
 msgid "Select the interface that needs to transmit data. If unchecked, all interfaces will pass data by default!"
 msgid "Select the interface that needs to transmit data. If unchecked, all interfaces will pass data by default!"
 msgstr "选择需要传递数据的接口。如果未选择,则默认情况下所有接口都将传递数据!"
 msgstr "选择需要传递数据的接口。如果未选择,则默认情况下所有接口都将传递数据!"
+
+msgid "Please fill in the Host, for example: www.baidu.com"
+msgstr "请填写Host,例如:www.baidu.com"
+
+msgid "Camouflage Type"
+msgstr "伪装类型"
+
+msgid "VideoCall (SRTP)"
+msgstr "视频通话 (SRTP)"
+
+msgid "BitTorrent (uTP)"
+msgstr "BT下载 (uTP)"
+
+msgid "WechatVideo"
+msgstr "微信视频通话"
+
+msgid "DTLS 1.2"
+msgstr "DTLS 1.2 数据包"
+
+msgid "WireGuard"
+msgstr "WireGuard 数据包"
+
+msgid "MTU"
+msgstr "最大传输单元"
+
+msgid "TTI"
+msgstr "传输时间间隔"
+
+msgid "Uplink Capacity"
+msgstr "上行链路容量"
+
+msgid "Downlink Capacity"
+msgstr "下行链路容量"
+
+msgid "Read Buffer Size"
+msgstr "读取缓冲区大小"
+
+msgid "Write Buffer Size"
+msgstr "写入缓冲区大小"
+
+msgid "Congestion"
+msgstr "拥塞控制"
+
+msgid "Network interface to use"
+msgstr "使用的网络接口"
+
+msgid "Please fill in reset"
+msgstr "请填写 reset"
+
+msgid "The content entered is incorrect!"
+msgstr "输入的内容不正确!"
+
+msgid "Reset complete"
+msgstr "重置完成"

+ 0 - 42
luci-app-ssr-plus/root/etc/config/shadowsocksr

@@ -1,42 +0,0 @@
-
-config global
-	option global_server 'nil'
-	option netflix_server 'nil'
-	option netflix_proxy '0'
-	option threads '0'
-	option run_mode 'router'
-	option dports '2'
-	option pdnsd_enable '1'
-	option tunnel_forward '8.8.4.4:53'
-	option monitor_enable '1'
-	option enable_switch '1'
-	option switch_time '667'
-	option switch_timeout '5'
-	option switch_try_count '3'
-	option gfwlist_url 'https://cdn.jsdelivr.net/gh/v2fly/domain-list-community@release/gfwlist.txt'
-	option chnroute_url 'https://ispip.clang.cn/all_cn.txt'
-	option nfip_url 'https://cdn.jsdelivr.net/gh/QiuSimons/Netflix_IP/getflix.txt'
-	option adblock_url 'https://anti-ad.net/anti-ad-for-dnsmasq.conf'
-
-config access_control
-	option lan_ac_mode '0'
-	option router_proxy '1'
-	list wan_fw_ips '149.154.160.0/20'
-	list wan_fw_ips '67.198.55.0/24'
-	list wan_fw_ips '91.108.4.0/22'
-	list wan_fw_ips '91.108.56.0/22'
-	list wan_fw_ips '109.239.140.0/24'
-	list Interface 'lan'
-
-config server_subscribe
-	option proxy '0'
-	option auto_update_time '2'
-	option auto_update '1'
-	option filter_words '过期时间/剩余流量/QQ群/官网/防失联地址/回国'
-
-config socks5_proxy
-	option socks '0'
-	option local_port '1080'
-
-config server_global
-	option enable_server '0'

文件差異過大導致無法顯示
+ 486 - 376
luci-app-ssr-plus/root/etc/init.d/shadowsocksr


+ 0 - 0
luci-app-ssr-plus/root/etc/ssr/ad.conf → luci-app-ssr-plus/root/etc/ssrplus/ad.conf


+ 0 - 0
luci-app-ssr-plus/root/etc/ssr/black.list → luci-app-ssr-plus/root/etc/ssrplus/black.list


+ 2 - 0
luci-app-ssr-plus/root/etc/ssr/china_ssr.txt → luci-app-ssr-plus/root/etc/ssrplus/china_ssr.txt

@@ -4109,6 +4109,8 @@
 103.159.142.0/23
 103.159.142.0/23
 103.160.32.0/23
 103.160.32.0/23
 103.160.34.0/23
 103.160.34.0/23
+103.160.112.0/23
+103.160.114.0/23
 103.192.0.0/22
 103.192.0.0/22
 103.192.4.0/22
 103.192.4.0/22
 103.192.8.0/22
 103.192.8.0/22

+ 0 - 0
luci-app-ssr-plus/root/etc/ssr/deny.list → luci-app-ssr-plus/root/etc/ssrplus/deny.list


+ 0 - 0
luci-app-ssr-plus/root/etc/ssr/gfw_base.conf → luci-app-ssr-plus/root/etc/ssrplus/gfw_base.conf


+ 10 - 0
luci-app-ssr-plus/root/etc/ssr/gfw_list.conf → luci-app-ssr-plus/root/etc/ssrplus/gfw_list.conf

@@ -4916,6 +4916,8 @@ server=/cmhalq.com/127.0.0.1#5335
 ipset=/cmhalq.com/gfwlist
 ipset=/cmhalq.com/gfwlist
 server=/cmpaas.com/127.0.0.1#5335
 server=/cmpaas.com/127.0.0.1#5335
 ipset=/cmpaas.com/gfwlist
 ipset=/cmpaas.com/gfwlist
+server=/cmu.edu/127.0.0.1#5335
+ipset=/cmu.edu/gfwlist
 server=/cnbc.com/127.0.0.1#5335
 server=/cnbc.com/127.0.0.1#5335
 ipset=/cnbc.com/gfwlist
 ipset=/cnbc.com/gfwlist
 server=/cnbcfm.com/127.0.0.1#5335
 server=/cnbcfm.com/127.0.0.1#5335
@@ -11166,6 +11168,8 @@ server=/keytransparency.foo/127.0.0.1#5335
 ipset=/keytransparency.foo/gfwlist
 ipset=/keytransparency.foo/gfwlist
 server=/keytransparency.org/127.0.0.1#5335
 server=/keytransparency.org/127.0.0.1#5335
 ipset=/keytransparency.org/gfwlist
 ipset=/keytransparency.org/gfwlist
+server=/kfs.io/127.0.0.1#5335
+ipset=/kfs.io/gfwlist
 server=/khanacademy.org/127.0.0.1#5335
 server=/khanacademy.org/127.0.0.1#5335
 ipset=/khanacademy.org/gfwlist
 ipset=/khanacademy.org/gfwlist
 server=/kickshatchannel.com/127.0.0.1#5335
 server=/kickshatchannel.com/127.0.0.1#5335
@@ -11250,6 +11254,12 @@ server=/kirbysuperstarultra.com/127.0.0.1#5335
 ipset=/kirbysuperstarultra.com/gfwlist
 ipset=/kirbysuperstarultra.com/gfwlist
 server=/kissjav.com/127.0.0.1#5335
 server=/kissjav.com/127.0.0.1#5335
 ipset=/kissjav.com/gfwlist
 ipset=/kissjav.com/gfwlist
+server=/kkbox.com/127.0.0.1#5335
+ipset=/kkbox.com/gfwlist
+server=/kktix.com/127.0.0.1#5335
+ipset=/kktix.com/gfwlist
+server=/kktv.me/127.0.0.1#5335
+ipset=/kktv.me/gfwlist
 server=/klik.me/127.0.0.1#5335
 server=/klik.me/127.0.0.1#5335
 ipset=/klik.me/gfwlist
 ipset=/klik.me/gfwlist
 server=/knovel.com/127.0.0.1#5335
 server=/knovel.com/127.0.0.1#5335

+ 0 - 0
luci-app-ssr-plus/root/etc/ssr/netflix.list → luci-app-ssr-plus/root/etc/ssrplus/netflix.list


+ 0 - 0
luci-app-ssr-plus/root/etc/ssr/netflixip.list → luci-app-ssr-plus/root/etc/ssrplus/netflixip.list


+ 0 - 0
luci-app-ssr-plus/root/etc/ssr/oversea_list.conf → luci-app-ssr-plus/root/etc/ssrplus/oversea_list.conf


+ 0 - 0
luci-app-ssr-plus/root/etc/ssr/white.list → luci-app-ssr-plus/root/etc/ssrplus/white.list


+ 13 - 14
luci-app-ssr-plus/root/etc/uci-defaults/luci-ssr-plus

@@ -11,19 +11,19 @@ set firewall.shadowsocksr.path=/var/etc/shadowsocksr.include
 set firewall.shadowsocksr.reload=1
 set firewall.shadowsocksr.reload=1
 commit firewall
 commit firewall
 EOF
 EOF
-rm -rf /etc/config/shadowsocksr-opkg /etc/ssr/*opkg
-touch /etc/ssr/china_ssr.txt
-touch /etc/ssr/deny.list
-touch /etc/ssr/white.list
-touch /etc/ssr/black.list
-touch /etc/ssr/netflix.list
-touch /etc/ssr/netflixip.list
-touch /etc/ssr/gfw_base.conf
-touch /etc/ssr/gfw_list.conf
-touch /etc/ssr/oversea_list.conf
-touch /etc/ssr/ad.conf
+rm -rf /etc/config/shadowsocksr-opkg /etc/ssrplus/*opkg
+touch /etc/ssrplus/china_ssr.txt
+touch /etc/ssrplus/deny.list
+touch /etc/ssrplus/white.list
+touch /etc/ssrplus/black.list
+touch /etc/ssrplus/netflix.list
+touch /etc/ssrplus/netflixip.list
+touch /etc/ssrplus/gfw_base.conf
+touch /etc/ssrplus/gfw_list.conf
+touch /etc/ssrplus/oversea_list.conf
+touch /etc/ssrplus/ad.conf
 touch /etc/config/shadowsocksr
 touch /etc/config/shadowsocksr
-if [ ! -s "/etc/config/shadowsocksr" ] ; then
+if [ ! -s "/etc/config/shadowsocksr" ]; then
 uci -q batch <<-EOF >/dev/null
 uci -q batch <<-EOF >/dev/null
 add shadowsocksr global
 add shadowsocksr global
 set shadowsocksr.@global[0].global_server='nil'
 set shadowsocksr.@global[0].global_server='nil'
@@ -42,7 +42,7 @@ set shadowsocksr.@global[0].switch_try_count='3'
 set shadowsocksr.@global[0].gfwlist_url='https://cdn.jsdelivr.net/gh/v2fly/domain-list-community@release/gfwlist.txt'
 set shadowsocksr.@global[0].gfwlist_url='https://cdn.jsdelivr.net/gh/v2fly/domain-list-community@release/gfwlist.txt'
 set shadowsocksr.@global[0].chnroute_url='https://ispip.clang.cn/all_cn.txt'
 set shadowsocksr.@global[0].chnroute_url='https://ispip.clang.cn/all_cn.txt'
 set shadowsocksr.@global[0].nfip_url='https://cdn.jsdelivr.net/gh/QiuSimons/Netflix_IP/getflix.txt'
 set shadowsocksr.@global[0].nfip_url='https://cdn.jsdelivr.net/gh/QiuSimons/Netflix_IP/getflix.txt'
-set shadowsocksr.@global[0].adblock_url='https://anti-ad.net/anti-ad-for-dnsmasq.conf'
+set shadowsocksr.@global[0].adblock_url='https://neodev.team/lite_host_dnsmasq.conf'
 add shadowsocksr server_subscribe
 add shadowsocksr server_subscribe
 set shadowsocksr.@server_subscribe[0].proxy='0'
 set shadowsocksr.@server_subscribe[0].proxy='0'
 set shadowsocksr.@server_subscribe[0].auto_update_time='2'
 set shadowsocksr.@server_subscribe[0].auto_update_time='2'
@@ -65,6 +65,5 @@ set shadowsocksr.@server_global[0].enable_server='0'
 commit shadowsocksr
 commit shadowsocksr
 EOF
 EOF
 fi
 fi
-sed -i "s/type 'v2ray'"/"type 'vmess'/g" /etc/config/shadowsocksr
 rm -rf /tmp/luci-modulecache /tmp/luci-indexcache
 rm -rf /tmp/luci-modulecache /tmp/luci-indexcache
 exit 0
 exit 0

+ 0 - 10
luci-app-ssr-plus/root/usr/bin/ssr-ad

@@ -1,10 +0,0 @@
-#!/bin/sh -e
-if [ -f /tmp/ssr-update.$1 ]; then
-	if (grep -wq "address=" /tmp/ssr-update.$1); then
-		return $?
-	else
-		cp /tmp/ssr-update.$1 /tmp/adnew.conf 
-		cat /tmp/adnew.conf | grep ^\|\|[^\*]*\^$ | sed -e 's:||:address\=\/:' -e 's:\^:/0\.0\.0\.0:' >/tmp/ssr-update.$1
-		rm -f /tmp/adnew.conf
-	fi
-fi

+ 0 - 27
luci-app-ssr-plus/root/usr/bin/ssr-gfw

@@ -1,27 +0,0 @@
-#!/bin/sh -e
-generate_china_banned() {
-cat $1 | base64 -d >/tmp/gfwlist.txt
-rm -f $1
-sed -i '/^@@|/d' /tmp/gfwlist.txt
-cat /tmp/gfwlist.txt | sort -u |
-sed 's#!.\+##; s#|##g; s#@##g; s#http:\/\/##; s#https:\/\/##;' |
-sed '/\*/d; /apple\.com/d; /sina\.cn/d; /sina\.com\.cn/d; /baidu\.com/d; /byr\.cn/d; /jlike\.com/d; /weibo\.com/d; /zhongsou\.com/d; /youdao\.com/d; /sogou\.com/d; /so\.com/d; /soso\.com/d; /aliyun\.com/d; /taobao\.com/d; /jd\.com/d; /qq\.com/d' |
-sed '/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/d' |
-grep '^[0-9a-zA-Z\.-]\+$' | grep '\.' | sed 's#^\.\+##' | sort -u |
-awk 'BEGIN { prev = "________"; } {
-cur = $0;
-if (index(cur, prev) == 1 && substr(cur, 1 + length(prev) ,1) == ".") {
-} else {
-print cur;
-prev = cur;
-}
-}' | sort -u
-rm -f /tmp/gfwlist.txt
-}
-if (grep -w 'google' /tmp/ssr-update.$1 >/dev/null) ;then
-cp -rf /tmp/ssr-update.$1 /tmp/gfw.txt
-else
-generate_china_banned /tmp/ssr-update.$1 >/tmp/gfw.txt
-fi
-sed '/.*/s/.*/server=\/&\/127.0.0.1#5335\nipset=\/&\/gfwlist/' /tmp/gfw.txt >/tmp/ssr-update.$1
-rm -f /tmp/gfw.txt

+ 21 - 61
luci-app-ssr-plus/root/usr/bin/ssr-monitor

@@ -6,53 +6,23 @@
 # This is free software, licensed under the GNU General Public License v3.
 # This is free software, licensed under the GNU General Public License v3.
 # See /LICENSE for more information.
 # See /LICENSE for more information.
 #
 #
+. $IPKG_INSTROOT/etc/init.d/shadowsocksr
 LOCK_FILE="/var/lock/ssr-monitor.lock"
 LOCK_FILE="/var/lock/ssr-monitor.lock"
 [ -f "$LOCK_FILE" ] && exit 2
 [ -f "$LOCK_FILE" ] && exit 2
 touch "$LOCK_FILE"
 touch "$LOCK_FILE"
-NAME=shadowsocksr
-
-uci_get_by_name() {
-	local ret=$(uci get $NAME.$1.$2 2>/dev/null)
-	echo ${ret:=$3}
-}
-
-uci_get_by_type() {
-	local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null)
-	echo ${ret:=$3}
-}
-
-get_host_ip() {
-	local host=$1
-	local isip=""
-	local ip=$host
-	isip=$(echo $host | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}")
-	if [ -z "$isip" ]; then
-		if [ "$host" != "${host#*:[0-9a-fA-F]}" ]; then
-			ip=$host
-		else
-			local ip=$(resolveip -4 -t 3 $host | awk 'NR==1{print}')
-			# local hostip=$(ping $host -W 1 -s 1 -c 1 | grep PING | cut -d'(' -f 2 | cut -d')' -f1)
-			[ -z "$ip" ] && ip=$(wget -q -O- http://119.29.29.29/d?dn=$1 | awk -F ';' '{print $1}')
-		fi
-	fi
-	echo ${ip:="ERROR"}
-}
-
 server_process_count=$1
 server_process_count=$1
 redir_tcp_process=$2
 redir_tcp_process=$2
 redir_udp_process=$3
 redir_udp_process=$3
-tunnel_process=$4
-kcp_process=$5
-local_process=$6
-pdnsd_process=$7
+kcp_process=$4
+local_process=$5
+pdnsd_process=$6
 if [ -z "$pdnsd_process" ]; then
 if [ -z "$pdnsd_process" ]; then
 	pdnsd_process=0
 	pdnsd_process=0
 fi
 fi
 i=0
 i=0
 GLOBAL_SERVER=$(uci_get_by_type global global_server)
 GLOBAL_SERVER=$(uci_get_by_type global global_server)
-server=$(get_host_ip $(uci_get_by_name $GLOBAL_SERVER server))
-[ "$server" == "ERROR" ] && hostip=$(uci_get_by_name $GLOBAL_SERVER ip)
-lkcp_port=$(uci_get_by_name $GLOBAL_SERVER kcp_port)
+server=$(uci_get_by_name $GLOBAL_SERVER server)
+kcp_port=$(uci_get_by_name $GLOBAL_SERVER kcp_port)
 server_port=$(uci_get_by_name $GLOBAL_SERVER server_port)
 server_port=$(uci_get_by_name $GLOBAL_SERVER server_port)
 password=$(uci_get_by_name $GLOBAL_SERVER kcp_password)
 password=$(uci_get_by_name $GLOBAL_SERVER kcp_password)
 kcp_param=$(uci_get_by_name $GLOBAL_SERVER kcp_param)
 kcp_param=$(uci_get_by_name $GLOBAL_SERVER kcp_param)
@@ -65,7 +35,7 @@ while [ "1" == "1" ]; do #死循环
 		icount=$(busybox ps -w | grep ssr-retcp | grep -v grep | wc -l)
 		icount=$(busybox ps -w | grep ssr-retcp | grep -v grep | wc -l)
 		if [ "$icount" == 0 ]; then
 		if [ "$icount" == 0 ]; then
 			logger -t "$NAME" "ssr redir tcp error.restart!"
 			logger -t "$NAME" "ssr redir tcp error.restart!"
-			echo "$(date "+%Y-%m-%d %H:%M:%S") ssr redir tcp error.restart!" >>/tmp/ssrplus.log
+			echolog "ssr redir tcp error.restart!"
 			/etc/init.d/shadowsocksr restart
 			/etc/init.d/shadowsocksr restart
 			exit 0
 			exit 0
 		fi
 		fi
@@ -75,17 +45,7 @@ while [ "1" == "1" ]; do #死循环
 		icount=$(busybox ps -w | grep ssr-reudp | grep -v grep | wc -l)
 		icount=$(busybox ps -w | grep ssr-reudp | grep -v grep | wc -l)
 		if [ "$icount" == 0 ]; then
 		if [ "$icount" == 0 ]; then
 			logger -t "$NAME" "ssr redir udp error.restart!"
 			logger -t "$NAME" "ssr redir udp error.restart!"
-			echo "$(date "+%Y-%m-%d %H:%M:%S") ssr redir udp error.restart!" >>/tmp/ssrplus.log
-			/etc/init.d/shadowsocksr restart
-			exit 0
-		fi
-	fi
-	#tunnel
-	if [ "$tunnel_process" -gt 0 ]; then
-		icount=$(busybox ps -w | grep ssr-tunnel | grep -v grep | wc -l)
-		if [ "$icount" == 0 ]; then
-			logger -t "$NAME" "ssr tunnel error.restart!"
-			echo "$(date "+%Y-%m-%d %H:%M:%S") ssr tunnel error.restart!" >>/tmp/ssrplus.log
+			echolog "ssr redir udp error.restart!"
 			/etc/init.d/shadowsocksr restart
 			/etc/init.d/shadowsocksr restart
 			exit 0
 			exit 0
 		fi
 		fi
@@ -95,7 +55,7 @@ while [ "1" == "1" ]; do #死循环
 		icount=$(busybox ps -w | grep ssr-server | grep -v grep | wc -l)
 		icount=$(busybox ps -w | grep ssr-server | grep -v grep | wc -l)
 		if [ "$icount" -lt "$server_process_count" ]; then #如果进程挂掉就重启它
 		if [ "$icount" -lt "$server_process_count" ]; then #如果进程挂掉就重启它
 			logger -t "$NAME" "ssr server error.restart!"
 			logger -t "$NAME" "ssr server error.restart!"
-			echo "$(date "+%Y-%m-%d %H:%M:%S") ssr server error.restart!" >>/tmp/ssrplus.log
+			echolog "ssr server error.restart!"
 			kill -9 $(busybox ps -w | grep ssr-server | grep -v grep | awk '{print $1}') >/dev/null 2>&1
 			kill -9 $(busybox ps -w | grep ssr-server | grep -v grep | awk '{print $1}') >/dev/null 2>&1
 			/etc/init.d/shadowsocksr restart
 			/etc/init.d/shadowsocksr restart
 			exit 0
 			exit 0
@@ -106,7 +66,7 @@ while [ "1" == "1" ]; do #死循环
 		icount=$(busybox ps -w | grep kcptun-client | grep -v grep | wc -l)
 		icount=$(busybox ps -w | grep kcptun-client | grep -v grep | wc -l)
 		if [ "$icount" -lt "$kcp_process" ]; then #如果进程挂掉就重启它
 		if [ "$icount" -lt "$kcp_process" ]; then #如果进程挂掉就重启它
 			logger -t "$NAME" "ssr kcptun error.restart!"
 			logger -t "$NAME" "ssr kcptun error.restart!"
-			echo "$(date "+%Y-%m-%d %H:%M:%S") ssr kcptun error.restart!" >>/tmp/ssrplus.log
+			echolog "ssr kcptun error.restart!"
 			killall -q -9 kcptun-client
 			killall -q -9 kcptun-client
 			(/usr/bin/kcptun-client -r $server:$kcp_port -l :$server_port $password $kcp_param &)
 			(/usr/bin/kcptun-client -r $server:$kcp_port -l :$server_port $password $kcp_param &)
 		fi
 		fi
@@ -116,7 +76,7 @@ while [ "1" == "1" ]; do #死循环
 		icount=$(busybox ps -w | grep ssr-local | grep -v grep | wc -l)
 		icount=$(busybox ps -w | grep ssr-local | grep -v grep | wc -l)
 		if [ "$icount" -lt "$local_process" ]; then #如果进程挂掉就重启它
 		if [ "$icount" -lt "$local_process" ]; then #如果进程挂掉就重启它
 			logger -t "$NAME" "global socks server error.restart!"
 			logger -t "$NAME" "global socks server error.restart!"
-			echo "$(date "+%Y-%m-%d %H:%M:%S") global socks server error.restart!" >>/tmp/ssrplus.log
+			echolog "global socks server error.restart!"
 			kill -9 $(busybox ps -w | grep ssr-local | grep -v grep | awk '{print $1}') >/dev/null 2>&1
 			kill -9 $(busybox ps -w | grep ssr-local | grep -v grep | awk '{print $1}') >/dev/null 2>&1
 			/etc/init.d/shadowsocksr restart
 			/etc/init.d/shadowsocksr restart
 			exit 0
 			exit 0
@@ -124,31 +84,31 @@ while [ "1" == "1" ]; do #死循环
 	fi
 	fi
 	#pdnsd
 	#pdnsd
 	if [ "$pdnsd_process" -eq 1 ]; then
 	if [ "$pdnsd_process" -eq 1 ]; then
-		icount=$(busybox ps -w | grep pdnsd | grep -v grep | wc -l)
+		icount=$(busybox ps -w | grep $TMP_BIN_PATH/pdnsd | grep -v grep | wc -l)
 		if [ "$icount" -lt "$pdnsd_process" ]; then #如果进程挂掉就重启它
 		if [ "$icount" -lt "$pdnsd_process" ]; then #如果进程挂掉就重启它
 			logger -t "$NAME" "pdnsd tunnel error.restart!"
 			logger -t "$NAME" "pdnsd tunnel error.restart!"
-			echo "$(date "+%Y-%m-%d %H:%M:%S") pdnsd tunnel error.restart!" >>/tmp/ssrplus.log
+			echolog "pdnsd tunnel error.restart!"
 			if [ -f /var/run/pdnsd.pid ]; then
 			if [ -f /var/run/pdnsd.pid ]; then
 				kill $(cat /var/run/pdnsd.pid) >/dev/null 2>&1
 				kill $(cat /var/run/pdnsd.pid) >/dev/null 2>&1
 			else
 			else
-				kill -9 $(ps | grep pdnsd | grep -v grep | awk '{print $1}') >/dev/null 2>&1
+				kill -9 $(ps | grep $TMP_PATH/pdnsd.conf | grep -v grep | awk '{print $1}') >/dev/null 2>&1
 			fi
 			fi
-			(/usr/sbin/pdnsd -c /var/etc/pdnsd.conf >/dev/null 2>&1 &)
+			ln_start_bin $(first_type pdnsd) pdnsd -c $TMP_PATH/pdnsd.conf
 		fi
 		fi
 	fi
 	fi
 	#dns2socks
 	#dns2socks
 	if [ "$pdnsd_process" -eq 2 ]; then
 	if [ "$pdnsd_process" -eq 2 ]; then
-		icount=$(busybox ps -w | grep -e ssr-dns -e dns2socks | grep -v grep | wc -l)
+		icount=$(busybox ps -w | grep -e ssrplus-dns -e "dns2socks 127.0.0.1 $tmp_dns_port" | grep -v grep | wc -l)
 		if [ "$icount" -lt 2 ]; then #如果进程挂掉就重启它
 		if [ "$icount" -lt 2 ]; then #如果进程挂掉就重启它
 			logger -t "$NAME" "dns2socks $dnsstr tunnel error.restart!"
 			logger -t "$NAME" "dns2socks $dnsstr tunnel error.restart!"
-			echo "$(date "+%Y-%m-%d %H:%M:%S") dns2socks $dnsstr tunnel error.restart!" >>/tmp/ssrplus.log
+			echolog "dns2socks $dnsstr tunnel error.restart!"
 			dnsstr=$(uci_get_by_type global tunnel_forward 8.8.4.4:53)
 			dnsstr=$(uci_get_by_type global tunnel_forward 8.8.4.4:53)
 			dnsserver=$(echo "$dnsstr" | awk -F ':' '{print $1}')
 			dnsserver=$(echo "$dnsstr" | awk -F ':' '{print $1}')
 			dnsport=$(echo "$dnsstr" | awk -F ':' '{print $2}')
 			dnsport=$(echo "$dnsstr" | awk -F ':' '{print $2}')
-			killall -q -9 dns2socks
-			kill -9 $(busybox ps -w | grep ssr-dns | grep -v grep | awk '{print $1}') >/dev/null 2>&1
-			microsocks -i 127.0.0.1 -p 10802 ssr-dns >/dev/null 2>&1 &
-			dns2socks 127.0.0.1:10802 $dnsserver:$dnsport 127.0.0.1:5335 -q >/dev/null 2>&1 &
+			kill -9 $(busybox ps -w | grep ssrplus-dns | grep -v grep | awk '{print $1}') >/dev/null 2>&1
+			kill -9 $(busybox ps -w | grep "dns2socks 127.0.0.1 $tmp_dns_port" | grep -v grep | awk '{print $1}') >/dev/null 2>&1
+			ln_start_bin $(first_type microsocks) microsocks -i 127.0.0.1 -p $tmp_dns_port ssrplus-dns
+			ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_dns_port $dnsserver:$dnsport 127.0.0.1:5335 -q
 		fi
 		fi
 	fi
 	fi
 done
 done

+ 72 - 72
luci-app-ssr-plus/root/usr/bin/ssr-rules

@@ -10,43 +10,43 @@ TAG="_SS_SPEC_RULE_"                                  # comment tag
 IPT="iptables -t nat"                                 # alias of iptables
 IPT="iptables -t nat"                                 # alias of iptables
 FWI=$(uci get firewall.shadowsocksr.path 2>/dev/null) # firewall include file
 FWI=$(uci get firewall.shadowsocksr.path 2>/dev/null) # firewall include file
 usage() {
 usage() {
-cat <<-EOF
-Usage: ssr-rules [options]
+	cat <<-EOF
+		Usage: ssr-rules [options]
 
 
-Valid options are:
+		Valid options are:
 
 
-    -s <server_ip>          ip address of shadowsocksr remote server
-    -l <local_port>         port number of shadowsocksr local server
-    -S <server_ip>          ip address of shadowsocksr remote UDP server
-    -L <local_port>         port number of shadowsocksr local UDP server
-    -i <ip_list_file>       a file content is bypassed ip list
-    -a <lan_ips>            lan ip of access control, need a prefix to
-                            define access control mode
-    -b <wan_ips>            wan ip of will be bypassed
-    -w <wan_ips>            wan ip of will be forwarded
-    -B <bp_lan_ips>         lan ip of will be bypassed proxy
-    -p <fp_lan_ips>         lan ip of will be global proxy
-    -G <gm_lan_ips>         lan ip of will be game mode proxy
-    -D <proxy_ports>        proxy ports
-    -F                      netflix mode
-    -N                      netflix server IP
-    -M                      netflix proxy mode
-    -m <Interface>          Interface name
-    -I <ip_list_file>       a file content is bypassed netflix ip list
-    -e <extra_options>      extra options for iptables
-    -o                      apply the rules to the OUTPUT chain
-    -O                      apply the global rules to the OUTPUT chain
-    -u                      enable udprelay mode, TPROXY is required
-    -U                      enable udprelay mode, using different IP
-                            and ports for TCP and UDP
-    -f                      flush the rules
-    -g                      gfwlist mode
-    -r                      router mode
-    -c                      oversea mode
-    -z                      all mode
-    -h                      show this help message and exit
-EOF
-exit $1
+		    -s <server_ip>          ip address of shadowsocksr remote server
+		    -l <local_port>         port number of shadowsocksr local server
+		    -S <server_ip>          ip address of shadowsocksr remote UDP server
+		    -L <local_port>         port number of shadowsocksr local UDP server
+		    -i <ip_list_file>       a file content is bypassed ip list
+		    -a <lan_ips>            lan ip of access control, need a prefix to
+		                            define access control mode
+		    -b <wan_ips>            wan ip of will be bypassed
+		    -w <wan_ips>            wan ip of will be forwarded
+		    -B <bp_lan_ips>         lan ip of will be bypassed proxy
+		    -p <fp_lan_ips>         lan ip of will be global proxy
+		    -G <gm_lan_ips>         lan ip of will be game mode proxy
+		    -D <proxy_ports>        proxy ports
+		    -F                      shunt mode
+		    -N                      shunt server IP
+		    -M                      shunt proxy mode
+		    -m <Interface>          Interface name
+		    -I <ip_list_file>       a file content is bypassed shunt ip list
+		    -e <extra_options>      extra options for iptables
+		    -o                      apply the rules to the OUTPUT chain
+		    -O                      apply the global rules to the OUTPUT chain
+		    -u                      enable udprelay mode, TPROXY is required
+		    -U                      enable udprelay mode, using different IP
+		                            and ports for TCP and UDP
+		    -f                      flush the rules
+		    -g                      gfwlist mode
+		    -r                      router mode
+		    -c                      oversea mode
+		    -z                      all mode
+		    -h                      show this help message and exit
+	EOF
+	exit $1
 }
 }
 
 
 loger() {
 loger() {
@@ -129,23 +129,24 @@ ipset_r() {
 	fi
 	fi
 	for ip in $WAN_BP_IP; do ipset -! add whitelist $ip; done
 	for ip in $WAN_BP_IP; do ipset -! add whitelist $ip; done
 	for ip in $WAN_FW_IP; do ipset -! add blacklist $ip; done
 	for ip in $WAN_FW_IP; do ipset -! add blacklist $ip; done
-	if [ "$NETFLIX" != "0" ]; then
+	if [ "$SHUNT_PORT" != "0" ]; then
 		ipset -N netflix hash:net 2>/dev/null
 		ipset -N netflix hash:net 2>/dev/null
-		for ip in $(cat ${NETFLIX_LIST:=/dev/null} 2>/dev/null); do ipset -! add netflix $ip; done
+		for ip in $(cat ${SHUNT_LIST:=/dev/null} 2>/dev/null); do ipset -! add netflix $ip; done
+		case "$SHUNT_PORT" in
+		0) ;;
+		1)
+			$IPT -I SS_SPEC_WAN_AC -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports $local_port
+			;;
+		*)
+			$IPT -I SS_SPEC_WAN_AC -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports $SHUNT_PORT
+			if [ "$SHUNT_PROXY" == "1" ]; then
+				$IPT -I SS_SPEC_WAN_AC -p tcp -d $SHUNT_IP -j REDIRECT --to-ports $local_port
+			else
+				ipset -! add whitelist $SHUNT_IP
+			fi
+			;;
+		esac
 	fi
 	fi
-	case "$NETFLIX" in
-	1)
-		$IPT -I SS_SPEC_WAN_AC -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports 4321
-		if [ "$NETFLIX_PROXY" == "1" ]; then
-			$IPT -I SS_SPEC_WAN_AC -p tcp -d $NETFLIX_IP -j REDIRECT --to-ports $local_port
-		else
-			ipset -! add whitelist $NETFLIX_IP
-		fi
-		;;
-	2)
-		$IPT -I SS_SPEC_WAN_AC -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports $local_port
-		;;
-	esac
 	return $?
 	return $?
 }
 }
 
 
@@ -188,9 +189,9 @@ ac_rule() {
 	if [ -z "$Interface" ]; then
 	if [ -z "$Interface" ]; then
 		$IPT -I PREROUTING 1 -p tcp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_WAN_AC
 		$IPT -I PREROUTING 1 -p tcp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_WAN_AC
 	else
 	else
-		for name in $Interface;do 
-		local IFNAME=$(uci -P /var/state get network.$name.ifname 2>/dev/null)
-		[ -n "$IFNAME" ] && $IPT -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p tcp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_WAN_AC
+		for name in $Interface; do
+			local IFNAME=$(uci -P /var/state get network.$name.ifname 2>/dev/null)
+			[ -n "$IFNAME" ] && $IPT -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p tcp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_WAN_AC
 		done
 		done
 	fi
 	fi
 
 
@@ -203,7 +204,7 @@ ac_rule() {
 			create ssr_gen_router hash:net
 			create ssr_gen_router hash:net
 			$(gen_spec_iplist | sed -e "s/^/add ssr_gen_router /")
 			$(gen_spec_iplist | sed -e "s/^/add ssr_gen_router /")
 		EOF
 		EOF
-		$IPT -N SS_SPEC_ROUTER 
+		$IPT -N SS_SPEC_ROUTER
 		$IPT -A SS_SPEC_ROUTER -m set --match-set ssr_gen_router dst -j RETURN
 		$IPT -A SS_SPEC_ROUTER -m set --match-set ssr_gen_router dst -j RETURN
 		$IPT -A SS_SPEC_ROUTER -j SS_SPEC_WAN_FW
 		$IPT -A SS_SPEC_ROUTER -j SS_SPEC_WAN_FW
 		$IPT -I OUTPUT 1 -p tcp -m comment --comment "$TAG" -j SS_SPEC_ROUTER
 		$IPT -I OUTPUT 1 -p tcp -m comment --comment "$TAG" -j SS_SPEC_ROUTER
@@ -257,9 +258,9 @@ tp_rule() {
 	if [ -z "$Interface" ]; then
 	if [ -z "$Interface" ]; then
 		$ipt -I PREROUTING 1 -p udp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_TPROXY
 		$ipt -I PREROUTING 1 -p udp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_TPROXY
 	else
 	else
-		for name in $Interface;do 
-		local IFNAME=$(uci -P /var/state get network.$name.ifname 2>/dev/null)
-		[ -n "$IFNAME" ] && $ipt -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p udp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_TPROXY
+		for name in $Interface; do
+			local IFNAME=$(uci -P /var/state get network.$name.ifname 2>/dev/null)
+			[ -n "$IFNAME" ] && $ipt -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p udp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_TPROXY
 		done
 		done
 	fi
 	fi
 	return $?
 	return $?
@@ -299,8 +300,7 @@ gen_include() {
 	[ -n "$FWI" ] || return 0
 	[ -n "$FWI" ] || return 0
 	extract_rules() {
 	extract_rules() {
 		echo "*$1"
 		echo "*$1"
-		iptables-save -t $1 | grep SS_SPEC_ | \
-		sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/"
+		iptables-save -t $1 | grep SS_SPEC_ | sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/"
 		echo 'COMMIT'
 		echo 'COMMIT'
 	}
 	}
 	cat <<-EOF >>$FWI
 	cat <<-EOF >>$FWI
@@ -358,16 +358,16 @@ while getopts ":m:s:l:S:L:i:e:a:B:b:w:p:G:D:F:N:M:I:oOuUfgrczh" arg; do
 		PROXY_PORTS=$OPTARG
 		PROXY_PORTS=$OPTARG
 		;;
 		;;
 	F)
 	F)
-		NETFLIX=$OPTARG
+		SHUNT_PORT=$OPTARG
 		;;
 		;;
 	N)
 	N)
-		NETFLIX_IP=$OPTARG
+		SHUNT_IP=$OPTARG
 		;;
 		;;
 	M)
 	M)
-		NETFLIX_PROXY=$OPTARG
+		SHUNT_PROXY=$OPTARG
 		;;
 		;;
 	I)
 	I)
-		NETFLIX_LIST=$OPTARG
+		SHUNT_LIST=$OPTARG
 		;;
 		;;
 	o)
 	o)
 		OUTPUT=1
 		OUTPUT=1
@@ -405,16 +405,16 @@ if [ -z "$server" -o -z "$local_port" ]; then
 	usage 2
 	usage 2
 fi
 fi
 
 
-	case "$TPROXY" in
-	1)
-		SERVER=$server
-		LOCAL_PORT=$local_port
-		;;
-	2)
-		: ${SERVER:?"You must assign an ip for the udp relay server."}
-		: ${LOCAL_PORT:?"You must assign a port for the udp relay server."}
+case "$TPROXY" in
+1)
+	SERVER=$server
+	LOCAL_PORT=$local_port
 	;;
 	;;
-	esac
+2)
+	: ${SERVER:?"You must assign an ip for the udp relay server."}
+	: ${LOCAL_PORT:?"You must assign a port for the udp relay server."}
+	;;
+esac
 
 
 flush_r && fw_rule && ipset_r && ac_rule && tp_rule && gen_include
 flush_r && fw_rule && ipset_r && ac_rule && tp_rule && gen_include
 RET=$?
 RET=$?

+ 15 - 26
luci-app-ssr-plus/root/usr/bin/ssr-switch

@@ -7,31 +7,20 @@
 # See /LICENSE for more information.
 # See /LICENSE for more information.
 #
 #
 
 
+. $IPKG_INSTROOT/etc/init.d/shadowsocksr
 LOCK_FILE="/var/lock/ssr-switch.lock"
 LOCK_FILE="/var/lock/ssr-switch.lock"
 [ -f "$LOCK_FILE" ] && exit 2
 [ -f "$LOCK_FILE" ] && exit 2
 touch "$LOCK_FILE"
 touch "$LOCK_FILE"
+LOG_FILE=/var/log/ssrplus.log
+
 cycle_time=60
 cycle_time=60
 switch_time=3
 switch_time=3
 normal_flag=0
 normal_flag=0
 server_locate=0
 server_locate=0
 server_count=0
 server_count=0
-NAME=shadowsocksr
 ENABLE_SERVER=nil
 ENABLE_SERVER=nil
-CONFIG_SWTICH_FILE=/var/etc/${NAME}_t.json
-
 [ -n "$1" ] && cycle_time=$1
 [ -n "$1" ] && cycle_time=$1
 [ -n "$2" ] && switch_time=$2
 [ -n "$2" ] && switch_time=$2
-
-uci_get_by_name() {
-	local ret=$(uci get $NAME.$1.$2 2>/dev/null)
-	echo ${ret:=$3}
-}
-
-uci_get_by_type() {
-	local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null)
-	echo ${ret:=$3}
-}
-
 DEFAULT_SERVER=$(uci_get_by_type global global_server)
 DEFAULT_SERVER=$(uci_get_by_type global global_server)
 CURRENT_SERVER=$DEFAULT_SERVER
 CURRENT_SERVER=$DEFAULT_SERVER
 
 
@@ -42,11 +31,11 @@ check_proxy() {
 	for i in $(seq 1 $try_count); do
 	for i in $(seq 1 $try_count); do
 		/usr/bin/ssr-check www.google.com 80 $switch_time 1
 		/usr/bin/ssr-check www.google.com 80 $switch_time 1
 		if [ "$?" == "0" ]; then
 		if [ "$?" == "0" ]; then
-			# echo "$(date "+%Y-%m-%d %H:%M:%S") Check Google Proxy Success, count=$i" >> /tmp/ssrplus.log
+			# echolog "Check Google Proxy Success, count=$i"
 			result=0
 			result=0
 			break
 			break
 		else
 		else
-			# echo "$(date "+%Y-%m-%d %H:%M:%S") Check Google Proxy Fail, count=$i" >> /tmp/ssrplus.log
+			# echolog "Check Google Proxy Fail, count=$i"
 			/usr/bin/ssr-check www.baidu.com 80 $switch_time 1
 			/usr/bin/ssr-check www.baidu.com 80 $switch_time 1
 			if [ "$?" == "0" ]; then
 			if [ "$?" == "0" ]; then
 				result=1
 				result=1
@@ -123,44 +112,44 @@ start() {
 		#判断当前代理是否为缺省服务器
 		#判断当前代理是否为缺省服务器
 		if [ "$CURRENT_SERVER" != "$DEFAULT_SERVER" ]; then
 		if [ "$CURRENT_SERVER" != "$DEFAULT_SERVER" ]; then
 			#echo "not default proxy"
 			#echo "not default proxy"
-			echo "$(date "+%Y-%m-%d %H:%M:%S") Current server is not default Main server, try to switch back." >>/tmp/ssrplus.log
+			echolog "Current server is not default Main server, try to switch back."
 			#检查缺省服务器是否正常
 			#检查缺省服务器是否正常
 			if test_proxy $DEFAULT_SERVER; then
 			if test_proxy $DEFAULT_SERVER; then
 				#echo "switch to default proxy"
 				#echo "switch to default proxy"
-				echo "$(date "+%Y-%m-%d %H:%M:%S") Main server is avilable." >>/tmp/ssrplus.log
+				echolog "Main server is avilable."
 				#缺省服务器正常,切换回来
 				#缺省服务器正常,切换回来
 				CURRENT_SERVER=$DEFAULT_SERVER
 				CURRENT_SERVER=$DEFAULT_SERVER
 				switch_proxy $CURRENT_SERVER
 				switch_proxy $CURRENT_SERVER
-				echo "$(date "+%Y-%m-%d %H:%M:%S") switch to default "$(uci_get_by_name $CURRENT_SERVER alias)" proxy!" >>/tmp/ssrplus.log
+				echolog "switch to default "$(uci_get_by_name $CURRENT_SERVER alias)" proxy!"
 			else
 			else
-				echo "$(date "+%Y-%m-%d %H:%M:%S") Main server is NOT avilable.Continue using current server." >>/tmp/ssrplus.log
+				echolog "Main server is NOT avilable.Continue using current server."
 			fi
 			fi
 		fi
 		fi
 		#判断当前代理是否正常
 		#判断当前代理是否正常
-		#echo "$(date "+%Y-%m-%d %H:%M:%S") Start checking if the current server is available." >>/tmp/ssrplus.log
+		#echolog "Start checking if the current server is available."
 		check_proxy
 		check_proxy
 		current_ret=$?
 		current_ret=$?
 		if [ "$current_ret" == "1" ]; then
 		if [ "$current_ret" == "1" ]; then
 			#当前代理错误,判断有无可用的服务器
 			#当前代理错误,判断有无可用的服务器
 			#echo "current error"
 			#echo "current error"
-			echo "$(date "+%Y-%m-%d %H:%M:%S") Current server error, try to switch another server." >>/tmp/ssrplus.log
+			echolog "Current server error, try to switch another server."
 			select_proxy
 			select_proxy
 			if [ "$ENABLE_SERVER" != nil ]; then
 			if [ "$ENABLE_SERVER" != nil ]; then
 				#有其他服务器可用,进行切换
 				#有其他服务器可用,进行切换
 				#echo $(uci_get_by_name $new_proxy server)
 				#echo $(uci_get_by_name $new_proxy server)
-				echo "$(date "+%Y-%m-%d %H:%M:%S") Another server is avilable, now switching server." >>/tmp/ssrplus.log
+				echolog "Another server is avilable, now switching server."
 				CURRENT_SERVER=$ENABLE_SERVER
 				CURRENT_SERVER=$ENABLE_SERVER
 				switch_proxy $CURRENT_SERVER
 				switch_proxy $CURRENT_SERVER
 				normal_flag=1
 				normal_flag=1
-				echo "$(date "+%Y-%m-%d %H:%M:%S") Switch to "$(uci_get_by_name $CURRENT_SERVER alias)" proxy!" >>/tmp/ssrplus.log
+				echolog "Switch to "$(uci_get_by_name $CURRENT_SERVER alias)" proxy!"
 			else
 			else
 				switch_proxy $CURRENT_SERVER
 				switch_proxy $CURRENT_SERVER
 				normal_flag=1
 				normal_flag=1
-				echo "$(date "+%Y-%m-%d %H:%M:%S") Try restart current server." >>/tmp/ssrplus.log
+				echolog "Try restart current server."
 			fi
 			fi
 		else
 		else
 			normal_flag=0
 			normal_flag=0
-			# echo "$(date "+%Y-%m-%d %H:%M:%S") ShadowsocksR No Problem." >>/tmp/ssrplus.log
+			# echolog "ShadowsocksR No Problem."
 		fi
 		fi
 	done
 	done
 }
 }

+ 6 - 6
luci-app-ssr-plus/root/usr/share/rpcd/acl.d/luci-app-ssr-plus.json

@@ -1,11 +1,11 @@
 {
 {
 	"luci-app-ssr-plus": {
 	"luci-app-ssr-plus": {
-	"description": "Grant UCI access for luci-app-ssr-plus",
-	"read": {
-		"uci": [ "shadowsocksr" ]
+		"description": "Grant UCI access for luci-app-ssr-plus",
+		"read": {
+			"uci": ["shadowsocksr"]
 		},
 		},
-	"write": {
-		"uci": [ "shadowsocksr" ]
+		"write": {
+			"uci": ["shadowsocksr"]
 		}
 		}
 	}
 	}
-}
+}

+ 1 - 1
luci-app-ssr-plus/root/usr/share/shadowsocksr/chinaipset.sh

@@ -3,5 +3,5 @@
 ipset -! flush china 2>/dev/null
 ipset -! flush china 2>/dev/null
 ipset -! -R <<-EOF || exit 1
 ipset -! -R <<-EOF || exit 1
 	create china hash:net
 	create china hash:net
-	$(cat ${china_ip:=/etc/ssr/china_ssr.txt} | sed -e "s/^/add china /")
+	$(cat ${china_ip:=/etc/ssrplus/china_ssr.txt} | sed -e "s/^/add china /")
 EOF
 EOF

+ 171 - 0
luci-app-ssr-plus/root/usr/share/shadowsocksr/gen_config.lua

@@ -0,0 +1,171 @@
+local ucursor = require"luci.model.uci".cursor()
+local json = require "luci.jsonc"
+local server_section = arg[1]
+local proto = arg[2]
+local local_port = arg[3] or "0"
+local socks_port = arg[4] or "0"
+local server = ucursor:get_all("shadowsocksr", server_section)
+local Xray = {
+	log = {
+		-- error = "/var/ssrplus.log",
+		loglevel = "warning"
+	},
+	-- 传入连接
+	inbound = (local_port ~= "0") and {
+		port = tonumber(local_port),
+		protocol = "dokodemo-door",
+		settings = {network = proto, followRedirect = true},
+		sniffing = {enabled = true, destOverride = {"http", "tls"}}
+	} or nil,
+	-- 开启 socks 代理
+	inboundDetour = (proto == "tcp" and socks_port ~= "0") and {
+		{
+			protocol = "socks",
+			port = tonumber(socks_port),
+			settings = {auth = "noauth", udp = true}
+		}
+	} or nil,
+	-- 传出连接
+	outbound = {
+		protocol = server.type,
+		settings = {
+			vnext = {
+				{
+					address = server.server,
+					port = tonumber(server.server_port),
+					users = {
+						{
+							id = server.vmess_id,
+							alterId = (server.type == "vmess") and tonumber(server.alter_id) or nil,
+							security = (server.type == "vmess") and server.security or nil,
+							encryption = (server.type == "vless") and server.vless_encryption or nil,
+							flow = (server.xtls == '1') and (server.vless_flow and server.vless_flow or "xtls-rprx-splice") or nil
+						}
+					}
+				}
+			}
+		},
+		-- 底层传输配置
+		streamSettings = {
+			network = server.transport,
+			security = (server.xtls == '1') and "xtls" or (server.tls == '1') and "tls" or "none",
+			tlsSettings = (server.tls == '1' and (server.insecure == "1" or server.tls_host)) and {
+				allowInsecure = (server.insecure == "1") and true or nil,
+				serverName = server.tls_host
+			} or nil,
+			xtlsSettings = (server.xtls == '1' and (server.insecure == "1" or server.tls_host)) and {
+				allowInsecure = (server.insecure == "1") and true or nil,
+				serverName = server.tls_host
+			} or nil,
+			tcpSettings = (server.transport == "tcp" and server.tcp_guise == "http") and {
+				header = {
+					type = server.tcp_guise,
+					request = {
+						path = {server.http_path} or {"/"},
+						headers = {Host = {server.http_host} or {}}
+					}
+				}
+			} or nil,
+			kcpSettings = (server.transport == "kcp") and {
+				mtu = tonumber(server.mtu),
+				tti = tonumber(server.tti),
+				uplinkCapacity = tonumber(server.uplink_capacity),
+				downlinkCapacity = tonumber(server.downlink_capacity),
+				congestion = (server.congestion == "1") and true or false,
+				readBufferSize = tonumber(server.read_buffer_size),
+				writeBufferSize = tonumber(server.write_buffer_size),
+				header = {type = server.kcp_guise},
+				seed = server.seed or nil
+			} or nil,
+			wsSettings = (server.transport == "ws") and (server.ws_path or server.ws_host or server.tls_host) and {
+				path = server.ws_path,
+				headers = (server.ws_host or server.tls_host) and {
+					Host = server.ws_host or server.tls_host
+				} or nil
+			} or nil,
+			httpSettings = (server.transport == "h2") and {
+				path = server.h2_path or "",
+				host = {server.h2_host} or nil
+			} or nil,
+			quicSettings = (server.transport == "quic") and {
+				security = server.quic_security,
+				key = server.quic_key,
+				header = {type = server.quic_guise}
+			} or nil
+		},
+		mux = (server.mux == "1" and server.xtls ~= "1") and {
+			enabled = true,
+			concurrency = tonumber(server.concurrency)
+		} or nil
+	} or nil
+}
+local trojan = {
+	log_level = 3,
+	run_type = (proto == "nat" or proto == "tcp") and "nat" or "client",
+	local_addr = "0.0.0.0",
+	local_port = tonumber(local_port),
+	remote_addr = server.server,
+	remote_port = tonumber(server.server_port),
+	udp_timeout = 60,
+	-- 传入连接
+	password = {server.password},
+	-- 传出连接
+	ssl = {
+		verify = (server.insecure == "0") and true or false,
+		verify_hostname = (server.tls == "1") and true or false,
+		cert = "",
+		cipher = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA",
+		cipher_tls13 = "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384",
+		sni = server.tls_host,
+		alpn = {"h2", "http/1.1"},
+		curve = "",
+		reuse_session = true,
+		session_ticket = false
+	},
+	tcp = {
+		no_delay = true,
+		keep_alive = true,
+		reuse_port = true,
+		fast_open = (server.fast_open == "1") and true or false,
+		fast_open_qlen = 20
+	}
+}
+local naiveproxy = {
+	proxy = (server.username and server.password and server.server and server.server_port) and "https://" .. server.username .. ":" .. server.password .. "@" .. server.server .. ":" .. server.server_port,
+	listen = (proto == "redir") and "redir" .. "://0.0.0.0:" .. tonumber(local_port) or "socks" .. "://0.0.0.0:" .. tonumber(local_port),
+	concurrency = (socks_port ~= "0") and tonumber(socks_port) or "1"
+}
+local ss = {
+	server = (server.kcp_enable == "1") and "127.0.0.1" or server.server,
+	server_port = tonumber(server.server_port),
+	local_address = "0.0.0.0",
+	local_port = tonumber(local_port),
+	password = server.password,
+	method = server.encrypt_method,
+	timeout = tonumber(server.timeout) or 60,
+	fast_open = (server.fast_open == "1") and true or false,
+	reuse_port = true
+}
+if server.type == "ss" then
+	if server.plugin then
+		ss.plugin = server.plugin
+		ss.plugin_opts = (server.simple_obfs) and server.simple_obfs .. server.plugin_opts or (server.v2ray_plugin ~= "none") and server.v2ray_plugin .. server.plugin_opts or nil
+	end
+	print(json.stringify(ss, 1))
+end
+if server.type == "ssr" then
+	ss.protocol = server.protocol
+	ss.protocol_param = server.protocol_param
+	ss.obfs = server.obfs
+	ss.obfs_param = server.obfs_param
+	print(json.stringify(ss, 1))
+end
+if server.type == "vless" or server.type == "vmess" then
+	print(json.stringify(Xray, 1))
+end
+if server.type == "trojan" then
+	print(json.stringify(trojan, 1))
+end
+if server.type == "naiveproxy" then
+	print(json.stringify(naiveproxy, 1))
+end

+ 85 - 62
luci-app-ssr-plus/root/usr/share/shadowsocksr/genred2config.sh

@@ -1,72 +1,95 @@
 #!/bin/sh
 #!/bin/sh
-
-cat <<-EOF >$1
-base {
+argv1=$1
+argv2=$2
+argv3=$3
+argv4=$4
+argv5=$5
+argv6=$6
+argv7=$7
+argv8=$8
+argv9=$9
+cat <<-EOF >$argv1
+	base {
 	log_debug = off;
 	log_debug = off;
 	log_info = off;
 	log_info = off;
 	log = stderr;
 	log = stderr;
 	daemon = on;
 	daemon = on;
 	redirector = iptables;
 	redirector = iptables;
 	reuseport = on;
 	reuseport = on;
-}
+	}
 EOF
 EOF
-
-if [ "$2" == "socks5" ]; then
-  if [ "$3" == "tcp" ]; then
-    if [ "$7" == "0" ]; then
-    cat <<-EOF >>$1
-redsocks {
-  bind = "0.0.0.0:$4";
-  relay = "$5:$6";
-  type = socks5;
-  autoproxy = 0;
-  timeout = 10;
+tcp() {
+	if [ "$argv7" == "0" ]; then
+		cat <<-EOF >>$argv1
+			redsocks {
+			bind = "0.0.0.0:$argv4";
+			relay = "$argv5:$argv6";
+			type = socks5;
+			autoproxy = 0;
+			timeout = 10;
+			}
+		EOF
+	else
+		cat <<-EOF >>$argv1
+			redsocks {
+			bind = "0.0.0.0:$argv4";
+			relay = "$argv5:$argv6";
+			type = socks5;
+			autoproxy = 0;
+			timeout = 10;
+			login = "$argv8";
+			password = "$argv9";
+			}
+		EOF
+	fi
 }
 }
-EOF
-  else
-    cat <<-EOF >>$1
-redsocks {
-  bind = "0.0.0.0:$4";
-  relay = "$5:$6";
-  type = socks5;
-  autoproxy = 0;
-  timeout = 10;
-  login = "$8";
-  password = "$9";
+udp() {
+	if [ "$argv7" == "0" ]; then
+		cat <<-EOF >>$argv1
+			redudp {
+			bind = "0.0.0.0:$argv4";
+			relay = "$argv5:$argv6";
+			type = socks5;
+			udp_timeout = 10;
+			}
+		EOF
+	else
+		cat <<-EOF >>$argv1
+			redudp {
+			bind = "0.0.0.0:$argv4";
+			relay = "$argv5:$argv6";
+			type = socks5;
+			udp_timeout = 10;
+			login = "$argv8";
+			password = "$argv9";
+			}
+		EOF
+	fi
 }
 }
-EOF
-    fi
-  else
-   if [ "$7" == "0" ]; then
-    cat <<-EOF >>$1
-redudp {
-  bind = "0.0.0.0:$4";
-  relay = "$5:$6";
-  type = socks5;
-  udp_timeout = 10;
-}
-EOF
-  else
-    cat <<-EOF >>$1
-redudp {
-  bind = "0.0.0.0:$4";
-  relay = "$5:$6";
-  type = socks5;
-  udp_timeout = 10;
-  login = "$8";
-  password = "$9";
-}
-EOF
-    fi
-  fi
-else
-    cat <<-EOF >>$1
-redsocks {
-  bind = "0.0.0.0:$4";
-  type = direct;
-  interface = $3;
-  autoproxy = 0;
-  timeout = 10;
-}
-EOF
-fi
+case "$argv2" in
+socks5)
+	case "$argv3" in
+	tcp)
+		tcp
+		;;
+	udp)
+		udp
+		;;
+	*)
+		tcp
+		udp
+		;;
+	esac
+	;;
+*)
+	cat <<-EOF >>$argv1
+		redsocks {
+		bind = "0.0.0.0:$argv4";
+		type = direct;
+		interface = $argv3;
+		autoproxy = 0;
+		timeout = 10;
+		}
+	EOF
+	;;
+esac

+ 0 - 40
luci-app-ssr-plus/root/usr/share/shadowsocksr/gentrojanconfig.lua

@@ -1,40 +0,0 @@
-local ucursor = require "luci.model.uci".cursor()
-local json = require "luci.jsonc"
-local server_section = arg[1]
-local proto = arg[2]
-local local_port = arg[3]
-
-local server = ucursor:get_all("shadowsocksr", server_section)
-
-local trojan = {
-	log_level = 3,
-	run_type = proto,
-	local_addr = "0.0.0.0",
-	local_port = tonumber(local_port),
-	remote_addr = server.server,
-	remote_port = tonumber(server.server_port),
-	udp_timeout = 60,
-	-- 传入连接
-	password = {server.password},
-	-- 传出连接
-	ssl = {
-		verify = (server.insecure == "0") and true or false,
-		verify_hostname = (server.tls == "1") and true or false,
-		cert = "",
-		cipher = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA",
-		cipher_tls13 = "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384",
-		sni = server.tls_host,
-		alpn = {"h2", "http/1.1"},
-		curve = "",
-		reuse_session = true,
-		session_ticket = false,
-		},
-		tcp = {
-			no_delay = true,
-			keep_alive = true,
-			reuse_port = true,
-			fast_open = (server.fast_open == "1") and true or false,
-			fast_open_qlen = 20
-		}
-}
-print(json.stringify(trojan, 1))

+ 0 - 117
luci-app-ssr-plus/root/usr/share/shadowsocksr/genv2config.lua

@@ -1,117 +0,0 @@
-local ucursor = require "luci.model.uci".cursor()
-local json = require "luci.jsonc"
-local server_section = arg[1]
-local proto = arg[2]
-local local_port = arg[3] or "0"
-local socks_port = arg[4] or "0"
-local server = ucursor:get_all("shadowsocksr", server_section)
-local Xray = {
-log = {
--- error = "/var/ssrplus.log",
-loglevel = "warning"
-},
--- 传入连接
-inbound = (local_port ~= "0") and {
-	port = tonumber(local_port),
-	protocol = "dokodemo-door",
-	settings = {
-		network = proto,
-		followRedirect = true
-	},
-	sniffing = {
-		enabled = true,
-		destOverride = { "http", "tls" }
-	}
-} or nil,
--- 开启 socks 代理
-inboundDetour = (proto == "tcp" and socks_port ~= "0") and {
-	{
-	protocol = "socks",
-	port = socks_port,
-		settings = {
-			auth = "noauth",
-			udp = true
-		}
-	}
-} or nil,
--- 传出连接
-outbound = {
-	protocol = server.type,
-	settings = {
-		vnext = {
-			{
-				address = server.server,
-				port = tonumber(server.server_port),
-				users = {
-					{
-						id = server.vmess_id,
-						alterId = (server.type == "vmess") and tonumber(server.alter_id) or nil,
-						security = (server.type == "vmess") and server.security or nil,
-						encryption = (server.type == "vless") and server.vless_encryption or nil,
-						flow = (server.xtls == '1') and (server.vless_flow and server.vless_flow or "xtls-rprx-splice") or nil,
-					}
-				}
-			}
-		}
-	},
--- 底层传输配置
-	streamSettings = {
-		network = server.transport,
-		security = (server.xtls == '1') and "xtls" or (server.tls == '1') and "tls" or "none",
-		tlsSettings = (server.tls == '1' and (server.insecure == "1" or server.tls_host)) and {
-			allowInsecure = (server.insecure == "1") and true or nil,
-			serverName=server.tls_host
-		} or nil,
-		xtlsSettings = (server.xtls == '1' and (server.insecure == "1" or server.tls_host)) and {
-			allowInsecure = (server.insecure == "1") and true or nil,
-			serverName=server.tls_host
-		} or nil,
-		tcpSettings = (server.transport == "tcp" and server.tcp_guise == "http") and {
-			header = {
-				type = server.tcp_guise,
-				request = {
-					path = {server.http_path} or {"/"},
-					headers = {
-						Host = {server.http_host} or {}
-					}
-				}
-			}
-		} or nil,
-		kcpSettings = (server.transport == "kcp") and {
-			mtu = tonumber(server.mtu),
-			tti = tonumber(server.tti),
-			uplinkCapacity = tonumber(server.uplink_capacity),
-			downlinkCapacity = tonumber(server.downlink_capacity),
-			congestion = (server.congestion == "1") and true or false,
-			readBufferSize = tonumber(server.read_buffer_size),
-			writeBufferSize = tonumber(server.write_buffer_size),
-			header = {
-				type = server.kcp_guise
-			},
-			seed = server.seed or nil
-		} or nil,
-		wsSettings = (server.transport == "ws") and (server.ws_path or server.ws_host or server.tls_host) and {
-			path = server.ws_path,
-			headers = (server.ws_host or server.tls_host) and {
-				Host = server.ws_host or server.tls_host
-			} or nil,
-		} or nil,
-		httpSettings = (server.transport == "h2") and {
-			path = server.h2_path or "",
-			host = {server.h2_host} or nil
-		} or nil,
-		quicSettings = (server.transport == "quic") and {
-			security = server.quic_security,
-			key = server.quic_key,
-			header = {
-				type = server.quic_guise
-			}
-		} or nil
-	},
-	mux = (server.mux == "1" and server.xtls ~= "1") and {
-		enabled = true,
-		concurrency = tonumber(server.concurrency)
-	} or nil
-} or nil
-}
-print(json.stringify(Xray,1))

+ 38 - 50
luci-app-ssr-plus/root/usr/share/shadowsocksr/gfw2ipset.sh

@@ -1,59 +1,47 @@
 #!/bin/sh
 #!/bin/sh
-NAME=shadowsocksr
-switch_server=$1
-uci_get_by_type() {
-	local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null)
-	echo ${ret:=$3}
+. $IPKG_INSTROOT/etc/init.d/shadowsocksr
+netflix() {
+	if [ -f "$TMP_DNSMASQ_PATH/gfw_list.conf" ]; then
+		for line in $(cat /etc/ssrplus/netflix.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_list.conf; done
+		for line in $(cat /etc/ssrplus/netflix.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_base.conf; done
+	fi
+	cat /etc/ssrplus/netflix.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/server=\/&\/127.0.0.1#$1\nipset=\/&\/netflix/" >$TMP_DNSMASQ_PATH/netflix_forward.conf
 }
 }
-if [ -z "$switch_server" ]; then
-	GLOBAL_SERVER=$(uci_get_by_type global global_server nil)
-else
-	GLOBAL_SERVER=$switch_server
-fi
-
-mkdir -p /tmp/dnsmasq.ssr
+mkdir -p $TMP_DNSMASQ_PATH
 if [ "$(uci_get_by_type global run_mode router)" == "oversea" ]; then
 if [ "$(uci_get_by_type global run_mode router)" == "oversea" ]; then
-	cp -rf /etc/ssr/oversea_list.conf /tmp/dnsmasq.ssr/
-else
-	cp -rf /etc/ssr/gfw_list.conf /tmp/dnsmasq.ssr/
-	cp -rf /etc/ssr/gfw_base.conf /tmp/dnsmasq.ssr/
-fi
-
-NETFLIX_SERVER=$(uci_get_by_type global netflix_server nil)
-[ "$NETFLIX_SERVER" == "same" ] && NETFLIX_SERVER=$GLOBAL_SERVER
-if [ "$NETFLIX_SERVER" != "nil" ]; then
-	netflix() {
-		if [ -f "/tmp/dnsmasq.ssr/gfw_list.conf" ]; then
-			for line in $(cat /etc/ssr/netflix.list); do sed -i "/$line/d" /tmp/dnsmasq.ssr/gfw_list.conf; done
-			for line in $(cat /etc/ssr/netflix.list); do sed -i "/$line/d" /tmp/dnsmasq.ssr/gfw_base.conf; done
-		fi
-		sed "/.*/s/.*/server=\/&\/127.0.0.1#$1\nipset=\/&\/netflix/" /etc/ssr/netflix.list >/tmp/dnsmasq.ssr/netflix_forward.conf
-	}
-	if [ "$NETFLIX_SERVER" != "$GLOBAL_SERVER" ]; then
-		netflix 5555
-	else
-		netflix 5335
-	fi
+	cp -rf /etc/ssrplus/oversea_list.conf $TMP_DNSMASQ_PATH/
 else
 else
-	rm -f /tmp/dnsmasq.ssr/netflix_forward.conf
+	cp -rf /etc/ssrplus/gfw_list.conf $TMP_DNSMASQ_PATH/
+	cp -rf /etc/ssrplus/gfw_base.conf $TMP_DNSMASQ_PATH/
 fi
 fi
-for line in $(cat /etc/ssr/black.list); do sed -i "/$line/d" /tmp/dnsmasq.ssr/gfw_list.conf; done
-for line in $(cat /etc/ssr/black.list); do sed -i "/$line/d" /tmp/dnsmasq.ssr/gfw_base.conf; done
-for line in $(cat /etc/ssr/white.list); do sed -i "/$line/d" /tmp/dnsmasq.ssr/gfw_list.conf; done
-for line in $(cat /etc/ssr/white.list); do sed -i "/$line/d" /tmp/dnsmasq.ssr/gfw_base.conf; done
-for line in $(cat /etc/ssr/deny.list); do sed -i "/$line/d" /tmp/dnsmasq.ssr/gfw_list.conf; done
-for line in $(cat /etc/ssr/deny.list); do sed -i "/$line/d" /tmp/dnsmasq.ssr/gfw_base.conf; done
-sed "/.*/s/.*/server=\/&\/127.0.0.1#5335\nipset=\/&\/blacklist/" /etc/ssr/black.list >/tmp/dnsmasq.ssr/blacklist_forward.conf
-sed "/.*/s/.*/server=\/&\/127.0.0.1\nipset=\/&\/whitelist/" /etc/ssr/white.list >/tmp/dnsmasq.ssr/whitelist_forward.conf
-sed "/.*/s/.*/address=\/&\//" /etc/ssr/deny.list >/tmp/dnsmasq.ssr/denylist.conf
+case "$(uci_get_by_type global netflix_server nil)" in
+nil)
+	rm -f $TMP_DNSMASQ_PATH/netflix_forward.conf
+	;;
+same)
+	netflix 5335
+	;;
+*)
+	netflix $tmp_shunt_dns_port
+	;;
+esac
+for line in $(cat /etc/ssrplus/black.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_list.conf; done
+for line in $(cat /etc/ssrplus/black.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_base.conf; done
+for line in $(cat /etc/ssrplus/white.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_list.conf; done
+for line in $(cat /etc/ssrplus/white.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_base.conf; done
+for line in $(cat /etc/ssrplus/deny.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_list.conf; done
+for line in $(cat /etc/ssrplus/deny.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_base.conf; done
+cat /etc/ssrplus/black.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/server=\/&\/127.0.0.1#5335\nipset=\/&\/blacklist/" >$TMP_DNSMASQ_PATH/blacklist_forward.conf
+cat /etc/ssrplus/white.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/server=\/&\/127.0.0.1\nipset=\/&\/whitelist/" >$TMP_DNSMASQ_PATH/whitelist_forward.conf
+cat /etc/ssrplus/deny.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/address=\/&\//" >$TMP_DNSMASQ_PATH/denylist.conf
 if [ "$(uci_get_by_type global adblock 0)" == "1" ]; then
 if [ "$(uci_get_by_type global adblock 0)" == "1" ]; then
-	[ -z "$switch_server" ] && cp -f /etc/ssr/ad.conf /tmp/dnsmasq.ssr/
-	if [ -f "/tmp/dnsmasq.ssr/ad.conf" ]; then
-		for line in $(cat /etc/ssr/black.list); do sed -i "/$line/d" /tmp/dnsmasq.ssr/ad.conf; done
-		for line in $(cat /etc/ssr/white.list); do sed -i "/$line/d" /tmp/dnsmasq.ssr/ad.conf; done
-		for line in $(cat /etc/ssr/deny.list); do sed -i "/$line/d" /tmp/dnsmasq.ssr/ad.conf; done
-		for line in $(cat /etc/ssr/netflix.list); do sed -i "/$line/d" /tmp/dnsmasq.ssr/ad.conf; done
+	cp -f /etc/ssrplus/ad.conf $TMP_DNSMASQ_PATH/
+	if [ -f "$TMP_DNSMASQ_PATH/ad.conf" ]; then
+		for line in $(cat /etc/ssrplus/black.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/ad.conf; done
+		for line in $(cat /etc/ssrplus/white.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/ad.conf; done
+		for line in $(cat /etc/ssrplus/deny.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/ad.conf; done
+		for line in $(cat /etc/ssrplus/netflix.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/ad.conf; done
 	fi
 	fi
 else
 else
-	rm -f /tmp/dnsmasq.ssr/ad.conf
+	rm -f $TMP_DNSMASQ_PATH/ad.conf
 fi
 fi

+ 1 - 1
luci-app-ssr-plus/root/usr/share/shadowsocksr/ssrplusupdate.sh

@@ -1,6 +1,6 @@
 #!/bin/sh
 #!/bin/sh
 /usr/bin/lua /usr/share/shadowsocksr/update.lua
 /usr/bin/lua /usr/share/shadowsocksr/update.lua
 sleep 2s
 sleep 2s
-/usr/share/shadowsocksr/chinaipset.sh /tmp/etc/china_ssr.txt
+/usr/share/shadowsocksr/chinaipset.sh /var/etc/ssrplus/china_ssr.txt
 sleep 2s
 sleep 2s
 /usr/bin/lua /usr/share/shadowsocksr/subscribe.lua
 /usr/bin/lua /usr/share/shadowsocksr/subscribe.lua

+ 19 - 30
luci-app-ssr-plus/root/usr/share/shadowsocksr/subscribe.lua

@@ -1,4 +1,5 @@
 #!/usr/bin/lua
 #!/usr/bin/lua
+
 ------------------------------------------------
 ------------------------------------------------
 -- This file is part of the luci-app-ssr-plus subscribe.lua
 -- This file is part of the luci-app-ssr-plus subscribe.lua
 -- @author William Chan <[email protected]>
 -- @author William Chan <[email protected]>
@@ -15,7 +16,7 @@ local ssub, slen, schar, sbyte, sformat, sgsub = string.sub, string.len, string.
 local jsonParse, jsonStringify = luci.jsonc.parse, luci.jsonc.stringify
 local jsonParse, jsonStringify = luci.jsonc.parse, luci.jsonc.stringify
 local b64decode = nixio.bin.b64decode
 local b64decode = nixio.bin.b64decode
 local cache = {}
 local cache = {}
-local nodeResult = setmetatable({}, { __index = cache }) -- update result
+local nodeResult = setmetatable({}, {__index = cache}) -- update result
 local name = 'shadowsocksr'
 local name = 'shadowsocksr'
 local uciType = 'servers'
 local uciType = 'servers'
 local ucic = luci.model.uci.cursor()
 local ucic = luci.model.uci.cursor()
@@ -24,7 +25,7 @@ local switch = ucic:get_first(name, 'server_subscribe', 'switch', '1')
 local subscribe_url = ucic:get_first(name, 'server_subscribe', 'subscribe_url', {})
 local subscribe_url = ucic:get_first(name, 'server_subscribe', 'subscribe_url', {})
 local filter_words = ucic:get_first(name, 'server_subscribe', 'filter_words', '过期时间/剩余流量')
 local filter_words = ucic:get_first(name, 'server_subscribe', 'filter_words', '过期时间/剩余流量')
 local log = function(...)
 local log = function(...)
-	print(os.date("%Y-%m-%d %H:%M:%S ") .. table.concat({ ... }, " "))
+	print(os.date("%Y-%m-%d %H:%M:%S ") .. table.concat({...}, " "))
 end
 end
 -- 分割字符串
 -- 分割字符串
 local function split(full, sep)
 local function split(full, sep)
@@ -79,7 +80,9 @@ end
 -- base64
 -- base64
 local function base64Decode(text)
 local function base64Decode(text)
 	local raw = text
 	local raw = text
-	if not text then return '' end
+	if not text then
+		return ''
+	end
 	text = text:gsub("%z", "")
 	text = text:gsub("%z", "")
 	text = text:gsub("_", "/")
 	text = text:gsub("_", "/")
 	text = text:gsub("-", "+")
 	text = text:gsub("-", "+")
@@ -94,11 +97,7 @@ local function base64Decode(text)
 end
 end
 -- 处理数据
 -- 处理数据
 local function processData(szType, content)
 local function processData(szType, content)
-	local result = {
-	type = szType,
-	local_port = 1234,
-	kcp_param = '--nocomp'
-	}
+	local result = {type = szType, local_port = 1234, kcp_param = '--nocomp'}
 	if szType == 'ssr' then
 	if szType == 'ssr' then
 		local dat = split(content, "/%?")
 		local dat = split(content, "/%?")
 		local hostInfo = split(dat[1], ':')
 		local hostInfo = split(dat[1], ':')
@@ -278,7 +277,7 @@ local function processData(szType, content)
 end
 end
 -- wget
 -- wget
 local function wget(url)
 local function wget(url)
-	local stdout = luci.sys.exec('wget-ssl -q --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36" --no-check-certificate -t 3 -T 10 -O- "' .. url .. '"')
+	local stdout = luci.sys.exec('wget -q --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36" --no-check-certificate -O- "' .. url .. '"')
 	return trim(stdout)
 	return trim(stdout)
 end
 end
 
 
@@ -315,16 +314,11 @@ local execute = function()
 					local nEnd = select(2, raw:find('ssd://'))
 					local nEnd = select(2, raw:find('ssd://'))
 					nodes = base64Decode(raw:sub(nEnd + 1, #raw))
 					nodes = base64Decode(raw:sub(nEnd + 1, #raw))
 					nodes = jsonParse(nodes)
 					nodes = jsonParse(nodes)
-					local extra = {
-					airport = nodes.airport,
-					port = nodes.port,
-					encryption = nodes.encryption,
-					password = nodes.password
-					}
+					local extra = {airport = nodes.airport, port = nodes.port, encryption = nodes.encryption, password = nodes.password}
 					local servers = {}
 					local servers = {}
 					-- SS里面包着 干脆直接这样
 					-- SS里面包着 干脆直接这样
 					for _, server in ipairs(nodes.servers) do
 					for _, server in ipairs(nodes.servers) do
-						tinsert(servers, setmetatable(server, { __index = extra }))
+						tinsert(servers, setmetatable(server, {__index = extra}))
 					end
 					end
 					nodes = servers
 					nodes = servers
 				else
 				else
@@ -355,14 +349,9 @@ local execute = function()
 						end
 						end
 						-- log(result)
 						-- log(result)
 						if result then
 						if result then
-							if
-								not result.server or
-								not result.server_port or
-								result.alias == "NULL" or
-								check_filer(result) or
-								result.server:match("[^0-9a-zA-Z%-%.%s]") -- 中文做地址的 也没有人拿中文域名搞,就算中文域也有Puny Code SB 机场
-								then
-								log('丢弃无效节点: ' .. result.type ..' 节点, ' .. result.alias)
+							-- 中文做地址的 也没有人拿中文域名搞,就算中文域也有Puny Code SB 机场
+							if not result.server or not result.server_port or result.alias == "NULL" or check_filer(result) or result.server:match("[^0-9a-zA-Z%-%.%s]") then
+								log('丢弃无效节点: ' .. result.type .. ' 节点, ' .. result.alias)
 							else
 							else
 								-- log('成功解析: ' .. result.type ..' 节点, ' .. result.alias)
 								-- log('成功解析: ' .. result.type ..' 节点, ' .. result.alias)
 								result.grouphashkey = groupHash
 								result.grouphashkey = groupHash
@@ -372,7 +361,7 @@ local execute = function()
 						end
 						end
 					end
 					end
 				end
 				end
-				log('成功解析节点数量: ' ..#nodes)
+				log('成功解析节点数量: ' .. #nodes)
 			else
 			else
 				log(url .. ': 获取内容为空')
 				log(url .. ': 获取内容为空')
 			end
 			end
@@ -398,7 +387,7 @@ local execute = function()
 					local dat = nodeResult[old.grouphashkey][old.hashkey]
 					local dat = nodeResult[old.grouphashkey][old.hashkey]
 					ucic:tset(name, old['.name'], dat)
 					ucic:tset(name, old['.name'], dat)
 					-- 标记一下
 					-- 标记一下
-					setmetatable(nodeResult[old.grouphashkey][old.hashkey], { __index = { _ignore = true } })
+					setmetatable(nodeResult[old.grouphashkey][old.hashkey], {__index = {_ignore = true}})
 				end
 				end
 			else
 			else
 				if not old.alias then
 				if not old.alias then
@@ -432,14 +421,14 @@ local execute = function()
 					luci.sys.call("/etc/init.d/" .. name .. " start > /dev/null 2>&1 &")
 					luci.sys.call("/etc/init.d/" .. name .. " start > /dev/null 2>&1 &")
 				else
 				else
 					log('维持当前主服务器节点。')
 					log('维持当前主服务器节点。')
-					luci.sys.call("/etc/init.d/" .. name .." restart > /dev/null 2>&1 &")
+					luci.sys.call("/etc/init.d/" .. name .. " restart > /dev/null 2>&1 &")
 				end
 				end
 			else
 			else
 				log('没有服务器节点了,停止服务')
 				log('没有服务器节点了,停止服务')
 				luci.sys.call("/etc/init.d/" .. name .. " stop > /dev/null 2>&1 &")
 				luci.sys.call("/etc/init.d/" .. name .. " stop > /dev/null 2>&1 &")
 			end
 			end
 		end
 		end
-		log('新增节点数量: ' ..add, '删除节点数量: ' .. del)
+		log('新增节点数量: ' .. add, '删除节点数量: ' .. del)
 		log('订阅更新成功')
 		log('订阅更新成功')
 	end
 	end
 end
 end
@@ -451,10 +440,10 @@ if subscribe_url and #subscribe_url > 0 then
 		log('发生错误, 正在恢复服务')
 		log('发生错误, 正在恢复服务')
 		local firstServer = ucic:get_first(name, uciType)
 		local firstServer = ucic:get_first(name, uciType)
 		if firstServer then
 		if firstServer then
-			luci.sys.call("/etc/init.d/" .. name .." restart > /dev/null 2>&1 &") -- 不加&的话日志会出现的更早
+			luci.sys.call("/etc/init.d/" .. name .. " restart > /dev/null 2>&1 &") -- 不加&的话日志会出现的更早
 			log('重启服务成功')
 			log('重启服务成功')
 		else
 		else
-			luci.sys.call("/etc/init.d/" .. name .." stop > /dev/null 2>&1 &") -- 不加&的话日志会出现的更早
+			luci.sys.call("/etc/init.d/" .. name .. " stop > /dev/null 2>&1 &") -- 不加&的话日志会出现的更早
 			log('停止服务成功')
 			log('停止服务成功')
 		end
 		end
 	end)
 	end)

+ 166 - 19
luci-app-ssr-plus/root/usr/share/shadowsocksr/update.lua

@@ -1,4 +1,5 @@
 #!/usr/bin/lua
 #!/usr/bin/lua
+
 ------------------------------------------------
 ------------------------------------------------
 -- This file is part of the luci-app-ssr-plus update.lua
 -- This file is part of the luci-app-ssr-plus update.lua
 -- By Mattraks
 -- By Mattraks
@@ -6,46 +7,192 @@
 require "luci.sys"
 require "luci.sys"
 require "luci.model.uci"
 require "luci.model.uci"
 local icount = 0
 local icount = 0
+local args = arg[1]
 local uci = luci.model.uci.cursor()
 local uci = luci.model.uci.cursor()
+local TMP_DNSMASQ_PATH = "/var/etc/dnsmasq-ssrplus.d"
+local TMP_PATH = "/var/etc/ssrplus"
+-- match comments/title/whitelist/ip address/excluded_domain
+local comment_pattern = "^[!\\[@]+"
+local ip_pattern = "^%d+%.%d+%.%d+%.%d+"
+local domain_pattern = "([%w%-%_]+%.[%w%.%-%_]+)[%/%*]*"
+local excluded_domain = {"apple.com", "sina.cn", "sina.com.cn", "baidu.com", "byr.cn", "jlike.com", "weibo.com", "zhongsou.com", "youdao.com", "sogou.com", "so.com", "soso.com", "aliyun.com", "taobao.com", "jd.com", "qq.com"}
+-- gfwlist parameter
+local mydnsip = '127.0.0.1'
+local mydnsport = '5335'
+local ipsetname = 'gfwlist'
+local bc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
+-- base64decoding
+local function base64_dec(data)
+	data = string.gsub(data, '[^' .. bc .. '=]', '')
+	return (data:gsub('.', function(x)
+		if (x == '=') then
+			return ''
+		end
+		local r, f = '', (bc:find(x) - 1)
+		for i = 6, 1, -1 do
+			r = r .. (f % 2 ^ i - f % 2 ^ (i - 1) > 0 and '1' or '0')
+		end
+		return r;
+	end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x)
+		if (#x ~= 8) then
+			return ''
+		end
+		local c = 0
+		for i = 1, 8 do
+			c = c + (x:sub(i, i) == '1' and 2 ^ (8 - i) or 0)
+		end
+		return string.char(c)
+	end))
+end
+-- check excluded domain
+local function check_excluded_domain(value)
+	for k, v in ipairs(excluded_domain) do
+		if value:find(v) then
+			return true
+		end
+	end
+end
+-- gfwlist转码至dnsmasq格式
+local function generate_gfwlist(type)
+	local domains = {}
+	local out = io.open("/tmp/ssr-update." .. type, "w")
+	for line in io.lines("/tmp/ssr-update.tmp") do
+		if not (string.find(line, comment_pattern) or string.find(line, ip_pattern) or check_excluded_domain(line)) then
+			local start, finish, match = string.find(line, domain_pattern)
+			if (start) then
+				domains[match] = true
+			end
+		end
+	end
+	for k, v in pairs(domains) do
+		out:write(string.format("server=/%s/%s#%s\n", k, mydnsip, mydnsport))
+		out:write(string.format("ipset=/%s/%s\n", k, ipsetname))
+	end
+	out:close()
+	os.remove("/tmp/ssr-update.tmp")
+end
+
+-- adblock转码至dnsmasq格式
+local function generate_adblock(type)
+	local domains = {}
+	local out = io.open("/tmp/ssr-update." .. type, "w")
+	for line in io.lines("/tmp/ssr-update.tmp") do
+		if not (string.find(line, comment_pattern)) then
+			local start, finish, match = string.find(line, domain_pattern)
+			if (start) then
+				domains[match] = true
+			end
+		end
+	end
+	for k, v in pairs(domains) do
+		out:write(string.format("address=/%s/\n", k))
+	end
+	out:close()
+	os.remove("/tmp/ssr-update.tmp")
+end
+
 local log = function(...)
 local log = function(...)
-	print(os.date("%Y-%m-%d %H:%M:%S ") .. table.concat({ ... }, " "))
+	if args then
+		print(...)
+	else
+		print(os.date("%Y-%m-%d %H:%M:%S ") .. table.concat({...}, " "))
+	end
 end
 end
 
 
 local function update(url, file, type, file2)
 local function update(url, file, type, file2)
 	local Num = 1
 	local Num = 1
-	refresh_cmd = "wget-ssl --no-check-certificate -t 3 -T 10 -O- " .. url .. " > /tmp/ssr-update." .. type
-	sret = luci.sys.call(refresh_cmd .. " 2>/dev/null")
+	local refresh_cmd = "wget --no-check-certificate -q -O /tmp/ssr-update." .. type .. " " .. url
+	local sret = luci.sys.call(refresh_cmd)
 	if sret == 0 then
 	if sret == 0 then
 		if type == "gfw_data" then
 		if type == "gfw_data" then
-			luci.sys.call("/usr/bin/ssr-gfw " .. type)
+			local gfwlist = io.open("/tmp/ssr-update." .. type, "r")
+			local decode = gfwlist:read("*a")
+			if not decode:find("google") then
+				decode = base64_dec(decode)
+			end
+			gfwlist:close()
+			-- 写回gfwlist
+			gfwlist = io.open("/tmp/ssr-update.tmp", "w")
+			gfwlist:write(decode)
+			gfwlist:close()
+			generate_gfwlist(type)
 			Num = 2
 			Num = 2
 		end
 		end
 		if type == "ad_data" then
 		if type == "ad_data" then
-			luci.sys.call("/usr/bin/ssr-ad " .. type)
+			local adblock = io.open("/tmp/ssr-update." .. type, "r")
+			local decode = adblock:read("*a")
+			if decode:find("address=") then
+				adblock:close()
+			else
+				adblock:close()
+				-- 写回adblock
+				adblock = io.open("/tmp/ssr-update.tmp", "w")
+				adblock:write(decode)
+				adblock:close()
+				generate_adblock(type)
+			end
 		end
 		end
 		local new_md5 = luci.sys.exec("echo -n $([ -f '/tmp/ssr-update." .. type .. "' ] && md5sum /tmp/ssr-update." .. type .. " | awk '{print $1}')")
 		local new_md5 = luci.sys.exec("echo -n $([ -f '/tmp/ssr-update." .. type .. "' ] && md5sum /tmp/ssr-update." .. type .. " | awk '{print $1}')")
 		local old_md5 = luci.sys.exec("echo -n $([ -f '" .. file .. "' ] && md5sum " .. file .. " | awk '{print $1}')")
 		local old_md5 = luci.sys.exec("echo -n $([ -f '" .. file .. "' ] && md5sum " .. file .. " | awk '{print $1}')")
 		if new_md5 == old_md5 then
 		if new_md5 == old_md5 then
-			log("你已经是最新数据,无需更新!")
+			if args then
+				log("0")
+			else
+				log("你已经是最新数据,无需更新!")
+			end
 		else
 		else
 			icount = luci.sys.exec("cat /tmp/ssr-update." .. type .. " | wc -l")
 			icount = luci.sys.exec("cat /tmp/ssr-update." .. type .. " | wc -l")
 			luci.sys.exec("cp -f /tmp/ssr-update." .. type .. " " .. file)
 			luci.sys.exec("cp -f /tmp/ssr-update." .. type .. " " .. file)
-			if file2 then luci.sys.exec("cp -f /tmp/ssr-update." .. type .. " " .. file2) end
-			log("更新成功! 新的总纪录数:" .. tostring(tonumber(icount)/Num))
+			if file2 then
+				luci.sys.exec("cp -f /tmp/ssr-update." .. type .. " " .. file2)
+			end
+			if type == "gfw_data" or type == "ad_data" then
+				luci.sys.call("/usr/share/shadowsocksr/gfw2ipset.sh")
+			else
+				luci.sys.call("/usr/share/shadowsocksr/chinaipset.sh " .. TMP_PATH .. "/china_ssr.txt")
+			end
+			if args then
+				log(tonumber(icount) / Num)
+			else
+				log("更新成功! 新的总纪录数:" .. tostring(tonumber(icount) / Num))
+			end
 		end
 		end
 	else
 	else
-		log("更新失败!")
+		if args then
+			log("-1")
+		else
+			log("更新失败!")
+		end
 	end
 	end
-	luci.sys.exec("rm -f /tmp/ssr-update." .. type)
+	os.remove("/tmp/ssr-update." .. type)
 end
 end
 
 
-log("正在更新【GFW列表】数据库")
-update(uci:get_first("shadowsocksr", "global", "gfwlist_url", "https://cdn.jsdelivr.net/gh/v2fly/domain-list-community@release/gfwlist.txt"), "/etc/ssr/gfw_list.conf", "gfw_data", "/tmp/dnsmasq.ssr/gfw_list.conf")
-log("正在更新【国内IP段】数据库")
-update(uci:get_first("shadowsocksr", "global", "chnroute_url","https://ispip.clang.cn/all_cn.txt"), "/etc/ssr/china_ssr.txt", "cnip", "/tmp/etc/china_ssr.txt")
-if uci:get_first("shadowsocksr", "global", "adblock","0") == "1" then
-	log("正在更新【广告屏蔽】数据库")
-	update(uci:get_first("shadowsocksr", "global", "adblock_url","https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt"), "/etc/ssr/ad.conf", "ad_data", "/tmp/dnsmasq.ssr/ad.conf")
+if args then
+	if args == "gfw_data" then
+		update(uci:get_first("shadowsocksr", "global", "gfwlist_url"), "/etc/ssrplus/gfw_list.conf", args, TMP_DNSMASQ_PATH .. "/gfw_list.conf")
+		os.exit(0)
+	end
+	if args == "ip_data" then
+		update(uci:get_first("shadowsocksr", "global", "chnroute_url"), "/etc/ssrplus/china_ssr.txt", args, TMP_PATH .. "/china_ssr.txt")
+		os.exit(0)
+	end
+	if args == "ad_data" then
+		update(uci:get_first("shadowsocksr", "global", "adblock_url"), "/etc/ssrplus/ad.conf", args, TMP_DNSMASQ_PATH .. "/ad.conf")
+		os.exit(0)
+	end
+	if args == "nfip_data" then
+		update(uci:get_first("shadowsocksr", "global", "nfip_url"), "/etc/ssrplus/netflixip.list", args)
+		os.exit(0)
+	end
+else
+	log("正在更新【GFW列表】数据库")
+	update(uci:get_first("shadowsocksr", "global", "gfwlist_url"), "/etc/ssrplus/gfw_list.conf", "gfw_data", TMP_DNSMASQ_PATH .. "/gfw_list.conf")
+	log("正在更新【国内IP段】数据库")
+	update(uci:get_first("shadowsocksr", "global", "chnroute_url"), "/etc/ssrplus/china_ssr.txt", "ip_data", TMP_PATH .. "/china_ssr.txt")
+	if uci:get_first("shadowsocksr", "global", "adblock", "0") == "1" then
+		log("正在更新【广告屏蔽】数据库")
+		update(uci:get_first("shadowsocksr", "global", "adblock_url"), "/etc/ssrplus/ad.conf", "ad_data", TMP_DNSMASQ_PATH .. "/ad.conf")
+	end
+	-- log("正在更新【Netflix IP段】数据库")
+	-- update(uci:get_first("shadowsocksr", "global", "nfip_url"), "/etc/ssrplus/netflixip.list", "nfip_data")
 end
 end
--- log("正在更新【Netflix IP段】数据库")
--- update(uci:get_first("shadowsocksr", "global", "nfip_url","https://raw.githubusercontent.com/QiuSimons/Netflix_IP/master/NF_only.txt"), "/etc/ssr/netflixip.list", "nfip_data")

+ 3 - 3
tcping/Makefile

@@ -12,9 +12,9 @@ PKG_VERSION:=0.3
 PKG_RELEASE:=1
 PKG_RELEASE:=1
 
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_PROTO:=git
-PKG_SOURCE_URL:=https://github.com/Lienol/tcping
+PKG_SOURCE_URL:=https://github.com/Mattraks/tcping
 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
-PKG_SOURCE_VERSION:=db9101834732dac9aaa59dbb7fb9c74612dbf723
+PKG_SOURCE_VERSION:=de2b709f8c386507678041d11102c671d470fea7
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)/$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)/$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
 
 
@@ -24,7 +24,7 @@ define Package/tcping
 	SECTION:=net
 	SECTION:=net
 	CATEGORY:=Network
 	CATEGORY:=Network
 	TITLE:=tcping measures the latency of a tcp-connection
 	TITLE:=tcping measures the latency of a tcp-connection
-	URL:=https://github.com/Lienol/tcping
+	URL:=https://github.com/Mattraks/tcping
 endef
 endef
 
 
 define Package/tcping/description
 define Package/tcping/description

+ 13 - 0
tcping/patches/0001-Remove-strip.patch

@@ -0,0 +1,13 @@
+diff --git a/Makefile b/Makefile
+index 1778ebf..e44119e 100644
+--- a/Makefile
++++ b/Makefile
+@@ -9,7 +9,7 @@ all: tcping
+ 
+ tcping: $(OBJS)
+ 	$(CC) $(OBJS) $(LDFLAGS) -o tcping
+-	strip tcping
++
+ 
+ install: tcping
+ 	cp tcping $(DESTDIR)/usr/bin

部分文件因文件數量過多而無法顯示