update 2022-05-22 23:42:54
This commit is contained in:
parent
78023e2056
commit
3c562ad20f
|
@ -3,306 +3,306 @@
|
|||
module('luci.controller.vssr', package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access('/etc/config/vssr') then
|
||||
return
|
||||
end
|
||||
if not nixio.fs.access('/etc/config/vssr') then
|
||||
return
|
||||
end
|
||||
|
||||
local page = entry({'admin', 'services', 'vssr'}, alias('admin', 'services', 'vssr', 'client'), _('Hello World'), 0) -- 首页
|
||||
page.dependent = true
|
||||
page.acl_depends = { "luci-app-vssr" }
|
||||
local page = entry({'admin', 'services', 'vssr'}, alias('admin', 'services', 'vssr', 'client'), _('Hello World'), 0) -- 首页
|
||||
page.dependent = true
|
||||
page.acl_depends = {'luci-app-vssr'}
|
||||
|
||||
entry({'admin', 'services', 'vssr', 'client'}, cbi('vssr/client'), _('SSR Client'), 10).leaf = true -- 基本设置
|
||||
entry({'admin', 'services', 'vssr', 'servers'}, cbi('vssr/servers'), _('Severs Nodes'), 11).leaf = true -- 服务器节点
|
||||
entry({'admin', 'services', 'vssr', 'servers'}, arcombine(cbi('vssr/servers'), cbi('vssr/client-config')), _('Severs Nodes'), 11).leaf = true -- 编辑节点
|
||||
entry({'admin', 'services', 'vssr', 'subscribe_config'}, cbi('vssr/subscribe-config', {hideapplybtn = true, hidesavebtn = true, hideresetbtn = true}), _('Subscribe'), 12).leaf = true -- 订阅设置
|
||||
entry({'admin', 'services', 'vssr', 'control'}, cbi('vssr/control'), _('Access Control'), 13).leaf = true -- 访问控制
|
||||
entry({'admin', 'services', 'vssr', 'router'}, cbi('vssr/router'), _('Router Config'), 14).leaf = true -- 访问控制
|
||||
entry({'admin', 'services', 'vssr', 'socks5'}, cbi('vssr/socks5'), _('Local Proxy'), 15).leaf = true -- Socks5代理
|
||||
entry({'admin', 'services', 'vssr', 'advanced'}, cbi('vssr/advanced'), _('Advanced Settings'), 16).leaf = true -- 高级设置
|
||||
entry({'admin', 'services', 'vssr', 'server'}, arcombine(cbi('vssr/server'), cbi('vssr/server-config')), _('SSR Server'), 20).leaf = true -- 服务端
|
||||
entry({'admin', 'services', 'vssr', 'log'}, cbi('vssr/log'), _('Log'), 30).leaf = true -- 日志
|
||||
--entry({'admin', 'services', 'vssr', 'licence'}, template('vssr/licence'), _('Licence'), 40).leaf = true
|
||||
entry({'admin', 'services', 'vssr', 'refresh'}, call('refresh_data')) -- 更新白名单和GFWLIST
|
||||
entry({'admin', 'services', 'vssr', 'checkport'}, call('check_port')) -- 检测单个端口并返回Ping
|
||||
entry({'admin', 'services', 'vssr', 'run'}, call('act_status')) -- 检测全局服务器状态
|
||||
entry({'admin', 'services', 'vssr', 'change'}, call('change_node')) -- 切换节点
|
||||
entry({'admin', 'services', 'vssr', 'allserver'}, call('get_servers')) -- 获取所有节点Json
|
||||
entry({'admin', 'services', 'vssr', 'subscribe'}, call('get_subscribe')) -- 执行订阅
|
||||
entry({'admin', 'services', 'vssr', 'flag'}, call('get_flag')) -- 获取节点国旗 iso code
|
||||
entry({'admin', 'services', 'vssr', 'ip'}, call('check_ip')) -- 获取ip情况
|
||||
entry({'admin', 'services', 'vssr', 'switch'}, call('switch')) -- 设置节点为自动切换
|
||||
entry({'admin', 'services', 'vssr', 'delnode'}, call('del_node')) -- 删除某个节点
|
||||
entry({'admin', 'services', 'vssr', 'client'}, cbi('vssr/client'), _('SSR Client'), 10).leaf = true -- 基本设置
|
||||
entry({'admin', 'services', 'vssr', 'servers'}, cbi('vssr/servers'), _('Severs Nodes'), 11).leaf = true -- 服务器节点
|
||||
entry({'admin', 'services', 'vssr', 'servers'}, arcombine(cbi('vssr/servers'), cbi('vssr/client-config')), _('Severs Nodes'), 11).leaf = true -- 编辑节点
|
||||
entry({'admin', 'services', 'vssr', 'subscribe_config'}, cbi('vssr/subscribe-config', {hideapplybtn = true, hidesavebtn = true, hideresetbtn = true}), _('Subscribe'), 12).leaf = true -- 订阅设置
|
||||
entry({'admin', 'services', 'vssr', 'control'}, cbi('vssr/control'), _('Access Control'), 13).leaf = true -- 访问控制
|
||||
entry({'admin', 'services', 'vssr', 'router'}, cbi('vssr/router'), _('Router Config'), 14).leaf = true -- 访问控制
|
||||
entry({'admin', 'services', 'vssr', 'socks5'}, cbi('vssr/socks5'), _('Local Proxy'), 15).leaf = true -- Socks5代理
|
||||
entry({'admin', 'services', 'vssr', 'advanced'}, cbi('vssr/advanced'), _('Advanced Settings'), 16).leaf = true -- 高级设置
|
||||
entry({'admin', 'services', 'vssr', 'server'}, arcombine(cbi('vssr/server'), cbi('vssr/server-config')), _('SSR Server'), 20).leaf = true -- 服务端
|
||||
entry({'admin', 'services', 'vssr', 'log'}, cbi('vssr/log'), _('Log'), 30).leaf = true -- 日志
|
||||
--entry({'admin', 'services', 'vssr', 'licence'}, template('vssr/licence'), _('Licence'), 40).leaf = true
|
||||
entry({'admin', 'services', 'vssr', 'refresh'}, call('refresh_data')) -- 更新白名单和GFWLIST
|
||||
entry({'admin', 'services', 'vssr', 'checkport'}, call('check_port')) -- 检测单个端口并返回Ping
|
||||
entry({'admin', 'services', 'vssr', 'run'}, call('act_status')) -- 检测全局服务器状态
|
||||
entry({'admin', 'services', 'vssr', 'change'}, call('change_node')) -- 切换节点
|
||||
entry({'admin', 'services', 'vssr', 'allserver'}, call('get_servers')) -- 获取所有节点Json
|
||||
entry({'admin', 'services', 'vssr', 'subscribe'}, call('get_subscribe')) -- 执行订阅
|
||||
entry({'admin', 'services', 'vssr', 'flag'}, call('get_flag')) -- 获取节点国旗 iso code
|
||||
entry({'admin', 'services', 'vssr', 'ip'}, call('check_ip')) -- 获取ip情况
|
||||
entry({'admin', 'services', 'vssr', 'switch'}, call('switch')) -- 设置节点为自动切换
|
||||
entry({'admin', 'services', 'vssr', 'delnode'}, call('del_node')) -- 删除某个节点
|
||||
end
|
||||
|
||||
-- 执行订阅
|
||||
function get_subscribe()
|
||||
local cjson = require 'luci.jsonc'
|
||||
local e = {}
|
||||
local name = 'vssr'
|
||||
local uci = luci.model.uci.cursor()
|
||||
local auto_update = luci.http.formvalue('auto_update')
|
||||
local auto_update_time = luci.http.formvalue('auto_update_time')
|
||||
local proxy = luci.http.formvalue('proxy')
|
||||
local subscribe_url = luci.http.formvalue('subscribe_url')
|
||||
local filter_words = luci.http.formvalue('filter_words')
|
||||
if subscribe_url ~= '[]' then
|
||||
uci:delete(name, '@server_subscribe[0]', subscribe_url)
|
||||
uci:set(name, '@server_subscribe[0]', 'auto_update', auto_update)
|
||||
uci:set(name, '@server_subscribe[0]', 'auto_update_time', auto_update_time)
|
||||
uci:set(name, '@server_subscribe[0]', 'proxy', proxy)
|
||||
uci:set(name, '@server_subscribe[0]', 'filter_words', filter_words)
|
||||
uci:set_list(name, '@server_subscribe[0]', 'subscribe_url', cjson.parse(subscribe_url))
|
||||
uci:commit(name)
|
||||
luci.sys.exec('/usr/bin/lua /usr/share/vssr/subscribe.lua >/www/check_update.htm 2>/dev/null &')
|
||||
e.error = 0
|
||||
else
|
||||
e.error = 1
|
||||
end
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(e)
|
||||
local cjson = require 'luci.jsonc'
|
||||
local e = {}
|
||||
local name = 'vssr'
|
||||
local uci = luci.model.uci.cursor()
|
||||
local auto_update = luci.http.formvalue('auto_update')
|
||||
local auto_update_time = luci.http.formvalue('auto_update_time')
|
||||
local proxy = luci.http.formvalue('proxy')
|
||||
local subscribe_url = luci.http.formvalue('subscribe_url')
|
||||
local filter_words = luci.http.formvalue('filter_words')
|
||||
if subscribe_url ~= '[]' then
|
||||
uci:delete(name, '@server_subscribe[0]', subscribe_url)
|
||||
uci:set(name, '@server_subscribe[0]', 'auto_update', auto_update)
|
||||
uci:set(name, '@server_subscribe[0]', 'auto_update_time', auto_update_time)
|
||||
uci:set(name, '@server_subscribe[0]', 'proxy', proxy)
|
||||
uci:set(name, '@server_subscribe[0]', 'filter_words', filter_words)
|
||||
uci:set_list(name, '@server_subscribe[0]', 'subscribe_url', cjson.parse(subscribe_url))
|
||||
uci:commit(name)
|
||||
luci.sys.exec('/usr/bin/lua /usr/share/vssr/subscribe.lua >/www/check_update.htm 2>/dev/null &')
|
||||
e.error = 0
|
||||
else
|
||||
e.error = 1
|
||||
end
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
-- 获取所有节点
|
||||
function get_servers()
|
||||
local uci = luci.model.uci.cursor()
|
||||
local server_table = {}
|
||||
uci:foreach(
|
||||
'vssr',
|
||||
'servers',
|
||||
function(s)
|
||||
local e = {}
|
||||
e['name'] = s['.name']
|
||||
table.insert(server_table, e)
|
||||
end
|
||||
)
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(server_table)
|
||||
local uci = luci.model.uci.cursor()
|
||||
local server_table = {}
|
||||
uci:foreach(
|
||||
'vssr',
|
||||
'servers',
|
||||
function(s)
|
||||
local e = {}
|
||||
e['name'] = s['.name']
|
||||
table.insert(server_table, e)
|
||||
end
|
||||
)
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(server_table)
|
||||
end
|
||||
|
||||
-- 删除指定节点
|
||||
function del_node()
|
||||
local e = {}
|
||||
local uci = luci.model.uci.cursor()
|
||||
local node = luci.http.formvalue('node')
|
||||
e.status = false
|
||||
e.node = node
|
||||
if node ~= '' then
|
||||
uci:delete('vssr', node)
|
||||
uci:save('vssr')
|
||||
uci:commit('vssr')
|
||||
e.status = true
|
||||
end
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(e)
|
||||
local e = {}
|
||||
local uci = luci.model.uci.cursor()
|
||||
local node = luci.http.formvalue('node')
|
||||
e.status = false
|
||||
e.node = node
|
||||
if node ~= '' then
|
||||
uci:delete('vssr', node)
|
||||
uci:save('vssr')
|
||||
uci:commit('vssr')
|
||||
e.status = true
|
||||
end
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
-- 切换节点
|
||||
function change_node()
|
||||
local sockets = require 'socket'
|
||||
local e = {}
|
||||
local uci = luci.model.uci.cursor()
|
||||
local sid = luci.http.formvalue('set')
|
||||
local server = luci.http.formvalue('server')
|
||||
e.status = false
|
||||
e.sid = sid
|
||||
if sid ~= '' and server ~= '' then
|
||||
uci:set('vssr', '@global[0]', server .. '_server', sid)
|
||||
if (server ~= 'global' and server ~= 'udp_relay') then
|
||||
uci:set('vssr', '@global[0]', 'v2ray_flow', '1')
|
||||
end
|
||||
uci:commit('vssr')
|
||||
luci.sys.call('/etc/init.d/vssr restart >/www/restartlog.htm 2>&1')
|
||||
e.status = true
|
||||
end
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(e)
|
||||
local sockets = require 'socket'
|
||||
local e = {}
|
||||
local uci = luci.model.uci.cursor()
|
||||
local sid = luci.http.formvalue('set')
|
||||
local server = luci.http.formvalue('server')
|
||||
e.status = false
|
||||
e.sid = sid
|
||||
if sid ~= '' and server ~= '' then
|
||||
uci:set('vssr', '@global[0]', server .. '_server', sid)
|
||||
if (server ~= 'global' and server ~= 'udp_relay') then
|
||||
uci:set('vssr', '@global[0]', 'v2ray_flow', '1')
|
||||
end
|
||||
uci:commit('vssr')
|
||||
luci.sys.call('/etc/init.d/vssr restart >/www/restartlog.htm 2>&1')
|
||||
e.status = true
|
||||
end
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
-- 设置节点为自动切换
|
||||
function switch()
|
||||
local e = {}
|
||||
local uci = luci.model.uci.cursor()
|
||||
local sid = luci.http.formvalue('node')
|
||||
local isSwitch = uci:get('vssr', sid, 'switch_enable')
|
||||
local toSwitch = (isSwitch == '1') and '0' or '1'
|
||||
uci:set('vssr', sid, 'switch_enable', toSwitch)
|
||||
uci:commit('vssr')
|
||||
if isSwitch == '1' then
|
||||
e.switch = false
|
||||
else
|
||||
e.switch = true
|
||||
end
|
||||
e.status = true
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(e)
|
||||
local e = {}
|
||||
local uci = luci.model.uci.cursor()
|
||||
local sid = luci.http.formvalue('node')
|
||||
local isSwitch = uci:get('vssr', sid, 'switch_enable')
|
||||
local toSwitch = (isSwitch == '1') and '0' or '1'
|
||||
uci:set('vssr', sid, 'switch_enable', toSwitch)
|
||||
uci:commit('vssr')
|
||||
if isSwitch == '1' then
|
||||
e.switch = false
|
||||
else
|
||||
e.switch = true
|
||||
end
|
||||
e.status = true
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
-- 检测全局服务器状态
|
||||
function act_status()
|
||||
math.randomseed(os.time())
|
||||
local e = {}
|
||||
-- 全局服务器
|
||||
e.global = luci.sys.call('busybox ps -w | grep vssr_t | grep -v grep >/dev/null') == 0
|
||||
-- 检测PDNSD状态
|
||||
e.pdnsd = luci.sys.call('pidof pdnsd >/dev/null') == 0
|
||||
-- 检测游戏模式状态
|
||||
e.game = luci.sys.call('busybox ps -w | grep vssr_u | grep -v grep >/dev/null') == 0
|
||||
-- 检测Socks5
|
||||
e.socks5 = luci.sys.call('busybox ps -w | grep vssr_s | grep -v grep >/dev/null') == 0
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(e)
|
||||
math.randomseed(os.time())
|
||||
local e = {}
|
||||
-- 全局服务器
|
||||
e.global = luci.sys.call('busybox ps -w | grep vssr_t | grep -v grep >/dev/null') == 0
|
||||
-- 检测PDNSD状态
|
||||
e.pdnsd = luci.sys.call('pidof pdnsd >/dev/null') == 0
|
||||
-- 检测游戏模式状态
|
||||
e.game = luci.sys.call('busybox ps -w | grep vssr_u | grep -v grep >/dev/null') == 0
|
||||
-- 检测Socks5
|
||||
e.socks5 = luci.sys.call('busybox ps -w | grep vssr_s | grep -v grep >/dev/null') == 0
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
-- 检测单个节点状态并返回连接速度
|
||||
function check_port()
|
||||
local sockets = require 'socket'
|
||||
local vssr = require 'vssrutil'
|
||||
local set = luci.http.formvalue('host')
|
||||
local port = luci.http.formvalue('port')
|
||||
local retstring = ''
|
||||
local t0 = sockets.gettime()
|
||||
ret = vssr.check_site(set, port)
|
||||
local t1 = sockets.gettime()
|
||||
retstring = tostring(ret) == 'true' and '1' or '0'
|
||||
local tt = t1 - t0
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json({ret = retstring, used = math.floor(tt * 1000 + 0.5)})
|
||||
local sockets = require 'socket'
|
||||
local vssr = require 'vssrutil'
|
||||
local set = luci.http.formvalue('host')
|
||||
local port = luci.http.formvalue('port')
|
||||
local retstring = ''
|
||||
local t0 = sockets.gettime()
|
||||
ret = vssr.check_site(set, port)
|
||||
local t1 = sockets.gettime()
|
||||
retstring = tostring(ret) == 'true' and '1' or '0'
|
||||
local tt = t1 - t0
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json({ret = retstring, used = math.floor(tt * 1000 + 0.5)})
|
||||
end
|
||||
|
||||
-- 读取 GeoLite2 库 国旗图标
|
||||
function get_iso(ip)
|
||||
local mm = require 'maxminddb'
|
||||
local db = mm.open('/usr/share/vssr/GeoLite2-Country.mmdb')
|
||||
local res = db:lookup(ip)
|
||||
return string.lower(res:get('country', 'iso_code'))
|
||||
local mm = require 'maxminddb'
|
||||
local db = mm.open('/usr/share/vssr/GeoLite2-Country.mmdb')
|
||||
local res = db:lookup(ip)
|
||||
return string.lower(res:get('country', 'iso_code'))
|
||||
end
|
||||
|
||||
-- 读取 GeoLite2 库 国旗名称
|
||||
function get_cname(ip)
|
||||
local mm = require 'maxminddb'
|
||||
local db = mm.open('/usr/share/vssr/GeoLite2-Country.mmdb')
|
||||
local res = db:lookup(ip)
|
||||
return string.lower(res:get('country', 'names', 'zh-CN'))
|
||||
local mm = require 'maxminddb'
|
||||
local db = mm.open('/usr/share/vssr/GeoLite2-Country.mmdb')
|
||||
local res = db:lookup(ip)
|
||||
return string.lower(res:get('country', 'names', 'zh-CN'))
|
||||
end
|
||||
|
||||
-- 获取当前代理状态 与节点ip
|
||||
function check_ip()
|
||||
local e = {}
|
||||
local d = {}
|
||||
local vssr = require 'vssrutil'
|
||||
local port = 80
|
||||
local ip = vssr.wget('http://api.ipify.org/')
|
||||
d.flag = 'un'
|
||||
d.country = 'Unknown'
|
||||
if (ip ~= '') then
|
||||
local status, code = pcall(get_iso, ip)
|
||||
if (status) then
|
||||
d.flag = code
|
||||
end
|
||||
local status1, country = pcall(get_cname, ip)
|
||||
if (status1) then
|
||||
d.country = country
|
||||
end
|
||||
end
|
||||
e.outboard = ip
|
||||
e.outboardip = d
|
||||
e.baidu = vssr.check_site('www.baidu.com', port)
|
||||
e.taobao = vssr.check_site('www.taobao.com', port)
|
||||
e.google = vssr.check_site('www.google.com', port)
|
||||
e.youtube = vssr.check_site('www.youtube.com', port)
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(e)
|
||||
local e = {}
|
||||
local d = {}
|
||||
local vssr = require 'vssrutil'
|
||||
local port = 80
|
||||
local ip = vssr.wget('http://api.ipify.org/')
|
||||
d.flag = 'un'
|
||||
d.country = 'Unknown'
|
||||
if (ip ~= '') then
|
||||
local status, code = pcall(get_iso, ip)
|
||||
if (status) then
|
||||
d.flag = code
|
||||
end
|
||||
local status1, country = pcall(get_cname, ip)
|
||||
if (status1) then
|
||||
d.country = country
|
||||
end
|
||||
end
|
||||
e.outboard = ip
|
||||
e.outboardip = d
|
||||
e.baidu = vssr.check_site('www.baidu.com', port)
|
||||
e.taobao = vssr.check_site('www.taobao.com', port)
|
||||
e.google = vssr.check_site('www.google.com', port)
|
||||
e.youtube = vssr.check_site('www.youtube.com', port)
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
-- 获取节点国旗 iso code
|
||||
function get_flag()
|
||||
local e = {}
|
||||
local vssr = require 'vssrutil'
|
||||
local host = luci.http.formvalue('host')
|
||||
local remark = luci.http.formvalue('remark')
|
||||
e.host = host
|
||||
e.flag = vssr.get_flag(remark, host)
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(e)
|
||||
local e = {}
|
||||
local vssr = require 'vssrutil'
|
||||
local host = luci.http.formvalue('host')
|
||||
local remark = luci.http.formvalue('remark')
|
||||
e.host = host
|
||||
e.flag = vssr.get_flag(remark, host)
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
-- 刷新检测文件
|
||||
function refresh_data()
|
||||
local uci = luci.model.uci.cursor()
|
||||
local set = luci.http.formvalue('set')
|
||||
local icount = 0
|
||||
local uci = luci.model.uci.cursor()
|
||||
local set = luci.http.formvalue('set')
|
||||
local icount = 0
|
||||
|
||||
if set == 'gfw_data' then
|
||||
refresh_cmd = 'wget-ssl --no-check-certificate https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt -O /tmp/gfw.b64'
|
||||
sret = luci.sys.call(refresh_cmd .. ' 2>/dev/null')
|
||||
if sret == 0 then
|
||||
luci.sys.call('/usr/bin/vssr-gfw')
|
||||
icount = luci.sys.exec('cat /tmp/gfwnew.txt | wc -l')
|
||||
if tonumber(icount) > 1000 then
|
||||
oldcount = luci.sys.exec('cat /etc/vssr/gfw_list.conf | wc -l')
|
||||
if tonumber(icount) ~= tonumber(oldcount) then
|
||||
luci.sys.exec('cp -f /tmp/gfwnew.txt /etc/vssr/gfw_list.conf')
|
||||
retstring = tostring(math.ceil(tonumber(icount) / 2))
|
||||
else
|
||||
retstring = '0'
|
||||
end
|
||||
else
|
||||
retstring = '-1'
|
||||
end
|
||||
luci.sys.exec('rm -f /tmp/gfwnew.txt ')
|
||||
else
|
||||
retstring = '-1'
|
||||
end
|
||||
elseif set == 'ip_data' then
|
||||
local ip_data_url = uci:get("vssr","@socks5_proxy[0]","ip_data_url")
|
||||
refresh_cmd = "wget-ssl -O- '" .. ip_data_url .. "' > /tmp/china_ssr.txt 2>/dev/null"
|
||||
sret = luci.sys.call(refresh_cmd)
|
||||
icount = luci.sys.exec('cat /tmp/china_ssr.txt | wc -l')
|
||||
if sret == 0 and tonumber(icount) > 1000 then
|
||||
oldcount = luci.sys.exec('cat /etc/vssr/china_ssr.txt | wc -l')
|
||||
if tonumber(icount) ~= tonumber(oldcount) then
|
||||
luci.sys.exec('cp -f /tmp/china_ssr.txt /etc/vssr/china_ssr.txt')
|
||||
retstring = tostring(tonumber(icount))
|
||||
else
|
||||
retstring = '0'
|
||||
end
|
||||
else
|
||||
retstring = '-1'
|
||||
end
|
||||
luci.sys.exec('rm -f /tmp/china_ssr.txt ')
|
||||
else
|
||||
local need_process = 0
|
||||
refresh_cmd = 'wget-ssl --no-check-certificate -O - https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt > /tmp/adnew.conf'
|
||||
need_process = 1
|
||||
sret = luci.sys.call(refresh_cmd .. ' 2>/dev/null')
|
||||
if sret == 0 then
|
||||
if need_process == 1 then
|
||||
luci.sys.call('/usr/bin/vssr-ad')
|
||||
end
|
||||
icount = luci.sys.exec('cat /tmp/ad.conf | wc -l')
|
||||
if tonumber(icount) > 1000 then
|
||||
if nixio.fs.access('/etc/vssr/ad.conf') then
|
||||
oldcount = luci.sys.exec('cat /etc/vssr/ad.conf | wc -l')
|
||||
else
|
||||
oldcount = 0
|
||||
end
|
||||
if tonumber(icount) ~= tonumber(oldcount) then
|
||||
luci.sys.exec('cp -f /tmp/ad.conf /etc/vssr/ad.conf')
|
||||
retstring = tostring(math.ceil(tonumber(icount)))
|
||||
if oldcount == 0 then
|
||||
luci.sys.call('/etc/init.d/dnsmasq restart')
|
||||
end
|
||||
else
|
||||
retstring = '0'
|
||||
end
|
||||
else
|
||||
retstring = '-1'
|
||||
end
|
||||
luci.sys.exec('rm -f /tmp/ad.conf')
|
||||
else
|
||||
retstring = '-1'
|
||||
end
|
||||
end
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json({ret = retstring, retcount = icount})
|
||||
if set == 'gfw_data' then
|
||||
refresh_cmd = 'wget-ssl --no-check-certificate https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt -O /tmp/gfw.b64'
|
||||
sret = luci.sys.call(refresh_cmd .. ' 2>/dev/null')
|
||||
if sret == 0 then
|
||||
luci.sys.call('/usr/bin/vssr-gfw')
|
||||
icount = luci.sys.exec('cat /tmp/gfwnew.txt | wc -l')
|
||||
if tonumber(icount) > 1000 then
|
||||
oldcount = luci.sys.exec('cat /etc/vssr/gfw_list.conf | wc -l')
|
||||
if tonumber(icount) ~= tonumber(oldcount) then
|
||||
luci.sys.exec('cp -f /tmp/gfwnew.txt /etc/vssr/gfw_list.conf')
|
||||
retstring = tostring(math.ceil(tonumber(icount) / 2))
|
||||
else
|
||||
retstring = '0'
|
||||
end
|
||||
else
|
||||
retstring = '-1'
|
||||
end
|
||||
luci.sys.exec('rm -f /tmp/gfwnew.txt ')
|
||||
else
|
||||
retstring = '-1'
|
||||
end
|
||||
elseif set == 'ip_data' then
|
||||
local ip_data_url = uci:get('vssr', '@socks5_proxy[0]', 'ip_data_url')
|
||||
refresh_cmd = "wget-ssl -O- '" .. ip_data_url .. "' > /tmp/china_ssr.txt 2>/dev/null"
|
||||
sret = luci.sys.call(refresh_cmd)
|
||||
icount = luci.sys.exec('cat /tmp/china_ssr.txt | wc -l')
|
||||
if sret == 0 and tonumber(icount) > 1000 then
|
||||
oldcount = luci.sys.exec('cat /etc/vssr/china_ssr.txt | wc -l')
|
||||
if tonumber(icount) ~= tonumber(oldcount) then
|
||||
luci.sys.exec('cp -f /tmp/china_ssr.txt /etc/vssr/china_ssr.txt')
|
||||
retstring = tostring(tonumber(icount))
|
||||
else
|
||||
retstring = '0'
|
||||
end
|
||||
else
|
||||
retstring = '-1'
|
||||
end
|
||||
luci.sys.exec('rm -f /tmp/china_ssr.txt ')
|
||||
else
|
||||
local need_process = 0
|
||||
refresh_cmd = 'wget-ssl --no-check-certificate -O - https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt > /tmp/adnew.conf'
|
||||
need_process = 1
|
||||
sret = luci.sys.call(refresh_cmd .. ' 2>/dev/null')
|
||||
if sret == 0 then
|
||||
if need_process == 1 then
|
||||
luci.sys.call('/usr/bin/vssr-ad')
|
||||
end
|
||||
icount = luci.sys.exec('cat /tmp/ad.conf | wc -l')
|
||||
if tonumber(icount) > 1000 then
|
||||
if nixio.fs.access('/etc/vssr/ad.conf') then
|
||||
oldcount = luci.sys.exec('cat /etc/vssr/ad.conf | wc -l')
|
||||
else
|
||||
oldcount = 0
|
||||
end
|
||||
if tonumber(icount) ~= tonumber(oldcount) then
|
||||
luci.sys.exec('cp -f /tmp/ad.conf /etc/vssr/ad.conf')
|
||||
retstring = tostring(math.ceil(tonumber(icount)))
|
||||
if oldcount == 0 then
|
||||
luci.sys.call('/etc/init.d/dnsmasq restart')
|
||||
end
|
||||
else
|
||||
retstring = '0'
|
||||
end
|
||||
else
|
||||
retstring = '-1'
|
||||
end
|
||||
luci.sys.exec('rm -f /tmp/ad.conf')
|
||||
else
|
||||
retstring = '-1'
|
||||
end
|
||||
end
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json({ret = retstring, retcount = icount})
|
||||
end
|
||||
|
|
|
@ -1,11 +1,4 @@
|
|||
--[[
|
||||
Author: your name
|
||||
Date: 2019-11-11 09:33:07
|
||||
LastEditTime: 2021-01-14 18:50:06
|
||||
LastEditors: Please set LastEditors
|
||||
Description: In User Settings Edit
|
||||
FilePath: \luci-app-vssr\luasrc\model\cbi\vssr\socks5.lua
|
||||
--]]
|
||||
|
||||
local vssr = 'vssr'
|
||||
local uci = luci.model.uci.cursor()
|
||||
local server_table = {}
|
||||
|
|
|
@ -21,6 +21,8 @@ CONFIG_UDP_FILE=/var/etc/${NAME}_u.json
|
|||
CONFIG_SOCK5_FILE=/var/etc/${NAME}_s.json
|
||||
CRON_FILE=/etc/crontabs/root
|
||||
|
||||
LOCK_FILE=/var/lock/vssr.lock
|
||||
|
||||
#定义可执行文件路径
|
||||
VSSR_RULES_BIN=/usr/bin/vssr-rules
|
||||
|
||||
|
@ -39,6 +41,30 @@ switch_server=$1
|
|||
MAXFD=32768
|
||||
threads=1
|
||||
|
||||
set_lock() {
|
||||
exec 1000>"$LOCK_FILE"
|
||||
flock -xn 1000
|
||||
}
|
||||
|
||||
unset_lock() {
|
||||
flock -u 1000
|
||||
rm -rf "$LOCK_FILE"
|
||||
}
|
||||
|
||||
unlock() {
|
||||
failcount=1
|
||||
while [ "$failcount" -le 10 ]; do
|
||||
if [ -f "$LOCK_FILE" ]; then
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") wait for file unlock: $failcount count" >> /tmp/vssr.log
|
||||
let "failcount++"
|
||||
sleep 1s
|
||||
[ "$failcount" -ge 10 ] && unset_lock
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
#读取 uci 数据
|
||||
uci_get_by_name() {
|
||||
|
@ -374,8 +400,6 @@ start_redir() {
|
|||
local stype=$(uci_get_by_name $GLOBAL_SERVER type)
|
||||
sscmd=$(find_bin $stype)
|
||||
|
||||
|
||||
|
||||
if [ "$(uci_get_by_type global threads 0)" = "0" ]; then
|
||||
threads=$(cat /proc/cpuinfo | grep 'processor' | wc -l)
|
||||
else
|
||||
|
@ -576,6 +600,7 @@ rules() {
|
|||
}
|
||||
|
||||
start() {
|
||||
set_lock
|
||||
if [ -z "$switch_server" ]; then
|
||||
GLOBAL_SERVER=$(uci_get_by_type global global_server)
|
||||
else
|
||||
|
@ -635,6 +660,8 @@ EOF
|
|||
fi
|
||||
fi
|
||||
|
||||
unset_lock
|
||||
|
||||
ENABLE_SERVER=$(uci_get_by_type global global_server)
|
||||
[ "$ENABLE_SERVER" = "nil" ] && return 1
|
||||
}
|
||||
|
@ -644,6 +671,9 @@ boot() {
|
|||
}
|
||||
|
||||
stop() {
|
||||
unlock
|
||||
set_lock
|
||||
|
||||
echo "stop"
|
||||
/usr/bin/vssr-rules -f
|
||||
srulecount=$(iptables -L | grep SSR-SERVER-RULE | wc -l)
|
||||
|
@ -665,4 +695,6 @@ stop() {
|
|||
/etc/init.d/dnsmasq restart >/dev/null 2>&1
|
||||
fi
|
||||
del_cron
|
||||
}
|
||||
|
||||
unset_lock
|
||||
}
|
|
@ -185,8 +185,6 @@ tp_rule() {
|
|||
ip route add local 0.0.0.0/0 dev lo table 100
|
||||
local ipt="iptables -t mangle"
|
||||
$ipt -N SS_SPEC_TPROXY
|
||||
$ipt -A SS_SPEC_TPROXY -p udp --dport 443 -j RETURN
|
||||
$ipt -A SS_SPEC_TPROXY -p udp --dport 80 -j RETURN
|
||||
$ipt -A SS_SPEC_TPROXY -p udp --dport 53 -j RETURN
|
||||
$ipt -A SS_SPEC_TPROXY -p udp -d 0.0.0.0/8 -j RETURN
|
||||
$ipt -A SS_SPEC_TPROXY -p udp -d 10.0.0.0/8 -j RETURN
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
#!/usr/bin/lua
|
||||
|
||||
------------------------------------------------
|
||||
-- This file is converter ip to country iso code
|
||||
-- @author Jerryk <jerrykuku@qq.com>
|
||||
------------------------------------------------
|
||||
|
||||
|
||||
local _M = {}
|
||||
|
||||
-- Get country iso code with remark or host
|
||||
|
@ -17,7 +19,30 @@ function _M.get_flag(remark, host)
|
|||
local search_table = json.decode(json_string)
|
||||
|
||||
local iso_code = nil
|
||||
local delete_table = {'%b[]', 'networks', 'test', 'game', 'gaming', 'tls', 'iepl', 'aead', 'hgc', 'hkbn', 'netflix', 'disney', 'hulu', 'hinet','sb','az','aws','cn','ss','ssr','trojan','all'}
|
||||
local delete_table = {
|
||||
'%b[]',
|
||||
'networks',
|
||||
'test',
|
||||
'game',
|
||||
'gaming',
|
||||
'tls',
|
||||
'iepl',
|
||||
'aead',
|
||||
'hgc',
|
||||
'hkbn',
|
||||
'netflix',
|
||||
'disney',
|
||||
'hulu',
|
||||
'hinet',
|
||||
'sb',
|
||||
'az',
|
||||
'aws',
|
||||
'cn',
|
||||
'ss',
|
||||
'ssr',
|
||||
'trojan',
|
||||
'all'
|
||||
}
|
||||
if (remark ~= nil) then
|
||||
-- 过滤
|
||||
remark = string.lower(remark)
|
||||
|
|
|
@ -12,10 +12,10 @@ function read_conf(file)
|
|||
if not nixio.fs.access(file) then
|
||||
return nil
|
||||
end
|
||||
local rfile = io.open(file, "r")
|
||||
local rfile = io.open(file, 'r')
|
||||
local ltable = {}
|
||||
for line in rfile:lines() do
|
||||
local re = string.gsub(line, "\r", "")
|
||||
local re = string.gsub(line, '\r', '')
|
||||
table.insert(ltable, re)
|
||||
end
|
||||
local rtable = next(ltable) ~= nil and ltable or nil
|
||||
|
@ -24,27 +24,26 @@ end
|
|||
|
||||
local v2ray_flow = ucursor:get_first(name, 'global', 'v2ray_flow', '0')
|
||||
|
||||
local custom_domain = read_conf("/etc/vssr/custom_domain.list")
|
||||
local custom_ip = read_conf("/etc/vssr/custom_ip.list")
|
||||
local custom_domain = read_conf('/etc/vssr/custom_domain.list')
|
||||
local custom_ip = read_conf('/etc/vssr/custom_ip.list')
|
||||
|
||||
local youtube_domain = read_conf("/etc/vssr/youtube_domain.list")
|
||||
local youtube_ip = read_conf("/etc/vssr/youtube_ip.list")
|
||||
local youtube_domain = read_conf('/etc/vssr/youtube_domain.list')
|
||||
local youtube_ip = read_conf('/etc/vssr/youtube_ip.list')
|
||||
|
||||
local tw_video_domain = read_conf("/etc/vssr/tw_video_domain.list")
|
||||
local tw_video_ip = read_conf("/etc/vssr/tw_video_ip.list")
|
||||
local tw_video_domain = read_conf('/etc/vssr/tw_video_domain.list')
|
||||
local tw_video_ip = read_conf('/etc/vssr/tw_video_ip.list')
|
||||
|
||||
local netflix_domain = read_conf("/etc/vssr/netflix_domain.list")
|
||||
local netflix_ip = read_conf("/etc/vssr/netflix_ip.list")
|
||||
local netflix_domain = read_conf('/etc/vssr/netflix_domain.list')
|
||||
local netflix_ip = read_conf('/etc/vssr/netflix_ip.list')
|
||||
|
||||
local disney_domain = read_conf("/etc/vssr/disney_domain.list")
|
||||
local disney_ip = read_conf("/etc/vssr/disney_ip.list")
|
||||
local disney_domain = read_conf('/etc/vssr/disney_domain.list')
|
||||
local disney_ip = read_conf('/etc/vssr/disney_ip.list')
|
||||
|
||||
local prime_domain = read_conf("/etc/vssr/prime_domain.list")
|
||||
local prime_ip = read_conf("/etc/vssr/prime_ip.list")
|
||||
|
||||
local tvb_domain = read_conf("/etc/vssr/tvb_domain.list")
|
||||
local tvb_ip = read_conf("/etc/vssr/tvb_ip.list")
|
||||
local prime_domain = read_conf('/etc/vssr/prime_domain.list')
|
||||
local prime_ip = read_conf('/etc/vssr/prime_ip.list')
|
||||
|
||||
local tvb_domain = read_conf('/etc/vssr/tvb_domain.list')
|
||||
local tvb_ip = read_conf('/etc/vssr/tvb_ip.list')
|
||||
|
||||
local flow_table = {
|
||||
yotube = {
|
||||
|
@ -125,7 +124,7 @@ function gen_outbound(server_node, tags, local_ports)
|
|||
bound = nil
|
||||
else
|
||||
local server = ucursor:get_all(name, server_node)
|
||||
local node_type = server.type == "vless" and "vless" or "vmess"
|
||||
local node_type = server.type == 'vless' and 'vless' or 'vmess'
|
||||
|
||||
if server.type ~= 'v2ray' and server.type ~= 'vless' then
|
||||
bound = {
|
||||
|
@ -133,7 +132,7 @@ function gen_outbound(server_node, tags, local_ports)
|
|||
protocol = 'socks',
|
||||
settings = {
|
||||
servers = {
|
||||
{ address = '127.0.0.1', port = tonumber(local_ports) }
|
||||
{address = '127.0.0.1', port = tonumber(local_ports)}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -149,10 +148,10 @@ function gen_outbound(server_node, tags, local_ports)
|
|||
users = {
|
||||
{
|
||||
id = server.vmess_id,
|
||||
alterId = server.type == "v2ray" and tonumber(server.alter_id) or nil,
|
||||
security = server.type == "v2ray" and server.security or nil,
|
||||
flow = (server.xtls == '1') and (server.vless_flow and server.vless_flow or "xtls-rprx-origin") or nil,
|
||||
encryption = server.type == "vless" and server.vless_encryption or nil
|
||||
alterId = server.type == 'v2ray' and tonumber(server.alter_id) or nil,
|
||||
security = server.type == 'v2ray' and server.security or nil,
|
||||
flow = (server.xtls == '1') and (server.vless_flow and server.vless_flow or 'xtls-rprx-origin') or nil,
|
||||
encryption = server.type == 'vless' and server.vless_encryption or nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -161,9 +160,9 @@ function gen_outbound(server_node, tags, local_ports)
|
|||
-- 底层传输配置
|
||||
streamSettings = {
|
||||
network = server.transport,
|
||||
security = (server.tls == '1') and ((server.xtls == '1') and "xtls" or "tls") or "none",
|
||||
tlsSettings = (server.tls == '1' and server.xtls ~= '1') and { allowInsecure = (server.insecure ~= "0") and true or false, serverName = server.tls_host, } or nil,
|
||||
xtlsSettings = (server.xtls == '1') and { allowInsecure = (server.insecure ~= "0") and true or false, serverName = server.tls_host, } or nil,
|
||||
security = (server.tls == '1') and ((server.xtls == '1') and 'xtls' or 'tls') or 'none',
|
||||
tlsSettings = (server.tls == '1' and server.xtls ~= '1') and {allowInsecure = (server.insecure ~= '0') and true or false, serverName = server.tls_host} or nil,
|
||||
xtlsSettings = (server.xtls == '1') and {allowInsecure = (server.insecure ~= '0') and true or false, serverName = server.tls_host} or nil,
|
||||
kcpSettings = (server.transport == 'kcp') and
|
||||
{
|
||||
mtu = tonumber(server.mtu),
|
||||
|
@ -173,21 +172,21 @@ function gen_outbound(server_node, tags, local_ports)
|
|||
congestion = (server.congestion == '1') and true or false,
|
||||
readBufferSize = tonumber(server.read_buffer_size),
|
||||
writeBufferSize = tonumber(server.write_buffer_size),
|
||||
header = { type = server.kcp_guise }
|
||||
header = {type = server.kcp_guise}
|
||||
} or
|
||||
nil,
|
||||
wsSettings = (server.transport == 'ws') and (server.ws_path ~= nil or server.ws_host ~= nil) and
|
||||
{
|
||||
path = server.ws_path,
|
||||
headers = (server.ws_host ~= nil) and { Host = server.ws_host } or nil
|
||||
headers = (server.ws_host ~= nil) and {Host = server.ws_host} or nil
|
||||
} or
|
||||
nil,
|
||||
httpSettings = (server.transport == 'h2') and { path = server.h2_path, host = server.h2_host } or nil,
|
||||
httpSettings = (server.transport == 'h2') and {path = server.h2_path, host = server.h2_host} or nil,
|
||||
quicSettings = (server.transport == 'quic') and
|
||||
{
|
||||
security = server.quic_security,
|
||||
key = server.quic_key,
|
||||
header = { type = server.quic_guise }
|
||||
header = {type = server.quic_guise}
|
||||
} or
|
||||
nil
|
||||
},
|
||||
|
@ -202,7 +201,6 @@ function gen_outbound(server_node, tags, local_ports)
|
|||
end
|
||||
|
||||
if v2ray_flow == '1' then
|
||||
|
||||
table.insert(outbounds_table, gen_outbound(server_section, 'global', 2080))
|
||||
for _, v in pairs(flow_table) do
|
||||
if (v.rules.domain ~= nil or v.rules.ip ~= nil) then
|
||||
|
@ -243,15 +241,15 @@ local v2ray = {
|
|||
{
|
||||
port = tonumber(local_port),
|
||||
protocol = 'dokodemo-door',
|
||||
settings = { network = proto, followRedirect = true },
|
||||
sniffing = { enabled = true, destOverride = { 'http', 'tls' } },
|
||||
settings = {network = proto, followRedirect = true},
|
||||
sniffing = {enabled = true, destOverride = {'http', 'tls'}},
|
||||
streamSettings = {
|
||||
sockopt = { tproxy = (proto == 'tcp') and 'redirect' or 'tproxy' }
|
||||
sockopt = {tproxy = (proto == 'tcp') and 'redirect' or 'tproxy'}
|
||||
}
|
||||
}
|
||||
},
|
||||
-- 传出连接
|
||||
outbounds = outbounds_table,
|
||||
routing = { domainStrategy = 'IPIfNonMatch', rules = rules_table }
|
||||
routing = {domainStrategy = 'IPIfNonMatch', rules = rules_table}
|
||||
}
|
||||
print(json.stringify(v2ray, 1))
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
-- This file is part of the luci-app-ssr-plus subscribe.lua
|
||||
-- @author William Chan <root@williamchan.me>
|
||||
------------------------------------------------
|
||||
|
||||
|
||||
require 'nixio'
|
||||
require 'luci.util'
|
||||
require 'luci.jsonc'
|
||||
|
@ -13,9 +15,7 @@ require 'luci.sys'
|
|||
-- so caching them is worth the effort
|
||||
local luci = luci
|
||||
local tinsert = table.insert
|
||||
local ssub, slen, schar, sbyte, sformat, sgsub = string.sub, string.len,
|
||||
string.char, string.byte,
|
||||
string.format, string.gsub
|
||||
local ssub, slen, schar, sbyte, sformat, sgsub = string.sub, string.len, string.char, string.byte, string.format, string.gsub
|
||||
local jsonParse, jsonStringify = luci.jsonc.parse, luci.jsonc.stringify
|
||||
local b64decode = nixio.bin.b64decode
|
||||
local cache = {}
|
||||
|
@ -25,31 +25,26 @@ local uciType = 'servers'
|
|||
local ucic = luci.model.uci.cursor()
|
||||
local proxy = ucic:get_first(name, 'server_subscribe', 'proxy', '0')
|
||||
local switch = '0'
|
||||
local subscribe_url = ucic:get_first(name, 'server_subscribe', 'subscribe_url',
|
||||
{})
|
||||
local filter_words = ucic:get_first(name, 'server_subscribe', 'filter_words',
|
||||
'过期时间/剩余流量')
|
||||
local subscribe_url = ucic:get_first(name, 'server_subscribe', 'subscribe_url', {})
|
||||
local filter_words = ucic:get_first(name, 'server_subscribe', 'filter_words', '过期时间/剩余流量')
|
||||
|
||||
function print_r(t)
|
||||
local print_r_cache = {}
|
||||
local function sub_print_r(t, indent)
|
||||
if (print_r_cache[tostring(t)]) then
|
||||
print(indent .. "*" .. tostring(t))
|
||||
print(indent .. '*' .. tostring(t))
|
||||
else
|
||||
print_r_cache[tostring(t)] = true
|
||||
if (type(t) == "table") then
|
||||
if (type(t) == 'table') then
|
||||
for pos, val in pairs(t) do
|
||||
if (type(val) == "table") then
|
||||
print(indent .. "[" .. pos .. "] => " .. tostring(t) ..
|
||||
" {")
|
||||
sub_print_r(val, indent ..
|
||||
string.rep(" ", string.len(pos) + 8))
|
||||
print(indent .. string.rep(" ", string.len(pos) + 6) ..
|
||||
"}")
|
||||
elseif (type(val) == "string") then
|
||||
print(indent .. "[" .. pos .. '] => "' .. val .. '"')
|
||||
if (type(val) == 'table') then
|
||||
print(indent .. '[' .. pos .. '] => ' .. tostring(t) .. ' {')
|
||||
sub_print_r(val, indent .. string.rep(' ', string.len(pos) + 8))
|
||||
print(indent .. string.rep(' ', string.len(pos) + 6) .. '}')
|
||||
elseif (type(val) == 'string') then
|
||||
print(indent .. '[' .. pos .. '] => "' .. val .. '"')
|
||||
else
|
||||
print(indent .. "[" .. pos .. "] => " .. tostring(val))
|
||||
print(indent .. '[' .. pos .. '] => ' .. tostring(val))
|
||||
end
|
||||
end
|
||||
else
|
||||
|
@ -57,12 +52,13 @@ function print_r(t)
|
|||
end
|
||||
end
|
||||
end
|
||||
if (type(t) == "table") then
|
||||
print(tostring(t) .. " {")
|
||||
sub_print_r(t, " ")
|
||||
print("}")
|
||||
|
||||
if (type(t) == 'table') then
|
||||
print(tostring(t) .. ' {')
|
||||
sub_print_r(t, ' ')
|
||||
print('}')
|
||||
else
|
||||
sub_print_r(t, " ")
|
||||
sub_print_r(t, ' ')
|
||||
end
|
||||
print()
|
||||
end
|
||||
|
@ -95,7 +91,7 @@ end
|
|||
local function clone(object)
|
||||
local lookup_table = {}
|
||||
local function copyObj(object)
|
||||
if type(object) ~= "table" then
|
||||
if type(object) ~= 'table' then
|
||||
return object
|
||||
elseif lookup_table[object] then
|
||||
return lookup_table[object]
|
||||
|
@ -108,6 +104,7 @@ local function clone(object)
|
|||
end
|
||||
return setmetatable(new_table, getmetatable(object))
|
||||
end
|
||||
|
||||
return copyObj(object)
|
||||
end
|
||||
|
||||
|
@ -119,7 +116,6 @@ local function table_unique(list)
|
|||
if v1.alias ~= v2.alias and v1.hashkey == v2.hashkey then
|
||||
table.remove(temp1, k1)
|
||||
table.remove(temp2, k1)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -127,7 +123,9 @@ local function table_unique(list)
|
|||
end
|
||||
|
||||
-- urlencode
|
||||
local function get_urlencode(c) return sformat('%%%02X', sbyte(c)) end
|
||||
local function get_urlencode(c)
|
||||
return sformat('%%%02X', sbyte(c))
|
||||
end
|
||||
|
||||
local function urlEncode(szText)
|
||||
local str = szText:gsub('([^0-9a-zA-Z ])', get_urlencode)
|
||||
|
@ -135,27 +133,35 @@ local function urlEncode(szText)
|
|||
return str
|
||||
end
|
||||
|
||||
local function get_urldecode(h) return schar(tonumber(h, 16)) end
|
||||
local function get_urldecode(h)
|
||||
return schar(tonumber(h, 16))
|
||||
end
|
||||
|
||||
local function UrlDecode(szText)
|
||||
return szText:gsub('+', ' '):gsub('%%(%x%x)', get_urldecode)
|
||||
end
|
||||
|
||||
-- trim
|
||||
local function trim(text)
|
||||
if not text or text == '' then return '' end
|
||||
if not text or text == '' then
|
||||
return ''
|
||||
end
|
||||
return (sgsub(text, '^%s*(.-)%s*$', '%1'))
|
||||
end
|
||||
|
||||
-- md5
|
||||
local function md5(content)
|
||||
local stdout = luci.sys.exec('echo "' .. urlEncode(content) ..
|
||||
'" | md5sum | cut -d " " -f1')
|
||||
local stdout = luci.sys.exec('echo "' .. urlEncode(content) .. '" | md5sum | cut -d " " -f1')
|
||||
-- assert(nixio.errno() == 0)
|
||||
return trim(stdout)
|
||||
end
|
||||
|
||||
-- base64
|
||||
local function base64Decode(text)
|
||||
local raw = text
|
||||
if not text then return '' end
|
||||
if not text then
|
||||
return ''
|
||||
end
|
||||
text = text:gsub('%z', '')
|
||||
text = text:gsub('_', '/')
|
||||
text = text:gsub('-', '+')
|
||||
|
@ -168,6 +174,7 @@ local function base64Decode(text)
|
|||
return raw
|
||||
end
|
||||
end
|
||||
|
||||
-- 处理数据
|
||||
local function processData(szType, content, groupName)
|
||||
local result = {
|
||||
|
@ -198,7 +205,9 @@ local function processData(szType, content, groupName)
|
|||
result.obfs_param = base64Decode(params.obfsparam)
|
||||
result.protocol_param = base64Decode(params.protoparam)
|
||||
local group = base64Decode(params.group)
|
||||
if group then result.alias = '[' .. group .. '] ' end
|
||||
if group then
|
||||
result.alias = '[' .. group .. '] '
|
||||
end
|
||||
result.alias = result.alias .. base64Decode(params.remarks)
|
||||
elseif szType == 'vmess' then
|
||||
local info = jsonParse(content)
|
||||
|
@ -238,7 +247,9 @@ local function processData(szType, content, groupName)
|
|||
result.quic_key = info.key
|
||||
result.quic_security = info.securty
|
||||
end
|
||||
if info.security then result.security = info.security end
|
||||
if info.security then
|
||||
result.security = info.security
|
||||
end
|
||||
if info.tls == 'tls' or info.tls == '1' then
|
||||
result.tls = '1'
|
||||
result.tls_host = info.host
|
||||
|
@ -274,14 +285,13 @@ local function processData(szType, content, groupName)
|
|||
local idx_pn = plugin_info:find(';')
|
||||
if idx_pn then
|
||||
result.plugin = plugin_info:sub(1, idx_pn - 1)
|
||||
result.plugin_opts =
|
||||
plugin_info:sub(idx_pn + 1, #plugin_info)
|
||||
result.plugin_opts = plugin_info:sub(idx_pn + 1, #plugin_info)
|
||||
else
|
||||
result.plugin = plugin_info
|
||||
end
|
||||
-- 部分机场下发的插件名为 simple-obfs,这里应该改为 obfs-local
|
||||
if result.plugin == "simple-obfs" then
|
||||
result.plugin = "obfs-local"
|
||||
if result.plugin == 'simple-obfs' then
|
||||
result.plugin = 'obfs-local'
|
||||
end
|
||||
end
|
||||
else
|
||||
|
@ -325,20 +335,20 @@ local function processData(szType, content, groupName)
|
|||
result.server_port = content.port
|
||||
result.password = content.password
|
||||
result.encrypt_method_ss = content.encryption
|
||||
if content.plugin == "simple-obfs" then
|
||||
result.plugin = "obfs-local"
|
||||
else
|
||||
result.plugin = content.plugin
|
||||
end
|
||||
if content.plugin == 'simple-obfs' then
|
||||
result.plugin = 'obfs-local'
|
||||
else
|
||||
result.plugin = content.plugin
|
||||
end
|
||||
result.plugin_opts = content.plugin_options
|
||||
|
||||
|
||||
result.alias = '[' .. content.airport .. '] ' .. content.remarks
|
||||
end
|
||||
if not result.alias then
|
||||
if result.server and result.server_port then
|
||||
result.alias = result.server .. ':' .. result.server_port
|
||||
else
|
||||
result.alias = "NULL"
|
||||
result.alias = 'NULL'
|
||||
end
|
||||
end
|
||||
-- alias 不参与 hashkey 计算
|
||||
|
@ -354,21 +364,22 @@ local function processData(szType, content, groupName)
|
|||
|
||||
return result
|
||||
end
|
||||
|
||||
-- wget
|
||||
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-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 .. '"'
|
||||
)
|
||||
return trim(stdout)
|
||||
end
|
||||
|
||||
local function check_filer(result)
|
||||
do
|
||||
local filter_word = split(filter_words, "/")
|
||||
local filter_word = split(filter_words, '/')
|
||||
for i, v in pairs(filter_word) do
|
||||
if result.alias:find(v) then
|
||||
log('订阅节点关键字过滤:“' .. v ..
|
||||
'” ,该节点被丢弃')
|
||||
log('订阅节点关键字过滤:“' .. v .. '” ,该节点被丢弃')
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
@ -383,10 +394,9 @@ local execute = function()
|
|||
luci.sys.init.stop(name)
|
||||
end
|
||||
for k, url in ipairs(subscribe_url) do
|
||||
local groupName = ""
|
||||
urlTable = split(url, ",")
|
||||
groupName =
|
||||
table.getn(urlTable) > 1 and '[' .. urlTable[1] .. '] ' or ""
|
||||
local groupName = ''
|
||||
urlTable = split(url, ',')
|
||||
groupName = table.getn(urlTable) > 1 and '[' .. urlTable[1] .. '] ' or ''
|
||||
url = table.getn(urlTable) > 1 and urlTable[2] or url
|
||||
local raw = wget(url)
|
||||
if #raw > 0 then
|
||||
|
@ -427,12 +437,9 @@ local execute = function()
|
|||
local dat = split(node, '://')
|
||||
if dat and dat[1] and dat[2] then
|
||||
if dat[1] == 'ss' then
|
||||
result =
|
||||
processData(dat[1], dat[2], groupName)
|
||||
result = processData(dat[1], dat[2], groupName)
|
||||
else
|
||||
result = processData(dat[1],
|
||||
base64Decode(dat[2]),
|
||||
groupName)
|
||||
result = processData(dat[1], base64Decode(dat[2]), groupName)
|
||||
end
|
||||
end
|
||||
else
|
||||
|
@ -440,19 +447,13 @@ local execute = function()
|
|||
end
|
||||
-- log(result)
|
||||
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)
|
||||
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 -- 中文做地址的 也没有人拿中文域名搞,就算中文域也有Puny Code SB 机场
|
||||
log('丢弃无效节点: ' .. result.type .. ' 节点, ' .. result.alias)
|
||||
else
|
||||
log('成功解析: ' .. result.type ..
|
||||
' 节点, ' .. result.alias)
|
||||
log('成功解析: ' .. result.type .. ' 节点, ' .. result.alias)
|
||||
result.grouphashkey = groupHash
|
||||
tinsert(nodeResult[index], result)
|
||||
cache[groupHash][result.hashkey] =
|
||||
nodeResult[index][#nodeResult[index]]
|
||||
cache[groupHash][result.hashkey] = nodeResult[index][#nodeResult[index]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -466,7 +467,7 @@ local execute = function()
|
|||
-- diff
|
||||
do
|
||||
if next(nodeResult) == nil then
|
||||
log("更新失败,没有可用的节点信息")
|
||||
log('更新失败,没有可用的节点信息')
|
||||
if proxy == '0' then
|
||||
luci.sys.init.start(name)
|
||||
log('订阅失败, 恢复服务')
|
||||
|
@ -474,32 +475,34 @@ local execute = function()
|
|||
return
|
||||
end
|
||||
local add, del = 0, 0
|
||||
ucic:foreach(name, uciType, function(old)
|
||||
if old.grouphashkey or old.hashkey then -- 没有 hash 的不参与删除
|
||||
if not nodeResult[old.grouphashkey] or
|
||||
not nodeResult[old.grouphashkey][old.hashkey] then
|
||||
ucic:delete(name, old['.name'])
|
||||
del = del + 1
|
||||
else
|
||||
local dat = nodeResult[old.grouphashkey][old.hashkey]
|
||||
ucic:tset(name, old['.name'], dat)
|
||||
-- 标记一下
|
||||
setmetatable(nodeResult[old.grouphashkey][old.hashkey],
|
||||
{__index = {_ignore = true}})
|
||||
end
|
||||
else
|
||||
if not old.alias then
|
||||
if not old.server or old.server_port then
|
||||
ucic:foreach(
|
||||
name,
|
||||
uciType,
|
||||
function(old)
|
||||
if old.grouphashkey or old.hashkey then -- 没有 hash 的不参与删除
|
||||
if not nodeResult[old.grouphashkey] or not nodeResult[old.grouphashkey][old.hashkey] then
|
||||
ucic:delete(name, old['.name'])
|
||||
del = del + 1
|
||||
else
|
||||
old.alias = old.server .. ':' .. old.server_port
|
||||
log('忽略手动添加的节点: ' .. old.alias)
|
||||
local dat = nodeResult[old.grouphashkey][old.hashkey]
|
||||
ucic:tset(name, old['.name'], dat)
|
||||
-- 标记一下
|
||||
setmetatable(nodeResult[old.grouphashkey][old.hashkey], {__index = {_ignore = true}})
|
||||
end
|
||||
else
|
||||
log('忽略手动添加的节点: ' .. old.alias)
|
||||
if not old.alias then
|
||||
if not old.server or old.server_port then
|
||||
ucic:delete(name, old['.name'])
|
||||
else
|
||||
old.alias = old.server .. ':' .. old.server_port
|
||||
log('忽略手动添加的节点: ' .. old.alias)
|
||||
end
|
||||
else
|
||||
log('忽略手动添加的节点: ' .. old.alias)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
)
|
||||
|
||||
for k, v in ipairs(nodeResult) do
|
||||
-- 如果订阅节点中有相同的节点信息 需要先去重。
|
||||
|
@ -519,36 +522,36 @@ local execute = function()
|
|||
local firstServer = ucic:get_first(name, uciType)
|
||||
if not ucic:get(name, globalServer) then
|
||||
if firstServer then
|
||||
ucic:set(name, ucic:get_first(name, 'global'), 'global_server',
|
||||
firstServer)
|
||||
ucic:set(name, ucic:get_first(name, 'global'), 'global_server', firstServer)
|
||||
ucic:commit(name)
|
||||
log('当前主服务器已更新,正在自动更换。')
|
||||
end
|
||||
end
|
||||
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') -- 不加&的话日志会出现的更早
|
||||
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') -- 不加&的话日志会出现的更早
|
||||
end
|
||||
log('新增节点数量: ' .. add, '删除节点数量: ' .. del)
|
||||
log('更新成功服务正在启动')
|
||||
log('更新成功服务启动成功')
|
||||
log('END SUBSCRIBE')
|
||||
end
|
||||
end
|
||||
|
||||
if subscribe_url and #subscribe_url > 0 then
|
||||
xpcall(execute, function(e)
|
||||
log(e)
|
||||
-- log(debug.traceback())
|
||||
log('发生错误, 正在恢复服务')
|
||||
log('END SUBSCRIBE')
|
||||
local firstServer = ucic:get_first(name, uciType)
|
||||
if firstServer then
|
||||
luci.sys.call('/etc/init.d/' .. name ..
|
||||
' restart > /dev/null 2>&1 &') -- 不加&的话日志会出现的更早
|
||||
else
|
||||
luci.sys.call('/etc/init.d/' .. name .. ' stop > /dev/null 2>&1 &') -- 不加&的话日志会出现的更早
|
||||
xpcall(
|
||||
execute,
|
||||
function(e)
|
||||
log(e)
|
||||
log(debug.traceback())
|
||||
log('发生错误, 正在恢复服务')
|
||||
log('END SUBSCRIBE')
|
||||
local firstServer = ucic:get_first(name, uciType)
|
||||
if firstServer then
|
||||
luci.sys.call('/etc/init.d/' .. name .. ' restart > /dev/null 2>&1') -- 不加&的话日志会出现的更早
|
||||
else
|
||||
luci.sys.call('/etc/init.d/' .. name .. ' stop > /dev/null 2>&1') -- 不加&的话日志会出现的更早
|
||||
end
|
||||
end
|
||||
end)
|
||||
)
|
||||
end
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
#!/usr/bin/lua
|
||||
|
||||
------------------------------------------------
|
||||
-- This file is part of the luci-app-ssr-plus update.lua
|
||||
-- By Mattraks
|
||||
------------------------------------------------
|
||||
|
||||
|
||||
require 'nixio'
|
||||
require 'luci.util'
|
||||
require 'luci.jsonc'
|
||||
|
@ -39,8 +41,8 @@ else
|
|||
end
|
||||
|
||||
log('正在更新【国内IP段】数据库')
|
||||
local ip_data_url = ucic:get("vssr","@socks5_proxy[0]","ip_data_url")
|
||||
refresh_cmd ="wget-ssl -O- '".. ip_data_url .."' > /tmp/china_ssr.txt 2>/dev/null"
|
||||
local ip_data_url = ucic:get('vssr', '@socks5_proxy[0]', 'ip_data_url')
|
||||
refresh_cmd = "wget-ssl -O- '" .. ip_data_url .. "' > /tmp/china_ssr.txt 2>/dev/null"
|
||||
sret = luci.sys.call(refresh_cmd)
|
||||
icount = luci.sys.exec('cat /tmp/china_ssr.txt | wc -l')
|
||||
if sret == 0 then
|
||||
|
|
Loading…
Reference in New Issue