Merge Mainline
This commit is contained in:
commit
9d0065ef2e
@ -12,8 +12,8 @@ include $(INCLUDE_DIR)/version.mk
|
||||
include $(INCLUDE_DIR)/feeds.mk
|
||||
|
||||
PKG_NAME:=base-files
|
||||
PKG_RELEASE:=218
|
||||
PKG_FLAGS:=nonshared
|
||||
PKG_RELEASE:=$(COMMITCOUNT)
|
||||
|
||||
PKG_FILE_DEPENDS:=$(PLATFORM_DIR)/ $(GENERIC_PLATFORM_DIR)/base-files/
|
||||
PKG_BUILD_DEPENDS:=usign/host ucert/host
|
||||
|
||||
@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
|
||||
PKG_NAME:=uboot-envtools
|
||||
PKG_DISTNAME:=u-boot
|
||||
PKG_VERSION:=2020.04
|
||||
PKG_RELEASE:=17
|
||||
PKG_RELEASE:=$(AUTORELEASE)
|
||||
|
||||
PKG_SOURCE:=$(PKG_DISTNAME)-$(PKG_VERSION).tar.bz2
|
||||
PKG_SOURCE_URL:= \
|
||||
|
||||
@ -8,12 +8,13 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=Luci for JD dailybonus Script
|
||||
LUCI_DEPENDS:=+node +node-request +coreutils +coreutils-nohup +wget
|
||||
LUCI_DEPENDS:=+coreutils +coreutils-nohup +node +node-request \
|
||||
+lua +luasocket +lua-cjson +lua-md5 +luasec +wget-ssl
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
PKG_NAME:=luci-app-jd-dailybonus
|
||||
PKG_VERSION:=0.8.9
|
||||
PKG_RELEASE:=20201230
|
||||
PKG_VERSION:=1.0.1
|
||||
PKG_RELEASE:=20210123
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
|
||||
Binary file not shown.
1
package/ctcgfw/luci-app-jd-dailybonus/htdocs/jd-dailybonus/qrcode.min.js
vendored
Normal file
1
package/ctcgfw/luci-app-jd-dailybonus/htdocs/jd-dailybonus/qrcode.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,82 +1,112 @@
|
||||
-- Copyright (C) 2020 jerrykuku <jerrykuku@gmail.com>
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
module("luci.controller.jd-dailybonus", package.seeall)
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/jd-dailybonus") then
|
||||
return
|
||||
module('luci.controller.jd-dailybonus', package.seeall)
|
||||
package.path = package.path .. ';/usr/share/jd-dailybonus/?.lua'
|
||||
function index()
|
||||
if not nixio.fs.access('/etc/config/jd-dailybonus') then
|
||||
return
|
||||
end
|
||||
|
||||
entry({"admin", "services", "jd-dailybonus"}, alias("admin", "services", "jd-dailybonus", "client"), _("JD-DailyBonus"), 10).dependent = true -- 首页
|
||||
entry({"admin", "services", "jd-dailybonus", "client"}, cbi("jd-dailybonus/client"),_("Client"), 10).leaf = true -- 基本设置
|
||||
entry({"admin", "services", "jd-dailybonus", "log"},form("jd-dailybonus/log"),_("Log"), 30).leaf = true -- 日志页面
|
||||
entry({"admin", "services", "jd-dailybonus", "script"},form("jd-dailybonus/script"),_("Script"), 20).leaf = true -- 直接配置脚本
|
||||
entry({"admin", "services", "jd-dailybonus", "run"}, call("run")) -- 执行程序
|
||||
entry({"admin", "services", "jd-dailybonus", "update"}, call("update")) -- 执行更新
|
||||
entry({"admin", "services", "jd-dailybonus", "check_update"}, call("check_update")) -- 检查更新
|
||||
entry({'admin', 'services', 'jd-dailybonus'}, alias('admin', 'services', 'jd-dailybonus', 'client'), _('京东签到服务'), 10).dependent = true -- 首页
|
||||
entry({'admin', 'services', 'jd-dailybonus', 'client'}, cbi('jd-dailybonus/client', {hidesavebtn = true, hideresetbtn = true}), _('客户端'), 10).leaf = true -- 基本设置
|
||||
entry({'admin', 'services', 'jd-dailybonus', 'log'}, form('jd-dailybonus/log'), _('日志'), 30).leaf = true -- 日志页面
|
||||
entry({'admin', 'services', 'jd-dailybonus', 'script'}, form('jd-dailybonus/script'), _('脚本查看'), 20).leaf = true -- 直接配置脚本
|
||||
entry({'admin', 'services', 'jd-dailybonus', 'run'}, call('run')) -- 执行程序
|
||||
entry({'admin', 'services', 'jd-dailybonus', 'update'}, call('update')) -- 执行更新
|
||||
entry({'admin', 'services', 'jd-dailybonus', 'check_update'}, call('check_update')) -- 检查更新
|
||||
entry({'admin', 'services', 'jd-dailybonus', 'qrcode'}, call('qrcode')) -- 获取二维码
|
||||
entry({'admin', 'services', 'jd-dailybonus', 'check_login'}, call('check_login')) -- 获取二维码
|
||||
end
|
||||
|
||||
|
||||
-- 写入配置
|
||||
function write_json(file, content)
|
||||
local json = require 'luci.jsonc'
|
||||
local f = assert(io.open(file, 'w'))
|
||||
f:write(json.stringify(content, 1))
|
||||
f:close()
|
||||
end
|
||||
-- 执行程序
|
||||
|
||||
function run()
|
||||
local e = {}
|
||||
local uci = luci.model.uci.cursor()
|
||||
local cookie = luci.http.formvalue("cookies")
|
||||
local cookie2 = luci.http.formvalue("cookies2")
|
||||
local auto_update = luci.http.formvalue("auto_update")
|
||||
local auto_update_time = luci.http.formvalue("auto_update_time")
|
||||
local auto_run = luci.http.formvalue("auto_run")
|
||||
local auto_run_time = luci.http.formvalue("auto_run_time")
|
||||
local stop = luci.http.formvalue("stop")
|
||||
local serverchan = luci.http.formvalue("serverchan")
|
||||
local failed = luci.http.formvalue("failed")
|
||||
local name = ""
|
||||
uci:foreach("vssr", "global", function(s) name = s[".name"] end)
|
||||
local data = luci.http.formvalue()
|
||||
|
||||
if cookie ~= " " then
|
||||
uci:set("jd-dailybonus", '@global[0]', 'auto_update', auto_update)
|
||||
uci:set("jd-dailybonus", '@global[0]', 'auto_update_time', auto_update_time)
|
||||
uci:set("jd-dailybonus", '@global[0]', 'auto_run', auto_run)
|
||||
uci:set("jd-dailybonus", '@global[0]', 'auto_run_time', auto_run_time)
|
||||
uci:set("jd-dailybonus", '@global[0]', 'stop', stop)
|
||||
uci:set("jd-dailybonus", '@global[0]', 'cookie', cookie)
|
||||
uci:set("jd-dailybonus", '@global[0]', 'cookie2', cookie2)
|
||||
uci:set("jd-dailybonus", '@global[0]', 'serverchan', serverchan)
|
||||
uci:set("jd-dailybonus", '@global[0]', 'failed', failed)
|
||||
uci:save("jd-dailybonus")
|
||||
uci:commit("jd-dailybonus")
|
||||
luci.sys.call("/usr/share/jd-dailybonus/newapp.sh -r")
|
||||
luci.sys.call("/usr/share/jd-dailybonus/newapp.sh -a")
|
||||
e.error = 0
|
||||
else
|
||||
e.error = 1
|
||||
end
|
||||
data.auto_run = data.auto_run ~= nil and data.auto_run or 0
|
||||
data.auto_update = data.auto_update ~= nil and data.auto_update or 0
|
||||
uci:tset('jd-dailybonus', '@global[0]', data)
|
||||
uci:commit('jd-dailybonus')
|
||||
local json_data = {
|
||||
CookieJD = data.cookie,
|
||||
CookieJD2 = data.cookie2:len() == 0 and nil or data.cookie2,
|
||||
JD_DailyBonusDelay = data.stop,
|
||||
JD_DailyBonusTimeOut = data.out
|
||||
}
|
||||
write_json('/root/CookieSet.json', json_data)
|
||||
write_json('/www/CookieSet.json', json_data)
|
||||
luci.sys.call('/usr/share/jd-dailybonus/newapp.sh -r')
|
||||
luci.sys.call('/usr/share/jd-dailybonus/newapp.sh -a')
|
||||
e.error = 0
|
||||
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(e)
|
||||
|
||||
end
|
||||
|
||||
--检查更新
|
||||
function check_update()
|
||||
local jd = "jd-dailybonus"
|
||||
local jd = 'jd-dailybonus'
|
||||
local e = {}
|
||||
local new_version = luci.sys.exec("/usr/share/jd-dailybonus/newapp.sh -n")
|
||||
local new_version = luci.sys.exec('/usr/share/jd-dailybonus/newapp.sh -n')
|
||||
e.new_version = new_version
|
||||
e.error = 0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
--执行更新
|
||||
function update()
|
||||
local jd = "jd-dailybonus"
|
||||
local jd = 'jd-dailybonus'
|
||||
local e = {}
|
||||
local uci = luci.model.uci.cursor()
|
||||
local version = luci.http.formvalue("version")
|
||||
local version = luci.http.formvalue('version')
|
||||
--下载脚本
|
||||
local code = luci.sys.exec("/usr/share/jd-dailybonus/newapp.sh -u")
|
||||
local code = luci.sys.exec('/usr/share/jd-dailybonus/newapp.sh -u')
|
||||
e.error = code
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
end
|
||||
|
||||
--获取二维码
|
||||
function qrcode()
|
||||
local jd_cookie = require 'jd_cookie'
|
||||
local e = {}
|
||||
e.error = 0
|
||||
e.data = jd_cookie.get_qrcode()
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
--检测登录
|
||||
function check_login()
|
||||
local jd_cookie = require 'jd_cookie'
|
||||
local uci = luci.model.uci.cursor()
|
||||
local data = luci.http.formvalue()
|
||||
local id = data.id
|
||||
local e = jd_cookie.checkLogin(data.check_url, data.cookies)
|
||||
if e.error == 0 then
|
||||
local cookieStr = 'pt_key=' .. e.cookie.pt_key .. ';pt_pin=' .. e.cookie.pt_pin .. ';'
|
||||
uci:set('jd-dailybonus', '@global[0]', id, cookieStr)
|
||||
local json_data = {
|
||||
CookieJD = uci:get('jd-dailybonus', '@global[0]', 'cookie'),
|
||||
CookieJD2 = uci:get('jd-dailybonus', '@global[0]', 'cookie2'),
|
||||
JD_DailyBonusDelay = uci:get('jd-dailybonus', '@global[0]', 'stop'),
|
||||
JD_DailyBonusTimeOut = uci:get('jd-dailybonus', '@global[0]', 'out')
|
||||
}
|
||||
write_json('/root/CookieSet.json', json_data)
|
||||
write_json('/www/CookieSet.json', json_data)
|
||||
uci:commit('jd-dailybonus')
|
||||
e.cstr = cookieStr
|
||||
end
|
||||
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
@ -1,75 +1,101 @@
|
||||
local jd = "jd-dailybonus"
|
||||
local jd = 'jd-dailybonus'
|
||||
local uci = luci.model.uci.cursor()
|
||||
local sys = require "luci.sys"
|
||||
local sys = require 'luci.sys'
|
||||
|
||||
m = Map(jd)
|
||||
-- [[ 基本设置 ]]--
|
||||
|
||||
s = m:section(TypedSection, "global",
|
||||
translate("Base Config"))
|
||||
s = m:section(TypedSection, 'global', translate('基本设置'))
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(DummyValue, "", "")
|
||||
o = s:option(DummyValue, '', '')
|
||||
o.rawhtml = true
|
||||
o.template = "jd-dailybonus/cookie_tools"
|
||||
o.template = 'jd-dailybonus/cookie_tools'
|
||||
|
||||
o = s:option(ListValue, "remote_url", translate("Source Update Url"))
|
||||
o:value("https://cdn.jsdelivr.net/gh/NobyDa/Script/JD-DailyBonus/JD_DailyBonus.js", translate("GitHub"))
|
||||
o:value("https://gitee.com/jerrykuku/staff/raw/master/JD_DailyBonus.js", translate("Gitee"))
|
||||
o.default = "nil"
|
||||
o.rmempty = false
|
||||
o.description = translate('当GitHub源无法更新时,可以选择使用国内Gitee源')
|
||||
|
||||
o = s:option(Value, "cookie", translate("First Cookie"))
|
||||
o = s:option(Value, 'cookie', translate('第一账号Cookie'))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "cookie2", translate("Second Cookie"))
|
||||
o = s:option(Value, 'cookie2', translate('第二账号Cookie'))
|
||||
o.rmempty = true
|
||||
o.description = translate('双账号用户抓取"账号1"Cookie后, 请勿点击退出账号(可能会导致Cookie失效), 需清除浏览器资料或更换浏览器登录"账号2"抓取.')
|
||||
|
||||
o = s:option(Value, "stop", translate("Execute Delay"))
|
||||
o = s:option(Value, 'stop', translate('延迟签到'))
|
||||
o.rmempty = false
|
||||
o.default = 0
|
||||
o.datatype = integer
|
||||
o.description = translate("自定义延迟签到,单位毫秒. 默认分批并发无延迟. (延迟作用于每个签到接口, 如填入延迟则切换顺序签到. ) ")
|
||||
o.description = translate('自定义延迟签到,单位毫秒. 默认分批并发无延迟. (延迟作用于每个签到接口, 如填入延迟则切换顺序签到. ) ')
|
||||
|
||||
o = s:option(ListValue, "serverurl", translate("ServerURL"))
|
||||
o:value("scu", translate("SCU"))
|
||||
o:value("sct", translate("SCT"))
|
||||
o.default = "scu"
|
||||
o = s:option(Value, 'out', translate('接口超时'))
|
||||
o.rmempty = false
|
||||
o.default = 0
|
||||
o.datatype = integer
|
||||
o.description = translate('接口超时退出,单位毫秒 用于可能发生的网络不稳定, 0则关闭.')
|
||||
|
||||
-- server chan
|
||||
o = s:option(ListValue, 'serverurl', translate('Server酱的推送接口地址'))
|
||||
o:value('scu', translate('SCU'))
|
||||
o:value('sct', translate('SCT'))
|
||||
o.default = 'scu'
|
||||
o.rmempty = false
|
||||
o.description = translate('选择Server酱的推送接口')
|
||||
|
||||
o = s:option(Value, "serverchan", translate("ServerChan SCKEY"))
|
||||
o = s:option(Value, 'serverchan', translate('Server酱 SCKEY'))
|
||||
o.rmempty = true
|
||||
o.description = translate("微信推送,基于Server酱服务,请自行登录 http://sc.ftqq.com/ 绑定并获取 SCKEY (仅在自动签到时推送)")
|
||||
o.description = translate('微信推送,基于Server酱服务,请自行登录 http://sc.ftqq.com/ 绑定并获取 SCKEY。')
|
||||
|
||||
o = s:option(Flag, "failed", translate("Failed Push"))
|
||||
-- telegram
|
||||
|
||||
o = s:option(Value, 'tg_token', translate('Telegram Bot Token'))
|
||||
o.rmempty = true
|
||||
o.description = translate('首先在Telegram上搜索BotFather机器人,创建一个属于自己的通知机器人,并获取Token。')
|
||||
|
||||
o = s:option(Value, 'tg_userid', translate('Telegram UserID'))
|
||||
o.rmempty = true
|
||||
o.description = translate('在Telegram上搜索getuserIDbot机器人,获取UserID。')
|
||||
|
||||
--Auto Run Script Service
|
||||
|
||||
o = s:option(Flag, 'auto_run', translate('自动签到'))
|
||||
o.rmempty = false
|
||||
o.description = translate("仅当cookie失效时推送")
|
||||
|
||||
o = s:option(Flag, "auto_update", translate("Auto Update"))
|
||||
o.rmempty = false
|
||||
o.description = translate("Auto Update Script Service")
|
||||
|
||||
o =s:option(ListValue, "auto_update_time", translate("Update time (every day)"))
|
||||
for t = 0, 23 do o:value(t, t .. ":01") end
|
||||
o = s:option(ListValue, 'auto_run_time_h', translate('每天签到时间(小时)'))
|
||||
for t = 0, 23 do
|
||||
o:value(t, t)
|
||||
end
|
||||
o.default = 1
|
||||
o.rmempty = true
|
||||
o:depends("auto_update", "1")
|
||||
|
||||
o = s:option(Flag, "auto_run", translate("Auto Run"))
|
||||
o.rmempty = false
|
||||
o.description = translate("Auto Run Script Service")
|
||||
|
||||
o =s:option(ListValue, "auto_run_time", translate("Run time (every day)"))
|
||||
for t = 0, 23 do o:value(t, t .. ":05") end
|
||||
o:depends('auto_run', '1')
|
||||
o = s:option(ListValue, 'auto_run_time_m', translate('每天签到时间(分钟)'))
|
||||
for t = 0, 59 do
|
||||
o:value(t, t)
|
||||
end
|
||||
o.default = 1
|
||||
o.rmempty = true
|
||||
o:depends("auto_run", "1")
|
||||
o:depends('auto_run', '1')
|
||||
|
||||
o = s:option(DummyValue, "", "")
|
||||
-- Auto Update Script Service
|
||||
|
||||
o = s:option(Flag, 'auto_update', translate('自动更新'))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, 'auto_update_time', translate('每天更新时间'))
|
||||
for t = 0, 23 do
|
||||
o:value(t, t .. ':01')
|
||||
end
|
||||
o.default = 1
|
||||
o.rmempty = true
|
||||
o:depends('auto_update', '1')
|
||||
|
||||
o = s:option(Value, 'remote_url', translate('更新源地址'))
|
||||
o:value('https://raw.githubusercontent.com/NobyDa/Script/master/JD-DailyBonus/JD_DailyBonus.js', translate('GitHub'))
|
||||
o:value('https://cdn.jsdelivr.net/gh/NobyDa/Script/JD-DailyBonus/JD_DailyBonus.js', translate('GitHub CDN'))
|
||||
o:value('https://gitee.com/jerrykuku/staff/raw/master/JD_DailyBonus.js', translate('Gitee'))
|
||||
o.default = 'nil'
|
||||
o.rmempty = false
|
||||
o.description = translate('当GitHub源无法更新时,可以选择使用国内Gitee源,GitHub CDN可能比原地址更晚更新,但速度快')
|
||||
|
||||
o = s:option(DummyValue, '', '')
|
||||
o.rawhtml = true
|
||||
o.version = sys.exec('uci get jd-dailybonus.@global[0].version')
|
||||
o.template = "jd-dailybonus/update_service"
|
||||
o.template = 'jd-dailybonus/update_service'
|
||||
|
||||
return m
|
||||
|
||||
@ -1,25 +1,13 @@
|
||||
<%+cbi/valueheader%>
|
||||
|
||||
<label class="cbi-value-title"><%= translate("Cookie Tools") %></label>
|
||||
<label class="cbi-value-title"><%= translate("获取Cookie") %></label>
|
||||
<div class="cbi-value-field">
|
||||
<input type="button" class="cbi-button cbi-input-reload" value="<%= translate('JDCookie Tools') %>" onclick="javascript:window.open('/jd-dailybonus/JDCookie.zip','target');" />
|
||||
<input type="button" data-rel="1" class="cbi-button cbi-input-reload cookie-button" value="<%= translate('获取第一Cookie') %>" />
|
||||
<input type="button" data-rel="2" class="cbi-button cbi-input-reload cookie-button" value="<%= translate('获取第二Cookie') %>" />
|
||||
<br>
|
||||
<div class="cbi-value-description">
|
||||
<span class="cbi-value-helpicon"><img src="/luci-static/resources/cbi/help.gif" alt="帮助"></span>
|
||||
<%= translate("Click to download the JDCookie.zip,unzip it,and use load Unpacked extensions to install.link:[chrome://extensions/]")%>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%+cbi/valuefooter%>
|
||||
<%+cbi/valueheader%>
|
||||
|
||||
<label class="cbi-value-title"><%= translate("JD Url") %></label>
|
||||
<div class="cbi-value-field">
|
||||
<input type="button" class="cbi-button cbi-input-reload" value="bean.m.jd.com" onclick="javascript:window.open('https://bean.m.jd.com','target');" />
|
||||
<br>
|
||||
<div class="cbi-value-description">
|
||||
<span class="cbi-value-helpicon"><img src="/luci-static/resources/cbi/help.gif" alt="帮助"></span>
|
||||
<%= translate("Sign in ,then click JDCookie button.you will copy JD cookies, paste the cookie below.")%>
|
||||
<%= translate("点击上面按钮使用京东手机app扫码获取Cookie")%>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
<%+cbi/valueheader%>
|
||||
<script src="/jd-dailybonus/jquery.min.js"></script>
|
||||
<script src="/jd-dailybonus/qrcode.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
var jq=$.noConflict();
|
||||
</script>
|
||||
<style>
|
||||
.modals-bg {
|
||||
position: fixed;
|
||||
@ -9,7 +13,8 @@
|
||||
left: 0;
|
||||
top: 0;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
display: none;
|
||||
transition: all 0.3s ease-in-out;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.modals {
|
||||
@ -29,7 +34,22 @@
|
||||
/* Firefox */
|
||||
-webkit-box-sizing: border-box;
|
||||
/* Safari */
|
||||
transition: all 0.3s ease-in-out;
|
||||
transform: scale(1);
|
||||
}
|
||||
.modals-bg.hide {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.modals.hide {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transform: scale(0.5);
|
||||
}
|
||||
|
||||
|
||||
.modals h2 {
|
||||
color: #fff;
|
||||
@ -72,6 +92,70 @@
|
||||
text-align: left;
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
#qrcontainer {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 5000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(255, 255, 255, .8);
|
||||
text-align: center;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
#qrcontainer.hidden{
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#qrcontainer .qframe {
|
||||
background-color: #ffffff;
|
||||
padding: 1rem;
|
||||
border-radius: 0.5rem;
|
||||
border: #6D8A88 1px solid;
|
||||
-webkit-box-shadow: 0px 0px 7px 3px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0px 0px 7px 3px rgba(0, 0, 0, 0.2);
|
||||
position: relative;
|
||||
}
|
||||
#qrcontainer .qframe #refresh_qrcode{
|
||||
width: 256px;
|
||||
height: 256px;
|
||||
position: absolute;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
left: 1rem;
|
||||
top: 1rem;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
#qrcontainer .qframe #refresh_qrcode.hidden{
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
#qrcontainer .qframe #refresh_qrcode h3{
|
||||
font-weight: normal;
|
||||
}
|
||||
#qrcontainer .qframe #refresh_qrcode .refresh{
|
||||
display: block;
|
||||
background: #e4393c;
|
||||
width: 80px;
|
||||
height: 30px;
|
||||
margin: 0 auto;
|
||||
line-height: 30px;
|
||||
opacity: 1;
|
||||
z-index: 19;
|
||||
color: #fbfbfb;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
#qrcontainer .qframe .info {
|
||||
padding: 1rem 0 0 0;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
.modals {
|
||||
@ -104,48 +188,54 @@
|
||||
}
|
||||
|
||||
</style>
|
||||
<label class="cbi-value-title"><%= translate("Run") %></label>
|
||||
<label class="cbi-value-title"><%= translate("执行") %></label>
|
||||
<div class="cbi-value-field">
|
||||
<input class="cbi-button cbi-button-reload" id="update_service" type="button" size="0"
|
||||
value="<%= translate("Save Cookies And Run Service") %>">
|
||||
value="<%= translate("保存Cookie,并马上进行签到") %>">
|
||||
</div>
|
||||
|
||||
<%+cbi/valuefooter%>
|
||||
<%+cbi/valueheader%>
|
||||
<label class="cbi-value-title"><%= translate("Current Script Version") %></label>
|
||||
<div class="cbi-value-field">
|
||||
<div class="cbi-value-version">
|
||||
v<%=self.version%>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<%+cbi/valuefooter%>
|
||||
|
||||
<%+cbi/valueheader%>
|
||||
<label class="cbi-value-title"><%= translate("Update Script") %></label>
|
||||
<label class="cbi-value-title"><%= translate("更新脚本") %></label>
|
||||
<div class="cbi-value-field">
|
||||
<input class="cbi-button cbi-button-reload" id="update_script" type="button" size="0"
|
||||
value="<%= translate("Check Script Version") %>">
|
||||
|
||||
value="<%= translate("手动检查脚本更新,当前版本:v")..self.version %>">
|
||||
</div>
|
||||
<%+cbi/valuefooter%>
|
||||
|
||||
<div id="qrcontainer" class="hidden">
|
||||
<div class="qframe">
|
||||
<div id="refresh_qrcode" class="hidden">
|
||||
<div>
|
||||
<h3>二维码已失效</h3>
|
||||
<div class="refresh">刷新</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="qrcode"></div>
|
||||
<div class="info">请使用京东手机APP扫码</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
const SAVE_URL = '<%=luci.dispatcher.build_url("admin", "services", "jd-dailybonus","run")%>';
|
||||
const CHECK_URL = '<%=luci.dispatcher.build_url("admin", "services", "jd-dailybonus","check_update")%>';
|
||||
const QRCODE_URL = '<%=luci.dispatcher.build_url("admin", "services", "jd-dailybonus","qrcode")%>';
|
||||
const CHECK_LOGIN_URL = '<%=luci.dispatcher.build_url("admin", "services", "jd-dailybonus","check_login")%>';
|
||||
const UPDATE_URL = '<%=luci.dispatcher.build_url("admin", "services", "jd-dailybonus","update")%>';
|
||||
const CHECKING_TEXT = '<%= translate("Checking the New Version ...") %>';
|
||||
const UPDATING_TEXT = '<%= translate("Updating script,please wait ...") %>';
|
||||
const NEW_VERSION = '<%= translate("Is currently the latest version") %>';
|
||||
const UPDATE_TEXT = '<%= translate("There is a new version, click to update") %>';
|
||||
const CHECKING_TEXT = '<%= translate("正在检查是否存在新的版本 ...") %>';
|
||||
const UPDATING_TEXT = '<%= translate("正在更新脚本,请稍候 ...") %>';
|
||||
const NEW_VERSION = '<%= translate("当前已是最新版本。") %>';
|
||||
const UPDATE_TEXT = '<%= translate("有新的版本,请点击更新") %>';
|
||||
|
||||
var needUpdate = false;
|
||||
var newVersion;
|
||||
var _responseLen;
|
||||
var noChange = 0;
|
||||
var modal = '<div class="modals-bg">' +
|
||||
'<div class="modals">' +
|
||||
var ckid = 0;
|
||||
var modal = '<div class="modals-bg hide">' +
|
||||
'<div class="modals hide">' +
|
||||
'<h2><%:Sign in info%></h2>' +
|
||||
'<h3 style="margin-left:0;"><%:Service is running,Please do not refresh!%></h3>' +
|
||||
'<textarea cols="63" rows="28" wrap="on" readonly="readonly" id="log_content3" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"></textarea>' +
|
||||
@ -154,52 +244,38 @@
|
||||
|
||||
//显示并开始刷新订阅
|
||||
function update_service() {
|
||||
$("body").append(modal);
|
||||
$(".modals-bg").show();
|
||||
setTimeout("get_realtime_log();", 500);
|
||||
jq("body").append(modal);
|
||||
jq(".modals-bg").removeClass("hide");
|
||||
setTimeout(function(){
|
||||
jq(".modals").removeClass("hide");
|
||||
}, 100);
|
||||
setTimeout("get_realtime_log();", 500);
|
||||
}
|
||||
//保存订阅按钮
|
||||
$("#update_service").click(function () {
|
||||
prefix_array = $("#cbi-jd-dailybonus-global .cbi-section-node").attr("id").split("-");
|
||||
prefix = prefix_array[prefix_array.length - 1];
|
||||
//console.log(prefix);
|
||||
if ($("[name='cbid.jd-dailybonus." + prefix + ".auto_update']").is(":checked")) {
|
||||
var auto_update = "1";
|
||||
var auto_update_time = $("[name='cbid.jd-dailybonus." + prefix + ".auto_update_time']").val();
|
||||
} else {
|
||||
var auto_update = "0";
|
||||
var auto_update_time = "0";
|
||||
}
|
||||
|
||||
if ($("[name='cbid.jd-dailybonus." + prefix + ".auto_run']").is(":checked")) {
|
||||
var auto_run = "1";
|
||||
var auto_run_time = $("[name='cbid.jd-dailybonus." + prefix + ".auto_run_time']").val();
|
||||
} else {
|
||||
var auto_run = "0";
|
||||
var auto_run_time = "0";
|
||||
}
|
||||
var stop = $("[name='cbid.jd-dailybonus." + prefix + ".stop']").val();
|
||||
var cookies = $("[name='cbid.jd-dailybonus." + prefix + ".cookie']").val();
|
||||
var cookies2 = $("[name='cbid.jd-dailybonus." + prefix + ".cookie2']").val();
|
||||
var failed=($("[name='cbid.jd-dailybonus." + prefix + ".failed']").is(":checked"))?"1":"0";
|
||||
var serverchan = $("[name='cbid.jd-dailybonus." + prefix + ".serverchan']").val();
|
||||
var data = {
|
||||
auto_update: auto_update,
|
||||
auto_update_time: auto_update_time,
|
||||
auto_run: auto_run,
|
||||
auto_run_time: auto_run_time,
|
||||
cookies: cookies,
|
||||
cookies2: cookies2,
|
||||
stop: stop,
|
||||
serverchan: serverchan,
|
||||
failed: failed
|
||||
}
|
||||
//console.log(data);
|
||||
$.ajax({
|
||||
jq("#update_service").click(function () {
|
||||
let prefix_array = jq(".cbi-input-text").eq(0).attr("id").split(".");
|
||||
prefix_array.pop()
|
||||
var prefix = prefix_array.join(".")+".";
|
||||
let array = jq("form[name*='cbi'").serializeArray()
|
||||
var json = {};
|
||||
jq.each(array, function () {
|
||||
if(this.name.indexOf(prefix) != -1){
|
||||
let aname = this.name.replace(prefix, "");
|
||||
if (json[aname]) {
|
||||
if (!json[aname].push) {
|
||||
json[aname] = [json[aname]];
|
||||
}
|
||||
json[aname].push(this.value || '');
|
||||
} else {
|
||||
json[aname] = this.value || '';
|
||||
}
|
||||
}
|
||||
});
|
||||
jq.ajax({
|
||||
type: "post",
|
||||
url: SAVE_URL,
|
||||
dataType: "json",
|
||||
data: data,
|
||||
data: json,
|
||||
success: function (d) {
|
||||
if (d.error == 0) {
|
||||
update_service();
|
||||
@ -212,29 +288,29 @@
|
||||
});
|
||||
|
||||
//更新脚本
|
||||
$("#update_script").click(function () {
|
||||
jq("#update_script").click(function () {
|
||||
check_version()
|
||||
return false;
|
||||
});
|
||||
|
||||
function updateS(){
|
||||
$("#update_script").attr("disabled", true);
|
||||
$("#update_script").val(UPDATING_TEXT);
|
||||
jq("#update_script").attr("disabled", true);
|
||||
jq("#update_script").val(UPDATING_TEXT);
|
||||
//console.log(data);
|
||||
var data = {
|
||||
version: $("#update_script").attr("data-version")
|
||||
version: jq("#update_script").attr("data-version")
|
||||
}
|
||||
$.ajax({
|
||||
jq.ajax({
|
||||
type: "post",
|
||||
url: UPDATE_URL,
|
||||
dataType: "json",
|
||||
data: data,
|
||||
success: function (d) {
|
||||
if (d.error == 0) {
|
||||
$("#update_script").val(NEW_VERSION);
|
||||
$(".cbi-value-version").text("v" + newVersion);
|
||||
jq("#update_script").val(NEW_VERSION);
|
||||
jq(".cbi-value-version").text("v" + newVersion);
|
||||
} else {
|
||||
$("#update_script").attr("disabled", false);
|
||||
jq("#update_script").attr("disabled", false);
|
||||
alert("更新错误请重试");
|
||||
}
|
||||
}
|
||||
@ -243,7 +319,7 @@
|
||||
|
||||
|
||||
function get_realtime_log() {
|
||||
$.ajax({
|
||||
jq.ajax({
|
||||
url: '/JD_DailyBonus.htm?v=' + parseInt(Math.random() * 100000000),
|
||||
dataType: 'html',
|
||||
error: function (xhr) {
|
||||
@ -272,9 +348,9 @@
|
||||
}
|
||||
|
||||
function check_version() {
|
||||
$("#update_script").attr("disabled", true);
|
||||
$("#update_script").val(CHECKING_TEXT);
|
||||
$.ajax({
|
||||
jq("#update_script").attr("disabled", true);
|
||||
jq("#update_script").val(CHECKING_TEXT);
|
||||
jq.ajax({
|
||||
url: CHECK_URL,
|
||||
dataType: 'json',
|
||||
error: function (xhr) {
|
||||
@ -282,20 +358,94 @@
|
||||
},
|
||||
success: function (data) {
|
||||
if(data.new_version == 501){
|
||||
$("#update_script").attr("disabled", false);
|
||||
$("#update_script").val("无法获取新版本,请重试!");
|
||||
jq("#update_script").attr("disabled", false);
|
||||
jq("#update_script").val("无法获取新版本,请重试!");
|
||||
}else if (data.new_version > <%= self.version %>) {
|
||||
$("#update_script").attr("disabled", false);
|
||||
$("#update_script").val(UPDATE_TEXT + " v" + data.new_version);
|
||||
$("#update_script").attr("data-version", data.new_version);
|
||||
jq("#update_script").attr("disabled", false);
|
||||
jq("#update_script").val(UPDATE_TEXT + " v" + data.new_version);
|
||||
jq("#update_script").attr("data-version", data.new_version);
|
||||
newVersion = data.new_version;
|
||||
updateS();
|
||||
} else {
|
||||
$("#update_script").val(NEW_VERSION + " v" + data.new_version);
|
||||
updateS();
|
||||
jq("#update_script").val(NEW_VERSION + " v" + data.new_version);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
qrcode = new QRCode(document.getElementById("qrcode"),
|
||||
{
|
||||
text: "sample",
|
||||
correctLevel: QRCode.CorrectLevel.L
|
||||
});
|
||||
|
||||
//获取二维码
|
||||
function get_code() {
|
||||
let timeStamp = (new Date()).getTime()
|
||||
$.get('/qrcode?t='+timeStamp, function (data) {
|
||||
if (data.err == 0) {
|
||||
jq("#qrcontainer").removeClass("hidden")
|
||||
jq("#refresh_qrcode").addClass("hidden")
|
||||
qrcode.clear();
|
||||
qrcode.makeCode(data.qrcode);
|
||||
checkLogin();
|
||||
} else {
|
||||
Swal.fire({
|
||||
text: data.msg,
|
||||
icon: "error"
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
jq(".cookie-button").click(function(){
|
||||
ckid = jq(this).attr("data-rel");
|
||||
get_code()
|
||||
return false;
|
||||
})
|
||||
|
||||
jq('.refresh').click(get_code);
|
||||
|
||||
|
||||
function get_code(){
|
||||
let timeStamp = (new Date()).getTime()
|
||||
jq.ajax({
|
||||
url: QRCODE_URL+"?t="+timeStamp,
|
||||
dataType: 'json',
|
||||
success: function (data) {
|
||||
if(data.error == 0){
|
||||
jq("#qrcontainer").removeClass("hidden")
|
||||
jq("#refresh_qrcode").addClass("hidden")
|
||||
console.log(data.data.qrcode_url)
|
||||
qrcode.clear();
|
||||
qrcode.makeCode(data.data.qrcode_url);
|
||||
checkLogin(data.data.check_url,data.data.cookies);
|
||||
} else {
|
||||
alert("出错了请重试。")
|
||||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkLogin(check_url,cookies){
|
||||
var timeId = setInterval(() => {
|
||||
let cname = ckid == 1?"cookie":"cookie2"
|
||||
jq.post( CHECK_LOGIN_URL, { check_url:check_url,cookies: cookies ,id: cname}, function( data ) {
|
||||
if (data.error == 0) {
|
||||
clearInterval(timeId)
|
||||
jq("#qrcontainer").addClass("hidden")
|
||||
jq("#refresh_qrcode").addClass("hidden")
|
||||
let prefix_array = jq(".cbi-input-text").eq(0).attr("id").split(".");
|
||||
prefix_array.pop()
|
||||
let prefix = prefix_array.join(".")+".";
|
||||
console.log("."+prefix+cname,data.cstr);
|
||||
document.getElementById(prefix+cname).value =data.cstr
|
||||
} else if (data.error == 21 || data.error == 261) {
|
||||
clearInterval(timeId)
|
||||
jq("#refresh_qrcode").removeClass("hidden")
|
||||
}
|
||||
}, "json");
|
||||
}, 3000)
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -1,111 +0,0 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
||||
msgid "JD-DailyBonus"
|
||||
msgstr "京东签到服务"
|
||||
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "Disable"
|
||||
msgstr "停用"
|
||||
|
||||
msgid "Log"
|
||||
msgstr "日志"
|
||||
|
||||
msgid "Script"
|
||||
msgstr "脚本"
|
||||
|
||||
msgid "Base Config"
|
||||
msgstr "基本设置"
|
||||
|
||||
msgid "Cookie Tools"
|
||||
msgstr "Cookie 工具"
|
||||
|
||||
msgid "JDCookie Tools"
|
||||
msgstr "获取京东cookie扩展工具"
|
||||
|
||||
msgid "Source Update Url"
|
||||
msgstr "更新源地址"
|
||||
|
||||
msgid "First Cookie"
|
||||
msgstr "主账号Cookie"
|
||||
|
||||
msgid "Second Cookie"
|
||||
msgstr "第二账号Cookie"
|
||||
|
||||
msgid "Click to download the JDCookie.zip,unzip it,and use load Unpacked extensions to install.link:[chrome://extensions/]")"
|
||||
msgstr "点击上面的按钮安装下载JDCookie.zip(获取京东cookie扩展工具),解压后在[chrome://extensions/]中使用加载已解压的扩展程序进行安装。 "
|
||||
|
||||
msgid "JD Url"
|
||||
msgstr "京东链接"
|
||||
|
||||
msgid "Sign in ,then click JDCookie button.you will copy JD cookies, paste the cookie below."
|
||||
msgstr "登录后点击JDCookie 扩展工具复制cookie,然后粘贴到下面输入框中。(请使用F12调试工具,进入模拟手机浏览器模式)"
|
||||
|
||||
msgid "Auto Update Script Service"
|
||||
msgstr "自动更新脚本服务"
|
||||
|
||||
msgid "Update time (every day)"
|
||||
msgstr "更新时间 (每天)"
|
||||
|
||||
msgid "Update Script"
|
||||
msgstr "更新脚本"
|
||||
|
||||
msgid "Execute Delay"
|
||||
msgstr "延迟签到"
|
||||
|
||||
msgid "ServerChan SCKEY"
|
||||
msgstr "Server酱 SCKEY"
|
||||
|
||||
msgid "ServerURL"
|
||||
msgstr "Server酱的推送接口地址"
|
||||
|
||||
msgid "SCT"
|
||||
msgstr "测试版推送接口地址"
|
||||
|
||||
msgid "SCU"
|
||||
msgstr "原版推送接口地址"
|
||||
|
||||
msgid "Failed Push"
|
||||
msgstr "失效时推送"
|
||||
|
||||
msgid "Auto Run"
|
||||
msgstr "自动签到"
|
||||
|
||||
msgid "Run"
|
||||
msgstr "执行"
|
||||
|
||||
msgid "Auto Run Script Service"
|
||||
msgstr "自动签到服务"
|
||||
|
||||
msgid "Run time (every day)"
|
||||
msgstr "签到时间 (每天)"
|
||||
|
||||
msgid "Save Cookies And Run Service"
|
||||
msgstr "保存Cookie并签到"
|
||||
|
||||
msgid "Sign in info"
|
||||
msgstr "签到信息"
|
||||
|
||||
msgid "Service is running,Please do not refresh!"
|
||||
msgstr "服务正在执行中,请勿刷新!"
|
||||
|
||||
msgid "Updating script,please wait ..."
|
||||
msgstr "正在更新脚本,请稍候 ..."
|
||||
|
||||
msgid "Is currently the latest version"
|
||||
msgstr "当前已是最新版本。"
|
||||
|
||||
msgid "There is a new version, click to update"
|
||||
msgstr "有新的版本,请点击更新"
|
||||
|
||||
msgid "Checking the New Version ..."
|
||||
msgstr "正在检查是否存在新的版本 ..."
|
||||
|
||||
msgid "Check Script Version"
|
||||
msgstr "手动检查脚本更新"
|
||||
|
||||
msgid "Current Script Version"
|
||||
msgstr "当前脚本版本"
|
||||
|
||||
@ -1,9 +1,14 @@
|
||||
config global
|
||||
option version '1.87'
|
||||
option auto_run_time '1'
|
||||
option auto_run '1'
|
||||
option auto_update_time '1'
|
||||
option version '1.90'
|
||||
option out '0'
|
||||
option stop '100'
|
||||
option serverchan ''
|
||||
option remote_url 'https://raw.githubusercontent.com/NobyDa/Script/master/JD-DailyBonus/JD_DailyBonus.js'
|
||||
option serverurl 'scu'
|
||||
option auto_update '1'
|
||||
option stop '0'
|
||||
option failed '0'
|
||||
option remote_url 'https://cdn.jsdelivr.net/gh/NobyDa/Script/JD-DailyBonus/JD_DailyBonus.js'
|
||||
option auto_update_time '23'
|
||||
option auto_run '1'
|
||||
option auto_run_time '0'
|
||||
option auto_run_time_m '1'
|
||||
option auto_run_time_h '1'
|
||||
option cookie ''
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
京东多合一签到脚本
|
||||
|
||||
更新时间: 2020.12.25 17:50 v1.89
|
||||
更新时间: 2021.01.07 17:00 v1.90
|
||||
有效接口: 40+
|
||||
脚本兼容: QuantumultX, Surge, Loon, JSBox, Node.js
|
||||
电报频道: @NobyDa
|
||||
@ -13,7 +13,7 @@
|
||||
【 JSbox, Node.js 说明 】 :
|
||||
*************************
|
||||
|
||||
开启抓包app后, Safari浏览器登录 https://bean.m.jd.com 点击签到并且出现签到日历后, 返回抓包app搜索关键字 functionId=signBean 复制请求头Cookie填入以下Key处的单引号内即可 */
|
||||
开启抓包app后, Safari浏览器登录 https://bean.m.jd.com/bean/signIndex.action 点击签到并且出现签到日历后, 返回抓包app搜索关键字 functionId=signBean 复制请求头Cookie填入以下Key处的单引号内即可 */
|
||||
|
||||
var Key = ''; //单引号内自行填写您抓取的Cookie
|
||||
|
||||
@ -30,7 +30,7 @@ var DualKey = ''; //如需双账号签到,此处单引号内填写抓取的"账
|
||||
【 QX, Surge, Loon 说明 】 :
|
||||
*************************
|
||||
|
||||
初次使用时, app配置文件添加脚本配置,并启用Mitm后, Safari浏览器打开登录 https://bean.m.jd.com ,点击签到并且出现签到日历后, 如果通知获得cookie成功, 则可以使用此签到脚本。 注: 请勿在京东APP内获取!!!
|
||||
初次使用时, app配置文件添加脚本配置,并启用Mitm后, Safari浏览器打开登录 https://bean.m.jd.com/bean/signIndex.action ,点击签到并且出现签到日历后, 如果通知获得cookie成功, 则可以使用此签到脚本。 注: 请勿在京东APP内获取!!!
|
||||
|
||||
由于cookie的有效性(经测试网页Cookie有效周期最长31天),如果脚本后续弹出cookie无效的通知,则需要重复上述步骤。
|
||||
签到脚本将在每天的凌晨0:05执行, 您可以修改执行时间。 因部分接口京豆限量领取, 建议调整为凌晨签到。
|
||||
@ -108,14 +108,12 @@ async function all() {
|
||||
case 0:
|
||||
await Promise.all([
|
||||
JingDongBean(stop), //京东京豆
|
||||
JDTakeaLook(stop), //京东发现-看一看
|
||||
JingDongStore(stop), //京东超市
|
||||
JingDongWebcasts(stop), //京东直播
|
||||
JingRongBean(stop), //金融简单赚钱
|
||||
JingRongSteel(stop), //金融钢镚
|
||||
JingDongTurn(stop), //京东转盘
|
||||
JDFlashSale(stop), //京东闪购
|
||||
JDOverseas(stop), //京东国际
|
||||
JingDongCash(stop), //京东现金红包
|
||||
JDMagicCube(stop, 2), //京东小魔方
|
||||
JingDongSubsidy(stop), //京东金贴
|
||||
@ -131,15 +129,13 @@ async function all() {
|
||||
JingRongDoll(stop, 'JRFiveDoll', '京东金融-签伍', '1D06AA3B0F')
|
||||
]);
|
||||
await Promise.all([
|
||||
JDUserSignPre(stop, 'JDClothing', '京东商城-服饰', '4RBT3H9jmgYg1k2kBnHF8NAHm7m8'), //京东服饰
|
||||
JDUserSignPre(stop, 'JDUnderwear', '京东商城-内衣', '4PgpL1xqPSW1sVXCJ3xopDbB1f69'), //京东内衣馆
|
||||
JDUserSignPre(stop, 'JDShoes', '京东商城-鞋靴', '4RXyb1W4Y986LJW8ToqMK14BdTD'), //京东鞋靴
|
||||
JDUserSignPre(stop, 'JDCalendar', '京东日历-翻牌', '36V2Qw59VPNsuLxY84vCFtxFzrFs'), //京东日历翻牌
|
||||
JDUserSignPre(stop, 'JDChild', '京东商城-童装', '3Af6mZNcf5m795T8dtDVfDwWVNhJ'), //京东童装馆
|
||||
JDUserSignPre(stop, 'JDBaby', '京东商城-母婴', '3BbAVGQPDd6vTyHYjmAutXrKAos6'), //京东母婴馆
|
||||
JDUserSignPre(stop, 'JD3C', '京东商城-数码', '4SWjnZSCTHPYjE5T7j35rxxuMTb6'), //京东数码电器馆
|
||||
JDUserSignPre(stop, 'JDSubsidy', '京东晚市-补贴', 'xK148m4kWj5hBcTPuJUNNXH3AkJ'), //京东晚市补贴金
|
||||
JDUserSignPre(stop, 'JDDrug', '京东商城-医药', '3tqTG5sF1xCUyC6vgEF5CLCxGn7w'), //京东医药馆
|
||||
// JDUserSignPre(stop, 'JDSubsidy', '京东晚市-补贴', 'xK148m4kWj5hBcTPuJUNNXH3AkJ'), //京东晚市补贴金
|
||||
// JDUserSignPre(stop, 'JDDrug', '京东商城-医药', '3tqTG5sF1xCUyC6vgEF5CLCxGn7w'), //京东医药馆
|
||||
JDUserSignPre(stop, 'JDWomen', '京东商城-女装', 'DpSh7ma8JV7QAxSE2gJNro8Q2h9'), //京东女装馆
|
||||
JDUserSignPre(stop, 'JDFineWine', '京东商城-酒饮', 'zGwAUzL3pVGjptBBGeYfpKjYdtX'), //京东酒饮馆
|
||||
JDUserSignPre(stop, 'JDBook', '京东商城-图书', '3SC6rw5iBg66qrXPGmZMqFDwcyXi'), //京东图书
|
||||
@ -147,15 +143,17 @@ async function all() {
|
||||
JingRongDoll(stop, 'XJDouble', '金融现金-双签', 'F68B2C3E71', '', '', '', 'xianjin') //京东金融 现金双签
|
||||
]);
|
||||
await Promise.all([
|
||||
JDUserSignPre(stop, 'JDClothing', '京东商城-服饰', '4RBT3H9jmgYg1k2kBnHF8NAHm7m8'), //京东服饰
|
||||
JDUserSignPre(stop, 'JDUnderwear', '京东商城-内衣', '4PgpL1xqPSW1sVXCJ3xopDbB1f69'), //京东内衣馆
|
||||
JDUserSignPre(stop, 'JDSuitcase', '京东商城-箱包', 'ZrH7gGAcEkY2gH8wXqyAPoQgk6t'), //京东箱包馆
|
||||
JDUserSignPre(stop, 'JDSchool', '京东商城-校园', '4812pn2PAcUyfNdWr7Cvpww5MCyW'), //京东校园
|
||||
JDUserSignPre(stop, 'JDHealth', '京东商城-健康', 'w2oeK5yLdHqHvwef7SMMy4PL8LF'), //京东健康
|
||||
JDUserSignPre(stop, 'JDPet', '京东商城-宠物', '37ta5sh5ocrMZF3Fz5UMJbTsL42'), //京东宠物馆
|
||||
JDUserSignPre(stop, 'JDShand', '京东拍拍-二手', '3S28janPLYmtFxypu37AYAGgivfp'), //京东拍拍二手
|
||||
// JDUserSignPre(stop, 'JDPet', '京东商城-宠物', '37ta5sh5ocrMZF3Fz5UMJbTsL42'), //京东宠物馆
|
||||
// JDUserSignPre(stop, 'JDShand', '京东拍拍-二手', '3S28janPLYmtFxypu37AYAGgivfp'), //京东拍拍二手
|
||||
JDUserSignPre(stop, 'JDClean', '京东商城-清洁', '2Tjm6ay1ZbZ3v7UbriTj6kHy9dn6'), //京东清洁馆
|
||||
JDUserSignPre(stop, 'JDCare', '京东商城-个护', 'NJ1kd1PJWhwvhtim73VPsD1HwY3'), //京东个人护理馆
|
||||
JDUserSignPre(stop, 'JDJewels', '京东商城-珠宝', 'zHUHpTHNTaztSRfNBFNVZscyFZU'), //京东珠宝馆
|
||||
JDUserSignPre(stop, 'JDClocks', '京东商城-钟表', '2BcJPCVVzMEtMUynXkPscCSsx68W'), //京东钟表馆
|
||||
// JDUserSignPre(stop, 'JDClocks', '京东商城-钟表', '2BcJPCVVzMEtMUynXkPscCSsx68W'), //京东钟表馆
|
||||
JDUserSignPre(stop, 'JDMakeup', '京东商城-美妆', '2smCxzLNuam5L14zNJHYu43ovbAP'), //京东美妆馆
|
||||
JDUserSignPre(stop, 'JDVege', '京东商城-菜场', 'Wcu2LVCFMkBP3HraRvb7pgSpt64') //京东菜场
|
||||
]);
|
||||
@ -164,14 +162,12 @@ async function all() {
|
||||
break;
|
||||
default:
|
||||
await JingDongBean(stop); //京东京豆
|
||||
await JDTakeaLook(stop); //京东发现-看一看
|
||||
await JingDongStore(stop); //京东超市
|
||||
await JingDongWebcasts(stop); //京东直播
|
||||
await JingRongBean(stop); //金融简单赚钱
|
||||
await JingRongSteel(stop); //金融钢镚
|
||||
await JingDongTurn(stop); //京东转盘
|
||||
await JDFlashSale(stop); //京东闪购
|
||||
await JDOverseas(stop); //京东国际
|
||||
await JingDongCash(stop); //京东现金红包
|
||||
await JDMagicCube(stop, 2); //京东小魔方
|
||||
await JingDongGetCash(stop); //京东领现金
|
||||
@ -197,13 +193,13 @@ async function all() {
|
||||
await JDUserSignPre(stop, 'JDChild', '京东商城-童装', '3Af6mZNcf5m795T8dtDVfDwWVNhJ'); //京东童装馆
|
||||
await JDUserSignPre(stop, 'JDBaby', '京东商城-母婴', '3BbAVGQPDd6vTyHYjmAutXrKAos6'); //京东母婴馆
|
||||
await JDUserSignPre(stop, 'JD3C', '京东商城-数码', '4SWjnZSCTHPYjE5T7j35rxxuMTb6'); //京东数码电器馆
|
||||
await JDUserSignPre(stop, 'JDSubsidy', '京东晚市-补贴', 'xK148m4kWj5hBcTPuJUNNXH3AkJ'); //京东晚市补贴金
|
||||
await JDUserSignPre(stop, 'JDClocks', '京东商城-钟表', '2BcJPCVVzMEtMUynXkPscCSsx68W'); //京东钟表馆
|
||||
await JDUserSignPre(stop, 'JDDrug', '京东商城-医药', '3tqTG5sF1xCUyC6vgEF5CLCxGn7w'); //京东医药馆
|
||||
// await JDUserSignPre(stop, 'JDSubsidy', '京东晚市-补贴', 'xK148m4kWj5hBcTPuJUNNXH3AkJ'); //京东晚市补贴金
|
||||
// await JDUserSignPre(stop, 'JDClocks', '京东商城-钟表', '2BcJPCVVzMEtMUynXkPscCSsx68W'); //京东钟表馆
|
||||
// await JDUserSignPre(stop, 'JDDrug', '京东商城-医药', '3tqTG5sF1xCUyC6vgEF5CLCxGn7w'); //京东医药馆
|
||||
await JDUserSignPre(stop, 'JDWomen', '京东商城-女装', 'DpSh7ma8JV7QAxSE2gJNro8Q2h9'); //京东女装馆
|
||||
await JDUserSignPre(stop, 'JDPet', '京东商城-宠物', '37ta5sh5ocrMZF3Fz5UMJbTsL42'); //京东宠物馆
|
||||
// await JDUserSignPre(stop, 'JDPet', '京东商城-宠物', '37ta5sh5ocrMZF3Fz5UMJbTsL42'); //京东宠物馆
|
||||
await JDUserSignPre(stop, 'JDBook', '京东商城-图书', '3SC6rw5iBg66qrXPGmZMqFDwcyXi'); //京东图书
|
||||
await JDUserSignPre(stop, 'JDShand', '京东拍拍-二手', '3S28janPLYmtFxypu37AYAGgivfp'); //京东拍拍二手
|
||||
// await JDUserSignPre(stop, 'JDShand', '京东拍拍-二手', '3S28janPLYmtFxypu37AYAGgivfp'); //京东拍拍二手
|
||||
await JDUserSignPre(stop, 'JDMakeup', '京东商城-美妆', '2smCxzLNuam5L14zNJHYu43ovbAP'); //京东美妆馆
|
||||
await JDUserSignPre(stop, 'JDFineWine', '京东商城-酒饮', 'zGwAUzL3pVGjptBBGeYfpKjYdtX'); //京东酒饮馆
|
||||
await JDUserSignPre(stop, 'JDVege', '京东商城-菜场', 'Wcu2LVCFMkBP3HraRvb7pgSpt64'); //京东菜场
|
||||
@ -1700,56 +1696,6 @@ function JingRongDoll(s, key, title, code, type, num, award, belong) {
|
||||
});
|
||||
}
|
||||
|
||||
function JDOverseas(s) {
|
||||
merge.Overseas = {};
|
||||
return new Promise(resolve => {
|
||||
if (disable("Overseas")) return resolve()
|
||||
setTimeout(() => {
|
||||
const OverseasUrl = {
|
||||
url: 'https://api.m.jd.com/client.action?functionId=checkin',
|
||||
headers: {
|
||||
Cookie: KEY
|
||||
},
|
||||
body: "body=%7B%7D&build=167237&client=apple&clientVersion=9.0.0&openudid=1fce88cd05c42fe2b054e846f11bdf33f016d676&partner=apple&scope=11&sign=e27f8b904040a0e3c99b87fc27e09c87&st=1591730990449&sv=101"
|
||||
};
|
||||
$nobyda.post(OverseasUrl, function(error, response, data) {
|
||||
try {
|
||||
if (error) {
|
||||
throw new Error(error)
|
||||
} else {
|
||||
const Details = LogDetails ? "response:\n" + data : '';
|
||||
if (data.match(/\"type\":\d+?,/)) {
|
||||
console.log("\n" + "京东商城-国际签到成功 " + Details)
|
||||
merge.Overseas.success = 1
|
||||
if (data.match(/\"jdBeanAmount\":[1-9]+/)) {
|
||||
merge.Overseas.bean = data.match(/\"jdBeanAmount\":(\d+)/)[1]
|
||||
merge.Overseas.notify = "京东商城-国际: 成功, 明细: " + merge.Overseas.bean + "京豆 🐶"
|
||||
} else {
|
||||
merge.Overseas.notify = "京东商城-国际: 成功, 明细: 无京豆 🐶"
|
||||
}
|
||||
} else {
|
||||
console.log("\n" + "京东商城-国际签到失败 " + Details)
|
||||
merge.Overseas.fail = 1
|
||||
if (data.match(/(\"code\":\"13\"|重复签到)/)) {
|
||||
merge.Overseas.notify = "京东商城-国际: 失败, 原因: 已签过 ⚠️"
|
||||
} else if (data.match(/\"code\":\"(-1|3)\"/)) {
|
||||
merge.Overseas.notify = "京东商城-国际: 失败, 原因: Cookie失效‼️"
|
||||
} else {
|
||||
merge.Overseas.notify = "京东商城-国际: 失败, 原因: 未知 ⚠️"
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (eor) {
|
||||
$nobyda.AnError("京东商城-国际", "Overseas", eor, response, data)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}, s)
|
||||
if (out) setTimeout(resolve, out + s)
|
||||
});
|
||||
}
|
||||
|
||||
function JingDongGetCash(s) {
|
||||
merge.JDGetCash = {};
|
||||
return new Promise(resolve => {
|
||||
@ -1834,45 +1780,6 @@ function JingDongWebcasts(s) {
|
||||
});
|
||||
}
|
||||
|
||||
function JDTakeaLook(s) {
|
||||
merge.TakeaLook = {};
|
||||
return new Promise(resolve => {
|
||||
if (disable("TakeaLook")) return resolve()
|
||||
setTimeout(() => {
|
||||
$nobyda.get({
|
||||
url: 'https://api.m.jd.com/client.action?functionId=discTaskList&body=%7B%22bizType%22%3A1%2C%22referPageId%22%3A%22discRecommend%22%7D&client=apple&clientVersion=9.1.6&openudid=1fce88cd05c42fe2b054e846f11bdf33f016d676&sign=17061147fe8e0eb10edfe8d9968b6d66&st=1601138337675&sv=102',
|
||||
headers: {
|
||||
Cookie: KEY
|
||||
}
|
||||
}, (error, response, data) => {
|
||||
try {
|
||||
if (error) throw new Error(error);
|
||||
const cc = JSON.parse(data);
|
||||
const Details = LogDetails ? "response:\n" + data : '';
|
||||
const tm = parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000
|
||||
if (data.match(/签到成功/) && !data.match(tm)) {
|
||||
console.log(`\n京东发现-看看签到成功 ${Details}`)
|
||||
const aw = data.match(/\"签到成功,获得(\d+)京豆\"/)
|
||||
merge.TakeaLook.success = 1
|
||||
merge.TakeaLook.bean = aw ? aw[1] : 0
|
||||
merge.TakeaLook.notify = `京东发现-看看: 成功, 明细: ${merge.TakeaLook.bean||`无`}京豆 🐶`
|
||||
} else {
|
||||
console.log(`\n京东发现-看看签到失败 ${Details}`)
|
||||
const tp = data.match(tm) ? `已签过` : cc.busiCode == 2001 ? `Cookie失效` : `${cc.message||`未知`}`
|
||||
merge.TakeaLook.notify = `京东发现-看看: 失败, 原因: ${tp}${cc.busiCode==2001?`‼️`:` ⚠️`}`
|
||||
merge.TakeaLook.fail = 1
|
||||
}
|
||||
} catch (eor) {
|
||||
$nobyda.AnError("京东发现-看看", "TakeaLook", eor, response, data)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}, s)
|
||||
if (out) setTimeout(resolve, out + s)
|
||||
});
|
||||
}
|
||||
|
||||
function JingDongStore(s) {
|
||||
merge.JDGStore = {};
|
||||
return new Promise(resolve => {
|
||||
|
||||
@ -0,0 +1,168 @@
|
||||
-- Copyright (C) 2021 jerrykuku <jerrykuku@gmail.com>
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
|
||||
local uci = require 'luci.model.uci'.cursor()
|
||||
local config = 'jd-dailybonus'
|
||||
package.path = package.path .. ';/usr/share/jd-dailybonus/?.lua'
|
||||
local requests = require 'requests'
|
||||
local socket = require 'socket'
|
||||
local tinsert = table.insert
|
||||
local ssub, slen, schar, sbyte, sformat, sgsub = string.sub, string.len, string.char, string.byte, string.format, string.gsub
|
||||
local User_Agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36'
|
||||
local Host = 'plogin.m.jd.com'
|
||||
local jd_cookie = {}
|
||||
|
||||
--打印table
|
||||
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))
|
||||
else
|
||||
print_r_cache[tostring(t)] = true
|
||||
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 .. '"')
|
||||
else
|
||||
print(indent .. '[' .. pos .. '] => ' .. tostring(val))
|
||||
end
|
||||
end
|
||||
else
|
||||
print(indent .. tostring(t))
|
||||
end
|
||||
end
|
||||
end
|
||||
if (type(t) == 'table') then
|
||||
print(tostring(t) .. ' {')
|
||||
sub_print_r(t, ' ')
|
||||
print('}')
|
||||
else
|
||||
sub_print_r(t, ' ')
|
||||
end
|
||||
print()
|
||||
end
|
||||
|
||||
-- 分割字符串
|
||||
local function split(full, sep)
|
||||
full = full:gsub('%z', '') -- 这里不是很清楚 有时候结尾带个\0
|
||||
local off, result = 1, {}
|
||||
while true do
|
||||
local nStart, nEnd = full:find(sep, off)
|
||||
if not nEnd then
|
||||
local res = ssub(full, off, slen(full))
|
||||
if #res > 0 then -- 过滤掉 \0
|
||||
tinsert(result, res)
|
||||
end
|
||||
break
|
||||
else
|
||||
tinsert(result, ssub(full, off, nStart - 1))
|
||||
off = nEnd + 1
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
--获取unix时间戳
|
||||
function jd_cookie.timestamp()
|
||||
return math.floor(socket.gettime() * 1000)
|
||||
end
|
||||
|
||||
--延时函数
|
||||
function sleep(n)
|
||||
os.execute('sleep ' .. n)
|
||||
end
|
||||
|
||||
--解析cookie
|
||||
function praseSetCookies(rcookie)
|
||||
local tbl = {}
|
||||
for k, v in rcookie:gmatch('([^;%s]+)=([^;]+)') do
|
||||
tbl[k] = v
|
||||
end
|
||||
return tbl
|
||||
end
|
||||
|
||||
--获取二维码链接和检测URL
|
||||
function jd_cookie.get_qrcode()
|
||||
local timeStamp = jd_cookie.timestamp()
|
||||
local url =
|
||||
'https://plogin.m.jd.com/cgi-bin/mm/new_login_entrance?lang=chs&appid=300&returnurl=https://wq.jd.com/passport/LoginRedirect?state=' ..
|
||||
timeStamp .. '&returnurl=https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport'
|
||||
local xformHeaders = {
|
||||
['Content-Type'] = 'application/x-www-form-urlencoded',
|
||||
['Connection'] = 'Keep-Alive',
|
||||
['Accept'] = 'application/json, text/plain, */*',
|
||||
['Accept-Language'] = 'zh-cn',
|
||||
['Referer'] = 'https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wq.jd.com/passport/LoginRedirect?state=' ..
|
||||
timeStamp .. '&returnurl=https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport',
|
||||
['User-Agent'] = User_Agent,
|
||||
['Host'] = Host
|
||||
}
|
||||
local response = requests.get {url, headers = xformHeaders}
|
||||
local s_token = response.json().s_token
|
||||
local dat = split(string.gsub(response.headers['set-cookie'], ' DOMAIN=.plogin.m.jd.com', ''), ';')
|
||||
local cookies = string.gsub(dat[1] .. dat[4] .. dat[6] .. dat[8], ',', ';') .. ';'
|
||||
|
||||
local timeStamp = jd_cookie.timestamp()
|
||||
local url = 'https://plogin.m.jd.com/cgi-bin/m/tmauthreflogurl?s_token=' .. s_token .. '&v=' .. timeStamp .. '&remember=true'
|
||||
local xformHeaders = {
|
||||
['Content-Type'] = 'application/x-www-form-urlencoded',
|
||||
['Connection'] = 'Keep-Alive',
|
||||
['Accept'] = 'application/json, text/plain, */*',
|
||||
['Accept-Language'] = 'zh-cn',
|
||||
['Referer'] = 'https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wq.jd.com/passport/LoginRedirect?state=' ..
|
||||
timeStamp .. '&returnurl=https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport',
|
||||
['User-Agent'] = User_Agent,
|
||||
['Host'] = Host
|
||||
}
|
||||
local response = requests.post {url, cookies = cookies, headers = xformHeaders}
|
||||
local json_body, error = response.json()
|
||||
local token = json_body['token']
|
||||
local ou_state = json_body['ou_state']
|
||||
local okl_token = praseSetCookies(response.headers['set-cookie']).okl_token
|
||||
local return_json = {
|
||||
qrcode_url = 'https://plogin.m.jd.com/cgi-bin/m/tmauth?appid=300&client_type=m&token=' .. token,
|
||||
check_url = 'https://plogin.m.jd.com/cgi-bin/m/tmauthchecktoken?&token=' .. token .. '&ou_state=' .. ou_state .. '&okl_token=' .. okl_token,
|
||||
cookies = cookies
|
||||
}
|
||||
return return_json
|
||||
end
|
||||
|
||||
--检测扫码状态 并返回cookie
|
||||
function jd_cookie.checkLogin(url, cookies)
|
||||
local xformHeaders = {
|
||||
['Content-Type'] = 'application/x-www-form-urlencoded',
|
||||
['Connection'] = 'Keep-Alive',
|
||||
['Accept'] = 'application/json, text/plain, */*',
|
||||
['Accept-Language'] = 'zh-cn',
|
||||
['Referer'] = 'https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wqlogin2.jd.com/passport/LoginRedirect?state=',
|
||||
['User-Agent'] = User_Agent,
|
||||
['Host'] = Host
|
||||
}
|
||||
local data =
|
||||
'lang=chs&appid=300&source=wq_passport&returnurl=https://wqlogin2.jd.com/passport/LoginRedirect?state=1100399130787&returnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action'
|
||||
local response = requests.post {url, data = data, cookies = cookies, headers = xformHeaders}
|
||||
--local cookie = jd_cookie.praseSetCookies(response.headers['set-cookie'])
|
||||
local json = response.json()
|
||||
local return_json = {}
|
||||
if json.errcode == 0 then
|
||||
local ucookie = praseSetCookies(response.headers['set-cookie'])
|
||||
return_json = {
|
||||
error = 0,
|
||||
cookie = ucookie
|
||||
}
|
||||
else
|
||||
return_json = {
|
||||
error = json.errcode,
|
||||
msg = json.message
|
||||
}
|
||||
end
|
||||
|
||||
return return_json
|
||||
end
|
||||
|
||||
return jd_cookie
|
||||
@ -49,78 +49,58 @@ cancel() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
fill_cookie() {
|
||||
cookie1=$(uci_get_by_type global cookie)
|
||||
if [ ! "$cookie1" = "" ]; then
|
||||
varb="var Key = '$cookie1';"
|
||||
a=$(sed -n '/var Key =/=' $JD_SCRIPT)
|
||||
b=$((a-1))
|
||||
sed -i "${a}d" $JD_SCRIPT
|
||||
sed -i "${b}a ${varb}" $JD_SCRIPT
|
||||
fi
|
||||
|
||||
cookie2=$(uci_get_by_type global cookie2)
|
||||
if [ ! "$cookie2" = "" ]; then
|
||||
varb2="var DualKey = '$cookie2';"
|
||||
aa=$(sed -n '/var DualKey =/=' $JD_SCRIPT)
|
||||
bb=$((aa-1))
|
||||
sed -i "${aa}d" $JD_SCRIPT
|
||||
sed -i "${bb}a ${varb2}" $JD_SCRIPT
|
||||
fi
|
||||
|
||||
stop=$(uci_get_by_type global stop)
|
||||
if [ ! "$stop" = "" ]; then
|
||||
varb3="var stop = $stop;"
|
||||
sed -i "s/^var stop =.*/$varb3/g" $JD_SCRIPT
|
||||
fi
|
||||
}
|
||||
|
||||
add_cron() {
|
||||
sed -i '/jd-dailybonus/d' $CRON_FILE
|
||||
[ $(uci_get_by_type global auto_run 0) -eq 1 ] && echo '5 '$(uci_get_by_type global auto_run_time)' * * * sleep '$(expr $(head -n 128 /dev/urandom | tr -dc "0123456789" | head -c4) % 180)'s; /usr/share/jd-dailybonus/newapp.sh -w' >>$CRON_FILE
|
||||
[ $(uci_get_by_type global auto_run 0) -eq 1 ] && echo $(uci_get_by_type global auto_run_time_m)' '$(uci_get_by_type global auto_run_time_h)' * * * /usr/share/jd-dailybonus/newapp.sh -w' >>$CRON_FILE
|
||||
[ $(uci_get_by_type global auto_update 0) -eq 1 ] && echo '1 '$(uci_get_by_type global auto_update_time)' * * * /usr/share/jd-dailybonus/newapp.sh -u' >>$CRON_FILE
|
||||
crontab $CRON_FILE
|
||||
/etc/init.d/cron restart
|
||||
}
|
||||
|
||||
# Run Script
|
||||
|
||||
serverchan() {
|
||||
sckey=$(uci_get_by_type global serverchan)
|
||||
failed=$(uci_get_by_type global failed)
|
||||
desc=$(cat /www/JD_DailyBonus.htm | grep -E '签到号|签到概览|签到奖励|其他奖励|账号总计|其他总计' | sed 's/$/&\n/g')
|
||||
serverurlflag=$(uci_get_by_type global serverurl)
|
||||
serverurl=https://sc.ftqq.com/
|
||||
if [ "$serverurlflag" = "sct" ]; then
|
||||
serverurl=https://sctapi.ftqq.com/
|
||||
fi
|
||||
if [ $failed -eq 1 ]; then
|
||||
grep "Cookie失效" /www/JD_DailyBonus.htm > /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
title="$(date '+%Y年%m月%d日') 京东签到 Cookie 失效"
|
||||
wget-ssl -q --output-document=/dev/null --post-data="text=$title~&desp=$desc" $serverurl$sckey.send
|
||||
fi
|
||||
notify() {
|
||||
grep "Cookie失效" /www/JD_DailyBonus.htm >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
title="$(date '+%Y年%m月%d日') 京东签到 Cookie 失效"
|
||||
else
|
||||
title="$(date '+%Y年%m月%d日') 京东签到"
|
||||
fi
|
||||
desc=$(cat /www/JD_DailyBonus.htm | grep -E '签到号|签到概览|签到奖励|其他奖励|账号总计|其他总计' | sed 's/$/&\n/g')
|
||||
#serverchan
|
||||
sckey=$(uci_get_by_type global serverchan)
|
||||
if [ ! -z $sckey ]; then
|
||||
serverurlflag=$(uci_get_by_type global serverurl)
|
||||
serverurl=https://sc.ftqq.com/
|
||||
if [ "$serverurlflag" = "sct" ]; then
|
||||
serverurl=https://sctapi.ftqq.com/
|
||||
fi
|
||||
wget-ssl -q --output-document=/dev/null --post-data="text=$title~&desp=$desc" $serverurl$sckey.send
|
||||
fi
|
||||
|
||||
#telegram
|
||||
TG_BOT_TOKEN=$(uci_get_by_type global tg_token)
|
||||
TG_USER_ID=$(uci_get_by_type global tg_userid)
|
||||
API_URL="https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage"
|
||||
if [ ! -z $TG_BOT_TOKEN ] && [ ! -z $TG_USER_ID ]; then
|
||||
text="*$title*
|
||||
|
||||
\`\`\`
|
||||
"$desc"
|
||||
====================================
|
||||
本消息来自京东签到插件 jd-dailybonus
|
||||
\`\`\`"
|
||||
wget-ssl -q --output-document=/dev/null --post-data="chat_id=$TG_USER_ID&text=$text&parse_mode=markdownv2" $API_URL
|
||||
fi
|
||||
}
|
||||
|
||||
run() {
|
||||
fill_cookie
|
||||
echo -e $(date '+%Y-%m-%d %H:%M:%S %A') >$LOG_HTM 2>/dev/null
|
||||
[ ! -f "/usr/bin/node" ] && echo -e "未安装node.js,请安装后再试!\nNode.js is not installed, please try again after installation!">>$LOG_HTM && exit 1
|
||||
node $JD_SCRIPT >>$LOG_HTM 2>/dev/null
|
||||
}
|
||||
|
||||
back_run() {
|
||||
run
|
||||
sleep 1s
|
||||
serverchan
|
||||
[ ! -f "/usr/bin/node" ] && echo -e "未安装node.js,请安装后再试!\nNode.js is not installed, please try again after installation!" >>$LOG_HTM && exit 1
|
||||
node $JD_SCRIPT >>$LOG_HTM 2>/dev/null && notify &
|
||||
}
|
||||
|
||||
save() {
|
||||
fill_cookie
|
||||
add_cron
|
||||
}
|
||||
|
||||
@ -156,7 +136,6 @@ update() {
|
||||
fi
|
||||
remote_ver=$(get_ver $TEMP_SCRIPT)
|
||||
cp -r $TEMP_SCRIPT $JD_SCRIPT
|
||||
fill_cookie
|
||||
uci set jd-dailybonus.@global[0].version=$remote_ver
|
||||
uci commit jd-dailybonus
|
||||
cancel "0"
|
||||
@ -169,7 +148,7 @@ while getopts ":alnruswh" arg; do
|
||||
exit 0
|
||||
;;
|
||||
l)
|
||||
serverchan
|
||||
notify
|
||||
exit 0
|
||||
;;
|
||||
n)
|
||||
@ -189,7 +168,7 @@ while getopts ":alnruswh" arg; do
|
||||
exit 0
|
||||
;;
|
||||
w)
|
||||
back_run
|
||||
run
|
||||
exit 0
|
||||
;;
|
||||
h)
|
||||
|
||||
@ -0,0 +1,303 @@
|
||||
-- Lua Requests library for http ease
|
||||
|
||||
local http_socket = require('socket.http')
|
||||
local https_socket = require('ssl.https')
|
||||
local url_parser = require('socket.url')
|
||||
local ltn12 = require('ltn12')
|
||||
local json = require('cjson.safe')
|
||||
local md5sum = require('md5') -- TODO: Make modular?
|
||||
local mime = require('mime')
|
||||
|
||||
local requests = {
|
||||
_DESCRIPTION = 'Http requests made simpler',
|
||||
http_socket = http_socket,
|
||||
https_socket = https_socket
|
||||
}
|
||||
|
||||
local _requests = {}
|
||||
|
||||
--User facing function the make a request use Digest Authentication
|
||||
--TODO: Determine what else should live in authentication
|
||||
function requests.HTTPDigestAuth(user, password)
|
||||
return { _type = 'digest', user = user, password = password}
|
||||
end
|
||||
|
||||
--User facing function the make a request use Basic Authentication
|
||||
--TODO: Determine what else should live in authentication
|
||||
function requests.HTTPBasicAuth(user, password)
|
||||
return { _type = 'basic', user = user, password = password}
|
||||
end
|
||||
|
||||
function requests.post(url, args)
|
||||
return requests.request("POST", url, args)
|
||||
end
|
||||
|
||||
function requests.get(url, args)
|
||||
return requests.request("GET", url, args)
|
||||
end
|
||||
|
||||
function requests.delete(url, args)
|
||||
return requests.request("DELETE", url, args)
|
||||
end
|
||||
|
||||
function requests.patch(url, args)
|
||||
return requests.request("PATCH", url, args)
|
||||
end
|
||||
|
||||
function requests.put(url, args)
|
||||
return requests.request("PUT", url, args)
|
||||
end
|
||||
|
||||
function requests.options(url, args)
|
||||
return requests.request("OPTIONS", url, args)
|
||||
end
|
||||
|
||||
function requests.head(url, args)
|
||||
return requests.request("HEAD", url, args)
|
||||
end
|
||||
|
||||
function requests.trace(url, args)
|
||||
return requests.request("TRACE", url, args)
|
||||
end
|
||||
|
||||
--Sets up all the data for a request and makes the request
|
||||
function requests.request(method, url, args)
|
||||
local request
|
||||
|
||||
if type(url) == "table" then
|
||||
request = url
|
||||
if not request.url and request[1] then
|
||||
request.url = table.remove(request, 1)
|
||||
end
|
||||
else
|
||||
request = args or {}
|
||||
request.url = url
|
||||
end
|
||||
|
||||
request.method = method
|
||||
_requests.parse_args(request)
|
||||
|
||||
-- TODO: Find a better way to do this
|
||||
if request.auth and request.auth._type == 'digest' then
|
||||
local response = _requests.make_request(request)
|
||||
return _requests.use_digest(response, request)
|
||||
else
|
||||
return _requests.make_request(request)
|
||||
end
|
||||
end
|
||||
|
||||
--Makes a request
|
||||
function _requests.make_request(request)
|
||||
local response_body = {}
|
||||
local full_request = {
|
||||
method = request.method,
|
||||
url = request.url,
|
||||
headers = request.headers,
|
||||
sink = ltn12.sink.table(response_body),
|
||||
redirect = request.allow_redirects,
|
||||
proxy = request.proxy
|
||||
}
|
||||
if request.data then
|
||||
full_request.source = ltn12.source.string(request.data)
|
||||
end
|
||||
|
||||
local response = {}
|
||||
local ok
|
||||
local socket = string.find(full_request.url, '^https:') and not request.proxy and https_socket or http_socket
|
||||
|
||||
ok, response.status_code, response.headers, response.status = socket.request(full_request)
|
||||
|
||||
assert(ok, 'error in '..request.method..' request: '..response.status_code)
|
||||
response.text = table.concat(response_body)
|
||||
response.json = function () return json.decode(response.text) end
|
||||
|
||||
return response
|
||||
end
|
||||
|
||||
--Parses through all the possible arguments for a request
|
||||
function _requests.parse_args(request)
|
||||
_requests.check_url(request)
|
||||
_requests.check_data(request)
|
||||
_requests.create_header(request)
|
||||
_requests.check_timeout(request.timeout)
|
||||
_requests.check_redirect(request.allow_redirects)
|
||||
end
|
||||
|
||||
--Format the the url based on the params argument
|
||||
function _requests.format_params(url, params) -- TODO: Clean
|
||||
if not params or next(params) == nil then return url end
|
||||
|
||||
url = url..'?'
|
||||
for key, value in pairs(params) do
|
||||
if tostring(value) then
|
||||
url = url..tostring(key)..'='
|
||||
|
||||
if type(value) == 'table' then
|
||||
local val_string = ''
|
||||
|
||||
for _, val in ipairs(value) do
|
||||
val_string = val_string..tostring(val)..','
|
||||
end
|
||||
|
||||
url = url..val_string:sub(0, -2)
|
||||
else
|
||||
url = url..tostring(value)
|
||||
end
|
||||
|
||||
url = url..'&'
|
||||
end
|
||||
end
|
||||
|
||||
return url:sub(0, -2)
|
||||
end
|
||||
|
||||
--Check that there is a URL given and append to it if params are passed in.
|
||||
function _requests.check_url(request)
|
||||
assert(request.url, 'No url specified for request')
|
||||
request.url = _requests.format_params(request.url, request.params)
|
||||
end
|
||||
|
||||
-- Add to the HTTP header
|
||||
function _requests.create_header(request)
|
||||
request.headers = request.headers or {}
|
||||
if request.data then
|
||||
request.headers['Content-Length'] = request.data:len()
|
||||
end
|
||||
|
||||
if request.cookies then
|
||||
if request.headers.cookie then
|
||||
request.headers.cookie = request.headers.cookie..'; '..request.cookies
|
||||
else
|
||||
request.headers.cookie = request.cookies
|
||||
end
|
||||
end
|
||||
|
||||
if request.auth then
|
||||
_requests.add_auth_headers(request)
|
||||
end
|
||||
end
|
||||
|
||||
--Makes sure that the data is in a format that can be sent
|
||||
function _requests.check_data(request)
|
||||
if type(request.data) == "table" then
|
||||
request.data = json.encode(request.data)
|
||||
elseif request.data then
|
||||
request.data = tostring(request.data)
|
||||
end
|
||||
end
|
||||
|
||||
--Set the timeout
|
||||
function _requests.check_timeout(timeout)
|
||||
http_socket.TIMEOUT = timeout or 5
|
||||
https_socket.TIMEOUT = timeout or 5
|
||||
end
|
||||
|
||||
--Checks is allow_redirects parameter is set correctly
|
||||
function _requests.check_redirect(allow_redirects)
|
||||
if allow_redirects and type(allow_redirects) ~= "boolean" then
|
||||
error("allow_redirects expects a boolean value. received type = "..type(allow_redirects))
|
||||
end
|
||||
end
|
||||
|
||||
--Create the Authorization header for Basic Auth
|
||||
function _requests.basic_auth_header(request)
|
||||
local encoded = mime.b64(request.auth.user..':'..request.auth.password)
|
||||
request.headers.Authorization = 'Basic '..encoded
|
||||
end
|
||||
|
||||
-- Create digest authorization string for request header TODO: Could be better, but it should work
|
||||
function _requests.digest_create_header_string(auth)
|
||||
local authorization = 'Digest username="'..auth.user..'", realm="'..auth.realm..'", nonce="'..auth.nonce
|
||||
authorization = authorization..'", uri="'..auth.uri..'", qop='..auth.qop..', nc='..auth.nc
|
||||
authorization = authorization..', cnonce="'..auth.cnonce..'", response="'..auth.response..'"'
|
||||
|
||||
if auth.opaque then
|
||||
authorization = authorization..', opaque="'..auth.opaque..'"'
|
||||
end
|
||||
|
||||
return authorization
|
||||
end
|
||||
|
||||
--MD5 hash all parameters
|
||||
local function md5_hash(...)
|
||||
return md5sum.sumhexa(table.concat({...}, ":"))
|
||||
end
|
||||
|
||||
-- Creates response hash TODO: Add functionality
|
||||
function _requests.digest_hash_response(auth_table)
|
||||
return md5_hash(
|
||||
md5_hash(auth_table.user, auth_table.realm, auth_table.password),
|
||||
auth_table.nonce,
|
||||
auth_table.nc,
|
||||
auth_table.cnonce,
|
||||
auth_table.qop,
|
||||
md5_hash(auth_table.method, auth_table.uri)
|
||||
)
|
||||
end
|
||||
|
||||
-- Add digest authentication to the request header
|
||||
function _requests.digest_auth_header(request)
|
||||
if not request.auth.nonce then return end
|
||||
|
||||
request.auth.cnonce = request.auth.cnonce or string.format("%08x", os.time())
|
||||
|
||||
request.auth.nc_count = request.auth.nc_count or 0
|
||||
request.auth.nc_count = request.auth.nc_count + 1
|
||||
|
||||
request.auth.nc = string.format("%08x", request.auth.nc_count)
|
||||
|
||||
local url = url_parser.parse(request.url)
|
||||
request.auth.uri = url_parser.build{path = url.path, query = url.query}
|
||||
request.auth.method = request.method
|
||||
request.auth.qop = 'auth'
|
||||
|
||||
request.auth.response = _requests.digest_hash_response(request.auth)
|
||||
|
||||
request.headers.Authorization = _requests.digest_create_header_string(request.auth)
|
||||
end
|
||||
|
||||
--Checks the resonse code and adds additional headers for Digest Auth
|
||||
-- TODO: Rename this
|
||||
function _requests.use_digest(response, request)
|
||||
if response.status_code == 401 then
|
||||
_requests.parse_digest_response_header(response,request)
|
||||
_requests.create_header(request)
|
||||
response = _requests.make_request(request)
|
||||
response.auth = request.auth
|
||||
response.cookies = request.headers.cookie
|
||||
return response
|
||||
else
|
||||
response.auth = request.auth
|
||||
response.cookies = request.headers.cookie
|
||||
return response
|
||||
end
|
||||
end
|
||||
|
||||
--Parse the first response from the host to make the Authorization header
|
||||
function _requests.parse_digest_response_header(response, request)
|
||||
for key, value in response.headers['www-authenticate']:gmatch('(%w+)="(%S+)"') do
|
||||
request.auth[key] = value
|
||||
end
|
||||
|
||||
if request.headers.cookie then
|
||||
request.headers.cookie = request.headers.cookie..'; '..response.headers['set-cookie']
|
||||
else
|
||||
request.headers.cookie = response.headers['set-cookie']
|
||||
end
|
||||
|
||||
request.auth.nc_count = 0
|
||||
end
|
||||
|
||||
-- Call the correct authentication header function
|
||||
function _requests.add_auth_headers(request)
|
||||
local auth_func = {
|
||||
basic = _requests.basic_auth_header,
|
||||
digest = _requests.digest_auth_header
|
||||
}
|
||||
|
||||
auth_func[request.auth._type](request)
|
||||
end
|
||||
|
||||
--Return public functions
|
||||
requests._private = _requests
|
||||
return requests
|
||||
@ -36,6 +36,10 @@ s = m:section(NamedSection, sid, "other_rules")
|
||||
s.anonymous = true
|
||||
s.addremove = false
|
||||
|
||||
o = s:option(Value, "Note", translate("Note"))
|
||||
o.default = "default"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "config", translate("Config File"))
|
||||
local e,a={}
|
||||
local groupnames,filename
|
||||
|
||||
@ -34,6 +34,7 @@ s:tab("dashboard", translate("Dashboard Settings"))
|
||||
s:tab("rules_update", translate("Rules Update"))
|
||||
s:tab("geo_update", translate("GEOIP Update"))
|
||||
s:tab("chnr_update", translate("Chnroute Update"))
|
||||
s:tab("auto_restart", translate("Auto Restart"))
|
||||
s:tab("version_update", translate("Version Update"))
|
||||
s:tab("debug", translate("Debug Logs"))
|
||||
|
||||
@ -469,6 +470,27 @@ o.write = function()
|
||||
end
|
||||
end
|
||||
|
||||
o = s:taboption("auto_restart", Flag, "auto_restart", translate("Auto Restart"))
|
||||
o.description = translate("Auto Restart OpenClash")
|
||||
o.default=0
|
||||
|
||||
o = s:taboption("auto_restart", ListValue, "auto_restart_week_time", translate("Restart Time (Every Week)"))
|
||||
o:value("*", translate("Every Day"))
|
||||
o:value("1", translate("Every Monday"))
|
||||
o:value("2", translate("Every Tuesday"))
|
||||
o:value("3", translate("Every Wednesday"))
|
||||
o:value("4", translate("Every Thursday"))
|
||||
o:value("5", translate("Every Friday"))
|
||||
o:value("6", translate("Every Saturday"))
|
||||
o:value("0", translate("Every Sunday"))
|
||||
o.default=1
|
||||
|
||||
o = s:taboption("auto_restart", ListValue, "auto_restart_day_time", translate("Restart time (every day)"))
|
||||
for t = 0,23 do
|
||||
o:value(t, t..":00")
|
||||
end
|
||||
o.default=0
|
||||
|
||||
---- Dashboard Settings
|
||||
local lan_ip=SYS.exec("uci get network.lan.ipaddr 2>/dev/null |awk -F '/' '{print $1}' 2>/dev/null |tr -d '\n'")
|
||||
local cn_port=SYS.exec("uci get openclash.config.cn_port 2>/dev/null |tr -d '\n'")
|
||||
@ -593,6 +615,11 @@ function o.cfgvalue(...)
|
||||
end
|
||||
end
|
||||
|
||||
o = ss:option(DummyValue, "Note", translate("Note"))
|
||||
function o.cfgvalue(...)
|
||||
return Value.cfgvalue(...) or translate("None")
|
||||
end
|
||||
|
||||
-- [[ Edit Authentication ]] --
|
||||
s = m:section(TypedSection, "authentication", translate("Set Authentication of SOCKS5/HTTP(S)"))
|
||||
s.anonymous = true
|
||||
|
||||
@ -1424,3 +1424,18 @@ msgstr "选择配置文件后请点击以获取对应的策略组"
|
||||
|
||||
msgid "Other Rules Name"
|
||||
msgstr "第三方规则"
|
||||
|
||||
msgid "Note"
|
||||
msgstr "备注"
|
||||
|
||||
msgid "Auto Restart"
|
||||
msgstr "定时重启"
|
||||
|
||||
msgid "Auto Restart OpenClash"
|
||||
msgstr "定时重启插件"
|
||||
|
||||
msgid "Restart Time (Every Week)"
|
||||
msgstr "重启时间(每周)"
|
||||
|
||||
msgid "Restart time (every day)"
|
||||
msgstr "重启时间(每天)"
|
||||
@ -48,6 +48,9 @@ add_cron()
|
||||
[ -z "$(grep "openclash_chnroute.sh" "$CRON_FILE" 2>/dev/null)" ] && {
|
||||
[ "$(uci get openclash.config.chnr_auto_update 2>/dev/null)" -eq 1 ] && echo "0 $(uci get openclash.config.chnr_update_day_time 2>/dev/null) * * $(uci get openclash.config.chnr_update_week_time 2>/dev/null) /usr/share/openclash/openclash_chnroute.sh" >> $CRON_FILE
|
||||
}
|
||||
[ -z "$(grep "/etc/init.d/openclash" "$CRON_FILE" 2>/dev/null)" ] && {
|
||||
[ "$(uci get openclash.config.auto_restart 2>/dev/null)" -eq 1 ] && echo "0 $(uci get openclash.config.auto_restart_day_time 2>/dev/null) * * $(uci get openclash.config.auto_restart_week_time 2>/dev/null) /etc/init.d/openclash restart 2>/dev/null" >> $CRON_FILE
|
||||
}
|
||||
crontab $CRON_FILE
|
||||
nohup /usr/share/openclash/openclash_watchdog.sh &
|
||||
}
|
||||
@ -1291,11 +1294,13 @@ fi
|
||||
fi
|
||||
|
||||
#common ports
|
||||
common_port="21 22 23 53 80 123 143 194 443 465 587 853 993 995 998 2052 2053 2082 2083 2086 2095 2096 5222 5228 5229 5230 8080 8443 8880 8888 8889"
|
||||
ipset create common_ports bitmap:port range 0-65535
|
||||
for i in $common_port; do
|
||||
ipset add common_ports $i
|
||||
done
|
||||
if [ "$common_ports" = "1" ]; then
|
||||
common_port="21 22 23 53 80 123 143 194 443 465 587 853 993 995 998 2052 2053 2082 2083 2086 2095 2096 5222 5228 5229 5230 8080 8443 8880 8888 8889"
|
||||
ipset create common_ports bitmap:port range 0-65535
|
||||
for i in $common_port; do
|
||||
ipset add common_ports $i
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "$en_mode_tun" ] || [ "$en_mode_tun" -eq 3 ]; then
|
||||
#tcp
|
||||
@ -1308,9 +1313,7 @@ if [ -z "$en_mode_tun" ] || [ "$en_mode_tun" -eq 3 ]; then
|
||||
iptables -t nat -A openclash -m set ! --match-set lan_ac_white_macs src -j RETURN >/dev/null 2>&1
|
||||
iptables -t nat -A openclash -m set ! --match-set lan_ac_white_ips src -j RETURN >/dev/null 2>&1
|
||||
if [ "$en_mode" = "redir-host" ]; then
|
||||
if [ "$common_ports" = "1" ]; then
|
||||
iptables -t nat -A openclash -m set ! --match-set common_ports dst -j RETURN >/dev/null 2>&1
|
||||
fi
|
||||
iptables -t nat -A openclash -m set ! --match-set common_ports dst -j RETURN >/dev/null 2>&1
|
||||
iptables -t nat -A openclash -m set --match-set china_ip_route dst -j RETURN >/dev/null 2>&1
|
||||
fi
|
||||
iptables -t nat -A openclash -p tcp -j REDIRECT --to-ports "$proxy_port"
|
||||
@ -1333,9 +1336,7 @@ if [ -z "$en_mode_tun" ] || [ "$en_mode_tun" -eq 3 ]; then
|
||||
iptables -t mangle -A openclash -m set ! --match-set lan_ac_white_ips src -j RETURN >/dev/null 2>&1
|
||||
iptables -t mangle -A openclash -m set ! --match-set lan_ac_white_macs src -j RETURN >/dev/null 2>&1
|
||||
if [ "$en_mode" = "redir-host" ]; then
|
||||
if [ "$common_ports" = "1" ]; then
|
||||
iptables -t mangle -A openclash -m set ! --match-set common_ports dst -j RETURN >/dev/null 2>&1
|
||||
fi
|
||||
iptables -t mangle -A openclash -m set ! --match-set common_ports dst -j RETURN >/dev/null 2>&1
|
||||
iptables -t mangle -A openclash -m set --match-set china_ip_route dst -j RETURN >/dev/null 2>&1
|
||||
fi
|
||||
iptables -t mangle -A openclash -p udp --dport 53 -j RETURN >/dev/null 2>&1
|
||||
@ -1444,9 +1445,7 @@ if [ -n "$en_mode_tun" ]; then
|
||||
iptables -t mangle -A openclash -m set ! --match-set lan_ac_white_ips src -j RETURN >/dev/null 2>&1
|
||||
iptables -t mangle -A openclash -m set ! --match-set lan_ac_white_macs src -j RETURN >/dev/null 2>&1
|
||||
if [ "$en_mode" = "redir-host" ]; then
|
||||
if [ "$common_ports" = "1" ]; then
|
||||
iptables -t mangle -A openclash -m set ! --match-set common_ports dst -j RETURN >/dev/null 2>&1
|
||||
fi
|
||||
iptables -t mangle -A openclash -m set ! --match-set common_ports dst -j RETURN >/dev/null 2>&1
|
||||
iptables -t mangle -A openclash -m set --match-set china_ip_route dst -j RETURN >/dev/null 2>&1
|
||||
fi
|
||||
iptables -t mangle -A openclash -j MARK --set-mark "$PROXY_FWMARK"
|
||||
|
||||
@ -48,7 +48,7 @@ yml_other_rules_del()
|
||||
if [ "$enabled" = "0" ] || [ "$config" != "$2" ] || [ "$rule_name" != "$3" ]; then
|
||||
return
|
||||
else
|
||||
uci delete openclash."$section" 2>/dev/null
|
||||
uci set openclash."$section".enabled=0 2>/dev/null
|
||||
fi
|
||||
}
|
||||
#写入代理集到配置文件
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-vssr
|
||||
PKG_VERSION:=1.21
|
||||
PKG_RELEASE:=20210114
|
||||
PKG_VERSION:=1.22
|
||||
PKG_RELEASE:=20210119
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
@ -46,7 +46,7 @@ define Package/luci-app-vssr
|
||||
SUBMENU:=3. Applications
|
||||
TITLE:=A New SS/SSR/V2Ray/Trojan LuCI interface
|
||||
PKGARCH:=all
|
||||
DEPENDS:=+shadowsocksr-libev-alt +ipset +ip-full +iptables-mod-tproxy +dnsmasq-full +coreutils +coreutils-base64 +bash +pdnsd-alt +wget-ssl +luasocket +lua-maxminddb \
|
||||
DEPENDS:=+shadowsocksr-libev-alt +ipset +ip-full +iptables-mod-tproxy +dnsmasq-full +coreutils +coreutils-base64 +bash +pdnsd-alt +wget-ssl +lua +luasocket +lua-maxminddb \
|
||||
+shadowsocks-libev-ss-local +shadowsocksr-libev-ssr-local +shadowsocks-libev-ss-redir +simple-obfs \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_plugin:v2ray-plugin \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray \
|
||||
|
||||
@ -12,12 +12,13 @@ function index()
|
||||
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', 'control'}, cbi('vssr/control'), _('Access Control'), 12).leaf = true -- 访问控制
|
||||
entry({'admin', 'services', 'vssr', 'router'}, cbi('vssr/router'), _('Router Config'), 13).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 -- 访问控制
|
||||
if nixio.fs.access('/usr/bin/v2ray/v2ray') or nixio.fs.access('/usr/bin/v2ray') or nixio.fs.access('/usr/bin/xray') or nixio.fs.access('/usr/bin/xray/xray') then
|
||||
entry({'admin', 'services', 'vssr', 'socks5'}, cbi('vssr/socks5'), _('Socks5'), 14).leaf = true -- Socks5代理
|
||||
entry({'admin', 'services', 'vssr', 'socks5'}, cbi('vssr/socks5'), _('Local Proxy'), 15).leaf = true -- Socks5代理
|
||||
end
|
||||
entry({'admin', 'services', 'vssr', 'advanced'}, cbi('vssr/advanced'), _('Advanced Settings'), 15).leaf = true -- 高级设置
|
||||
entry({'admin', 'services', 'vssr', 'advanced'}, cbi('vssr/advanced'), _('Advanced Settings'), 16).leaf = true -- 高级设置
|
||||
elseif nixio.fs.access('/usr/bin/ssr-server') then
|
||||
entry({'admin', 'services', 'vssr'}, alias('admin', 'services', 'vssr', 'server'), _('vssr'), 10).dependent = true
|
||||
else
|
||||
@ -240,11 +241,7 @@ function refresh_data()
|
||||
local icount = 0
|
||||
|
||||
if set == 'gfw_data' then
|
||||
if nixio.fs.access('/usr/bin/wget-ssl') then
|
||||
refresh_cmd = 'wget-ssl --no-check-certificate https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt -O /tmp/gfw.b64'
|
||||
else
|
||||
refresh_cmd = 'wget -O /tmp/gfw.b64 http://iytc.net/tools/list.b64'
|
||||
end
|
||||
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')
|
||||
@ -265,7 +262,7 @@ function refresh_data()
|
||||
retstring = '-1'
|
||||
end
|
||||
elseif set == 'ip_data' then
|
||||
refresh_cmd ="wget -O- 'https://ispip.clang.cn/all_cn.txt' > /tmp/china_ssr.txt 2>/dev/null"
|
||||
refresh_cmd = "wget-ssl -O- 'https://ispip.clang.cn/all_cn.txt' > /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
|
||||
@ -282,12 +279,8 @@ function refresh_data()
|
||||
luci.sys.exec('rm -f /tmp/china_ssr.txt ')
|
||||
else
|
||||
local need_process = 0
|
||||
if nixio.fs.access('/usr/bin/wget-ssl') then
|
||||
refresh_cmd = 'wget-ssl --no-check-certificate -O - https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt > /tmp/adnew.conf'
|
||||
need_process = 1
|
||||
else
|
||||
refresh_cmd = 'wget -O /tmp/ad.conf http://iytc.net/tools/ad.conf'
|
||||
end
|
||||
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
|
||||
@ -319,4 +312,4 @@ function refresh_data()
|
||||
end
|
||||
luci.http.prepare_content('application/json')
|
||||
luci.http.write_json({ret = retstring, retcount = icount})
|
||||
end
|
||||
end
|
||||
|
||||
@ -61,59 +61,6 @@ o.datatype = 'uinteger'
|
||||
o:depends('enable_switch', '1')
|
||||
o.default = 3
|
||||
|
||||
-- [[ 节点订阅 ]]--
|
||||
|
||||
s = m:section(TypedSection, 'server_subscribe', translate('Servers subscription and manage'))
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(Flag, 'auto_update', translate('Auto Update'))
|
||||
o.rmempty = false
|
||||
o.description = translate('Auto Update Server subscription, GFW list and CHN route')
|
||||
|
||||
o = s:option(ListValue, 'auto_update_time', translate('Update time (every day)'))
|
||||
for t = 0, 23 do
|
||||
o:value(t, t .. ':00')
|
||||
end
|
||||
o.default = 2
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(DynamicList, 'subscribe_url', translate('Subscribe URL'))
|
||||
o.rmempty = true
|
||||
o.description = translate('You can manually add group names in front of the URL, splited by ,')
|
||||
|
||||
o = s:option(Value, "filter_words", translate("Subscribe Filter Words"))
|
||||
o.rmempty = true
|
||||
o.description = translate("Filter Words splited by /")
|
||||
|
||||
o = s:option(Flag, 'proxy', translate('Through proxy update'))
|
||||
o.rmempty = false
|
||||
o.description = translate('Through proxy update list, Not Recommended ')
|
||||
|
||||
o = s:option(DummyValue, '', '')
|
||||
o.rawhtml = true
|
||||
o.template = 'vssr/update_subscribe'
|
||||
|
||||
o = s:option(Button, 'delete', translate('Delete All Subscribe Severs'))
|
||||
o.inputstyle = 'reset'
|
||||
o.description = string.format(translate('Server Count') .. ': %d', server_count)
|
||||
o.write = function()
|
||||
uci:delete_all(
|
||||
'vssr',
|
||||
'servers',
|
||||
function(s)
|
||||
if s.hashkey or s.isSubscribe then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
)
|
||||
uci:save('vssr')
|
||||
uci:commit('vssr')
|
||||
luci.sys.exec('/etc/init.d/vssr restart')
|
||||
luci.http.redirect(luci.dispatcher.build_url('admin', 'services', 'vssr', 'servers'))
|
||||
return
|
||||
end
|
||||
|
||||
-- [[ adblock ]]--
|
||||
s = m:section(TypedSection, 'global', translate('adblock settings'))
|
||||
|
||||
@ -93,15 +93,7 @@ for i, v in pairs(route_name) do
|
||||
o = s:option(ListValue, v, translate(route_label[i]))
|
||||
o:value('nil', translate('Same as Main Server'))
|
||||
for _, key in pairs(server_table) do
|
||||
if(v == 'tw_video_server' and key.flag == "tw") then
|
||||
o:value(key.name, key.gname)
|
||||
end
|
||||
if(v == 'tvb_server' and key.flag == "hk") then
|
||||
o:value(key.name, key.gname)
|
||||
end
|
||||
if(v ~= 'tvb_server' and v ~= 'tw_video_server') then
|
||||
o:value(key.name, key.gname)
|
||||
end
|
||||
o:value(key.name, key.gname)
|
||||
end
|
||||
o:depends('v2ray_flow', '1')
|
||||
o.default = 'nil'
|
||||
|
||||
@ -2,7 +2,8 @@ local fs = require 'nixio.fs'
|
||||
local conffile = '/tmp/ssrpro.log'
|
||||
|
||||
f = SimpleForm('logview')
|
||||
|
||||
f.submit = false
|
||||
f.reset = false
|
||||
t = f:field(TextValue, 'conf')
|
||||
t.rmempty = true
|
||||
t.rows = 20
|
||||
|
||||
@ -1,31 +1,31 @@
|
||||
local m, s, o
|
||||
local NXFS = require 'nixio.fs'
|
||||
local router_table = {
|
||||
yotube = {
|
||||
a1 = {
|
||||
name = 'youtube',
|
||||
des = 'Youtube Domain'
|
||||
},
|
||||
tw_video = {
|
||||
a2 = {
|
||||
name = 'tw_video',
|
||||
des = 'Tw Video Domain'
|
||||
},
|
||||
netflix = {
|
||||
a3 = {
|
||||
name = 'netflix',
|
||||
des = 'Netflix Domain'
|
||||
},
|
||||
disney = {
|
||||
a4 = {
|
||||
name = 'disney',
|
||||
des = 'Disney+ Domain'
|
||||
},
|
||||
prime = {
|
||||
a5 = {
|
||||
name = 'prime',
|
||||
des = 'Prime Video Domain'
|
||||
},
|
||||
tvb = {
|
||||
a6 = {
|
||||
name = 'tvb',
|
||||
des = 'TVB Domain'
|
||||
},
|
||||
custom = {
|
||||
a7 = {
|
||||
name = 'custom',
|
||||
des = 'Custom Domain'
|
||||
}
|
||||
@ -39,6 +39,7 @@ for _, v in pairs(router_table) do
|
||||
local conf = '/etc/vssr/'.. v.name ..'_domain.list'
|
||||
o = s:taboption(v.name, TextValue, v.name ..'conf')
|
||||
o.rows = 13
|
||||
o.description = translate('↑ Put your domain list here')
|
||||
o.wrap = 'off'
|
||||
o.rmempty = true
|
||||
o.cfgvalue = function(self, section)
|
||||
@ -50,6 +51,23 @@ for _, v in pairs(router_table) do
|
||||
o.remove = function(self, section, value)
|
||||
NXFS.writefile(conf, '')
|
||||
end
|
||||
|
||||
|
||||
local conf1 = '/etc/vssr/'.. v.name ..'_ip.list'
|
||||
o = s:taboption(v.name, TextValue, v.name ..'conf1')
|
||||
o.rows = 13
|
||||
o.wrap = 'off'
|
||||
o.description = translate('↑ Put your IP list here')
|
||||
o.rmempty = true
|
||||
o.cfgvalue = function(self, section)
|
||||
return NXFS.readfile(conf1) or ' '
|
||||
end
|
||||
o.write = function(self, section, value)
|
||||
NXFS.writefile(conf1, value:gsub('\r\n', '\n'))
|
||||
end
|
||||
o.remove = function(self, section, value)
|
||||
NXFS.writefile(conf1, '')
|
||||
end
|
||||
end
|
||||
|
||||
return m
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
local vssr = 'vssr'
|
||||
local uci = luci.model.uci.cursor()
|
||||
local server_table = {}
|
||||
|
||||
local gfwmode = 0
|
||||
local gfw_count = 0
|
||||
local ip_count = 0
|
||||
local ad_count = 0
|
||||
local server_count = 0
|
||||
|
||||
local sys = require 'luci.sys'
|
||||
|
||||
uci:foreach(
|
||||
'vssr',
|
||||
'servers',
|
||||
function(s)
|
||||
server_count = server_count + 1
|
||||
end
|
||||
)
|
||||
|
||||
m = Map(vssr)
|
||||
|
||||
-- [[ 节点订阅 ]]--
|
||||
|
||||
s = m:section(TypedSection, 'server_subscribe', translate('Servers subscription and manage'))
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(Flag, 'auto_update', translate('Auto Update'))
|
||||
o.rmempty = false
|
||||
o.description = translate('Auto Update Server subscription, GFW list and CHN route')
|
||||
|
||||
o = s:option(ListValue, 'auto_update_time', translate('Update time (every day)'))
|
||||
for t = 0, 23 do
|
||||
o:value(t, t .. ':00')
|
||||
end
|
||||
o.default = 2
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(DynamicList, 'subscribe_url', translate('Subscribe URL'))
|
||||
o.rmempty = true
|
||||
o.description = translate('You can manually add group names in front of the URL, splited by ,')
|
||||
|
||||
o = s:option(Value, 'filter_words', translate('Subscribe Filter Words'))
|
||||
o.rmempty = true
|
||||
o.description = translate('Filter Words splited by /')
|
||||
|
||||
o = s:option(Flag, 'proxy', translate('Through proxy update'))
|
||||
o.rmempty = false
|
||||
o.description = translate('Through proxy update list, Not Recommended ')
|
||||
|
||||
o = s:option(DummyValue, '', '')
|
||||
o.rawhtml = true
|
||||
o.template = 'vssr/update_subscribe'
|
||||
|
||||
o = s:option(Button, 'delete', translate('Delete All Subscribe Severs'))
|
||||
o.inputstyle = 'reset'
|
||||
o.description = string.format(translate('Server Count') .. ': %d', server_count)
|
||||
o.write = function()
|
||||
uci:delete_all(
|
||||
'vssr',
|
||||
'servers',
|
||||
function(s)
|
||||
if s.hashkey or s.isSubscribe then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
)
|
||||
uci:save('vssr')
|
||||
uci:commit('vssr')
|
||||
luci.sys.exec('/etc/init.d/vssr restart')
|
||||
luci.http.redirect(luci.dispatcher.build_url('admin', 'services', 'vssr', 'servers'))
|
||||
return
|
||||
end
|
||||
|
||||
return m
|
||||
@ -2,304 +2,305 @@
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
|
||||
const GET_FLAG_URL = '<%=luci.dispatcher.build_url("admin", "services", "vssr","flag")%>';
|
||||
var sid;
|
||||
const GET_FLAG_URL = '<%=luci.dispatcher.build_url("admin", "services", "vssr","flag")%>';
|
||||
var sid;
|
||||
|
||||
function getFlag(remark, hosts, sid) {
|
||||
XHR.get(GET_FLAG_URL,
|
||||
{ host: hosts, remark: remark },
|
||||
function (x, rv) {
|
||||
el('.flag').value = rv.flag.replace(/[\r\n]/g, "");
|
||||
function getFlag(remark, hosts, sid) {
|
||||
XHR.get(GET_FLAG_URL,
|
||||
{ host: hosts, remark: remark },
|
||||
function (x, rv) {
|
||||
el('.flag').value = rv.flag.replace(/[\r\n]/g, "");
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
function padright(str, cnt, pad) {
|
||||
return str + Array(cnt + 1).join(pad);
|
||||
}
|
||||
function b64EncodeUnicode(str) {
|
||||
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
|
||||
return String.fromCharCode('0x' + p1);
|
||||
}));
|
||||
}
|
||||
function b64encutf8safe(str) {
|
||||
return b64EncodeUnicode(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '');
|
||||
}
|
||||
function b64DecodeUnicode(str) {
|
||||
return decodeURIComponent(Array.prototype.map.call(atob(str), function (c) {
|
||||
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||
}).join(''));
|
||||
}
|
||||
function b64decutf8safe(str) {
|
||||
var l;
|
||||
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
||||
l = str.length;
|
||||
l = (4 - l % 4) % 4;
|
||||
if (l)
|
||||
str = padright(str, l, "=");
|
||||
return b64DecodeUnicode(str);
|
||||
}
|
||||
function b64encsafe(str) {
|
||||
return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '')
|
||||
}
|
||||
function b64decsafe(str) {
|
||||
var l;
|
||||
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
||||
l = str.length;
|
||||
l = (4 - l % 4) % 4;
|
||||
if (l)
|
||||
str = padright(str, l, "=");
|
||||
try {
|
||||
return atob(str);
|
||||
} catch (err) {
|
||||
return str;
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
function padright(str, cnt, pad) {
|
||||
return str + Array(cnt + 1).join(pad);
|
||||
}
|
||||
function b64EncodeUnicode(str) {
|
||||
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
|
||||
return String.fromCharCode('0x' + p1);
|
||||
}));
|
||||
}
|
||||
function b64encutf8safe(str) {
|
||||
return b64EncodeUnicode(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '');
|
||||
}
|
||||
function b64DecodeUnicode(str) {
|
||||
return decodeURIComponent(Array.prototype.map.call(atob(str), function (c) {
|
||||
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||
}).join(''));
|
||||
}
|
||||
function b64decutf8safe(str) {
|
||||
var l;
|
||||
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
||||
l = str.length;
|
||||
l = (4 - l % 4) % 4;
|
||||
if (l)
|
||||
str = padright(str, l, "=");
|
||||
return b64DecodeUnicode(str);
|
||||
}
|
||||
function b64encsafe(str) {
|
||||
return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '')
|
||||
}
|
||||
function b64decsafe(str) {
|
||||
var l;
|
||||
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
||||
l = str.length;
|
||||
l = (4 - l % 4) % 4;
|
||||
if (l)
|
||||
str = padright(str, l, "=");
|
||||
try {
|
||||
return atob(str);
|
||||
} catch (err) {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
function dictvalue(d, key) {
|
||||
var v = d[key];
|
||||
if (typeof (v) == 'undefined' || v == '')
|
||||
return '';
|
||||
return b64decsafe(v);
|
||||
}
|
||||
|
||||
function el(id) {
|
||||
return document.getElementById('cbid.vssr.' + sid + id);
|
||||
}
|
||||
|
||||
function import_ssr_url(btn, urlname, sids) {
|
||||
sid = sids;
|
||||
var s = document.getElementById(urlname + '-status');
|
||||
if (!s)
|
||||
return false;
|
||||
var ssrurl = prompt("<%:Paste Node Link Here%> ssr:// | ss:// | vmess:// | trojan://", "");
|
||||
if (ssrurl == null || ssrurl == "") {
|
||||
s.innerHTML = "<font color='red'><%:User Cancel%></font>";
|
||||
return false;
|
||||
}
|
||||
s.innerHTML = "";
|
||||
//var ssu = ssrurl.match(/ssr:\/\/([A-Za-z0-9_-]+)/i);
|
||||
var ssu = ssrurl.split('://');
|
||||
console.log(ssu.length);
|
||||
if ((ssu[0] != "ssr" && ssu[0] != "ss" && ssu[0] != "vmess" && ssu[0] != "trojan") || ssu[1] == "") {
|
||||
s.innerHTML = "<font color='red'><%:Invalid Format%></font>";
|
||||
return false;
|
||||
function dictvalue(d, key) {
|
||||
var v = d[key];
|
||||
if (typeof (v) == 'undefined' || v == '')
|
||||
return '';
|
||||
return b64decsafe(v);
|
||||
}
|
||||
|
||||
function el(id) {
|
||||
return document.getElementById('cbid.vssr.' + sid + id);
|
||||
}
|
||||
|
||||
var event = document.createEvent("HTMLEvents");
|
||||
event.initEvent("change", true, true);
|
||||
var rema = "";
|
||||
if (ssu[0] == "ssr") {
|
||||
var sstr = b64decsafe(ssu[1]);
|
||||
var ploc = sstr.indexOf("/?");
|
||||
|
||||
el('.type').value = "ssr";
|
||||
el('.type').dispatchEvent(event);
|
||||
var url0, param = "";
|
||||
if (ploc > 0) {
|
||||
url0 = sstr.substr(0, ploc);
|
||||
param = sstr.substr(ploc + 2);
|
||||
}
|
||||
var ssm = url0.match(/^(.+):([^:]+):([^:]*):([^:]+):([^:]*):([^:]+)/);
|
||||
if (!ssm || ssm.length < 7)
|
||||
function import_ssr_url(btn, urlname, sids) {
|
||||
sid = sids;
|
||||
var s = document.getElementById(urlname + '-status');
|
||||
if (!s)
|
||||
return false;
|
||||
var ssrurl = prompt("<%:Paste Node Link Here%> ssr:// | ss:// | vmess:// | trojan://", "");
|
||||
if (ssrurl == null || ssrurl == "") {
|
||||
s.innerHTML = "<font color='red'><%:User Cancel%></font>";
|
||||
return false;
|
||||
var pdict = {};
|
||||
if (param.length > 2) {
|
||||
var a = param.split('&');
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
var b = a[i].split('=');
|
||||
pdict[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || '');
|
||||
}
|
||||
}
|
||||
el('.server').value = ssm[1];
|
||||
el('.server_port').value = ssm[2];
|
||||
el('.protocol').value = ssm[3];
|
||||
el('.encrypt_method').value = ssm[4];
|
||||
el('.obfs').value = ssm[5];
|
||||
el('.password').value = b64decsafe(ssm[6]);
|
||||
el('.obfs_param').value = dictvalue(pdict, 'obfsparam');
|
||||
el('.protocol_param').value = dictvalue(pdict, 'protoparam');
|
||||
s.innerHTML = "";
|
||||
//var ssu = ssrurl.match(/ssr:\/\/([A-Za-z0-9_-]+)/i);
|
||||
var ssu = ssrurl.split('://');
|
||||
console.log(ssu.length);
|
||||
|
||||
var rem = pdict['remarks'];
|
||||
if (typeof (rem) != 'undefined' && rem != '' && rem.length > 0)
|
||||
rema = b64decutf8safe(rem);
|
||||
el('.alias').value = b64decutf8safe(rem);
|
||||
getFlag(rema, ssm[1], sid); //get flag iso code
|
||||
s.innerHTML = "<font color='green'><%:Import%>ShadowsocksR<%:Configuration Succeeded%></font>";
|
||||
return false;
|
||||
} else if (ssu[0] == "ss") {
|
||||
var url0, param = "";
|
||||
var sipIndex = ssu[1].indexOf("@");
|
||||
var ploc = ssu[1].indexOf("#");
|
||||
if (ploc > 0) {
|
||||
url0 = ssu[1].substr(0, ploc);
|
||||
param = ssu[1].substr(ploc + 1);
|
||||
} else {
|
||||
url0 = ssu[1];
|
||||
}
|
||||
var event = document.createEvent("HTMLEvents");
|
||||
event.initEvent("change", true, true);
|
||||
var rema = "";
|
||||
switch (ssu[0]) {
|
||||
case "ssr":
|
||||
var sstr = b64decsafe(ssu[1]);
|
||||
var ploc = sstr.indexOf("/?");
|
||||
el('.type').value = "ssr";
|
||||
el('.type').dispatchEvent(event);
|
||||
var url0, param = "";
|
||||
if (ploc > 0) {
|
||||
url0 = sstr.substr(0, ploc);
|
||||
param = sstr.substr(ploc + 2);
|
||||
}
|
||||
var ssm = url0.match(/^(.+):([^:]+):([^:]*):([^:]+):([^:]*):([^:]+)/);
|
||||
if (!ssm || ssm.length < 7)
|
||||
return false;
|
||||
var pdict = {};
|
||||
if (param.length > 2) {
|
||||
var a = param.split('&');
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
var b = a[i].split('=');
|
||||
pdict[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || '');
|
||||
}
|
||||
}
|
||||
el('.server').value = ssm[1];
|
||||
el('.server_port').value = ssm[2];
|
||||
el('.protocol').value = ssm[3];
|
||||
el('.encrypt_method').value = ssm[4];
|
||||
el('.obfs').value = ssm[5];
|
||||
el('.password').value = b64decsafe(ssm[6]);
|
||||
el('.obfs_param').value = dictvalue(pdict, 'obfsparam');
|
||||
el('.protocol_param').value = dictvalue(pdict, 'protoparam');
|
||||
|
||||
if (sipIndex != -1) {
|
||||
// SIP002
|
||||
var userInfo = b64decsafe(url0.substr(0, sipIndex));
|
||||
var temp = url0.substr(sipIndex + 1).split("/?");
|
||||
var serverInfo = temp[0].split(":");
|
||||
var server = serverInfo[0];
|
||||
var port = serverInfo[1];
|
||||
var method, password, plugin, pluginOpts;
|
||||
if (temp[1]) {
|
||||
var pluginInfo = decodeURIComponent(temp[1]);
|
||||
var pluginIndex = pluginInfo.indexOf(";");
|
||||
var pluginNameInfo = pluginInfo.substr(0, pluginIndex);
|
||||
plugin = pluginNameInfo.substr(pluginNameInfo.indexOf("=") + 1)
|
||||
pluginOpts = pluginInfo.substr(pluginIndex + 1);
|
||||
}
|
||||
var rem = pdict['remarks'];
|
||||
if (typeof (rem) != 'undefined' && rem != '' && rem.length > 0)
|
||||
rema = b64decutf8safe(rem);
|
||||
el('.alias').value = b64decutf8safe(rem);
|
||||
getFlag(rema, ssm[1], sid); //get flag iso code
|
||||
s.innerHTML = "<font color='green'><%:Import%>ShadowsocksR<%:Configuration Succeeded%></font>";
|
||||
break;
|
||||
case "ss":
|
||||
var url0, param = "";
|
||||
var sipIndex = ssu[1].indexOf("@");
|
||||
var ploc = ssu[1].indexOf("#");
|
||||
if (ploc > 0) {
|
||||
url0 = ssu[1].substr(0, ploc);
|
||||
param = ssu[1].substr(ploc + 1);
|
||||
} else {
|
||||
url0 = ssu[1];
|
||||
}
|
||||
|
||||
var userInfoSplitIndex = userInfo.indexOf(":");
|
||||
if (userInfoSplitIndex != -1) {
|
||||
method = userInfo.substr(0, userInfoSplitIndex);
|
||||
password = userInfo.substr(userInfoSplitIndex + 1);
|
||||
}
|
||||
el('.type').value = "ss";
|
||||
el('.type').dispatchEvent(event);
|
||||
el('.server').value = server;
|
||||
el('.server_port').value = port;
|
||||
el('.password').value = password || "";
|
||||
el('.encrypt_method_ss').value = method || "";
|
||||
el('.plugin').value = plugin || "";
|
||||
el('.plugin_opts').value = pluginOpts || "";
|
||||
} else {
|
||||
var sstr = b64decsafe(url0);
|
||||
el('.type').value = "ss";
|
||||
el('.type').dispatchEvent(event);
|
||||
var team = sstr.split('@');
|
||||
console.log(param);
|
||||
var part1 = team[0].split(':');
|
||||
var part2 = team[1].split(':');
|
||||
el('.server').value = part2[0];
|
||||
el('.server_port').value = part2[1];
|
||||
el('.password').value = part1[1];
|
||||
el('.encrypt_method_ss').value = part1[0];
|
||||
el('.plugin').value = "";
|
||||
el('.plugin_opts').value = "";
|
||||
}
|
||||
if (sipIndex != -1) {
|
||||
// SIP002
|
||||
var userInfo = b64decsafe(url0.substr(0, sipIndex));
|
||||
var temp = url0.substr(sipIndex + 1).split("/?");
|
||||
if(temp.length == 1){
|
||||
temp = url0.substr(sipIndex + 1).split("?");
|
||||
}
|
||||
var serverInfo = temp[0].split(":");
|
||||
var server = serverInfo[0];
|
||||
var port = serverInfo[1];
|
||||
var method, password, plugin, pluginOpts;
|
||||
if (temp[1]) {
|
||||
var pluginInfo = decodeURIComponent(temp[1]);
|
||||
var pluginIndex = pluginInfo.indexOf(";");
|
||||
var pluginNameInfo = pluginInfo.substr(0, pluginIndex);
|
||||
plugin = pluginNameInfo.substr(pluginNameInfo.indexOf("=") + 1)
|
||||
pluginOpts = pluginInfo.substr(pluginIndex + 1);
|
||||
}
|
||||
|
||||
if (param != undefined) {
|
||||
rema = decodeURI(param)
|
||||
el('.alias').value = decodeURI(param);
|
||||
}
|
||||
getFlag(rema, server, sid); //get flag iso code
|
||||
s.innerHTML = "<font color='green'><%:Import%>Shadowsocks<%:Configuration Succeeded%></font>";
|
||||
return false;
|
||||
} else if (ssu[0] == "trojan") {
|
||||
var ploc = ssu[1].indexOf("#");
|
||||
if (ploc > 0) {
|
||||
url0 = ssu[1].substr(0, ploc);
|
||||
param = ssu[1].substr(ploc + 1);
|
||||
} else {
|
||||
url0 = ssu[1]
|
||||
}
|
||||
var sstr = b64decsafe(url0);
|
||||
el('.type').value = "trojan";
|
||||
el('.type').dispatchEvent(event);
|
||||
var team = sstr.split('@');
|
||||
console.log(team);
|
||||
var part1 = team[0].split(':');
|
||||
var part2 = team[1].split(':');
|
||||
var others = part2[1].split('?');
|
||||
var queryParam = {}
|
||||
if (others.length > 1) {
|
||||
var queryParams = others[1]
|
||||
var queryArray = queryParams.split('&')
|
||||
for (i = 0; i < queryArray.length; i++) {
|
||||
var params = queryArray[i].split('=');
|
||||
queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || '');
|
||||
}
|
||||
}
|
||||
el('.server').value = part2[0];
|
||||
el('.server_port').value = others[0];
|
||||
el('.password').value = part1[0];
|
||||
if (queryParam.peer || queryParam.sni) {
|
||||
el('.tls').checked = true;
|
||||
el('.peer').value = queryParam.peer || queryParam.sni;
|
||||
}
|
||||
var userInfoSplitIndex = userInfo.indexOf(":");
|
||||
if (userInfoSplitIndex != -1) {
|
||||
method = userInfo.substr(0, userInfoSplitIndex);
|
||||
password = userInfo.substr(userInfoSplitIndex + 1);
|
||||
}
|
||||
el('.type').value = "ss";
|
||||
el('.type').dispatchEvent(event);
|
||||
el('.server').value = server;
|
||||
el('.server_port').value = port;
|
||||
el('.password').value = password || "";
|
||||
el('.encrypt_method_ss').value = method || "";
|
||||
el('.plugin').value = plugin || "";
|
||||
el('.plugin_opts').value = pluginOpts || "";
|
||||
} else {
|
||||
var sstr = b64decsafe(url0);
|
||||
el('.type').value = "ss";
|
||||
el('.type').dispatchEvent(event);
|
||||
var team = sstr.split('@');
|
||||
console.log(param);
|
||||
var part1 = team[0].split(':');
|
||||
var part2 = team[1].split(':');
|
||||
el('.server').value = part2[0];
|
||||
el('.server_port').value = part2[1];
|
||||
el('.password').value = part1[1];
|
||||
el('.encrypt_method_ss').value = part1[0];
|
||||
el('.plugin').value = "";
|
||||
el('.plugin_opts').value = "";
|
||||
}
|
||||
|
||||
if (param != undefined) {
|
||||
rema = decodeURI(param)
|
||||
el('.alias').value = decodeURI(param);
|
||||
}
|
||||
getFlag(rema, part2[0], sid); //get flag iso code
|
||||
if (param != undefined) {
|
||||
rema = decodeURI(param)
|
||||
el('.alias').value = decodeURI(param);
|
||||
}
|
||||
getFlag(rema, server, sid); //get flag iso code
|
||||
s.innerHTML = "<font color='green'><%:Import%>Shadowsocks<%:Configuration Succeeded%></font>";
|
||||
break;
|
||||
case "trojan":
|
||||
var ploc = ssu[1].indexOf("#");
|
||||
if (ploc > 0) {
|
||||
url0 = ssu[1].substr(0, ploc);
|
||||
param = ssu[1].substr(ploc + 1);
|
||||
} else {
|
||||
url0 = ssu[1]
|
||||
}
|
||||
var sstr = b64decsafe(url0);
|
||||
el('.type').value = "trojan";
|
||||
el('.type').dispatchEvent(event);
|
||||
var team = sstr.split('@');
|
||||
console.log(team);
|
||||
var part1 = team[0].split(':');
|
||||
var part2 = team[1].split(':');
|
||||
var others = part2[1].split('?');
|
||||
var queryParam = {}
|
||||
if (others.length > 1) {
|
||||
var queryParams = others[1]
|
||||
var queryArray = queryParams.split('&')
|
||||
for (i = 0; i < queryArray.length; i++) {
|
||||
var params = queryArray[i].split('=');
|
||||
queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || '');
|
||||
}
|
||||
}
|
||||
el('.server').value = part2[0];
|
||||
el('.server_port').value = others[0];
|
||||
el('.password').value = part1[0];
|
||||
if (queryParam.peer || queryParam.sni) {
|
||||
el('.tls').checked = true;
|
||||
el('.peer').value = queryParam.peer || queryParam.sni;
|
||||
}
|
||||
|
||||
s.innerHTML = "<font color='green'>导入Trojan<%:Configuration Succeeded%></font>";
|
||||
return false;
|
||||
} else if (ssu[0] == "vmess") {
|
||||
var sstr = b64DecodeUnicode(ssu[1]);
|
||||
var ploc = sstr.indexOf("/?");
|
||||
el('.type').value = "v2ray";
|
||||
el('.type').dispatchEvent(event);
|
||||
var url0, param = "";
|
||||
if (ploc > 0) {
|
||||
url0 = sstr.substr(0, ploc);
|
||||
param = sstr.substr(ploc + 2);
|
||||
}
|
||||
var ssm = JSON.parse(sstr);
|
||||
el('.alias').value = ssm.ps;
|
||||
el('.server').value = ssm.add;
|
||||
el('.server_port').value = ssm.port;
|
||||
el('.alter_id').value = ssm.aid;
|
||||
el('.vmess_id').value = ssm.id;
|
||||
el('.transport').value = ssm.net;
|
||||
el('.transport').dispatchEvent(event);
|
||||
if (ssm.net == "tcp") {
|
||||
try {
|
||||
el('.http_host').value = ssm.host;
|
||||
el('.http_path').value = ssm.path;
|
||||
} catch (err) { }
|
||||
if (param != undefined) {
|
||||
rema = decodeURI(param)
|
||||
el('.alias').value = decodeURI(param);
|
||||
}
|
||||
getFlag(rema, part2[0], sid); //get flag iso code
|
||||
|
||||
s.innerHTML = "<font color='green'>导入Trojan<%:Configuration Succeeded%></font>";
|
||||
break;
|
||||
case "vmess":
|
||||
var sstr = b64DecodeUnicode(ssu[1]);
|
||||
var ploc = sstr.indexOf("/?");
|
||||
el('.type').value = "v2ray";
|
||||
el('.type').dispatchEvent(event);
|
||||
var url0, param = "";
|
||||
if (ploc > 0) {
|
||||
url0 = sstr.substr(0, ploc);
|
||||
param = sstr.substr(ploc + 2);
|
||||
}
|
||||
var ssm = JSON.parse(sstr);
|
||||
el('.alias').value = ssm.ps;
|
||||
el('.server').value = ssm.add;
|
||||
el('.server_port').value = ssm.port;
|
||||
el('.alter_id').value = ssm.aid;
|
||||
el('.vmess_id').value = ssm.id;
|
||||
el('.transport').value = ssm.net;
|
||||
el('.transport').dispatchEvent(event);
|
||||
if (ssm.net == "tcp") {
|
||||
try {
|
||||
el('.http_host').value = ssm.host;
|
||||
el('.http_path').value = ssm.path;
|
||||
} catch (err) { }
|
||||
|
||||
}
|
||||
if (ssm.net == "ws") {
|
||||
try {
|
||||
el('.ws_host').value = ssm.host;
|
||||
el('.ws_path').value = ssm.path;
|
||||
} catch (err) { }
|
||||
}
|
||||
if (ssm.net == "h2") {
|
||||
try {
|
||||
el('.h2_host').value = ssm.host;
|
||||
el('.h2_path').value = ssm.path;
|
||||
} catch (err) { }
|
||||
}
|
||||
if (ssm.net == "quic") {
|
||||
try {
|
||||
el('.quic_security').value = ssm.securty;
|
||||
el('.quic_key').value = ssm.key;
|
||||
} catch (err) { }
|
||||
}
|
||||
if (ssm.net == "kcp") {
|
||||
try {
|
||||
el('.kcp_guise').value = ssm.type;
|
||||
} catch (err) { }
|
||||
try {
|
||||
el('.seed').value = ssm.seed;
|
||||
} catch (err) { }
|
||||
}
|
||||
if (ssm.tls == "tls") {
|
||||
try {
|
||||
el('.tls').checked = true;
|
||||
el('.tls').dispatchEvent(event);
|
||||
el('.tls_host').value = ssm.host;
|
||||
} catch (err) { }
|
||||
}
|
||||
el('.mux').checked = true;
|
||||
el('.mux').dispatchEvent(event);
|
||||
|
||||
getFlag(ssm.ps, ssm.add, sid); //get flag iso code
|
||||
|
||||
s.innerHTML = "<font color='green'><%:Import%>V2ray<%:Configuration Succeeded%></font>";
|
||||
break;
|
||||
default:
|
||||
s.innerHTML = "<font color='red'><%:Invalid Format%></font>";
|
||||
|
||||
}
|
||||
if (ssm.net == "ws") {
|
||||
try {
|
||||
el('.ws_host').value = ssm.host;
|
||||
el('.ws_path').value = ssm.path;
|
||||
} catch (err) { }
|
||||
}
|
||||
if (ssm.net == "h2") {
|
||||
try {
|
||||
el('.h2_host').value = ssm.host;
|
||||
el('.h2_path').value = ssm.path;
|
||||
} catch (err) { }
|
||||
}
|
||||
if (ssm.net == "quic") {
|
||||
try {
|
||||
el('.quic_security').value = ssm.securty;
|
||||
el('.quic_key').value = ssm.key;
|
||||
} catch (err) { }
|
||||
}
|
||||
if (ssm.net == "kcp") {
|
||||
try {
|
||||
el('.kcp_guise').value = ssm.type;
|
||||
} catch (err) { }
|
||||
try {
|
||||
el('.seed').value = ssm.seed;
|
||||
} catch (err) { }
|
||||
}
|
||||
if (ssm.tls == "tls") {
|
||||
try {
|
||||
el('.tls').checked = true;
|
||||
el('.tls').dispatchEvent(event);
|
||||
el('.tls_host').value = ssm.host;
|
||||
} catch (err) { }
|
||||
}
|
||||
el('.mux').checked = true;
|
||||
el('.mux').dispatchEvent(event);
|
||||
|
||||
getFlag(ssm.ps, ssm.add, sid); //get flag iso code
|
||||
|
||||
s.innerHTML = "<font color='green'><%:Import%>V2ray<%:Configuration Succeeded%></font>";
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//]]></script>
|
||||
|
||||
<input type="button" class="cbi-button cbi-button-apply" value="<%:Import Configuration%>"
|
||||
|
||||
@ -26,6 +26,9 @@
|
||||
function resize() {
|
||||
wW = $(window).width();
|
||||
lw = $(".main-left").width()
|
||||
if(lw == undefined){
|
||||
lw = 0;
|
||||
}
|
||||
$(".status-bar").width(wW - lw);
|
||||
$(".status-bar .flag").width($(".status-bar .flag").height() / 3 * 4);
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<% math.randomseed(os.time()) %>
|
||||
<link rel="stylesheet" href="/luci-static/vssr/css/vssr.css?v=<%=math.random(1,100000)%>">
|
||||
|
||||
<script src="<%=media%>/js/jquery.min.js"></script>
|
||||
<script src="/luci-static/vssr/jquery.min.js"></script>
|
||||
|
||||
<div class="pure-g status">
|
||||
<div class="pure-u-1-4">
|
||||
|
||||
@ -3,87 +3,113 @@
|
||||
<script type="text/javascript" src="/luci-static/vssr/polyfill.js?v=1.16"></script>
|
||||
<!-- tblsection -->
|
||||
<fieldset class="cbi-section" id="cbi-<%=self.config%>-<%=self.sectiontype%>">
|
||||
<button class="cbi-button cbi-button-check "><%:Ping All Servers%></button><span class="panel-title">总计
|
||||
<%- print(self.des)-%>个节点</span>
|
||||
<div class="ssr-title">
|
||||
<button class="cbi-button cbi-button-check ">
|
||||
<%:Ping All Servers%>
|
||||
</button><span class="panel-title">总计
|
||||
<%- print(self.des)-%>个节点
|
||||
</span>
|
||||
<div style="clear:both;"></div>
|
||||
</div>
|
||||
|
||||
<div class="cbi-section-node">
|
||||
<%- local count = 0 -%>
|
||||
<div class="cbi-section-table pure-g p-in5">
|
||||
<%- local count=0 -%>
|
||||
|
||||
<div class="cbi-section-table pure-g p-in5">
|
||||
|
||||
<%- local isempty=true for i, k in ipairs(self.serverTable) do section=k isempty=false local
|
||||
fc=(section.name==self.current) and "fast" or "" local flag_icon=(section.flag ~=nil)
|
||||
and "flag-icon-" .. section.flag or "flag-icon-un" local switch_enable=(section.switch_enable=="1" )
|
||||
and "" or "hidden" scope={ valueheader="cbi/cell_valueheader" , valuefooter="cbi/cell_valuefooter" }
|
||||
-%>
|
||||
|
||||
<%- local isempty = true
|
||||
for i, k in ipairs(self.serverTable) do
|
||||
section = k
|
||||
isempty = false
|
||||
local fc = (section.name == self.current) and "fast" or ""
|
||||
local flag_icon = (section.flag ~= nil) and "flag-icon-" .. section.flag or "flag-icon-un"
|
||||
local switch_enable = (section.switch_enable == "1") and "" or "hidden"
|
||||
scope = { valueheader = "cbi/cell_valueheader", valuefooter = "cbi/cell_valuefooter" }
|
||||
-%>
|
||||
|
||||
<div class="pure-u-1-5">
|
||||
<div class="cbi-section-table-row <%=fc %> " id="cbi-<%=self.config%>-<%=section.name%>" data-flag="<%=section.flag%>" server="<%=section.server%>" server_port="<%=section.server_port%>">
|
||||
<div class="loadings hide"></div>
|
||||
<div class="incon type flag-icon <%=flag_icon %>" data-setction="<%=section.name%>">
|
||||
<img class="pure-imgw <%=switch_enable %>" src="/luci-static/vssr/img/switch.png">
|
||||
<div class="tp"><%=section.type%></div>
|
||||
</div>
|
||||
<div class="incon alias"><%=section.alias%></div>
|
||||
<%- if self.extedit or self.addremove then -%>
|
||||
<div class="cbi-section-table-cell">
|
||||
<div class="host_con"></div>
|
||||
<a class="cbi-button ssr-button" type="button" value="" onclick="apply_node('<%=section.name%>')"
|
||||
alt="<%:Apply%>" title="<%:Apply%>"><span class="icon-use"></span> <%:Apply%></a>
|
||||
<%- if self.extedit then -%>
|
||||
<a class="cbi-button ssr-button " type="button" value="" <%- if type(self.extedit) == "string" then
|
||||
%> onclick="location.href='<%=self.extedit:format(section.name)%>'" <%- elseif type(self.extedit) == "function" then
|
||||
%> onclick="location.href='<%=self:extedit(section.name)%>'" <%- end
|
||||
%> alt="<%:Edit%>" title="<%:Edit%>"><span class="icon-edit"></span> <%:Edit%></a>
|
||||
<%- end; if self.addremove then %>
|
||||
<a class="cbi-button ssr-button" type="button" value="" onclick="delete_node('<%=section.name%>')"
|
||||
alt="<%:Delete%>" title="<%:Delete%>" /><span
|
||||
class="icon-delete"></span> <%:Delete%></a>
|
||||
<%- end -%>
|
||||
<div class="pure-u-1-5">
|
||||
<div class="cbi-section-table-row <%=fc %> " id="cbi-<%=self.config%>-<%=section.name%>"
|
||||
data-flag="<%=section.flag%>" server="<%=section.server%>"
|
||||
server_port="<%=section.server_port%>">
|
||||
<div class="loadings hide"></div>
|
||||
<div class="incon type flag-icon <%=flag_icon %>" data-setction="<%=section.name%>">
|
||||
<img class="pure-imgw <%=switch_enable %>" src="/luci-static/vssr/img/switch.png">
|
||||
<div class="tp">
|
||||
<%=section.type%>
|
||||
</div>
|
||||
</div>
|
||||
<div class=" alias">
|
||||
<%=section.alias%>
|
||||
</div>
|
||||
<%- if self.extedit or self.addremove then -%>
|
||||
<div class="cbi-section-table-cell">
|
||||
<div class="host_con"></div>
|
||||
<a class="cbi-button ssr-button" type="button" value=""
|
||||
onclick="apply_node('<%=section.name%>')" alt="<%:Apply%>"
|
||||
title="<%:Apply%>"><span class="icon-use"></span>
|
||||
<%:Apply%>
|
||||
</a>
|
||||
<%- if self.extedit then -%>
|
||||
<a class="cbi-button ssr-button " type="button" value="" <%- if type(self.extedit) == "string" then
|
||||
%> onclick="location.href='<%=self.extedit:format(section.name)%>'" <%- elseif type(self.extedit) == "function" then
|
||||
%> onclick="location.href='<%=self:extedit(section.name)%>'" <%- end
|
||||
%> alt="<%:Edit%>" title="<%:Edit%>"><span class="icon-edit"></span> <%:Edit%></a>
|
||||
<%- end; if self.addremove then %>
|
||||
<a class="cbi-button ssr-button" type="button" value=""
|
||||
onclick="delete_node('<%=section.name%>')" alt="<%:Delete%>"
|
||||
title="<%:Delete%>" /><span class="icon-delete"></span>
|
||||
<%:Delete%></a>
|
||||
<%- end -%>
|
||||
</div>
|
||||
<%- end -%>
|
||||
</div>
|
||||
</div>
|
||||
<%- end -%>
|
||||
|
||||
<%- if isempty then -%>
|
||||
<div class="cbi-section-table-row">
|
||||
<div colspan="<%=count%>"><em><br />
|
||||
<%:This section contains no values yet%>
|
||||
</em></div>
|
||||
</div>
|
||||
<%- end -%>
|
||||
</div>
|
||||
|
||||
<% if self.error then %>
|
||||
<div class="cbi-section-error">
|
||||
<ul>
|
||||
<% for _, c in pairs(self.error) do for _, e in ipairs(c) do -%>
|
||||
<li>
|
||||
<%=pcdata(e):gsub("\n","<br />")%>
|
||||
</li>
|
||||
<%- end end %>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<%- end -%>
|
||||
<% end %>
|
||||
|
||||
<%- if isempty then -%>
|
||||
<div class="cbi-section-table-row">
|
||||
<div colspan="<%=count%>"><em><br /><%:This section contains no values yet%></em></div>
|
||||
</div>
|
||||
<%- end -%>
|
||||
</div>
|
||||
|
||||
<% if self.error then %>
|
||||
<div class="cbi-section-error">
|
||||
<ul><% for _, c in pairs(self.error) do for _, e in ipairs(c) do -%>
|
||||
<li><%=pcdata(e):gsub("\n","<br />")%></li>
|
||||
<%- end end %></ul>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%- if self.addremove then -%>
|
||||
<% if self.template_addremove then include(self.template_addremove) else -%>
|
||||
<div class="cbi-section-create cbi-tblsection-create">
|
||||
<% if self.anonymous then %>
|
||||
<input class="cbi-button cbi-button-add" type="submit" value="<%:Add%>"
|
||||
name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" title="<%:Add%>" />
|
||||
<% else %>
|
||||
<% if self.invalid_cts then -%><div class="cbi-section-error"><% end %>
|
||||
<input type="text" class="cbi-section-create-name"
|
||||
id="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>"
|
||||
name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" data-type="uciname"
|
||||
data-optional="true" />
|
||||
<input class="cbi-button cbi-button-add" type="submit"
|
||||
onclick="this.form.cbi_state = 'add-section'; return true" value="<%:Add%>" title="<%:Add%>" />
|
||||
<% if self.invalid_cts then -%>
|
||||
<br /><%:Invalid%></div>
|
||||
<%- end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<%- end %>
|
||||
<%- end -%>
|
||||
<%- if self.addremove then -%>
|
||||
<% if self.template_addremove then include(self.template_addremove) else -%>
|
||||
<div class="cbi-section-create cbi-tblsection-create">
|
||||
<% if self.anonymous then %>
|
||||
<input class="cbi-button cbi-button-add" type="submit" value="<%:Add%>"
|
||||
name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>"
|
||||
title="<%:Add%>" />
|
||||
<% else %>
|
||||
<% if self.invalid_cts then -%>
|
||||
<div class="cbi-section-error">
|
||||
<% end %>
|
||||
<input type="text" class="cbi-section-create-name"
|
||||
id="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>"
|
||||
name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>"
|
||||
data-type="uciname" data-optional="true" />
|
||||
<input class="cbi-button cbi-button-add" type="submit"
|
||||
onclick="this.form.cbi_state = 'add-section'; return true"
|
||||
value="<%:Add%>" title="<%:Add%>" />
|
||||
<% if self.invalid_cts then -%>
|
||||
<br />
|
||||
<%:Invalid%>
|
||||
</div>
|
||||
<%- end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<%- end %>
|
||||
<%- end -%>
|
||||
</div>
|
||||
</fieldset>
|
||||
<!-- /tblsection -->
|
||||
@ -120,15 +146,15 @@
|
||||
$html += '<div class="pure-u-1-2"><div class="gap"><button class="cbi-button cbi-button-apply change-node" data-server="global" data-node="' + node + '"> 主服务器 </button></div></div>';
|
||||
$html += '<div class="pure-u-1-2"><div class="gap"><button class="cbi-button cbi-button-apply change-node" data-server="udp_relay" data-node="' + node + '"> UDP游戏模式 </button></div></div>';
|
||||
$html += '<div class="pure-u-1-2"><div class="gap"><button class="cbi-button cbi-button-apply change-node" data-server="youtube" data-node="' + node + '"> Youtube </button></div></div>';
|
||||
if ($('#cbi-' + CONFIG + '-' + node).attr("data-flag") == "tw") {
|
||||
//if ($('#cbi-' + CONFIG + '-' + node).attr("data-flag") == "tw") {
|
||||
$html += '<div class="pure-u-1-2"><div class="gap"><button class="cbi-button cbi-button-apply change-node" data-server="tw_video" data-node="' + node + '"> TW Video </button></div></div>';
|
||||
}
|
||||
//}
|
||||
$html += '<div class="pure-u-1-2"><div class="gap"><button class="cbi-button cbi-button-apply change-node" data-server="netflix" data-node="' + node + '"> Netflix </button></div></div>';
|
||||
$html += '<div class="pure-u-1-2"><div class="gap"><button class="cbi-button cbi-button-apply change-node" data-server="disney" data-node="' + node + '"> Diseny+ </button></div></div>';
|
||||
$html += '<div class="pure-u-1-2"><div class="gap"><button class="cbi-button cbi-button-apply change-node" data-server="prime" data-node="' + node + '"> Prime Video </button></div></div>';
|
||||
if ($('#cbi-' + CONFIG + '-' + node).attr("data-flag") == "hk") {
|
||||
//if ($('#cbi-' + CONFIG + '-' + node).attr("data-flag") == "hk") {
|
||||
$html += '<div class="pure-u-1-2"><div class="gap"><button class="cbi-button cbi-button-apply change-node" data-server="tvb" data-node="' + node + '"> TVB Video </button></div></div>';
|
||||
}
|
||||
//}
|
||||
$html += '<div class="pure-u-1-2"><div class="gap"><button class="cbi-button cbi-button-apply change-node" data-server="custom" data-node="' + node + '"> 自定义 </button></div></div>';
|
||||
$html += '</div>';
|
||||
Swal.fire({
|
||||
@ -165,9 +191,9 @@
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//删除节点
|
||||
function delete_node(node){
|
||||
function delete_node(node) {
|
||||
XHR.halt();
|
||||
$.each(ajaxArray, function (n, value) { value.abort(); }) //中断所有的ajax请求
|
||||
$.get(DELETE_NODE_URL, { node: node },
|
||||
@ -223,10 +249,7 @@
|
||||
function (data, status) {
|
||||
currentCheckCount++
|
||||
var host_con = $(target).find(".host_con");
|
||||
host_con.removeClass("fast");
|
||||
host_con.removeClass("middle");
|
||||
host_con.removeClass("slow");
|
||||
host_con.removeClass("nopass");
|
||||
host_con.removeClass("fast middle slow nopass");
|
||||
if (data.ret == 1) {
|
||||
if (data.used == "") {
|
||||
host_con.addClass("nopass");
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<%+cbi/valueheader%>
|
||||
<link rel="stylesheet" href="/luci-static/vssr/css/vssr.css?v=<%=math.random(1,100000)%>">
|
||||
<script src="/luci-static/vssr/jquery.min.js"></script>
|
||||
<label class="cbi-value-title"><%= translate("Update") %></label>
|
||||
<div class="cbi-value-field">
|
||||
<input class="cbi-button cbi-button-reload" id="update_subscribe" type="button" size="0"
|
||||
@ -7,7 +8,7 @@
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
|
||||
const SAVE_SUBSCRIBE_URL = '<%=luci.dispatcher.build_url("admin", "services", "vssr","subscribe")%>';
|
||||
const SERVERS_URL = '<%=luci.dispatcher.build_url("admin", "services", "vssr","servers")%>';
|
||||
|
||||
@ -20,14 +21,14 @@
|
||||
'<textarea cols="63" rows="28" wrap="on" readonly="readonly" id="log_content3" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"></textarea>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
|
||||
$(document).ready(function () {
|
||||
//显示并开始刷新订阅
|
||||
function update_subscribe() {
|
||||
$("body").append(modal);
|
||||
$(".modals-bg").removeClass("hide");
|
||||
setTimeout(function(){
|
||||
$(".modals").removeClass("hide");
|
||||
}, 200);
|
||||
}, 100);
|
||||
setTimeout("get_realtime_log();", 500);
|
||||
}
|
||||
//保存订阅按钮
|
||||
@ -76,7 +77,7 @@
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function get_realtime_log() {
|
||||
$.ajax({
|
||||
@ -106,7 +107,7 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<%+cbi/valuefooter%>
|
||||
|
||||
@ -128,13 +128,13 @@ msgid "SSR Server"
|
||||
msgstr "服务端"
|
||||
|
||||
msgid "vssr Server"
|
||||
msgstr "vssr 服务端"
|
||||
msgstr "Hello World 服务端"
|
||||
|
||||
msgid "vssr Server is running"
|
||||
msgstr "vssr 服务端运行中"
|
||||
msgstr "Hello World 服务端运行中"
|
||||
|
||||
msgid "vssr Server is not running"
|
||||
msgstr "vssr 服务端未运行"
|
||||
msgstr "Hello World 服务端未运行"
|
||||
|
||||
msgid "Enable Server"
|
||||
msgstr "启动服务端"
|
||||
@ -710,3 +710,15 @@ msgstr "TVB 域名"
|
||||
|
||||
msgid "Custom Domain"
|
||||
msgstr "自定义域名"
|
||||
|
||||
msgid "Subscribe"
|
||||
msgstr "订阅设置"
|
||||
|
||||
msgid "Local Proxy"
|
||||
msgstr "本地代理"
|
||||
|
||||
msgid "↑ Put your IP list here"
|
||||
msgstr "↑ 在上面放置你需要分流的IP列表"
|
||||
|
||||
msgid "↑ Put your domain list here"
|
||||
msgstr "↑ 在上面放置你需要分流的域名列表"
|
||||
|
||||
@ -609,6 +609,7 @@ EOF
|
||||
/etc/init.d/dnsmasq restart >/dev/null 2>&1
|
||||
start_server
|
||||
start_local
|
||||
scount=$(count_shunt)
|
||||
if [ $scount != "0" ]; then
|
||||
start_shunt
|
||||
fi
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
local ucursor = require 'luci.model.uci'.cursor()
|
||||
local name = 'vssr'
|
||||
local json = require 'luci.jsonc'
|
||||
local nixio = require 'nixio'
|
||||
local server_section = arg[1]
|
||||
local proto = arg[2]
|
||||
local local_port = arg[3]
|
||||
@ -8,6 +9,9 @@ local outbounds_table = {}
|
||||
local rules_table = {}
|
||||
|
||||
function read_conf(file)
|
||||
if not nixio.fs.access(file) then
|
||||
return nil
|
||||
end
|
||||
local rfile = io.open(file, "r")
|
||||
local ltable = {}
|
||||
for line in rfile:lines() do
|
||||
@ -18,15 +22,30 @@ function read_conf(file)
|
||||
return rtable
|
||||
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 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 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 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 = {
|
||||
@ -35,6 +54,7 @@ local flow_table = {
|
||||
rules = {
|
||||
type = 'field',
|
||||
domain = youtube_domain,
|
||||
ip = youtube_ip,
|
||||
outboundTag = 'youtube'
|
||||
}
|
||||
},
|
||||
@ -44,6 +64,7 @@ local flow_table = {
|
||||
rules = {
|
||||
type = 'field',
|
||||
domain = tw_video_domain,
|
||||
ip = tw_video_ip,
|
||||
outboundTag = 'tw_video'
|
||||
}
|
||||
},
|
||||
@ -53,6 +74,7 @@ local flow_table = {
|
||||
rules = {
|
||||
type = 'field',
|
||||
domain = netflix_domain,
|
||||
ip = netflix_ip,
|
||||
outboundTag = 'netflix'
|
||||
}
|
||||
},
|
||||
@ -62,6 +84,7 @@ local flow_table = {
|
||||
rules = {
|
||||
type = 'field',
|
||||
domain = disney_domain,
|
||||
ip = disney_ip,
|
||||
outboundTag = 'disney'
|
||||
}
|
||||
},
|
||||
@ -71,6 +94,7 @@ local flow_table = {
|
||||
rules = {
|
||||
type = 'field',
|
||||
domain = prime_domain,
|
||||
ip = prime_ip,
|
||||
outboundTag = 'prime'
|
||||
}
|
||||
},
|
||||
@ -80,6 +104,7 @@ local flow_table = {
|
||||
rules = {
|
||||
type = 'field',
|
||||
domain = tvb_domain,
|
||||
ip = tvb_ip,
|
||||
outboundTag = 'tvb'
|
||||
}
|
||||
},
|
||||
@ -89,6 +114,7 @@ local flow_table = {
|
||||
rules = {
|
||||
type = 'field',
|
||||
domain = custom_domain,
|
||||
ip = custom_ip,
|
||||
outboundTag = 'custom'
|
||||
}
|
||||
}
|
||||
@ -113,7 +139,7 @@ local bt_rules1 = {
|
||||
'BitTorrent',
|
||||
'announce_peer',
|
||||
'announce.php?passkey='
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
function gen_outbound(server_node, tags, local_ports)
|
||||
@ -210,12 +236,30 @@ function gen_bt_outbounds()
|
||||
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) then
|
||||
if(v.rules.domain ~= nil or v.rules.ip ~= nil) then
|
||||
local server = ucursor:get_first(name, 'global', v.name .. '_server')
|
||||
table.insert(outbounds_table, gen_outbound(server, v.name, v.port))
|
||||
table.insert(rules_table, (server ~= nil and server ~= 'nil' ) and v.rules or nil)
|
||||
|
||||
if(v.rules.domain ~= nil) then
|
||||
domain_rules = {
|
||||
type = 'field',
|
||||
domain = v.rules.domain,
|
||||
outboundTag = v.rules.outboundTag
|
||||
}
|
||||
table.insert(rules_table, (server ~= nil and server ~= 'nil' ) and domain_rules or nil)
|
||||
end
|
||||
|
||||
if(v.rules.ip ~= nil) then
|
||||
ip_rules = {
|
||||
type = 'field',
|
||||
ip = v.rules.ip,
|
||||
outboundTag = v.rules.outboundTag
|
||||
}
|
||||
table.insert(rules_table, (server ~= nil and server ~= 'nil' ) and ip_rules or nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
@ -246,6 +290,6 @@ local v2ray = {
|
||||
},
|
||||
-- 传出连接
|
||||
outbounds = outbounds_table,
|
||||
routing = {domainStrategy = 'AsIs', rules = rules_table}
|
||||
routing = {domainStrategy = 'IPIfNonMatch', rules = rules_table}
|
||||
}
|
||||
print(json.stringify(v2ray, 1))
|
||||
|
||||
@ -33,6 +33,40 @@ 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', '过期时间/剩余流量')
|
||||
|
||||
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))
|
||||
else
|
||||
print_r_cache[tostring(t)]=true
|
||||
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..'"')
|
||||
else
|
||||
print(indent.."["..pos.."] => "..tostring(val))
|
||||
end
|
||||
end
|
||||
else
|
||||
print(indent..tostring(t))
|
||||
end
|
||||
end
|
||||
end
|
||||
if (type(t)=="table") then
|
||||
print(tostring(t).." {")
|
||||
sub_print_r(t," ")
|
||||
print("}")
|
||||
else
|
||||
sub_print_r(t," ")
|
||||
end
|
||||
print()
|
||||
end
|
||||
|
||||
local log = function(...)
|
||||
print(os.date('%Y-%m-%d %H:%M:%S ') .. table.concat({...}, ' '))
|
||||
end
|
||||
@ -55,6 +89,43 @@ local function split(full, sep)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
--table去重
|
||||
|
||||
local function clone( object )
|
||||
local lookup_table = {}
|
||||
local function copyObj( object )
|
||||
if type( object ) ~= "table" then
|
||||
return object
|
||||
elseif lookup_table[object] then
|
||||
return lookup_table[object]
|
||||
end
|
||||
|
||||
local new_table = {}
|
||||
lookup_table[object] = new_table
|
||||
for key, value in pairs( object ) do
|
||||
new_table[copyObj( key )] = copyObj( value )
|
||||
end
|
||||
return setmetatable( new_table, getmetatable( object ) )
|
||||
end
|
||||
return copyObj( object )
|
||||
end
|
||||
|
||||
local function table_unique(list)
|
||||
local temp1 = clone(list)
|
||||
local temp2 = clone(list)
|
||||
for k1, v1 in ipairs(temp1) do
|
||||
for k2, v2 in ipairs(temp2) do
|
||||
if v1.alias ~= v2.alias and v1.hashkey == v2.hashkey then
|
||||
table.remove(temp1, k1)
|
||||
table.remove(temp2, k1)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
return temp1
|
||||
end
|
||||
|
||||
-- urlencode
|
||||
local function get_urlencode(c)
|
||||
return sformat('%%%02X', sbyte(c))
|
||||
@ -385,12 +456,21 @@ local execute = function()
|
||||
end
|
||||
end
|
||||
log('成功解析节点数量: ' .. #nodes)
|
||||
end
|
||||
else
|
||||
log(url .. ': 获取内容为空')
|
||||
end
|
||||
end
|
||||
end
|
||||
-- diff
|
||||
do
|
||||
assert(next(nodeResult), '获取不到节点信息,请检查路由器是否能够访问网络,或者订阅链接是否正确')
|
||||
if next(nodeResult) == nil then
|
||||
log("更新失败,没有可用的节点信息")
|
||||
if proxy == '0' then
|
||||
luci.sys.init.start(name)
|
||||
log('订阅失败, 恢复服务')
|
||||
end
|
||||
return
|
||||
end
|
||||
local add, del = 0, 0
|
||||
ucic:foreach(
|
||||
name,
|
||||
@ -407,17 +487,24 @@ local execute = function()
|
||||
setmetatable(nodeResult[old.grouphashkey][old.hashkey], {__index = {_ignore = true}})
|
||||
end
|
||||
else
|
||||
if (old.alias ~= nil) then
|
||||
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('忽略手动添加的无效节点')
|
||||
log('忽略手动添加的节点: ' .. old.alias)
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
for k, v in ipairs(nodeResult) do
|
||||
for kk, vv in ipairs(v) do
|
||||
-- 如果订阅节点中有相同的节点信息 需要先去重。
|
||||
new_nodes = table_unique(v)
|
||||
for kk, vv in ipairs(new_nodes) do
|
||||
if not vv._ignore then
|
||||
local section = ucic:add(name, uciType)
|
||||
ucic:tset(name, section, vv)
|
||||
|
||||
@ -16,11 +16,7 @@ local log = function(...)
|
||||
end
|
||||
|
||||
log('正在更新【GFW列表】数据库')
|
||||
if nixio.fs.access('/usr/bin/wget-ssl') then
|
||||
refresh_cmd = 'wget-ssl --no-check-certificate https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt -O /tmp/gfw.b64'
|
||||
else
|
||||
refresh_cmd = 'wget -O /tmp/gfw.b64 http://iytc.net/tools/list.b64'
|
||||
end
|
||||
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')
|
||||
@ -43,7 +39,7 @@ else
|
||||
end
|
||||
|
||||
log('正在更新【国内IP段】数据库')
|
||||
refresh_cmd ="wget -O- 'https://ispip.clang.cn/all_cn.txt' > /tmp/china_ssr.txt 2>/dev/null"
|
||||
refresh_cmd ="wget-ssl -O- 'https://ispip.clang.cn/all_cn.txt' > /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
|
||||
@ -69,12 +65,8 @@ end
|
||||
if ucic:get_first('vssr', 'global', 'adblock', '') == '1' then
|
||||
log('正在更新【广告屏蔽】数据库')
|
||||
local need_process = 0
|
||||
if nixio.fs.access('/usr/bin/wget-ssl') then
|
||||
refresh_cmd = 'wget-ssl --no-check-certificate -O - https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt > /tmp/adnew.conf'
|
||||
need_process = 1
|
||||
else
|
||||
refresh_cmd = 'wget -O /tmp/ad.conf http://iytc.net/tools/ad.conf'
|
||||
end
|
||||
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
|
||||
|
||||
@ -0,0 +1,232 @@
|
||||
/*!
|
||||
Pure v1.0.1
|
||||
Copyright 2013 Yahoo!
|
||||
Licensed under the BSD License.
|
||||
https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
*/
|
||||
.pure-g {
|
||||
letter-spacing: -.31em;
|
||||
text-rendering: optimizespeed;
|
||||
font-family: FreeSans, Arimo, "Droid Sans", Helvetica, Arial, sans-serif;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: normal;
|
||||
-webkit-flex-flow: row wrap;
|
||||
-ms-flex-flow: row wrap;
|
||||
flex-flow: row wrap;
|
||||
-webkit-align-content: flex-start;
|
||||
-ms-flex-line-pack: start;
|
||||
align-content: flex-start
|
||||
}
|
||||
|
||||
@media all and (-ms-high-contrast:none),
|
||||
(-ms-high-contrast:active) {
|
||||
table .pure-g {
|
||||
display: block
|
||||
}
|
||||
}
|
||||
|
||||
.opera-only :-o-prefocus,
|
||||
.pure-g {
|
||||
word-spacing: -.43em
|
||||
}
|
||||
|
||||
.pure-u {
|
||||
display: inline-block;
|
||||
zoom: 1;
|
||||
letter-spacing: normal;
|
||||
word-spacing: normal;
|
||||
vertical-align: top;
|
||||
text-rendering: auto
|
||||
}
|
||||
|
||||
.pure-g [class*=pure-u] {
|
||||
font-family: sans-serif
|
||||
}
|
||||
|
||||
.pure-u-1,
|
||||
.pure-u-1-1,
|
||||
.pure-u-1-12,
|
||||
.pure-u-1-2,
|
||||
.pure-u-1-24,
|
||||
.pure-u-1-3,
|
||||
.pure-u-1-4,
|
||||
.pure-u-1-5,
|
||||
.pure-u-1-6,
|
||||
.pure-u-1-8,
|
||||
.pure-u-10-24,
|
||||
.pure-u-11-12,
|
||||
.pure-u-11-24,
|
||||
.pure-u-12-24,
|
||||
.pure-u-13-24,
|
||||
.pure-u-14-24,
|
||||
.pure-u-15-24,
|
||||
.pure-u-16-24,
|
||||
.pure-u-17-24,
|
||||
.pure-u-18-24,
|
||||
.pure-u-19-24,
|
||||
.pure-u-2-24,
|
||||
.pure-u-2-3,
|
||||
.pure-u-2-5,
|
||||
.pure-u-20-24,
|
||||
.pure-u-21-24,
|
||||
.pure-u-22-24,
|
||||
.pure-u-23-24,
|
||||
.pure-u-24-24,
|
||||
.pure-u-3-24,
|
||||
.pure-u-3-4,
|
||||
.pure-u-3-5,
|
||||
.pure-u-3-8,
|
||||
.pure-u-4-24,
|
||||
.pure-u-4-5,
|
||||
.pure-u-5-12,
|
||||
.pure-u-5-24,
|
||||
.pure-u-5-5,
|
||||
.pure-u-5-6,
|
||||
.pure-u-5-8,
|
||||
.pure-u-6-24,
|
||||
.pure-u-7-12,
|
||||
.pure-u-7-24,
|
||||
.pure-u-7-8,
|
||||
.pure-u-8-24,
|
||||
.pure-u-9-24 {
|
||||
display: inline-block;
|
||||
zoom: 1;
|
||||
letter-spacing: normal;
|
||||
word-spacing: normal;
|
||||
vertical-align: top;
|
||||
text-rendering: auto
|
||||
}
|
||||
|
||||
.pure-u-1-24 {
|
||||
width: 4.1667%
|
||||
}
|
||||
|
||||
.pure-u-1-12,
|
||||
.pure-u-2-24 {
|
||||
width: 8.3333%
|
||||
}
|
||||
|
||||
.pure-u-1-8,
|
||||
.pure-u-3-24 {
|
||||
width: 12.5%
|
||||
}
|
||||
|
||||
.pure-u-1-6,
|
||||
.pure-u-4-24 {
|
||||
width: 16.6667%
|
||||
}
|
||||
|
||||
.pure-u-1-5 {
|
||||
width: 20%
|
||||
}
|
||||
|
||||
.pure-u-5-24 {
|
||||
width: 20.8333%
|
||||
}
|
||||
|
||||
.pure-u-1-4,
|
||||
.pure-u-6-24 {
|
||||
width: 25%
|
||||
}
|
||||
|
||||
.pure-u-7-24 {
|
||||
width: 29.1667%
|
||||
}
|
||||
|
||||
.pure-u-1-3,
|
||||
.pure-u-8-24 {
|
||||
width: 33.3333%
|
||||
}
|
||||
|
||||
.pure-u-3-8,
|
||||
.pure-u-9-24 {
|
||||
width: 37.5%
|
||||
}
|
||||
|
||||
.pure-u-2-5 {
|
||||
width: 40%
|
||||
}
|
||||
|
||||
.pure-u-10-24,
|
||||
.pure-u-5-12 {
|
||||
width: 41.6667%
|
||||
}
|
||||
|
||||
.pure-u-11-24 {
|
||||
width: 45.8333%
|
||||
}
|
||||
|
||||
.pure-u-1-2,
|
||||
.pure-u-12-24 {
|
||||
width: 50%
|
||||
}
|
||||
|
||||
.pure-u-13-24 {
|
||||
width: 54.1667%
|
||||
}
|
||||
|
||||
.pure-u-14-24,
|
||||
.pure-u-7-12 {
|
||||
width: 58.3333%
|
||||
}
|
||||
|
||||
.pure-u-3-5 {
|
||||
width: 60%
|
||||
}
|
||||
|
||||
.pure-u-15-24,
|
||||
.pure-u-5-8 {
|
||||
width: 62.5%
|
||||
}
|
||||
|
||||
.pure-u-16-24,
|
||||
.pure-u-2-3 {
|
||||
width: 66.6667%
|
||||
}
|
||||
|
||||
.pure-u-17-24 {
|
||||
width: 70.8333%
|
||||
}
|
||||
|
||||
.pure-u-18-24,
|
||||
.pure-u-3-4 {
|
||||
width: 75%
|
||||
}
|
||||
|
||||
.pure-u-19-24 {
|
||||
width: 79.1667%
|
||||
}
|
||||
|
||||
.pure-u-4-5 {
|
||||
width: 80%
|
||||
}
|
||||
|
||||
.pure-u-20-24,
|
||||
.pure-u-5-6 {
|
||||
width: 83.3333%
|
||||
}
|
||||
|
||||
.pure-u-21-24,
|
||||
.pure-u-7-8 {
|
||||
width: 87.5%
|
||||
}
|
||||
|
||||
.pure-u-11-12,
|
||||
.pure-u-22-24 {
|
||||
width: 91.6667%
|
||||
}
|
||||
|
||||
.pure-u-23-24 {
|
||||
width: 95.8333%
|
||||
}
|
||||
|
||||
.pure-u-1,
|
||||
.pure-u-1-1,
|
||||
.pure-u-24-24,
|
||||
.pure-u-5-5 {
|
||||
width: 100%
|
||||
}
|
||||
@ -1,245 +1,73 @@
|
||||
@import url("flag-icon.min.css?v=1.16");
|
||||
@import url("sweetalert2.css?v=1.16");
|
||||
/*!
|
||||
Pure v1.0.1
|
||||
Copyright 2013 Yahoo!
|
||||
Licensed under the BSD License.
|
||||
https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
*/
|
||||
@import url("pure.css?v=1.16");
|
||||
|
||||
|
||||
.pure-g {
|
||||
letter-spacing: -.31em;
|
||||
text-rendering: optimizespeed;
|
||||
font-family: FreeSans, Arimo, "Droid Sans", Helvetica, Arial, sans-serif;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: normal;
|
||||
-webkit-flex-flow: row wrap;
|
||||
-ms-flex-flow: row wrap;
|
||||
flex-flow: row wrap;
|
||||
-webkit-align-content: flex-start;
|
||||
-ms-flex-line-pack: start;
|
||||
align-content: flex-start
|
||||
/** Common **/
|
||||
.pure-img {
|
||||
max-height: 100%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
@media all and (-ms-high-contrast:none),
|
||||
(-ms-high-contrast:active) {
|
||||
table .pure-g {
|
||||
display: block
|
||||
}
|
||||
.pure-imgw {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.opera-only :-o-prefocus,
|
||||
.pure-g {
|
||||
word-spacing: -.43em
|
||||
}
|
||||
|
||||
.pure-u {
|
||||
display: inline-block;
|
||||
zoom: 1;
|
||||
letter-spacing: normal;
|
||||
word-spacing: normal;
|
||||
vertical-align: top;
|
||||
text-rendering: auto
|
||||
}
|
||||
|
||||
.pure-g [class*=pure-u] {
|
||||
font-family: sans-serif
|
||||
}
|
||||
|
||||
.pure-u-1,
|
||||
.pure-u-1-1,
|
||||
.pure-u-1-12,
|
||||
.pure-u-1-2,
|
||||
.pure-u-1-24,
|
||||
.pure-u-1-3,
|
||||
.pure-u-1-4,
|
||||
.pure-u-1-5,
|
||||
.pure-u-1-6,
|
||||
.pure-u-1-8,
|
||||
.pure-u-10-24,
|
||||
.pure-u-11-12,
|
||||
.pure-u-11-24,
|
||||
.pure-u-12-24,
|
||||
.pure-u-13-24,
|
||||
.pure-u-14-24,
|
||||
.pure-u-15-24,
|
||||
.pure-u-16-24,
|
||||
.pure-u-17-24,
|
||||
.pure-u-18-24,
|
||||
.pure-u-19-24,
|
||||
.pure-u-2-24,
|
||||
.pure-u-2-3,
|
||||
.pure-u-2-5,
|
||||
.pure-u-20-24,
|
||||
.pure-u-21-24,
|
||||
.pure-u-22-24,
|
||||
.pure-u-23-24,
|
||||
.pure-u-24-24,
|
||||
.pure-u-3-24,
|
||||
.pure-u-3-4,
|
||||
.pure-u-3-5,
|
||||
.pure-u-3-8,
|
||||
.pure-u-4-24,
|
||||
.pure-u-4-5,
|
||||
.pure-u-5-12,
|
||||
.pure-u-5-24,
|
||||
.pure-u-5-5,
|
||||
.pure-u-5-6,
|
||||
.pure-u-5-8,
|
||||
.pure-u-6-24,
|
||||
.pure-u-7-12,
|
||||
.pure-u-7-24,
|
||||
.pure-u-7-8,
|
||||
.pure-u-8-24,
|
||||
.pure-u-9-24 {
|
||||
display: inline-block;
|
||||
zoom: 1;
|
||||
letter-spacing: normal;
|
||||
word-spacing: normal;
|
||||
vertical-align: top;
|
||||
text-rendering: auto
|
||||
}
|
||||
|
||||
.pure-u-1-24 {
|
||||
width: 4.1667%
|
||||
}
|
||||
|
||||
.pure-u-1-12,
|
||||
.pure-u-2-24 {
|
||||
width: 8.3333%
|
||||
}
|
||||
|
||||
.pure-u-1-8,
|
||||
.pure-u-3-24 {
|
||||
width: 12.5%
|
||||
}
|
||||
|
||||
.pure-u-1-6,
|
||||
.pure-u-4-24 {
|
||||
width: 16.6667%
|
||||
}
|
||||
|
||||
.pure-u-1-5 {
|
||||
width: 20%
|
||||
}
|
||||
|
||||
.pure-u-5-24 {
|
||||
width: 20.8333%
|
||||
}
|
||||
|
||||
.pure-u-1-4,
|
||||
.pure-u-6-24 {
|
||||
width: 25%
|
||||
}
|
||||
|
||||
.pure-u-7-24 {
|
||||
width: 29.1667%
|
||||
}
|
||||
|
||||
.pure-u-1-3,
|
||||
.pure-u-8-24 {
|
||||
width: 33.3333%
|
||||
}
|
||||
|
||||
.pure-u-3-8,
|
||||
.pure-u-9-24 {
|
||||
width: 37.5%
|
||||
}
|
||||
|
||||
.pure-u-2-5 {
|
||||
width: 40%
|
||||
}
|
||||
|
||||
.pure-u-10-24,
|
||||
.pure-u-5-12 {
|
||||
width: 41.6667%
|
||||
}
|
||||
|
||||
.pure-u-11-24 {
|
||||
width: 45.8333%
|
||||
}
|
||||
|
||||
.pure-u-1-2,
|
||||
.pure-u-12-24 {
|
||||
width: 50%
|
||||
}
|
||||
|
||||
.pure-u-13-24 {
|
||||
width: 54.1667%
|
||||
}
|
||||
|
||||
.pure-u-14-24,
|
||||
.pure-u-7-12 {
|
||||
width: 58.3333%
|
||||
}
|
||||
|
||||
.pure-u-3-5 {
|
||||
width: 60%
|
||||
}
|
||||
|
||||
.pure-u-15-24,
|
||||
.pure-u-5-8 {
|
||||
width: 62.5%
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
|
||||
.pure-u-16-24,
|
||||
.pure-u-2-3 {
|
||||
width: 66.6667%
|
||||
.gap {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.pure-u-17-24 {
|
||||
width: 70.8333%
|
||||
|
||||
/** 复写theme **/
|
||||
|
||||
.cbi-section {
|
||||
|
||||
border: 0;
|
||||
border-radius: .375rem;
|
||||
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.pure-u-18-24,
|
||||
.pure-u-3-4 {
|
||||
width: 75%
|
||||
.cbi-section-node {
|
||||
|
||||
border: 0;
|
||||
border-radius: .375rem;
|
||||
margin-bottom: 0px;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
padding: 0rem 0;
|
||||
}
|
||||
|
||||
.pure-u-19-24 {
|
||||
width: 79.1667%
|
||||
#cbi-vssr {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.pure-u-4-5 {
|
||||
width: 80%
|
||||
}
|
||||
|
||||
.pure-u-20-24,
|
||||
.pure-u-5-6 {
|
||||
width: 83.3333%
|
||||
}
|
||||
|
||||
.pure-u-21-24,
|
||||
.pure-u-7-8 {
|
||||
width: 87.5%
|
||||
}
|
||||
|
||||
.pure-u-11-12,
|
||||
.pure-u-22-24 {
|
||||
width: 91.6667%
|
||||
}
|
||||
|
||||
.pure-u-23-24 {
|
||||
width: 95.8333%
|
||||
}
|
||||
|
||||
.pure-u-1,
|
||||
.pure-u-1-1,
|
||||
.pure-u-24-24,
|
||||
.pure-u-5-5 {
|
||||
width: 100%
|
||||
#cbi-vssr .panel-title {
|
||||
width: 100%;
|
||||
display: block;
|
||||
margin-bottom: 0;
|
||||
padding: .8755rem 1.5rem;
|
||||
|
||||
margin-bottom: 0rem;
|
||||
letter-spacing: .1rem;
|
||||
|
||||
font-weight: 600;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/** Top StatusBar **/
|
||||
.status {
|
||||
margin: 1rem -0.5rem 1rem -0.5rem;
|
||||
margin: 0.5rem -0.5rem 1rem -0.5rem;
|
||||
}
|
||||
|
||||
.block {
|
||||
.status .block {
|
||||
margin: 0.5rem 0.5rem;
|
||||
padding: 0;
|
||||
font-weight: normal;
|
||||
@ -255,56 +83,28 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
box-shadow: 0 0 2rem 0 rgba(136, 152, 170, .15);
|
||||
}
|
||||
|
||||
.img-con {
|
||||
.status .block .img-con {
|
||||
margin: 1rem;
|
||||
|
||||
}
|
||||
|
||||
.pure-img {
|
||||
max-height: 100%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.pure-imgw {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.green {
|
||||
.status .block .green {
|
||||
font-size: 1.25rem;
|
||||
color: #2dce89;
|
||||
}
|
||||
|
||||
.red {
|
||||
.status .block .red {
|
||||
font-size: 1.25rem;
|
||||
color: #fb6340;
|
||||
}
|
||||
|
||||
.sk-text-success {
|
||||
color: #2dce89;
|
||||
}
|
||||
|
||||
.sk-text-error {
|
||||
color: #fb6340;
|
||||
}
|
||||
|
||||
.gap {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.block img {
|
||||
.status .block img {
|
||||
width: 48px;
|
||||
height: auto;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.pure-u-5-8 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
|
||||
.block h4 {
|
||||
.status .block h4 {
|
||||
font-size: .8125rem;
|
||||
font-weight: 600;
|
||||
margin: 1rem;
|
||||
@ -312,12 +112,10 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
line-height: 1.8em;
|
||||
}
|
||||
|
||||
.p-in5 {
|
||||
padding: 8px;
|
||||
}
|
||||
/** Server List **/
|
||||
|
||||
.flag-icon:before {
|
||||
position: absolute;
|
||||
.p-in5 {
|
||||
margin: 8px !important;
|
||||
}
|
||||
|
||||
.cbi-section-table-row {
|
||||
@ -346,6 +144,17 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.ssr-button:link,
|
||||
.ssr-button:hover,
|
||||
.ssr-button:focus,
|
||||
.ssr-button:visited,
|
||||
.ssr-button:active {
|
||||
|
||||
outline: 0;
|
||||
text-decoration: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.cbi-section-table-row.fast .ssr-button {
|
||||
color: #fff;
|
||||
}
|
||||
@ -363,6 +172,15 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.host_con {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 70px;
|
||||
text-align: left;
|
||||
height: 22px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.host_con.fast {
|
||||
color: #6f9a37;
|
||||
}
|
||||
@ -379,7 +197,19 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
color: #fb6340;
|
||||
}
|
||||
|
||||
.host_ok {
|
||||
color: #fff;
|
||||
background: #2dce89;
|
||||
padding: 0.1rem 0.5rem;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
|
||||
.host_error {
|
||||
color: #fff;
|
||||
background: #f5365c;
|
||||
padding: 0.1rem 0.5rem;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
|
||||
.loadings.hide {
|
||||
opacity: 0;
|
||||
@ -392,20 +222,20 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.flag-icon:before {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.alias {
|
||||
margin-bottom: 1px;
|
||||
padding-left: 0px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.incon {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.incon .pure-imgw {
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.incon:nth-child(2) {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
@ -414,10 +244,13 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
border: 0;
|
||||
border-right: #d1dfed 1px solid;
|
||||
background-position: top;
|
||||
|
||||
}
|
||||
|
||||
.incon:nth-child(2) .tp {
|
||||
.incon .pure-imgw {
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.incon .tp {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
@ -430,34 +263,29 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
background: #525f7f;
|
||||
}
|
||||
|
||||
.incon:nth-child(3) {
|
||||
padding-left: 0px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.incon:nth-child(5),
|
||||
.incon:nth-child(6) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cbi-section-table-cell {
|
||||
text-align: right;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ssr-button {
|
||||
background: none;
|
||||
border: none;
|
||||
color: #525f7f;
|
||||
padding: 0 0 0 0;
|
||||
padding: 0 0.2rem 0 0;
|
||||
height: auto;
|
||||
line-height: 1.5em;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.ssr-button:hover,
|
||||
.ssr-button:focus,
|
||||
.ssr-button:active {
|
||||
color: #525f7f;
|
||||
|
||||
outline: 0;
|
||||
text-decoration: none;
|
||||
box-shadow: none;
|
||||
@ -472,37 +300,18 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
color: #fff !important;
|
||||
background-color: #337ab7 !important;
|
||||
border-color: #2e6da4 !important;
|
||||
background-image: none;
|
||||
float: right;
|
||||
margin-right: 18px;
|
||||
margin-top: 1rem;
|
||||
margin-top: .25rem !important;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.cbi-section-table-cell {
|
||||
position: relative;
|
||||
.cbi-button-check:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.host_con {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 70px;
|
||||
text-align: left;
|
||||
height: 22px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.host_ok {
|
||||
color: #fff;
|
||||
background: #2dce89;
|
||||
padding: 0.1rem 0.5rem;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
|
||||
.host_error {
|
||||
color: #fff;
|
||||
background: #f5365c;
|
||||
padding: 0.1rem 0.5rem;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
/** Bottom StatusBar **/
|
||||
|
||||
footer.mobile-hide {
|
||||
display: block;
|
||||
@ -537,6 +346,7 @@ footer.mobile-hide {
|
||||
|
||||
.status-bar .inner .status-info {
|
||||
font-weight: bold;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.status-bar .icon-con {
|
||||
@ -544,6 +354,8 @@ footer.mobile-hide {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/** Node choose panel **/
|
||||
|
||||
.choose_node .gap {
|
||||
margin: 0.5rem 1rem;
|
||||
position: relative;
|
||||
@ -553,66 +365,8 @@ footer.mobile-hide {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 2000px) {
|
||||
.pure-u-1-5 {
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1600px) {
|
||||
.pure-u-1-5 {
|
||||
width: 33.33333333%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
.pure-u-1-5 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.status .pure-u-1-5 {
|
||||
width: 33.333%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 700px) {
|
||||
.pure-u-1-4 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.pure-u-1-2 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pure-u-1-5 {
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.status .pure-u-1-5 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.cbi-button-add {
|
||||
position: fixed;
|
||||
padding: 0.3rem 0.5rem;
|
||||
z-index: 1000;
|
||||
width: 50px !important;
|
||||
height: 50px;
|
||||
bottom: 90px;
|
||||
right: 5px;
|
||||
font-size: 16px;
|
||||
border-radius: 50%;
|
||||
display: block;
|
||||
background-color: #fb6340 !important;
|
||||
border-color: #fb6340 !important;
|
||||
box-shadow: 0 0 1rem 0 rgba(136, 152, 170, .75);
|
||||
}
|
||||
|
||||
.choose_node .pure-u-1-2 {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
/** Subscribe panel **/
|
||||
|
||||
.modals-bg {
|
||||
position: fixed;
|
||||
@ -625,7 +379,7 @@ footer.mobile-hide {
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.modals-bg.hide{
|
||||
.modals-bg.hide {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
}
|
||||
@ -651,7 +405,7 @@ footer.mobile-hide {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.modals.hide{
|
||||
.modals.hide {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transform: scale(0.5);
|
||||
@ -688,7 +442,27 @@ footer.mobile-hide {
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
@media screen and (max-width: 2000px) {
|
||||
.pure-u-1-5 {
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1600px) {
|
||||
.pure-u-1-5 {
|
||||
width: 33.33333333%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
.pure-u-1-5 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.status .pure-u-1-5 {
|
||||
width: 33.333%;
|
||||
}
|
||||
|
||||
.modals {
|
||||
position: fixed;
|
||||
z-index: 100;
|
||||
@ -704,6 +478,45 @@ footer.mobile-hide {
|
||||
}
|
||||
|
||||
@media screen and (max-width: 700px) {
|
||||
.pure-u-1-4 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.pure-u-1-2 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pure-u-1-5 {
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.status .pure-u-1-5 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.cbi-button-add {
|
||||
position: fixed;
|
||||
padding: 0.3rem 0.5rem;
|
||||
z-index: 1000;
|
||||
width: 50px !important;
|
||||
height: 50px !important;
|
||||
bottom: 90px;
|
||||
color: #fff;
|
||||
right: 5px;
|
||||
font-size: 16px;
|
||||
border-radius: 50%;
|
||||
display: block;
|
||||
background-color: #fb6340 !important;
|
||||
border-color: #fb6340 !important;
|
||||
box-shadow: 0 0 1rem 0 rgba(136, 152, 170, .75);
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.choose_node .pure-u-1-2 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.modals-bg {
|
||||
position: fixed;
|
||||
z-index: 100000;
|
||||
@ -732,6 +545,14 @@ footer.mobile-hide {
|
||||
height: 2.5em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.p-in5 {
|
||||
padding-bottom: 3rem;
|
||||
}
|
||||
|
||||
.cbi-page-actions {
|
||||
padding-bottom: 4rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
@ -753,4 +574,5 @@ footer.mobile-hide {
|
||||
.ssr-button {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
}
|
||||
@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=autocore
|
||||
PKG_VERSION:=1
|
||||
PKG_RELEASE:=36
|
||||
PKG_RELEASE:=37
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
cpu_arch="$(cat "/proc/cpuinfo" | grep "model name" | sed -n "1p" | awk -F ': ' '{print $2}')"
|
||||
[ -z "${cpu_arch}" ] && cpu_arch="ARMv8 Processor"
|
||||
cpu_cores="$(cat "/proc/cpuinfo" | grep "processor" | wc -l)"
|
||||
|
||||
if grep -q "bcm27xx" "/etc/openwrt_release"; then
|
||||
|
||||
@ -31,7 +31,6 @@ ln -sf /sbin/ip /usr/bin/ip
|
||||
|
||||
sed -i 's#https://downloads.openwrt.org#https://mirrors.cloud.tencent.com/lede#g' /etc/opkg/distfeeds.conf
|
||||
sed -i '/openwrt_luci/ { s/snapshots/releases\/18.06.9/g; }' /etc/opkg/distfeeds.conf
|
||||
sed -i '/openwrt_packages/ { s/snapshots/releases\/19.07.5/g; }' /etc/opkg/distfeeds.conf
|
||||
sed -i "s/# //g" /etc/opkg/distfeeds.conf
|
||||
|
||||
sed -i 's/root::0:0:99999:7:::/root:$1$V4UetPzk$CYXluq4wUazHjmCDBCqXF.:0:0:99999:7:::/g' /etc/shadow
|
||||
|
||||
@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-ssr-plus
|
||||
PKG_VERSION:=182
|
||||
PKG_RELEASE:=5
|
||||
PKG_RELEASE:=9
|
||||
|
||||
define Package/$(PKG_NAME)/conffiles
|
||||
/etc/config/shadowsocksr
|
||||
@ -10,69 +10,89 @@ define Package/$(PKG_NAME)/conffiles
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/config
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Xray
|
||||
bool "Include Xray"
|
||||
default y if i386||x86_64||arm||aarch64
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Trojan
|
||||
bool "Include Trojan"
|
||||
default y if i386||x86_64||arm||aarch64
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Redsocks2
|
||||
bool "Include Redsocks2"
|
||||
default y if i386||x86_64||arm||aarch64
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun
|
||||
bool "Include Kcptun"
|
||||
default n
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy
|
||||
bool "Include NaiveProxy"
|
||||
depends on !(arc||armeb||mips||mips64||powerpc)
|
||||
default y if i386||x86_64||arm||aarch64
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray
|
||||
bool "Include V2ray"
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Redsocks2
|
||||
bool "Include Redsocks2"
|
||||
default n
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Trojan_Go
|
||||
bool "Include Trojan-Go"
|
||||
default n
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks
|
||||
bool "Include Shadowsocks-libev"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun
|
||||
bool "Include Kcptun"
|
||||
default n
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_plugin
|
||||
bool "Include Shadowsocks V2ray Plugin"
|
||||
default n
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR
|
||||
bool "Include ShadowsocksR-libev"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server
|
||||
bool "Include ShadowsocksR Server"
|
||||
default y if i386||x86_64||arm||aarch64
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs
|
||||
bool "Include Shadowsocks Simple Obfs Plugin"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Trojan
|
||||
bool "Include Trojan"
|
||||
default y if i386||arm
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Trojan_Go
|
||||
bool "Include Trojan-Go"
|
||||
default y if x86_64||aarch64
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray
|
||||
bool "Include V2ray"
|
||||
default n
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin
|
||||
bool "Include Shadowsocks V2ray Plugin"
|
||||
default n
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Xray
|
||||
bool "Include Xray"
|
||||
default y if i386||x86_64||arm||aarch64
|
||||
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_Trojan_Go \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun \
|
||||
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
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Trojan \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Trojan_Go \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Xray
|
||||
|
||||
LUCI_TITLE:=SS/SSR/V2Ray/Trojan/NaiveProxy/Socks5/Tun LuCI interface
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+shadowsocksr-libev-alt +ipset +ip-full +iptables-mod-tproxy +dnsmasq-full +coreutils +coreutils-base64 +pdnsd-alt +wget-ssl +lua +libuci-lua \
|
||||
+microsocks +dns2socks +shadowsocks-libev-ss-local +shadowsocksr-libev-ssr-local +shadowsocks-libev-ss-redir +simple-obfs +tcping +resolveip\
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_plugin:v2ray-plugin \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:xray \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:trojan \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan_Go:trojan-go \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:ipt2socks \
|
||||
LUCI_DEPENDS:=+coreutils +coreutils-base64 +dns2socks +dnsmasq-full +ipset +ip-full \
|
||||
+iptables-mod-tproxy +lua +libuci-lua +microsocks +pdnsd-alt +tcping +resolveip \
|
||||
+shadowsocksr-libev-alt +wget-ssl \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun-client \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy:naiveproxy \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Redsocks2:redsocks2 \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun-client \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server:shadowsocksr-libev-server
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks:shadowsocks-libev-ss-local \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks:shadowsocks-libev-ss-redir \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR:shadowsocksr-libev-ssr-local \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server:shadowsocksr-libev-server \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs:simple-obfs \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:trojan \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:ipt2socks \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan_Go:trojan-go \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin:v2ray-plugin \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:xray
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
|
||||
@ -361,8 +361,8 @@ function import_ssr_url(btn, urlname, sid) {
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.vless_encryption')[0].value = queryParam.encryption || "none";
|
||||
if (queryParam.security == "tls") {
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].checked = true;
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = queryParam.sni || serverPart[0];
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event);
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = queryParam.sni || serverPart[0];
|
||||
}
|
||||
switch (queryParam.type) {
|
||||
case "ws":
|
||||
|
||||
@ -44,7 +44,6 @@ CRON_FILE=/etc/crontabs/root
|
||||
EXTRA_COMMANDS='reset'
|
||||
EXTRA_HELP=" reset Reset to default settings"
|
||||
#extra_command "reset" "Reset to default settings"
|
||||
trap 'rm -f "$LOCK_FILE"; exit $?' INT TERM EXIT
|
||||
|
||||
uci_get_by_name() {
|
||||
local ret=$(uci get $NAME.$1.$2 2>/dev/null)
|
||||
@ -283,7 +282,7 @@ gen_config_file() { #server1 type2 code3 local_port4 socks_port5 threads5
|
||||
vmess | vless)
|
||||
lua /usr/share/shadowsocksr/gen_config.lua $1 $mode $4 $5 >$config_file
|
||||
;;
|
||||
trojan | trojan-go)
|
||||
trojan)
|
||||
case "$3" in
|
||||
1)
|
||||
lua /usr/share/shadowsocksr/gen_config.lua $1 nat $4 >$config_file
|
||||
@ -292,10 +291,25 @@ gen_config_file() { #server1 type2 code3 local_port4 socks_port5 threads5
|
||||
lua /usr/share/shadowsocksr/gen_config.lua $1 client $4 >$config_file
|
||||
;;
|
||||
3)
|
||||
lua /usr/share/shadowsocksr/gen_config.lua $1 nat $4 >$config_file
|
||||
lua /usr/share/shadowsocksr/gen_config.lua $1 client $tmp_port >$shunt_dns_config_file
|
||||
;;
|
||||
4)
|
||||
lua /usr/share/shadowsocksr/gen_config.lua $1 $mode $4 >$config_file
|
||||
lua /usr/share/shadowsocksr/gen_config.lua $1 client $4 >$config_file
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
trojan-go)
|
||||
case "$3" in
|
||||
1 | 2)
|
||||
lua /usr/share/shadowsocksr/gen_config.lua $1 nat $4 >$config_file
|
||||
;;
|
||||
3)
|
||||
lua /usr/share/shadowsocksr/gen_config.lua $1 nat $4 >$config_file
|
||||
lua /usr/share/shadowsocksr/gen_config.lua $1 client $tmp_port >$shunt_dns_config_file
|
||||
;;
|
||||
4)
|
||||
lua /usr/share/shadowsocksr/gen_config.lua $1 client $4 >$config_file
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
@ -342,20 +356,29 @@ start_udp() {
|
||||
ln_start_bin $(first_type xray v2ray) v2ray -config $udp_config_file
|
||||
echolog "UDP TPROXY Relay:$($(first_type "xray" "v2ray") -version | head -1) Started!"
|
||||
;;
|
||||
trojan | trojan-go) #client
|
||||
trojan) #client
|
||||
gen_config_file $UDP_RELAY_SERVER $type 2 $tmp_udp_local_port
|
||||
ln_start_bin $(first_type trojan-go trojan) $type --config $udp_config_file
|
||||
ln_start_bin $(first_type ipt2socks) ipt2socks -U -b 0.0.0.0 -4 -s 127.0.0.1 -p $tmp_udp_local_port -l $tmp_udp_port
|
||||
echolog "UDP TPROXY Relay:$($(first_type trojan-go trojan) --version 2>&1 | head -1) Started!"
|
||||
;;
|
||||
trojan-go)
|
||||
gen_config_file $UDP_RELAY_SERVER $type 2 $udp_config_file
|
||||
ln_start_bin $(first_type trojan-go trojan) $type --config $udp_config_file
|
||||
echolog "UDP TPROXY Relay:$($(first_type trojan-go trojan) --version 2>&1 | head -1) Started!"
|
||||
;;
|
||||
naiveproxy)
|
||||
echolog "NaïveProxy UDP TPROXY Relay not supported!"
|
||||
redir_udp=0
|
||||
ARG_UDP=""
|
||||
;;
|
||||
socks5)
|
||||
gen_config_file $UDP_RELAY_SERVER $type 2 $tmp_udp_port
|
||||
ln_start_bin $(first_type redsocks2) redsocks2 -c $udp_config_file
|
||||
if [ "$(uci_get_by_name $UDP_RELAY_SERVER auth_enable 0)" == "1" ]; then
|
||||
local auth="-a $(uci_get_by_name $UDP_RELAY_SERVER username) -k $(uci_get_by_name $UDP_RELAY_SERVER password)"
|
||||
fi
|
||||
ln_start_bin $(first_type ipt2socks) ipt2socks $udp_config_file -U -4 -s $(uci_get_by_name $UDP_RELAY_SERVER server) -p $(uci_get_by_name $UDP_RELAY_SERVER server_port) -l $tmp_udp_port $auth
|
||||
#gen_config_file $UDP_RELAY_SERVER $type 2 $tmp_udp_port
|
||||
#ln_start_bin $(first_type redsocks2) redsocks2 -c $udp_config_file
|
||||
echolog "UDP TPROXY Relay:Socks5 REDIRECT/TPROXY Started!"
|
||||
;;
|
||||
tun)
|
||||
@ -371,7 +394,6 @@ start_shunt() {
|
||||
case "$type" in
|
||||
ss | ssr)
|
||||
gen_config_file $SHUNT_SERVER $type 3 $tmp_shunt_port
|
||||
#gen_config_file $SHUNT_SERVER $type 3 $tmp_local_port
|
||||
ln_start_bin $(first_type ${type}-redir) ${type}-redir -c $shunt_config_file
|
||||
if [ -n "$tmp_local_port" ]; then
|
||||
local tmp_port=$tmp_local_port
|
||||
@ -418,6 +440,22 @@ start_shunt() {
|
||||
echolog "shunt:$($(first_type "naive") --version 2>&1 | head -1) Started!"
|
||||
redir_udp=0
|
||||
;;
|
||||
socks5)
|
||||
if [ "$(uci_get_by_name $SHUNT_SERVER auth_enable 0)" == "1" ]; then
|
||||
local auth="-a $(uci_get_by_name $SHUNT_SERVER username) -k $(uci_get_by_name $SHUNT_SERVER password)"
|
||||
fi
|
||||
ln_start_bin $(first_type ipt2socks) ipt2socks $shunt_config_file -R -4 -s $(uci_get_by_name $SHUNT_SERVER server) -p $(uci_get_by_name $SHUNT_SERVER server_port) -l $tmp_shunt_port $auth
|
||||
#gen_config_file $SHUNT_SERVER $type 3 $tmp_shunt_port
|
||||
#ln_start_bin $(first_type redsocks2) redsocks2 -c $shunt_config_file
|
||||
if [ -n "$tmp_local_port" ]; then
|
||||
local tmp_port=$tmp_local_port
|
||||
else
|
||||
local tmp_port=$tmp_shunt_local_port
|
||||
ln_start_bin $(first_type microsocks) microsocks -i 127.0.0.1 -p $tmp_port shunt-dns-ssr-plus
|
||||
fi
|
||||
ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_port 8.8.8.8:53 127.0.0.1:$tmp_shunt_dns_port -q
|
||||
echolog "shunt:$type REDIRECT/TPROXY Started!"
|
||||
;;
|
||||
*)
|
||||
gen_config_file $SHUNT_SERVER $type 3 $tmp_shunt_port
|
||||
ln_start_bin $(first_type redsocks2) redsocks2 -c $shunt_config_file
|
||||
@ -445,7 +483,7 @@ start_local() {
|
||||
echolog "Global_Socks5:$(get_name $type) Started!"
|
||||
;;
|
||||
vmess | vless)
|
||||
if [ "_local" == "1" ]; then
|
||||
if [ "$_local" == "2" ]; then
|
||||
gen_config_file $LOCAL_SERVER $type 4 0 $local_port
|
||||
ln_start_bin $(first_type xray v2ray) v2ray -config $local_config_file
|
||||
echolog "Global_Socks5:$($(first_type "xray" "v2ray") -version | head -1) Started!"
|
||||
@ -514,7 +552,7 @@ Start_Run() {
|
||||
trojan | trojan-go)
|
||||
gen_config_file $GLOBAL_SERVER $type 1 $tcp_port
|
||||
ln_start_bin $(first_type trojan-go trojan) $type --config $tcp_config_file
|
||||
echolog "Main node:$($(first_type $type) --version 2>&1 | head -1) Started!"
|
||||
echolog "Main node:$($(first_type trojan-go trojan) --version 2>&1 | head -1) Started!"
|
||||
;;
|
||||
naiveproxy)
|
||||
gen_config_file $GLOBAL_SERVER $type 1 $tcp_port
|
||||
@ -522,10 +560,14 @@ Start_Run() {
|
||||
echolog "Main node:$($(first_type naive) --version 2>&1 | head -1) , $threads Threads Started!"
|
||||
;;
|
||||
socks5)
|
||||
gen_config_file $GLOBAL_SERVER $type 1 $tcp_port
|
||||
for i in $(seq 1 $threads); do
|
||||
ln_start_bin $(first_type redsocks2) redsocks2 -c $tcp_config_file
|
||||
done
|
||||
if [ "$(uci_get_by_name $GLOBAL_SERVER auth_enable 0)" == "1" ]; then
|
||||
local auth="-a $(uci_get_by_name $GLOBAL_SERVER username) -k $(uci_get_by_name $GLOBAL_SERVER password)"
|
||||
fi
|
||||
ln_start_bin $(first_type ipt2socks) ipt2socks $tcp_config_file -R -4 -j $threads -s $(uci_get_by_name $GLOBAL_SERVER server) -p $(uci_get_by_name $GLOBAL_SERVER server_port) -l $tcp_port $auth
|
||||
#gen_config_file $GLOBAL_SERVER $type 1 $tcp_port
|
||||
#for i in $(seq 1 $threads); do
|
||||
# ln_start_bin $(first_type redsocks2) redsocks2 -c $tcp_config_file
|
||||
#done
|
||||
echolog "Main node:Socks5 REDIRECT/TPROXY $threads Threads Started!"
|
||||
;;
|
||||
tun)
|
||||
@ -729,7 +771,6 @@ start_rules() {
|
||||
w | W | b | B) local ac_ips="$lan_ac_mode$lan_ac_ips" ;;
|
||||
esac
|
||||
fi
|
||||
#deal gfw firewall rule
|
||||
gfwmode() {
|
||||
case "$(uci_get_by_type global run_mode)" in
|
||||
gfw) echo "-g" ;;
|
||||
@ -830,7 +871,6 @@ stop() {
|
||||
ps -w | grep -v "grep" | grep ssr-monitor | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 &
|
||||
ps -w | grep -v "grep" | grep "sleep 0000" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 &
|
||||
ps -w | grep -v "grep" | grep "$TMP_PATH" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 &
|
||||
#killall -q -9 ss-redir ss-local obfs-local ssr-redir ssr-local ssr-server v2ray v2ray-plugin xray trojan naive microsocks ipt2socks dns2socks redsocks2 pdnsd
|
||||
killall -q -9 v2ray-plugin obfs-local
|
||||
rm -f /var/lock/ssr-monitor.lock
|
||||
if [ -f "/var/dnsmasq.d/dnsmasq-ssrplus.conf" ]; then
|
||||
|
||||
@ -18,7 +18,7 @@ local Xray = {
|
||||
sniffing = {enabled = true, destOverride = {"http", "tls"}}
|
||||
} or nil,
|
||||
-- 开启 socks 代理
|
||||
inboundDetour = (proto == "tcp" and socks_port ~= "0") and {
|
||||
inboundDetour = (proto:find("tcp") and socks_port ~= "0") and {
|
||||
{
|
||||
protocol = "socks",
|
||||
port = tonumber(socks_port),
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2020 Openwrt.org
|
||||
# Copyright (C) 2021 Openwrt.org
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
@ -10,8 +10,8 @@ LUCI_DEPENDS:=+uugamebooster
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_NAME:=luci-app-uugamebooster
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=5
|
||||
PKG_RELEASE:=7
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
@ -1,15 +0,0 @@
|
||||
module("luci.controller.uugamebooster",package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/uugamebooster") then return end
|
||||
|
||||
entry({"admin", "services", "uugamebooster"}, cbi("uugamebooster/uugamebooster"), ("UU Game Booster"),99).dependent=true
|
||||
entry({"admin","services","uugamebooster","status"},call("act_status")).leaf=true
|
||||
end
|
||||
|
||||
function act_status()
|
||||
local e={}
|
||||
e.running=luci.sys.call("pgrep -f uugamebooster >/dev/null")==0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
@ -0,0 +1,15 @@
|
||||
module("luci.controller.uuplugin",package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/uuplugin") then return end
|
||||
|
||||
entry({"admin", "services", "uuplugin"}, cbi("uuplugin/uuplugin"), ("UU GameAcc"),99).dependent=true
|
||||
entry({"admin","services","uuplugin","status"},call("act_status")).leaf=true
|
||||
end
|
||||
|
||||
function act_status()
|
||||
local e={}
|
||||
e.running=luci.sys.call("pgrep -f uuplugin >/dev/null")==0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
@ -1,24 +0,0 @@
|
||||
require("luci.util")
|
||||
|
||||
mp = Map("uugamebooster", translate("UU Game Booster"))
|
||||
mp.description = translate("A Paid Game Acceleration service")
|
||||
mp:section(SimpleSection).template = "uugamebooster/uugamebooster_status"
|
||||
|
||||
s = mp:section(TypedSection, "uugamebooster")
|
||||
s.anonymous=true
|
||||
s.addremove=false
|
||||
|
||||
o = s:option(Flag, "enabled", translate("Enable"))
|
||||
o.default = 0
|
||||
o.optional = false
|
||||
|
||||
function o.write(self, section, value)
|
||||
if value == "1" then
|
||||
luci.sys.call("/etc/init.d/uugamebooster start >/dev/null && /etc/init.d/uugamebooster enable >/dev/null")
|
||||
else
|
||||
luci.sys.call("/etc/init.d/uugamebooster stop >/dev/null && /etc/init.d/uugamebooster disable >/dev/null")
|
||||
end
|
||||
return Flag.write(self, section, value)
|
||||
end
|
||||
|
||||
return mp
|
||||
@ -0,0 +1,17 @@
|
||||
require("luci.util")
|
||||
|
||||
mp = Map("uuplugin", translate("UU Game Accelerator"))
|
||||
mp.description = translate("A Paid Game Acceleration service")
|
||||
mp:section(SimpleSection).template = "uuplugin/uuplugin_status"
|
||||
|
||||
s = mp:section(TypedSection, "uuplugin")
|
||||
s.anonymous=true
|
||||
s.addremove=false
|
||||
|
||||
o = s:option(Flag, "enabled", translate("Enable"))
|
||||
o.default = 0
|
||||
o.optional = false
|
||||
|
||||
mp:section(SimpleSection).template = "uuplugin/uuplugin_qcode"
|
||||
|
||||
return mp
|
||||
@ -1,21 +0,0 @@
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(3, '<%=url([[admin]], [[services]], [[uugamebooster]], [[status]])%>', null,
|
||||
function(x, data) {
|
||||
var tb = document.getElementById('uugamebooster_status');
|
||||
if (data && tb) {
|
||||
if (data.running) {
|
||||
tb.innerHTML = '<em><b><font color=green>UU Game Booster <%:RUNNING%></font></b></em>';
|
||||
} else {
|
||||
tb.innerHTML = '<em><b><font color=red>UU Game Booster <%:NOT RUNNING%></font></b></em>';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
|
||||
<fieldset class="cbi-section">
|
||||
<p id="uugamebooster_status">
|
||||
<em><%:Collecting data...%></em>
|
||||
</p>
|
||||
</fieldset>
|
||||
@ -0,0 +1,6 @@
|
||||
|
||||
<fieldset class="cbi-section">
|
||||
<p id="uugamebooster_qcode">
|
||||
<img src="/uuios.png" height="300" /><img src="/uuandriod.png" height="300" />
|
||||
</p>
|
||||
</fieldset>
|
||||
@ -0,0 +1,21 @@
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(3, '<%=url([[admin]], [[services]], [[uuplugin]], [[status]])%>', null,
|
||||
function(x, data) {
|
||||
var tb = document.getElementById('uuplugin_status');
|
||||
if (data && tb) {
|
||||
if (data.running) {
|
||||
tb.innerHTML = '<em><b><font color=green>UU GameAcc <%:RUNNING%></font></b></em>';
|
||||
} else {
|
||||
tb.innerHTML = '<em><b><font color=red>UU GameAcc <%:NOT RUNNING%></font></b></em>';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
|
||||
<fieldset class="cbi-section">
|
||||
<p id="uuplugin_status">
|
||||
<em><%:Collecting data...%></em>
|
||||
</p>
|
||||
</fieldset>
|
||||
@ -1,9 +0,0 @@
|
||||
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "UU Game Booster"
|
||||
msgstr "网易UU网游加速器"
|
||||
|
||||
msgid "A Paid Game Acceleration service"
|
||||
msgstr "一个富家子弟用的游戏加速器"
|
||||
12
package/lean/luci-app-uugamebooster/po/zh-cn/uuplugin.po
Normal file
12
package/lean/luci-app-uugamebooster/po/zh-cn/uuplugin.po
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "UU GameAcc"
|
||||
msgstr "UU游戏加速器"
|
||||
|
||||
msgid "UU Game Accelerator"
|
||||
msgstr "UU游戏加速器"
|
||||
|
||||
msgid "A Paid Game Acceleration service"
|
||||
msgstr "一个富家子弟用的主机游戏加速器 (开启服务后,使用手机APP绑定路由器并指定加速主机)"
|
||||
@ -1,4 +0,0 @@
|
||||
|
||||
config uugamebooster 'uugamebooster'
|
||||
option enabled '0'
|
||||
|
||||
@ -0,0 +1,4 @@
|
||||
|
||||
config uuplugin 'uuplugin'
|
||||
option enabled '0'
|
||||
|
||||
23
package/lean/luci-app-uugamebooster/root/etc/init.d/uuplugin
Executable file
23
package/lean/luci-app-uugamebooster/root/etc/init.d/uuplugin
Executable file
@ -0,0 +1,23 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=99
|
||||
STOP=10
|
||||
|
||||
USE_PROCD=1
|
||||
|
||||
NAME="uugamebooster"
|
||||
UU_BIN="/usr/share/uugamebooster/uuplugin"
|
||||
UU_CONF="/usr/share/uugamebooster/uu.conf"
|
||||
UU_LOGFILE="/tmp/uugamebooster.log"
|
||||
|
||||
start_service() {
|
||||
config_load uuplugin
|
||||
local enable
|
||||
config_get_bool enable uuplugin enabled
|
||||
if [ "$enable" -eq 1 ]; then
|
||||
procd_open_instance
|
||||
procd_set_param command $UU_BIN $UU_CONF >$UU_LOGFILE 2>&1
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
fi
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@uugamebooster[-1]
|
||||
add ucitrack uugamebooster
|
||||
set ucitrack.@uugamebooster[-1].init=uugamebooster
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
||||
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@uuplugin[-1]
|
||||
add ucitrack uuplugin
|
||||
set ucitrack.@uuplugin[-1].init=uuplugin
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
||||
@ -23,18 +23,19 @@ PKG_BUILD_PARALLEL:=1
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/shadowsocksr-libev
|
||||
define Package/shadowsocksr-libev/Default
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
SUBMENU:=Web Servers/Proxies
|
||||
TITLE:=Lightweight Secured Socks5 Proxy
|
||||
URL:=https://github.com/shadowsocksrr/shadowsocksr-libev
|
||||
DEPENDS:=+libev +libsodium +libopenssl +libpthread +libpcre +libudns +zlib
|
||||
PROVIDES:=shadowsocksr-libev
|
||||
endef
|
||||
|
||||
Package/shadowsocksr-libev-server = $(Package/shadowsocksr-libev)
|
||||
Package/shadowsocksr-libev-alt = $(Package/shadowsocksr-libev)
|
||||
Package/shadowsocksr-libev-ssr-local = $(Package/shadowsocksr-libev)
|
||||
Package/shadowsocksr-libev-server = $(Package/shadowsocksr-libev/Default)
|
||||
Package/shadowsocksr-libev-alt = $(Package/shadowsocksr-libev/Default)
|
||||
Package/shadowsocksr-libev-ssr-local = $(Package/shadowsocksr-libev/Default)
|
||||
|
||||
CONFIGURE_ARGS += --disable-documentation --disable-ssp --disable-assert \
|
||||
--enable-system-shared-lib
|
||||
@ -42,15 +43,6 @@ CONFIGURE_ARGS += --disable-documentation --disable-ssp --disable-assert \
|
||||
TARGET_CFLAGS += -flto
|
||||
TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed
|
||||
|
||||
define Package/shadowsocksr-libev/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/ss-redir $(1)/usr/bin/ssr-redir
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/ss-local $(1)/usr/bin/ssr-local
|
||||
$(LN) ssr-local $(1)/usr/bin/ssr-tunnel
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/server/ss-check $(1)/usr/bin/ssr-check
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/server/ss-server $(1)/usr/bin/ssr-server
|
||||
endef
|
||||
|
||||
define Package/shadowsocksr-libev-alt/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/ss-redir $(1)/usr/bin/ssr-redir
|
||||
@ -68,7 +60,6 @@ define Package/shadowsocksr-libev-ssr-local/install
|
||||
$(LN) ssr-local $(1)/usr/bin/ssr-tunnel
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,shadowsocksr-libev))
|
||||
$(eval $(call BuildPackage,shadowsocksr-libev-alt))
|
||||
$(eval $(call BuildPackage,shadowsocksr-libev-server))
|
||||
$(eval $(call BuildPackage,shadowsocksr-libev-ssr-local))
|
||||
|
||||
@ -13,7 +13,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=uugamebooster
|
||||
PKG_VERSION:=v2.7.2
|
||||
PKG_RELEASE:=6
|
||||
PKG_RELEASE:=5
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
@ -70,8 +70,8 @@ define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/uugamebooster.init $(1)/etc/init.d/uugamebooster
|
||||
# $(INSTALL_DIR) $(1)/etc/init.d
|
||||
# $(INSTALL_BIN) ./files/uugamebooster.init $(1)/etc/init.d/uuplugin
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/share/$(PKG_NAME)
|
||||
$(INSTALL_BIN) $(UNTAR_DIR)/uuplugin $(1)/usr/share/$(PKG_NAME)/uuplugin
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=99
|
||||
STOP=10
|
||||
|
||||
USE_PROCD=1
|
||||
|
||||
NAME="uugamebooster"
|
||||
UU_BIN="/usr/share/uugamebooster/uuplugin"
|
||||
UU_CONF="/usr/share/uugamebooster/uu.conf"
|
||||
UU_LOGFILE="/tmp/uugamebooster.log"
|
||||
|
||||
start_service() {
|
||||
procd_open_instance
|
||||
procd_set_param command $UU_BIN $UU_CONF >$UU_LOGFILE 2>&1
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
}
|
||||
@ -9,13 +9,13 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=xray
|
||||
PKG_VERSION:=1.2.2
|
||||
PKG_VERSION:=1.2.3
|
||||
PKG_RELEASE:=1
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/Xray-core-$(PKG_VERSION)
|
||||
|
||||
PKG_SOURCE:=xray-core-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/XTLS/xray-core/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=b9b38bc69e660d3a6d0545efea4d0891ee81a2d55c83a6fa893cbd680a071023
|
||||
PKG_HASH:=1deed281d2b976c0132b57194a09b62a1b978ec1b35d8329894b80f8d47befb7
|
||||
|
||||
PKG_LICENSE:=MPL
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
@ -79,7 +79,6 @@ endef
|
||||
ifeq ($(CONFIG_XRAY_COMPRESS_GOPROXY),y)
|
||||
export GO111MODULE=on
|
||||
export GOPROXY=https://goproxy.io
|
||||
#export GOPROXY=https://mirrors.aliyun.com/goproxy/
|
||||
endif
|
||||
|
||||
GEOIP_VER:=latest
|
||||
|
||||
@ -7,8 +7,8 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall
|
||||
PKG_VERSION:=4
|
||||
PKG_RELEASE:=7
|
||||
PKG_DATE:=20210111
|
||||
PKG_RELEASE:=10
|
||||
PKG_DATE:=20210122
|
||||
|
||||
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
|
||||
@ -69,10 +69,6 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG
|
||||
bool "Include ChinaDNS-NG"
|
||||
default n
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_https_dns_proxy
|
||||
bool "Include Https DNS Proxy(DoH)"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_dns2socks
|
||||
bool "Include dns2socks"
|
||||
default n
|
||||
@ -96,7 +92,6 @@ define Package/$(PKG_NAME)
|
||||
DEPENDS:=+libmbedtls +iptables-mod-tproxy +ip +ipset +coreutils +coreutils-base64 +coreutils-nohup +luci-lib-jsonc \
|
||||
+curl +ca-certificates +resolveip +unzip +dnsmasq-full +tcping +libuci-lua \
|
||||
+ipt2socks \
|
||||
+ssocks \
|
||||
+microsocks \
|
||||
+pdnsd-alt \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks:shadowsocks-libev-ss-redir \
|
||||
@ -106,7 +101,6 @@ define Package/$(PKG_NAME)
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR:shadowsocksr-libev-ssr-local \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server:shadowsocksr-libev-server \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:xray \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan_Plus:trojan-plus \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan_GO:trojan-go \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy:naiveproxy \
|
||||
@ -114,7 +108,6 @@ define Package/$(PKG_NAME)
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_kcptun:kcptun-client \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_haproxy:haproxy \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG:chinadns-ng \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_https_dns_proxy:https-dns-proxy \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_dns2socks:dns2socks \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_v2ray-plugin:v2ray-plugin \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs:simple-obfs
|
||||
|
||||
@ -9,7 +9,6 @@ local api = require "luci.model.cbi.passwall.api.api"
|
||||
local kcptun = require "luci.model.cbi.passwall.api.kcptun"
|
||||
local brook = require "luci.model.cbi.passwall.api.brook"
|
||||
local xray = require "luci.model.cbi.passwall.api.xray"
|
||||
local v2ray = require "luci.model.cbi.passwall.api.v2ray"
|
||||
local trojan_go = require "luci.model.cbi.passwall.api.trojan_go"
|
||||
|
||||
function index()
|
||||
@ -72,8 +71,6 @@ function index()
|
||||
entry({"admin", "services", appname, "brook_update"}, call("brook_update")).leaf = true
|
||||
entry({"admin", "services", appname, "xray_check"}, call("xray_check")).leaf = true
|
||||
entry({"admin", "services", appname, "xray_update"}, call("xray_update")).leaf = true
|
||||
entry({"admin", "services", appname, "v2ray_check"}, call("v2ray_check")).leaf = true
|
||||
entry({"admin", "services", appname, "v2ray_update"}, call("v2ray_update")).leaf = true
|
||||
entry({"admin", "services", appname, "trojan_go_check"}, call("trojan_go_check")).leaf = true
|
||||
entry({"admin", "services", appname, "trojan_go_update"}, call("trojan_go_update")).leaf = true
|
||||
end
|
||||
@ -191,12 +188,12 @@ function socks_status()
|
||||
local index = luci.http.formvalue("index")
|
||||
local id = luci.http.formvalue("id")
|
||||
e.index = index
|
||||
e.socks_status = luci.sys.call(string.format("ps -w | grep -v grep | grep '%s/bin/' | grep 'SOCKS_%s' > /dev/null", appname, id)) == 0
|
||||
e.socks_status = luci.sys.call(string.format("ps -w | grep -v grep | grep '%s/bin/' | grep '%s' | grep 'SOCKS_' > /dev/null", appname, id)) == 0
|
||||
local use_http = ucic:get(appname, id, "http_port") or 0
|
||||
e.use_http = 0
|
||||
if tonumber(use_http) > 0 then
|
||||
e.use_http = 1
|
||||
e.http_status = luci.sys.call(string.format("ps -w | grep -v grep | grep '%s/bin/' | grep 'SOCKS2HTTP_%s' > /dev/null", appname, id)) == 0
|
||||
e.http_status = luci.sys.call(string.format("ps -w | grep -v grep | grep '%s/bin/' | grep '%s' | grep -E 'HTTP_|HTTP2SOCKS' > /dev/null", appname, id)) == 0
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
@ -413,25 +410,6 @@ function xray_update()
|
||||
http_write_json(json)
|
||||
end
|
||||
|
||||
function v2ray_check()
|
||||
local json = v2ray.to_check("")
|
||||
http_write_json(json)
|
||||
end
|
||||
|
||||
function v2ray_update()
|
||||
local json = nil
|
||||
local task = http.formvalue("task")
|
||||
if task == "extract" then
|
||||
json = v2ray.to_extract(http.formvalue("file"), http.formvalue("subfix"))
|
||||
elseif task == "move" then
|
||||
json = v2ray.to_move(http.formvalue("file"))
|
||||
else
|
||||
json = v2ray.to_download(http.formvalue("url"))
|
||||
end
|
||||
|
||||
http_write_json(json)
|
||||
end
|
||||
|
||||
function trojan_go_check()
|
||||
local json = trojan_go.to_check("")
|
||||
http_write_json(json)
|
||||
|
||||
@ -149,31 +149,6 @@ function get_xray_version(file)
|
||||
return ""
|
||||
end
|
||||
|
||||
function get_v2ray_path()
|
||||
local path = uci_get_type("global_app", "v2ray_file")
|
||||
return path
|
||||
end
|
||||
|
||||
function get_v2ray_version(file)
|
||||
if file == nil then file = get_v2ray_path() end
|
||||
chmod_755(file)
|
||||
if fs.access(file) then
|
||||
if file == get_v2ray_path() then
|
||||
local md5 = sys.exec("echo -n $(md5sum " .. file .. " | awk '{print $1}')")
|
||||
if fs.access("/tmp/psw_" .. md5) then
|
||||
return sys.exec("cat /tmp/psw_" .. md5)
|
||||
else
|
||||
local version = sys.exec("echo -n $(%s -version | awk '{print $2}' | sed -n 1P)" % file)
|
||||
sys.call("echo '" .. version .. "' > " .. "/tmp/psw_" .. md5)
|
||||
return version
|
||||
end
|
||||
else
|
||||
return sys.exec("echo -n $(%s -version | awk '{print $2}' | sed -n 1P)" % file)
|
||||
end
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
function get_trojan_go_path()
|
||||
local path = uci_get_type("global_app", "trojan_go_file")
|
||||
return path
|
||||
|
||||
@ -1,15 +1,8 @@
|
||||
module("luci.model.cbi.passwall.api.gen_xray", package.seeall)
|
||||
local api = require "luci.model.cbi.passwall.api.api"
|
||||
local ucursor = require"luci.model.uci".cursor()
|
||||
local sys = require "luci.sys"
|
||||
local json = require "luci.jsonc"
|
||||
local appname = "passwall"
|
||||
local inbounds = {}
|
||||
local outbounds = {}
|
||||
local routing = nil
|
||||
|
||||
local myarg = {
|
||||
"-node", "-proto", "-redir_port", "-socks_proxy_port", "-loglevel"
|
||||
"-node", "-proto", "-redir_port", "-socks_proxy_port", "-http_proxy_port", "-dns_listen_port", "-dns_server", "-doh_url", "-doh_host", "-doh_socks_address", "-doh_socks_port", "-loglevel"
|
||||
}
|
||||
|
||||
local var = api.get_args(arg, myarg)
|
||||
@ -18,10 +11,26 @@ local node_section = var["-node"]
|
||||
local proto = var["-proto"]
|
||||
local redir_port = var["-redir_port"]
|
||||
local socks_proxy_port = var["-socks_proxy_port"]
|
||||
local http_proxy_port = var["-http_proxy_port"]
|
||||
local dns_listen_port = var["-dns_listen_port"]
|
||||
local dns_server = var["-dns_server"]
|
||||
local doh_url = var["-doh_url"]
|
||||
local doh_host = var["-doh_host"]
|
||||
local doh_socks_address = var["-doh_socks_address"]
|
||||
local doh_socks_port = var["-doh_socks_port"]
|
||||
local loglevel = var["-loglevel"] or "warning"
|
||||
local network = proto
|
||||
local new_port
|
||||
|
||||
local ucursor = require"luci.model.uci".cursor()
|
||||
local sys = require "luci.sys"
|
||||
local json = require "luci.jsonc"
|
||||
local appname = "passwall"
|
||||
local dns = nil
|
||||
local inbounds = {}
|
||||
local outbounds = {}
|
||||
local routing = nil
|
||||
|
||||
local function get_new_port()
|
||||
if new_port then
|
||||
new_port = tonumber(sys.exec(string.format("echo -n $(/usr/share/%s/app.sh get_new_port %s tcp)", appname, new_port + 1)))
|
||||
@ -48,13 +57,13 @@ function gen_outbound(node, tag, relay_port)
|
||||
node.port = new_port
|
||||
sys.call(string.format('/usr/share/%s/app.sh run_socks "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s"> /dev/null',
|
||||
appname,
|
||||
new_port,
|
||||
node_id,
|
||||
"127.0.0.1",
|
||||
new_port,
|
||||
string.format("/var/etc/%s/v2_%s_%s.json", appname, node_type, node_id),
|
||||
"0",
|
||||
"nil",
|
||||
"4",
|
||||
relay_port and tostring(relay_port) or ""
|
||||
)
|
||||
)
|
||||
@ -142,7 +151,7 @@ function gen_outbound(node, tag, relay_port)
|
||||
{
|
||||
id = node.uuid,
|
||||
alterId = tonumber(node.alter_id),
|
||||
level = node.level and tonumber(node.level) or 0,
|
||||
level = 0,
|
||||
security = (node.protocol == "vmess") and node.security or nil,
|
||||
encryption = node.encryption or "none",
|
||||
flow = node.flow or nil
|
||||
@ -178,6 +187,14 @@ if node_section then
|
||||
})
|
||||
network = "tcp,udp"
|
||||
end
|
||||
if http_proxy_port then
|
||||
table.insert(inbounds, {
|
||||
listen = "0.0.0.0",
|
||||
port = tonumber(http_proxy_port),
|
||||
protocol = "http",
|
||||
settings = {allowTransparent = false}
|
||||
})
|
||||
end
|
||||
|
||||
if redir_port then
|
||||
table.insert(inbounds, {
|
||||
@ -269,6 +286,38 @@ if node_section then
|
||||
local default_node_id = node.default_node or nil
|
||||
if default_node_id and default_node_id ~= "nil" then
|
||||
local default_node = ucursor:get_all(appname, default_node_id)
|
||||
if "1" == node.default_proxy then
|
||||
local node_id = node.main_node or nil
|
||||
if node_id and node_id ~= "nil" then
|
||||
if node_id == default_node_id then
|
||||
else
|
||||
new_port = get_new_port()
|
||||
table.insert(inbounds, {
|
||||
tag = "proxy_default",
|
||||
listen = "127.0.0.1",
|
||||
port = new_port,
|
||||
protocol = "dokodemo-door",
|
||||
settings = {network = "tcp,udp", address = default_node.address, port = tonumber(default_node.port)}
|
||||
})
|
||||
if default_node.tls_serverName == nil then
|
||||
default_node.tls_serverName = default_node.address
|
||||
end
|
||||
default_node.address = "127.0.0.1"
|
||||
default_node.port = new_port
|
||||
local node = ucursor:get_all(appname, node_id)
|
||||
local outbound = gen_outbound(node, "main")
|
||||
if outbound then
|
||||
table.insert(outbounds, outbound)
|
||||
local rule = {
|
||||
type = "field",
|
||||
inboundTag = {"proxy_default"},
|
||||
outboundTag = "main"
|
||||
}
|
||||
table.insert(rules, rule)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
local default_outbound = gen_outbound(default_node, "default")
|
||||
if default_outbound then
|
||||
table.insert(outbounds, default_outbound)
|
||||
@ -307,21 +356,132 @@ if node_section then
|
||||
local outbound = gen_outbound(node)
|
||||
if outbound then table.insert(outbounds, outbound) end
|
||||
end
|
||||
end
|
||||
|
||||
-- 额外传出连接
|
||||
table.insert(outbounds, {protocol = "freedom", tag = "direct", settings = {keep = ""}})
|
||||
if dns_server then
|
||||
local rules = {}
|
||||
|
||||
dns = {
|
||||
tag = "dns-in1",
|
||||
servers = {
|
||||
dns_server
|
||||
}
|
||||
}
|
||||
if doh_url and doh_host then
|
||||
dns.hosts = {
|
||||
[doh_host] = dns_server
|
||||
}
|
||||
dns.servers = {
|
||||
doh_url
|
||||
}
|
||||
end
|
||||
|
||||
if dns_listen_port then
|
||||
table.insert(inbounds, {
|
||||
listen = "127.0.0.1",
|
||||
port = tonumber(dns_listen_port),
|
||||
protocol = "dokodemo-door",
|
||||
tag = "dns-in",
|
||||
settings = {
|
||||
address = dns_server,
|
||||
port = 53,
|
||||
network = "udp"
|
||||
}
|
||||
})
|
||||
table.insert(outbounds, {
|
||||
protocol = "dns",
|
||||
tag = "dns-out"
|
||||
})
|
||||
end
|
||||
|
||||
table.insert(rules, {
|
||||
type = "field",
|
||||
inboundTag = {
|
||||
"dns-in"
|
||||
},
|
||||
outboundTag = "dns-out"
|
||||
})
|
||||
|
||||
if doh_socks_address and doh_socks_port then
|
||||
table.insert(outbounds, {
|
||||
tag = "out",
|
||||
protocol = "socks",
|
||||
streamSettings = {
|
||||
network = "tcp",
|
||||
security = "none"
|
||||
},
|
||||
settings = {
|
||||
servers = {
|
||||
{
|
||||
address = doh_socks_address,
|
||||
port = tonumber(doh_socks_port)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
table.insert(rules, {
|
||||
type = "field",
|
||||
inboundTag = {
|
||||
"dns-in1"
|
||||
},
|
||||
outboundTag = "out"
|
||||
})
|
||||
else
|
||||
table.insert(rules, {
|
||||
type = "field",
|
||||
inboundTag = {
|
||||
"dns-in1"
|
||||
},
|
||||
outboundTag = "direct"
|
||||
})
|
||||
end
|
||||
|
||||
routing = {
|
||||
domainStrategy = "IPOnDemand",
|
||||
rules = rules
|
||||
}
|
||||
end
|
||||
|
||||
if inbounds or outbounds then
|
||||
table.insert(outbounds, {
|
||||
protocol = "freedom",
|
||||
tag = "direct",
|
||||
settings = {domainStrategy = "UseIPv4"}
|
||||
})
|
||||
|
||||
local xray = {
|
||||
log = {
|
||||
-- error = string.format("/var/etc/passwall/%s.log", node[".name"]),
|
||||
loglevel = loglevel
|
||||
},
|
||||
-- DNS
|
||||
dns = dns,
|
||||
-- 传入连接
|
||||
inbounds = inbounds,
|
||||
-- 传出连接
|
||||
outbounds = outbounds,
|
||||
-- 路由
|
||||
routing = routing
|
||||
routing = routing,
|
||||
-- 本地策略
|
||||
--[[
|
||||
policy = {
|
||||
levels = {
|
||||
[0] = {
|
||||
handshake = 4,
|
||||
connIdle = 300,
|
||||
uplinkOnly = 2,
|
||||
downlinkOnly = 5,
|
||||
bufferSize = 10240,
|
||||
statsUserUplink = false,
|
||||
statsUserDownlink = false
|
||||
}
|
||||
},
|
||||
system = {
|
||||
statsInboundUplink = false,
|
||||
statsInboundDownlink = false
|
||||
}
|
||||
}
|
||||
]]--
|
||||
}
|
||||
print(json.stringify(xray, 1))
|
||||
end
|
||||
|
||||
@ -1,173 +0,0 @@
|
||||
module("luci.model.cbi.passwall.api.v2ray", package.seeall)
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
local util = require "luci.util"
|
||||
local i18n = require "luci.i18n"
|
||||
local api = require "luci.model.cbi.passwall.api.api"
|
||||
|
||||
local v2ray_api = "https://api.github.com/repos/v2fly/v2ray-core/releases/latest"
|
||||
local is_armv7 = false
|
||||
|
||||
function to_check(arch)
|
||||
local app_path = api.get_v2ray_path() or ""
|
||||
if app_path == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("You did not fill in the %s path. Please save and apply then update manually.", "V2ray")
|
||||
}
|
||||
end
|
||||
if not arch or arch == "" then arch = api.auto_get_arch() end
|
||||
|
||||
local file_tree, sub_version = api.get_file_info(arch)
|
||||
if sub_version == "7" then is_armv7 = true end
|
||||
|
||||
if file_tree == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Can't determine ARCH, or ARCH not supported.")
|
||||
}
|
||||
end
|
||||
|
||||
if file_tree == "amd64" then file_tree = "64" end
|
||||
if file_tree == "386" then file_tree = "32" end
|
||||
|
||||
local json = api.get_api_json(v2ray_api)
|
||||
|
||||
if json.tag_name == nil then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Get remote version info failed.")
|
||||
}
|
||||
end
|
||||
|
||||
local now_version = api.get_v2ray_version()
|
||||
local remote_version = json.tag_name:match("[^v]+")
|
||||
local needs_update = api.compare_versions(now_version, "<", remote_version)
|
||||
local html_url, download_url
|
||||
|
||||
if needs_update then
|
||||
html_url = json.html_url
|
||||
for _, v in ipairs(json.assets) do
|
||||
if v.name and v.name:match("linux%-" .. file_tree) then
|
||||
download_url = v.browser_download_url
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if needs_update and not download_url then
|
||||
return {
|
||||
code = 1,
|
||||
now_version = now_version,
|
||||
version = remote_version,
|
||||
html_url = html_url,
|
||||
error = i18n.translate("New version found, but failed to get new version download url.")
|
||||
}
|
||||
end
|
||||
|
||||
return {
|
||||
code = 0,
|
||||
update = needs_update,
|
||||
now_version = now_version,
|
||||
version = remote_version,
|
||||
url = {html = html_url, download = download_url}
|
||||
}
|
||||
end
|
||||
|
||||
function to_download(url)
|
||||
local app_path = api.get_v2ray_path() or ""
|
||||
if app_path == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("You did not fill in the %s path. Please save and apply then update manually.", "V2ray")
|
||||
}
|
||||
end
|
||||
if not url or url == "" then
|
||||
return {code = 1, error = i18n.translate("Download url is required.")}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -f /tmp/v2ray_download.*")
|
||||
|
||||
local tmp_file = util.trim(util.exec("mktemp -u -t v2ray_download.XXXXXX"))
|
||||
|
||||
local result = api.exec(api.curl, {api._unpack(api.curl_args), "-o", tmp_file, url}, nil, api.command_timeout) == 0
|
||||
|
||||
if not result then
|
||||
api.exec("/bin/rm", {"-f", tmp_file})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("File download failed or timed out: %s", url)
|
||||
}
|
||||
end
|
||||
|
||||
return {code = 0, file = tmp_file}
|
||||
end
|
||||
|
||||
function to_extract(file, subfix)
|
||||
local app_path = api.get_v2ray_path() or ""
|
||||
if app_path == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("You did not fill in the %s path. Please save and apply then update manually.", "V2ray")
|
||||
}
|
||||
end
|
||||
|
||||
if not file or file == "" or not fs.access(file) then
|
||||
return {code = 1, error = i18n.translate("File path required.")}
|
||||
end
|
||||
|
||||
if sys.exec("echo -n $(opkg list-installed | grep -c unzip)") ~= "1" then
|
||||
api.exec("/bin/rm", {"-f", file})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Not installed unzip, Can't unzip!")
|
||||
}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -rf /tmp/v2ray_extract.*")
|
||||
local tmp_dir = util.trim(util.exec("mktemp -d -t v2ray_extract.XXXXXX"))
|
||||
|
||||
local output = {}
|
||||
api.exec("/usr/bin/unzip", {"-o", file, "-d", tmp_dir},
|
||||
function(chunk) output[#output + 1] = chunk end)
|
||||
|
||||
local files = util.split(table.concat(output))
|
||||
|
||||
api.exec("/bin/rm", {"-f", file})
|
||||
|
||||
return {code = 0, file = tmp_dir}
|
||||
end
|
||||
|
||||
function to_move(file)
|
||||
local app_path = api.get_v2ray_path() or ""
|
||||
if app_path == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("You did not fill in the %s path. Please save and apply then update manually.", "V2ray")
|
||||
}
|
||||
end
|
||||
if not file or file == "" then
|
||||
sys.call("/bin/rm -rf /tmp/v2ray_extract.*")
|
||||
return {code = 1, error = i18n.translate("Client file is required.")}
|
||||
end
|
||||
|
||||
if not arch or arch == "" then arch = api.auto_get_arch() end
|
||||
local file_tree, sub_version = api.get_file_info(arch)
|
||||
local t = ""
|
||||
sys.call("/etc/init.d/passwall stop")
|
||||
local result = nil
|
||||
if sub_version and sub_version == "7" then t = "_armv7" end
|
||||
result = api.exec("/bin/mv", { "-f", file .. "/v2ray" .. t, app_path }, nil, api.command_timeout) == 0
|
||||
sys.call("/bin/rm -rf /tmp/v2ray_extract.*")
|
||||
if not result or not fs.access(app_path) then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("Can't move new file to path: %s", app_path)
|
||||
}
|
||||
end
|
||||
|
||||
api.chmod_755(app_path)
|
||||
sys.call("/etc/init.d/passwall restart >/dev/null 2>&1 &")
|
||||
|
||||
return {code = 0}
|
||||
end
|
||||
@ -10,7 +10,6 @@ s = m:section(TypedSection, "global_app", translate("App Update"),
|
||||
"</font>")
|
||||
s.anonymous = true
|
||||
s:append(Template(appname .. "/app_update/xray_version"))
|
||||
s:append(Template(appname .. "/app_update/v2ray_version"))
|
||||
s:append(Template(appname .. "/app_update/trojan_go_version"))
|
||||
s:append(Template(appname .. "/app_update/kcptun_version"))
|
||||
s:append(Template(appname .. "/app_update/brook_version"))
|
||||
@ -19,10 +18,6 @@ o = s:option(Value, "xray_file", translatef("%s App Path", "Xray"))
|
||||
o.default = "/usr/bin/xray"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "v2ray_file", translatef("%s App Path", "V2ray"))
|
||||
o.default = "/usr/bin/v2ray"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "trojan_go_file", translatef("%s App Path", "Trojan-Go"))
|
||||
o.default = "/usr/bin/trojan-go"
|
||||
o.rmempty = false
|
||||
|
||||
@ -2,16 +2,27 @@ local d = require "luci.dispatcher"
|
||||
local uci = require"luci.model.uci".cursor()
|
||||
local api = require "luci.model.cbi.passwall.api.api"
|
||||
local appname = "passwall"
|
||||
local has_xray = api.is_finded("xray")
|
||||
|
||||
m = Map(appname)
|
||||
|
||||
local nodes_table = {}
|
||||
for k, e in ipairs(api.get_valid_nodes()) do
|
||||
nodes_table[#nodes_table + 1] = {
|
||||
id = e[".name"],
|
||||
remarks = e.remarks_name
|
||||
remarks = e.remarks_name,
|
||||
type = e["type"]
|
||||
}
|
||||
end
|
||||
|
||||
local socks_table = {}
|
||||
if tonumber(m:get("@global[0]", "tcp_node_socks") or 0) == 1 then
|
||||
local id = "127.0.0.1" .. ":" .. m:get("@global[0]", "tcp_node_socks_port")
|
||||
socks_table[#socks_table + 1] = {
|
||||
id = id,
|
||||
remarks = id .. " - " .. translate("TCP Node")
|
||||
}
|
||||
end
|
||||
uci:foreach(appname, "socks", function(s)
|
||||
if s.enabled == "1" and s.node then
|
||||
local id, remarks
|
||||
@ -25,7 +36,7 @@ uci:foreach(appname, "socks", function(s)
|
||||
end
|
||||
end
|
||||
end
|
||||
id = "0.0.0.0" .. ":" .. s.port
|
||||
id = "127.0.0.1" .. ":" .. s.port
|
||||
socks_table[#socks_table + 1] = {
|
||||
id = id,
|
||||
remarks = id .. " - " .. (remarks or translate("Misconfigured"))
|
||||
@ -55,7 +66,6 @@ local doh_validate = function(self, value, t)
|
||||
return nil, translate("DoH request address") .. " " .. translate("Format must be:") .. " URL,IP"
|
||||
end
|
||||
|
||||
m = Map(appname)
|
||||
local status = m:get("@global_other[0]", "status") or ""
|
||||
if status:find("big_icon") then
|
||||
m:append(Template(appname .. "/global/status"))
|
||||
@ -74,11 +84,11 @@ o = s:taboption("Main", Flag, "enabled", translate("Main switch"))
|
||||
o.rmempty = false
|
||||
|
||||
---- TCP Node
|
||||
o = s:taboption("Main", ListValue, "tcp_node", translate("TCP Node"))
|
||||
o.title = translate("TCP Node")
|
||||
o.description = ""
|
||||
--o.description = translate("For proxy specific list.")
|
||||
--o.description = o.description .. "<br />"
|
||||
tcp_node = s:taboption("Main", ListValue, "tcp_node", translate("TCP Node"))
|
||||
tcp_node.title = translate("TCP Node")
|
||||
tcp_node.description = ""
|
||||
--tcp_node.description = translate("For proxy specific list.")
|
||||
--tcp_node.description = o.description .. "<br />"
|
||||
local current_node = luci.sys.exec(string.format("[ -f '/var/etc/%s/id/TCP' ] && echo -n $(cat /var/etc/%s/id/TCP)", appname, appname))
|
||||
if current_node and current_node ~= "" and current_node ~= "nil" then
|
||||
local n = uci:get_all(appname, current_node)
|
||||
@ -86,7 +96,7 @@ if current_node and current_node ~= "" and current_node ~= "nil" then
|
||||
if tonumber(m:get("@auto_switch[0]", "enable") or 0) == 1 then
|
||||
local remarks = api.get_full_node_remarks(n)
|
||||
local url = d.build_url("admin", "services", appname, "node_config", current_node)
|
||||
o.description = o.description .. translatef("Current node: %s", string.format('<a href="%s">%s</a>', url, remarks)) .. "<br />"
|
||||
tcp_node.description = tcp_node.description .. translatef("Current node: %s", string.format('<a href="%s">%s</a>', url, remarks)) .. "<br />"
|
||||
end
|
||||
if n.protocol and n.protocol == "_shunt" then
|
||||
uci:foreach(appname, "shunt_rules", function(e)
|
||||
@ -95,7 +105,7 @@ if current_node and current_node ~= "" and current_node ~= "nil" then
|
||||
if n[id] and n[id] ~= "nil" then
|
||||
local url = d.build_url("admin", "services", appname, "node_config", n[id])
|
||||
local r = api.get_full_node_remarks(uci:get_all(appname, n[id]))
|
||||
o.description = o.description .. remarks .. ":" .. string.format('<a href="%s">%s</a>', url, r) .. "<br />"
|
||||
tcp_node.description = tcp_node.description .. remarks .. ":" .. string.format('<a href="%s">%s</a>', url, r) .. "<br />"
|
||||
end
|
||||
end)
|
||||
local id = "default_node"
|
||||
@ -103,22 +113,32 @@ if current_node and current_node ~= "" and current_node ~= "nil" then
|
||||
if n[id] and n[id] ~= "nil" then
|
||||
local url = d.build_url("admin", "services", appname, "node_config", n[id])
|
||||
local r = api.get_full_node_remarks(uci:get_all(appname, n[id]))
|
||||
o.description = o.description .. remarks .. ":" .. string.format('<a href="%s">%s</a>', url, r) .. "<br />"
|
||||
tcp_node.description = tcp_node.description .. remarks .. ":" .. string.format('<a href="%s">%s</a>', url, r) .. "<br />"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
o:value("nil", translate("Close"))
|
||||
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
|
||||
tcp_node:value("nil", translate("Close"))
|
||||
|
||||
o = s:taboption("Main", ListValue, "udp_node", translate("UDP Node"))
|
||||
o:value("nil", translate("Close"))
|
||||
o.title = translate("UDP Node")
|
||||
--o.description = translate("For proxy game network, DNS hijack etc.") .. "<br />" .. translate("The selected server will not use Kcptun.")
|
||||
o:value("tcp_", translate("Same as the tcp node"))
|
||||
--o:value("tcp", translate("Same as the tcp node"))
|
||||
--o:value("tcp_", translate("Same as the tcp node") .. "(" .. translate("New process") .. ")")
|
||||
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
|
||||
udp_node = s:taboption("Main", ListValue, "udp_node", translate("UDP Node"))
|
||||
udp_node:value("nil", translate("Close"))
|
||||
udp_node.title = translate("UDP Node")
|
||||
--udp_node.description = translate("For proxy game network, DNS hijack etc.") .. "<br />" .. translate("The selected server will not use Kcptun.")
|
||||
udp_node:value("tcp_", translate("Same as the tcp node"))
|
||||
--udp_node:value("tcp", translate("Same as the tcp node"))
|
||||
--udp_node:value("tcp_", translate("Same as the tcp node") .. "(" .. translate("New process") .. ")")
|
||||
|
||||
tcp_node_socks = s:taboption("Main", Flag, "tcp_node_socks", translate("Enable") .. translate("TCP Node") .. "Socks")
|
||||
o = s:taboption("Main", Value, "tcp_node_socks_port", "Socks" .. translate("Listen Port"))
|
||||
o.default = 1080
|
||||
o.datatype = "port"
|
||||
o:depends("tcp_node_socks", true)
|
||||
|
||||
tcp_node_http = s:taboption("Main", Flag, "tcp_node_http", translate("Enable") .. translate("TCP Node") .. "Http")
|
||||
o = s:taboption("Main", Value, "tcp_node_http_port", "HTTP" .. translate("Listen Port"))
|
||||
o.default = 1180
|
||||
o.datatype = "port"
|
||||
o:depends("tcp_node_http", true)
|
||||
|
||||
s:tab("DNS", translate("DNS"))
|
||||
|
||||
@ -131,12 +151,12 @@ if api.is_finded("chinadns-ng") then
|
||||
o:depends("chinadns_ng", "1")
|
||||
end
|
||||
|
||||
o = s:taboption("DNS", Value, "up_china_dns", translate("Resolver For Local/WhiteList Domains") .. "(UDP)")
|
||||
o = s:taboption("DNS", Value, "up_china_dns", translate("Local DNS") .. "(UDP)")
|
||||
o.description = translate("IP:Port mode acceptable, multi value split with english comma.") .. "<br />" .. translate("When the selection is not the default, this DNS is forced to be set to dnsmasq upstream DNS.")
|
||||
o.default = "default"
|
||||
o:value("default", translate("Default"))
|
||||
if api.is_finded("https-dns-proxy") then
|
||||
o:value("https-dns-proxy", "https-dns-proxy(DoH)")
|
||||
if has_xray then
|
||||
o:value("xray_doh", "Xray DNS(DoH)")
|
||||
end
|
||||
o:value("223.5.5.5", "223.5.5.5 (" .. translate("Ali") .. "DNS)")
|
||||
o:value("223.6.6.6", "223.6.6.6 (" .. translate("Ali") .. "DNS)")
|
||||
@ -150,24 +170,24 @@ o:value("180.76.76.76", "180.76.76.76 (" .. translate("Baidu") .. "DNS)")
|
||||
|
||||
---- DoH
|
||||
o = s:taboption("DNS", Value, "up_china_dns_doh", translate("DoH request address"))
|
||||
o:value("https://dns.alidns.com/dns-query,223.5.5.5,223.6.6.6", "AliDNS")
|
||||
o:value("https://doh.pub/dns-query,119.29.29.29,119.28.28.28", "DNSPod")
|
||||
o.default = "https://dns.alidns.com/dns-query,223.5.5.5,223.6.6.6"
|
||||
o:value("https://dns.alidns.com/dns-query,223.5.5.5", "AliDNS")
|
||||
o:value("https://doh.pub/dns-query,119.29.29.29", "DNSPod")
|
||||
o.default = "https://dns.alidns.com/dns-query,223.5.5.5"
|
||||
o.validate = doh_validate
|
||||
o:depends("up_china_dns", "https-dns-proxy")
|
||||
o:depends("up_china_dns", "xray_doh")
|
||||
|
||||
---- DNS Forward Mode
|
||||
o = s:taboption("DNS", ListValue, "dns_mode", translate("Filter Mode"))
|
||||
o.rmempty = false
|
||||
o:reset_values()
|
||||
if api.is_finded("pdnsd") then
|
||||
o:value("pdnsd", "pdnsd")
|
||||
o:value("pdnsd", "pdnsd " .. translatef("Requery DNS By %s", translate("TCP Node")))
|
||||
end
|
||||
if api.is_finded("dns2socks") then
|
||||
o:value("dns2socks", "dns2socks")
|
||||
end
|
||||
if api.is_finded("https-dns-proxy") then
|
||||
o:value("https-dns-proxy", "https-dns-proxy(DoH)")
|
||||
if has_xray then
|
||||
o:value("xray_doh", "Xray DNS(DoH)")
|
||||
end
|
||||
o:value("udp", translatef("Requery DNS By %s", translate("UDP Node")))
|
||||
o:value("nonuse", translate("No Filter"))
|
||||
@ -185,17 +205,10 @@ o.validate = function(self, value, t)
|
||||
end
|
||||
o:depends({dns_mode = "custom"})
|
||||
|
||||
o = s:taboption("DNS", ListValue, "up_trust_pdnsd_dns", translate("Resolver For The List Proxied"))
|
||||
-- o.description = translate("You can use other resolving DNS services as trusted DNS, Example: dns2socks, dns-forwarder... 127.0.0.1#5353<br />Only use two at most, english comma separation, If you do not fill in the # and the following port, you are using port 53.")
|
||||
o.default = "tcp"
|
||||
o:value("tcp", translatef("Requery DNS By %s", translate("TCP Node")))
|
||||
o:value("udp", translatef("Requery DNS By %s", translate("UDP Node")))
|
||||
o:depends("dns_mode", "pdnsd")
|
||||
|
||||
o = s:taboption("DNS", ListValue, "up_trust_doh_dns", translate("Resolver For The List Proxied"))
|
||||
o:value("tcp", translatef("Requery DNS By %s", translate("TCP Node")))
|
||||
o:value("socks", translatef("Requery DNS By %s", translate("Socks Node")))
|
||||
o:depends("dns_mode", "https-dns-proxy")
|
||||
o:depends("dns_mode", "xray_doh")
|
||||
|
||||
o = s:taboption("DNS", Value, "socks_server", translate("Socks Server"), translate("Make sure socks service is available on this address."))
|
||||
for k, v in pairs(socks_table) do o:value(v.id, v.remarks) end
|
||||
@ -206,27 +219,28 @@ o.validate = function(self, value, t)
|
||||
return value
|
||||
end
|
||||
o:depends({dns_mode = "dns2socks"})
|
||||
o:depends({dns_mode = "https-dns-proxy", up_trust_doh_dns = "socks"})
|
||||
o:depends({dns_mode = "xray_doh", up_trust_doh_dns = "socks"})
|
||||
|
||||
---- DoH
|
||||
o = s:taboption("DNS", Value, "up_trust_doh", translate("DoH request address"))
|
||||
o:value("https://dns.adguard.com/dns-query,176.103.130.130,176.103.130.131", "AdGuard")
|
||||
o:value("https://cloudflare-dns.com/dns-query,1.1.1.1,1.0.0.1", "Cloudflare")
|
||||
o:value("https://security.cloudflare-dns.com/dns-query,1.1.1.2,1.0.0.2", "Cloudflare-Security")
|
||||
o:value("https://doh.opendns.com/dns-query,208.67.222.222,208.67.220.220", "OpenDNS")
|
||||
o:value("https://dns.google/dns-query,8.8.8.8,8.8.4.4", "Google")
|
||||
o:value("https://dns.adguard.com/dns-query,176.103.130.130", "AdGuard")
|
||||
o:value("https://cloudflare-dns.com/dns-query,1.1.1.1", "Cloudflare")
|
||||
o:value("https://security.cloudflare-dns.com/dns-query,1.1.1.2", "Cloudflare-Security")
|
||||
o:value("https://doh.opendns.com/dns-query,208.67.222.222", "OpenDNS")
|
||||
o:value("https://dns.google/dns-query,8.8.8.8", "Google")
|
||||
o:value("https://doh.libredns.gr/dns-query,116.202.176.26", "LibreDNS")
|
||||
o:value("https://doh.libredns.gr/ads,116.202.176.26", "LibreDNS (No Ads)")
|
||||
o:value("https://dns.quad9.net/dns-query,9.9.9.9,149.112.112.112", "Quad9-Recommended")
|
||||
o.default = "https://dns.google/dns-query,8.8.8.8,8.8.4.4"
|
||||
o:value("https://dns.quad9.net/dns-query,9.9.9.9", "Quad9-Recommended")
|
||||
o.default = "https://dns.google/dns-query,8.8.8.8"
|
||||
o.validate = doh_validate
|
||||
o:depends({dns_mode = "https-dns-proxy"})
|
||||
o:depends({dns_mode = "xray_doh"})
|
||||
|
||||
---- DNS Forward
|
||||
o = s:taboption("DNS", Value, "dns_forward", translate("Filtered DNS(For Proxied Domains)"), translate("IP:Port mode acceptable, the 1st for 'dns2socks' if split with english comma."))
|
||||
o.default = "8.8.4.4"
|
||||
o:value("8.8.4.4", "8.8.4.4 (Google DNS)")
|
||||
o = s:taboption("DNS", Value, "dns_forward", translate("Remote DNS"))
|
||||
--o.description = translate("IP:Port mode acceptable, multi value split with english comma.") .. " " .. translate("If you use dns2socks, only the first one is valid.")
|
||||
o.default = "8.8.8.8"
|
||||
o:value("8.8.8.8", "8.8.8.8 (Google DNS)")
|
||||
o:value("8.8.4.4", "8.8.4.4 (Google DNS)")
|
||||
o:value("208.67.222.222", "208.67.222.222 (Open DNS)")
|
||||
o:value("208.67.220.220", "208.67.220.220 (Open DNS)")
|
||||
o:depends({dns_mode = "dns2socks"})
|
||||
@ -240,9 +254,6 @@ o:depends({dns_mode = "dns2socks"})
|
||||
o:depends({dns_mode = "pdnsd"})
|
||||
]]--
|
||||
|
||||
o = s:taboption("DNS", Flag, "use_chnlist", translate("Use ChinaList"), translate("Only useful in non-gfwlist mode.") .. "<br />" .. translate("When used, the domestic DNS will be used only when the chnlist rule is hit, and the domain name that misses the rule will be resolved by remote DNS."))
|
||||
o.default = "0"
|
||||
|
||||
o = s:taboption("DNS", Button, "clear_ipset", translate("Clear IPSET"), translate("Try this feature if the rule modification does not take effect."))
|
||||
o.inputstyle = "remove"
|
||||
function o.write(e, e)
|
||||
@ -344,21 +355,35 @@ o = s:option(Flag, "enabled", translate("Enable"))
|
||||
o.default = 1
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "node", translate("Socks Node"))
|
||||
o:value("tcp", translate("Same as the tcp node"))
|
||||
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
|
||||
socks_node = s:option(ListValue, "node", translate("Socks Node"))
|
||||
|
||||
o = s:option(Value, "port", "Socks" .. translate("Listen Port"))
|
||||
o.default = 9050
|
||||
o.datatype = "port"
|
||||
o.rmempty = false
|
||||
|
||||
if api.is_finded("xray") or api.is_finded("v2ray") then
|
||||
if has_xray then
|
||||
o = s:option(Value, "http_port", "HTTP" .. translate("Listen Port") .. " " .. translate("0 is not use"))
|
||||
o.default = 0
|
||||
o.datatype = "port"
|
||||
end
|
||||
|
||||
for k, v in pairs(nodes_table) do
|
||||
tcp_node:value(v.id, v.remarks)
|
||||
tcp_node_socks:depends("tcp_node", v.id)
|
||||
if has_xray then
|
||||
tcp_node_http:depends("tcp_node", v.id)
|
||||
end
|
||||
udp_node:value(v.id, v.remarks)
|
||||
if v.type == "Socks" then
|
||||
if has_xray then
|
||||
socks_node:value(v.id, v.remarks)
|
||||
end
|
||||
else
|
||||
socks_node:value(v.id, v.remarks)
|
||||
end
|
||||
end
|
||||
|
||||
m:append(Template(appname .. "/global/footer"))
|
||||
|
||||
--[[
|
||||
|
||||
@ -83,9 +83,6 @@ if api.is_finded("xray") then
|
||||
type:value("Xray", translate("Xray"))
|
||||
type.description = translate("Xray is currently directly compatible with V2ray and used.")
|
||||
end
|
||||
if api.is_finded("v2ray") then
|
||||
type:value("V2ray", translate("V2ray"))
|
||||
end
|
||||
if api.is_finded("brook") then
|
||||
type:value("Brook", translate("Brook"))
|
||||
end
|
||||
@ -113,7 +110,6 @@ protocol:value("shadowsocks", translate("Shadowsocks"))
|
||||
protocol:value("trojan", translate("Trojan"))
|
||||
protocol:value("_balancing", translate("Balancing"))
|
||||
protocol:value("_shunt", translate("Shunt"))
|
||||
protocol:depends("type", "V2ray")
|
||||
protocol:depends("type", "Xray")
|
||||
|
||||
local nodes_table = {}
|
||||
@ -155,6 +151,14 @@ default_node:value("nil", translate("Close"))
|
||||
for k, v in pairs(nodes_table) do default_node:value(v.id, v.remarks) end
|
||||
default_node:depends("protocol", "_shunt")
|
||||
|
||||
default_proxy = s:option(Flag, "default_proxy", translate("Default") .. translate("Node") .. translate("Preproxy"), translate("Use the under node for the transit."))
|
||||
default_proxy.default = 0
|
||||
default_proxy:depends("protocol", "_shunt")
|
||||
|
||||
o = s:option(ListValue, "main_node", " ")
|
||||
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
|
||||
o:depends("default_proxy", "1")
|
||||
|
||||
domainStrategy = s:option(ListValue, "domainStrategy", translate("Domain Strategy"))
|
||||
domainStrategy:value("AsIs")
|
||||
domainStrategy:value("IPIfNonMatch")
|
||||
@ -209,12 +213,6 @@ address:depends({ type = "Xray", protocol = "http" })
|
||||
address:depends({ type = "Xray", protocol = "socks" })
|
||||
address:depends({ type = "Xray", protocol = "shadowsocks" })
|
||||
address:depends({ type = "Xray", protocol = "trojan" })
|
||||
address:depends({ type = "V2ray", protocol = "vmess" })
|
||||
address:depends({ type = "V2ray", protocol = "vless" })
|
||||
address:depends({ type = "V2ray", protocol = "http" })
|
||||
address:depends({ type = "V2ray", protocol = "socks" })
|
||||
address:depends({ type = "V2ray", protocol = "shadowsocks" })
|
||||
address:depends({ type = "V2ray", protocol = "trojan" })
|
||||
|
||||
--[[
|
||||
use_ipv6 = s:option(Flag, "use_ipv6", translate("Use IPv6"))
|
||||
@ -232,12 +230,6 @@ use_ipv6:depends({ type = "Xray", protocol = "http" })
|
||||
use_ipv6:depends({ type = "Xray", protocol = "socks" })
|
||||
use_ipv6:depends({ type = "Xray", protocol = "shadowsocks" })
|
||||
use_ipv6:depends({ type = "Xray", protocol = "trojan" })
|
||||
use_ipv6:depends({ type = "V2ray", protocol = "vmess" })
|
||||
use_ipv6:depends({ type = "V2ray", protocol = "vless" })
|
||||
use_ipv6:depends({ type = "V2ray", protocol = "http" })
|
||||
use_ipv6:depends({ type = "V2ray", protocol = "socks" })
|
||||
use_ipv6:depends({ type = "V2ray", protocol = "shadowsocks" })
|
||||
use_ipv6:depends({ type = "V2ray", protocol = "trojan" })
|
||||
--]]
|
||||
|
||||
port = s:option(Value, "port", translate("Port"))
|
||||
@ -257,20 +249,12 @@ port:depends({ type = "Xray", protocol = "http" })
|
||||
port:depends({ type = "Xray", protocol = "socks" })
|
||||
port:depends({ type = "Xray", protocol = "shadowsocks" })
|
||||
port:depends({ type = "Xray", protocol = "trojan" })
|
||||
port:depends({ type = "V2ray", protocol = "vmess" })
|
||||
port:depends({ type = "V2ray", protocol = "vless" })
|
||||
port:depends({ type = "V2ray", protocol = "http" })
|
||||
port:depends({ type = "V2ray", protocol = "socks" })
|
||||
port:depends({ type = "V2ray", protocol = "shadowsocks" })
|
||||
port:depends({ type = "V2ray", protocol = "trojan" })
|
||||
|
||||
username = s:option(Value, "username", translate("Username"))
|
||||
username:depends("type", "Socks")
|
||||
username:depends("type", "Naiveproxy")
|
||||
username:depends({ type = "Xray", protocol = "http" })
|
||||
username:depends({ type = "Xray", protocol = "socks" })
|
||||
username:depends({ type = "V2ray", protocol = "http" })
|
||||
username:depends({ type = "V2ray", protocol = "socks" })
|
||||
|
||||
password = s:option(Value, "password", translate("Password"))
|
||||
password.password = true
|
||||
@ -286,10 +270,6 @@ password:depends({ type = "Xray", protocol = "http" })
|
||||
password:depends({ type = "Xray", protocol = "socks" })
|
||||
password:depends({ type = "Xray", protocol = "shadowsocks" })
|
||||
password:depends({ type = "Xray", protocol = "trojan" })
|
||||
password:depends({ type = "V2ray", protocol = "http" })
|
||||
password:depends({ type = "V2ray", protocol = "socks" })
|
||||
password:depends({ type = "V2ray", protocol = "shadowsocks" })
|
||||
password:depends({ type = "V2ray", protocol = "trojan" })
|
||||
|
||||
ss_encrypt_method = s:option(ListValue, "ss_encrypt_method", translate("Encrypt Method"))
|
||||
for a, t in ipairs(ss_encrypt_method_list) do ss_encrypt_method:value(t) end
|
||||
@ -314,12 +294,10 @@ end
|
||||
security = s:option(ListValue, "security", translate("Encrypt Method"))
|
||||
for a, t in ipairs(security_list) do security:value(t) end
|
||||
security:depends({ type = "Xray", protocol = "vmess" })
|
||||
security:depends({ type = "V2ray", protocol = "vmess" })
|
||||
|
||||
encryption = s:option(Value, "encryption", translate("Encrypt Method"))
|
||||
encryption.default = "none"
|
||||
encryption:depends({ type = "Xray", protocol = "vless" })
|
||||
encryption:depends({ type = "V2ray", protocol = "vless" })
|
||||
|
||||
v_ss_encrypt_method = s:option(ListValue, "v_ss_encrypt_method", translate("Encrypt Method"))
|
||||
for a, t in ipairs(v_ss_encrypt_method_list) do v_ss_encrypt_method:value(t) end
|
||||
@ -411,21 +389,10 @@ uuid = s:option(Value, "uuid", translate("ID"))
|
||||
uuid.password = true
|
||||
uuid:depends({ type = "Xray", protocol = "vmess" })
|
||||
uuid:depends({ type = "Xray", protocol = "vless" })
|
||||
uuid:depends({ type = "V2ray", protocol = "vmess" })
|
||||
uuid:depends({ type = "V2ray", protocol = "vless" })
|
||||
|
||||
alter_id = s:option(Value, "alter_id", translate("Alter ID"))
|
||||
alter_id:depends("protocol", "vmess")
|
||||
|
||||
level = s:option(Value, "level", translate("User Level"))
|
||||
level.default = 1
|
||||
level:depends({ type = "Xray", protocol = "vmess" })
|
||||
level:depends({ type = "Xray", protocol = "vless" })
|
||||
level:depends({ type = "Xray", protocol = "trojan" })
|
||||
level:depends({ type = "V2ray", protocol = "vmess" })
|
||||
level:depends({ type = "V2ray", protocol = "vless" })
|
||||
level:depends({ type = "V2ray", protocol = "trojan" })
|
||||
|
||||
tls = s:option(Flag, "tls", translate("TLS"))
|
||||
tls.default = 0
|
||||
tls.validate = function(self, value, t)
|
||||
@ -442,11 +409,6 @@ tls:depends({ type = "Xray", protocol = "vless" })
|
||||
tls:depends({ type = "Xray", protocol = "socks" })
|
||||
tls:depends({ type = "Xray", protocol = "trojan" })
|
||||
tls:depends({ type = "Xray", protocol = "shadowsocks" })
|
||||
tls:depends({ type = "V2ray", protocol = "vmess" })
|
||||
tls:depends({ type = "V2ray", protocol = "vless" })
|
||||
tls:depends({ type = "V2ray", protocol = "socks" })
|
||||
tls:depends({ type = "V2ray", protocol = "shadowsocks" })
|
||||
tls:depends({ type = "Xray", protocol = "trojan" })
|
||||
tls:depends("type", "Trojan")
|
||||
tls:depends("type", "Trojan-Plus")
|
||||
tls:depends("type", "Trojan-Go")
|
||||
@ -535,11 +497,6 @@ transport:depends({ type = "Xray", protocol = "vless" })
|
||||
transport:depends({ type = "Xray", protocol = "socks" })
|
||||
transport:depends({ type = "Xray", protocol = "shadowsocks" })
|
||||
transport:depends({ type = "Xray", protocol = "trojan" })
|
||||
transport:depends({ type = "V2ray", protocol = "vmess" })
|
||||
transport:depends({ type = "V2ray", protocol = "vless" })
|
||||
transport:depends({ type = "V2ray", protocol = "socks" })
|
||||
transport:depends({ type = "V2ray", protocol = "shadowsocks" })
|
||||
transport:depends({ type = "V2ray", protocol = "trojan" })
|
||||
|
||||
--[[
|
||||
ss_transport = s:option(ListValue, "ss_transport", translate("Transport"))
|
||||
@ -547,7 +504,6 @@ ss_transport:value("ws", "WebSocket")
|
||||
ss_transport:value("h2", "HTTP/2")
|
||||
ss_transport:value("h2+ws", "HTTP/2 & WebSocket")
|
||||
ss_transport:depends({ type = "Xray", protocol = "shadowsocks" })
|
||||
ss_transport:depends({ type = "V2ray", protocol = "shadowsocks" })
|
||||
]]--
|
||||
|
||||
-- [[ TCP部分 ]]--
|
||||
@ -667,11 +623,6 @@ mux:depends({ type = "Xray", protocol = "vless", xtls = false })
|
||||
mux:depends({ type = "Xray", protocol = "http" })
|
||||
mux:depends({ type = "Xray", protocol = "socks" })
|
||||
mux:depends({ type = "Xray", protocol = "shadowsocks" })
|
||||
mux:depends({ type = "V2ray", protocol = "vmess" })
|
||||
mux:depends({ type = "V2ray", protocol = "vless" })
|
||||
mux:depends({ type = "V2ray", protocol = "http" })
|
||||
mux:depends({ type = "V2ray", protocol = "socks" })
|
||||
mux:depends({ type = "V2ray", protocol = "shadowsocks" })
|
||||
mux:depends("type", "Trojan-Go")
|
||||
|
||||
mux_concurrency = s:option(Value, "mux_concurrency", translate("Mux Concurrency"))
|
||||
@ -683,7 +634,6 @@ mux_concurrency:depends("mux", "1")
|
||||
tcp_socks = s:option(Flag, "tcp_socks", translate("TCP Open Socks"), translate("When using this TCP node, whether to open the socks proxy at the same time"))
|
||||
tcp_socks.default = 0
|
||||
tcp_socks:depends("type", "Xray")
|
||||
tcp_socks:depends("type", "V2ray")
|
||||
|
||||
tcp_socks_port = s:option(Value, "tcp_socks_port", "Socks " .. translate("Port"), translate("Do not conflict with other ports"))
|
||||
tcp_socks_port.datatype = "port"
|
||||
|
||||
@ -63,7 +63,7 @@ if nodes_display:find("compact_display_nodes") then
|
||||
local remarks = m:get(n, "remarks") or ""
|
||||
local type = m:get(n, "type") or ""
|
||||
str = str .. string.format("<input type='hidden' id='cbid.%s.%s.type' value='%s'/>", appname, n, type)
|
||||
if type == "Xray" or type == "V2ray" then
|
||||
if type == "Xray" then
|
||||
local protocol = m:get(n, "protocol")
|
||||
if protocol == "_balancing" then
|
||||
type = type .. " 负载均衡"
|
||||
@ -106,7 +106,7 @@ else
|
||||
local v = Value.cfgvalue(t, n)
|
||||
if v then
|
||||
result = translate(v)
|
||||
if v == "Xray" or v == "V2ray" then
|
||||
if v == "Xray" then
|
||||
local protocol = m:get(n, "protocol")
|
||||
if protocol == "_balancing" then
|
||||
result = result .. " 负载均衡"
|
||||
|
||||
@ -49,7 +49,7 @@ for e = 0, 23 do o:value(e, e .. translate("oclock")) end
|
||||
o.default = 0
|
||||
o:depends("auto_update", 1)
|
||||
|
||||
s = m:section(TypedSection, "shunt_rules", "Xray/V2ray" .. translate("Shunt") .. translate("Rule"))
|
||||
s = m:section(TypedSection, "shunt_rules", "Xray" .. translate("Shunt") .. translate("Rule"))
|
||||
s.template = "cbi/tblsection"
|
||||
s.anonymous = false
|
||||
s.addremove = true
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
local d = require "luci.dispatcher"
|
||||
local appname = "passwall"
|
||||
|
||||
m = Map(appname, "Xray/V2ray" .. translate("Shunt") .. translate("Rule"))
|
||||
m = Map(appname, "Xray" .. translate("Shunt") .. translate("Rule"))
|
||||
m.redirect = d.build_url("admin", "services", appname)
|
||||
|
||||
s = m:section(NamedSection, arg[1], "shunt_rules", "")
|
||||
|
||||
@ -112,9 +112,6 @@ local function start()
|
||||
elseif type == "Xray" then
|
||||
config = require("luci.model.cbi.passwall.server.api.xray").gen_config(user)
|
||||
bin = ln_start(_api.get_xray_path(), "xray", "-config=" .. config_file, log_path)
|
||||
elseif type == "V2ray" then
|
||||
config = require("luci.model.cbi.passwall.server.api.v2ray").gen_config(user)
|
||||
bin = ln_start(_api.get_v2ray_path(), "v2ray", "-config=" .. config_file, log_path)
|
||||
elseif type == "Trojan" then
|
||||
config = require("luci.model.cbi.passwall.server.api.trojan").gen_config(user)
|
||||
bin = ln_start("/usr/sbin/trojan", "trojan", "-c " .. config_file, log_path)
|
||||
|
||||
@ -1,177 +0,0 @@
|
||||
module("luci.model.cbi.passwall.server.api.v2ray", package.seeall)
|
||||
local ucic = require"luci.model.uci".cursor()
|
||||
|
||||
function gen_config(user)
|
||||
local settings = nil
|
||||
local routing = nil
|
||||
local outbounds = {
|
||||
{protocol = "freedom", tag = "direct"}, {protocol = "blackhole", tag = "blocked"}
|
||||
}
|
||||
|
||||
if user.protocol == "vmess" or user.protocol == "vless" then
|
||||
if user.uuid then
|
||||
local clients = {}
|
||||
for i = 1, #user.uuid do
|
||||
clients[i] = {
|
||||
id = user.uuid[i],
|
||||
flow = user.flow or nil,
|
||||
level = tonumber(user.level),
|
||||
alterId = tonumber(user.alter_id)
|
||||
}
|
||||
end
|
||||
settings = {
|
||||
clients = clients,
|
||||
decryption = user.decryption or "none"
|
||||
}
|
||||
end
|
||||
elseif user.protocol == "socks" then
|
||||
settings = {
|
||||
auth = (user.auth and user.auth == "1") and "password" or "noauth",
|
||||
accounts = (user.auth and user.auth == "1") and {
|
||||
{
|
||||
user = user.username,
|
||||
pass = user.password
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif user.protocol == "http" then
|
||||
settings = {
|
||||
allowTransparent = false,
|
||||
accounts = (user.auth and user.auth == "1") and {
|
||||
{
|
||||
user = user.username,
|
||||
pass = user.password
|
||||
}
|
||||
}
|
||||
}
|
||||
user.transport = "tcp"
|
||||
user.tcp_guise = "none"
|
||||
elseif user.protocol == "shadowsocks" then
|
||||
settings = {
|
||||
method = user.method,
|
||||
password = user.password,
|
||||
level = tonumber(user.level) or 1,
|
||||
network = user.ss_network or "TCP,UDP"
|
||||
}
|
||||
elseif user.protocol == "trojan" then
|
||||
if user.uuid then
|
||||
local clients = {}
|
||||
for i = 1, #user.uuid do
|
||||
clients[i] = {
|
||||
password = user.uuid[i],
|
||||
level = tonumber(user.level)
|
||||
}
|
||||
end
|
||||
settings = {
|
||||
clients = clients
|
||||
}
|
||||
end
|
||||
elseif user.protocol == "mtproto" then
|
||||
settings = {
|
||||
users = {
|
||||
{
|
||||
level = tonumber(user.level) or 1,
|
||||
secret = (user.password == nil) and "" or user.password
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
routing = {
|
||||
domainStrategy = "IPOnDemand",
|
||||
rules = {
|
||||
{
|
||||
type = "field",
|
||||
ip = {"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"},
|
||||
outboundTag = (user.accept_lan == nil or user.accept_lan == "0") and "blocked" or "direct"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if user.transit_node and user.transit_node ~= "nil" then
|
||||
local gen_v2ray = require("luci.model.cbi.passwall.api.gen_v2ray")
|
||||
local client = gen_v2ray.gen_outbound(ucic:get_all("passwall", user.transit_node), "transit")
|
||||
table.insert(outbounds, 1, client)
|
||||
end
|
||||
|
||||
local config = {
|
||||
log = {
|
||||
-- error = "/var/etc/passwall_server/log/" .. user[".name"] .. ".log",
|
||||
loglevel = (user.log and user.log == "1") and user.loglevel or "none"
|
||||
},
|
||||
-- 传入连接
|
||||
inbounds = {
|
||||
{
|
||||
listen = (user.bind_local == "1") and "127.0.0.1" or nil,
|
||||
port = tonumber(user.port),
|
||||
protocol = user.protocol,
|
||||
settings = settings,
|
||||
streamSettings = {
|
||||
network = user.transport,
|
||||
security = "none",
|
||||
tlsSettings = (user.tls and user.tls == "1") and {
|
||||
disableSystemRoot = false,
|
||||
certificates = {
|
||||
{
|
||||
certificateFile = user.tls_certificateFile,
|
||||
keyFile = user.tls_keyFile
|
||||
}
|
||||
}
|
||||
} or nil,
|
||||
tcpSettings = (user.transport == "tcp") and {
|
||||
header = {
|
||||
type = user.tcp_guise,
|
||||
request = (user.tcp_guise == "http") and {
|
||||
path = user.tcp_guise_http_path or {"/"},
|
||||
headers = {
|
||||
Host = user.tcp_guise_http_host or {}
|
||||
}
|
||||
} or nil
|
||||
}
|
||||
} or nil,
|
||||
kcpSettings = (user.transport == "mkcp") and {
|
||||
mtu = tonumber(user.mkcp_mtu),
|
||||
tti = tonumber(user.mkcp_tti),
|
||||
uplinkCapacity = tonumber(user.mkcp_uplinkCapacity),
|
||||
downlinkCapacity = tonumber(user.mkcp_downlinkCapacity),
|
||||
congestion = (user.mkcp_congestion == "1") and true or false,
|
||||
readBufferSize = tonumber(user.mkcp_readBufferSize),
|
||||
writeBufferSize = tonumber(user.mkcp_writeBufferSize),
|
||||
seed = (user.mkcp_seed and user.mkcp_seed ~= "") and user.mkcp_seed or nil,
|
||||
header = {type = user.mkcp_guise}
|
||||
} or nil,
|
||||
wsSettings = (user.transport == "ws") and {
|
||||
acceptProxyProtocol = false,
|
||||
headers = (user.ws_host) and {Host = user.ws_host} or nil,
|
||||
path = user.ws_path
|
||||
} or nil,
|
||||
httpSettings = (user.transport == "h2") and {
|
||||
path = user.h2_path, host = user.h2_host
|
||||
} or nil,
|
||||
dsSettings = (user.transport == "ds") and {
|
||||
path = user.ds_path
|
||||
} or nil,
|
||||
quicSettings = (user.transport == "quic") and {
|
||||
security = user.quic_security,
|
||||
key = user.quic_key,
|
||||
header = {type = user.quic_guise}
|
||||
} or nil
|
||||
}
|
||||
}
|
||||
},
|
||||
-- 传出连接
|
||||
outbounds = outbounds,
|
||||
routing = routing
|
||||
}
|
||||
|
||||
if user.tls and user.tls == "1" then
|
||||
config.inbounds[1].streamSettings.security = "tls"
|
||||
end
|
||||
|
||||
if user.transport == "mkcp" or user.transport == "quic" then
|
||||
config.inbounds[1].streamSettings.security = "none"
|
||||
config.inbounds[1].streamSettings.tlsSettings = nil
|
||||
end
|
||||
|
||||
return config
|
||||
end
|
||||
@ -47,7 +47,7 @@ e = t:option(DummyValue, "type", translate("Type"))
|
||||
e.cfgvalue = function(t, n)
|
||||
local v = Value.cfgvalue(t, n)
|
||||
if v then
|
||||
if v == "Xray" or v == "V2ray" then
|
||||
if v == "Xray" then
|
||||
local protocol = m:get(n, "protocol")
|
||||
return v .. " -> " .. protocol
|
||||
end
|
||||
|
||||
@ -80,9 +80,6 @@ end
|
||||
if api.is_finded("xray") then
|
||||
type:value("Xray", translate("Xray"))
|
||||
end
|
||||
if api.is_finded("v2ray") then
|
||||
type:value("V2ray", translate("V2ray"))
|
||||
end
|
||||
if api.is_finded("brook") then
|
||||
type:value("Brook", translate("Brook"))
|
||||
end
|
||||
@ -107,7 +104,6 @@ protocol:value("shadowsocks", "Shadowsocks")
|
||||
protocol:value("trojan", "Trojan")
|
||||
protocol:value("mtproto", "MTProto")
|
||||
protocol:depends("type", "Xray")
|
||||
protocol:depends("type", "V2ray")
|
||||
|
||||
-- Brook协议
|
||||
brook_protocol = s:option(ListValue, "brook_protocol", translate("Protocol"))
|
||||
@ -142,8 +138,6 @@ end
|
||||
auth:depends("type", "Socks")
|
||||
auth:depends({ type = "Xray", protocol = "socks" })
|
||||
auth:depends({ type = "Xray", protocol = "http" })
|
||||
auth:depends({ type = "V2ray", protocol = "socks" })
|
||||
auth:depends({ type = "V2ray", protocol = "http" })
|
||||
|
||||
username = s:option(Value, "username", translate("Username"))
|
||||
username:depends("auth", "1")
|
||||
@ -155,11 +149,9 @@ password:depends("type", "SS")
|
||||
password:depends("type", "SSR")
|
||||
password:depends("type", "Brook")
|
||||
password:depends({ type = "Xray", protocol = "shadowsocks" })
|
||||
password:depends({ type = "V2ray", protocol = "shadowsocks" })
|
||||
|
||||
mtproto_password = s:option(Value, "mtproto_password", translate("Password"), translate("The MTProto protocol must be 32 characters and can only contain characters from 0 to 9 and a to f."))
|
||||
mtproto_password:depends({ type = "Xray", protocol = "mtproto" })
|
||||
mtproto_password:depends({ type = "V2ray", protocol = "mtproto" })
|
||||
mtproto_password.default = arg[1]
|
||||
function mtproto_password.cfgvalue(self, section)
|
||||
return m:get(section, "password")
|
||||
@ -171,7 +163,6 @@ end
|
||||
decryption = s:option(Value, "decryption", translate("Encrypt Method"))
|
||||
decryption.default = "none"
|
||||
decryption:depends({ type = "Xray", protocol = "vless" })
|
||||
decryption:depends({ type = "V2ray", protocol = "vless" })
|
||||
|
||||
ss_encrypt_method = s:option(ListValue, "ss_encrypt_method", translate("Encrypt Method"))
|
||||
for a, t in ipairs(ss_encrypt_method_list) do ss_encrypt_method:value(t) end
|
||||
@ -196,7 +187,6 @@ end
|
||||
v_ss_encrypt_method = s:option(ListValue, "v_ss_encrypt_method", translate("Encrypt Method"))
|
||||
for a, t in ipairs(v_ss_encrypt_method_list) do v_ss_encrypt_method:value(t) end
|
||||
v_ss_encrypt_method:depends({ type = "Xray", protocol = "shadowsocks" })
|
||||
v_ss_encrypt_method:depends({ type = "V2ray", protocol = "shadowsocks" })
|
||||
function v_ss_encrypt_method.cfgvalue(self, section)
|
||||
return m:get(section, "method")
|
||||
end
|
||||
@ -210,7 +200,6 @@ ss_network:value("tcp", "TCP")
|
||||
ss_network:value("udp", "UDP")
|
||||
ss_network:value("tcp,udp", "TCP,UDP")
|
||||
ss_network:depends({ type = "Xray", protocol = "shadowsocks" })
|
||||
ss_network:depends({ type = "V2ray", protocol = "shadowsocks" })
|
||||
|
||||
ssr_protocol = s:option(ListValue, "ssr_protocol", translate("Protocol"))
|
||||
for a, t in ipairs(ssr_protocol_list) do ssr_protocol:value(t) end
|
||||
@ -250,16 +239,12 @@ end
|
||||
uuid:depends({ type = "Xray", protocol = "vmess" })
|
||||
uuid:depends({ type = "Xray", protocol = "vless" })
|
||||
uuid:depends({ type = "Xray", protocol = "trojan" })
|
||||
uuid:depends({ type = "V2ray", protocol = "vmess" })
|
||||
uuid:depends({ type = "V2ray", protocol = "vless" })
|
||||
uuid:depends({ type = "V2ray", protocol = "trojan" })
|
||||
uuid:depends("type", "Trojan")
|
||||
uuid:depends("type", "Trojan-Go")
|
||||
uuid:depends("type", "Trojan-Plus")
|
||||
|
||||
alter_id = s:option(Value, "alter_id", translate("Alter ID"))
|
||||
alter_id:depends({ type = "Xray", protocol = "vmess" })
|
||||
alter_id:depends({ type = "V2ray", protocol = "vmess" })
|
||||
|
||||
level = s:option(Value, "level", translate("User Level"))
|
||||
level:depends({ type = "Xray", protocol = "vmess" })
|
||||
@ -267,11 +252,6 @@ level:depends({ type = "Xray", protocol = "vless" })
|
||||
level:depends({ type = "Xray", protocol = "shadowsocks" })
|
||||
level:depends({ type = "Xray", protocol = "trojan" })
|
||||
level:depends({ type = "Xray", protocol = "mtproto" })
|
||||
level:depends({ type = "V2ray", protocol = "vmess" })
|
||||
level:depends({ type = "V2ray", protocol = "vless" })
|
||||
level:depends({ type = "V2ray", protocol = "shadowsocks" })
|
||||
level:depends({ type = "V2ray", protocol = "trojan" })
|
||||
level:depends({ type = "V2ray", protocol = "mtproto" })
|
||||
|
||||
tls = s:option(Flag, "tls", translate("TLS"))
|
||||
tls.default = 0
|
||||
@ -296,10 +276,6 @@ tls:depends({ type = "Xray", protocol = "vless" })
|
||||
tls:depends({ type = "Xray", protocol = "socks" })
|
||||
tls:depends({ type = "Xray", protocol = "shadowsocks" })
|
||||
tls:depends({ type = "Xray", protocol = "trojan" })
|
||||
tls:depends({ type = "V2ray", protocol = "vmess" })
|
||||
tls:depends({ type = "V2ray", protocol = "vless" })
|
||||
tls:depends({ type = "V2ray", protocol = "socks" })
|
||||
tls:depends({ type = "V2ray", protocol = "shadowsocks" })
|
||||
tls:depends("type", "Trojan")
|
||||
tls:depends("type", "Trojan-Plus")
|
||||
tls:depends("type", "Trojan-Go")
|
||||
@ -374,11 +350,6 @@ transport:depends({ type = "Xray", protocol = "vless" })
|
||||
transport:depends({ type = "Xray", protocol = "socks" })
|
||||
transport:depends({ type = "Xray", protocol = "shadowsocks" })
|
||||
transport:depends({ type = "Xray", protocol = "trojan" })
|
||||
transport:depends({ type = "V2ray", protocol = "vmess" })
|
||||
transport:depends({ type = "V2ray", protocol = "vless" })
|
||||
transport:depends({ type = "V2ray", protocol = "socks" })
|
||||
transport:depends({ type = "V2ray", protocol = "shadowsocks" })
|
||||
transport:depends({ type = "V2ray", protocol = "trojan" })
|
||||
|
||||
trojan_transport = s:option(ListValue, "trojan_transport", translate("Transport"))
|
||||
trojan_transport:value("original", "Original")
|
||||
@ -512,15 +483,11 @@ quic_guise:depends("transport", "quic")
|
||||
acceptProxyProtocol = s:option(Flag, "acceptProxyProtocol", translate("acceptProxyProtocol"), translate("Whether to receive PROXY protocol, when this node want to be fallback or forwarded by proxy, it must be enable, otherwise it cannot be used."))
|
||||
acceptProxyProtocol:depends({ type = "Xray", transport = "tcp" })
|
||||
acceptProxyProtocol:depends({ type = "Xray", transport = "ws" })
|
||||
acceptProxyProtocol:depends({ type = "V2ray", transport = "tcp" })
|
||||
acceptProxyProtocol:depends({ type = "V2ray", transport = "ws" })
|
||||
|
||||
-- [[ Fallback部分 ]]--
|
||||
fallback = s:option(Flag, "fallback", translate("Fallback"))
|
||||
fallback:depends({ type = "Xray", protocol = "vless", transport = "tcp" })
|
||||
fallback:depends({ type = "Xray", protocol = "trojan", transport = "tcp" })
|
||||
fallback:depends({ type = "V2ray", protocol = "vless", transport = "tcp" })
|
||||
fallback:depends({ type = "V2ray", protocol = "trojan", transport = "tcp" })
|
||||
|
||||
--[[
|
||||
fallback_alpn = s:option(Value, "fallback_alpn", "Fallback alpn")
|
||||
@ -580,17 +547,15 @@ remote_port:depends("remote_enable", 1)
|
||||
bind_local = s:option(Flag, "bind_local", translate("Bind Local"), translate("When selected, it can only be accessed locally, It is recommended to turn on when using reverse proxies or be fallback."))
|
||||
bind_local.default = "0"
|
||||
bind_local:depends("type", "Xray")
|
||||
bind_local:depends("type", "V2ray")
|
||||
|
||||
accept_lan = s:option(Flag, "accept_lan", translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!"))
|
||||
accept_lan.default = "0"
|
||||
accept_lan.rmempty = false
|
||||
accept_lan:depends("type", "Xray")
|
||||
accept_lan:depends("type", "V2ray")
|
||||
|
||||
local nodes_table = {}
|
||||
for k, e in ipairs(api.get_valid_nodes()) do
|
||||
if e.node_type == "normal" and e.type == "Xray" or e.type == "V2ray" then
|
||||
if e.node_type == "normal" and e.type == "Xray" then
|
||||
nodes_table[#nodes_table + 1] = {
|
||||
id = e[".name"],
|
||||
remarks = e.remarks_name
|
||||
@ -603,7 +568,6 @@ transit_node:value("nil", translate("Close"))
|
||||
for k, v in pairs(nodes_table) do transit_node:value(v.id, v.remarks) end
|
||||
transit_node.default = "nil"
|
||||
transit_node:depends("type", "Xray")
|
||||
transit_node:depends("type", "V2ray")
|
||||
|
||||
log = s:option(Flag, "log", translate("Enable") .. translate("Log"))
|
||||
log.default = "1"
|
||||
@ -616,7 +580,6 @@ loglevel:value("info")
|
||||
loglevel:value("warning")
|
||||
loglevel:value("error")
|
||||
loglevel:depends({ type = "Xray", log = true })
|
||||
loglevel:depends({ type = "V2ray", log = true })
|
||||
|
||||
trojan_loglevel = s:option(ListValue, "trojan_loglevel", translate("Log Level"))
|
||||
trojan_loglevel.default = "2"
|
||||
|
||||
@ -1,172 +0,0 @@
|
||||
<%
|
||||
local v2ray_version = require "luci.model.cbi.passwall.api.api".get_v2ray_version()
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var v2rayInfo;
|
||||
var tokenStr = '<%=token%>';
|
||||
var manuallyUpdateText = '<%:Manually update%>';
|
||||
var noUpdateText = '<%:It is the latest version%>';
|
||||
var updateSuccessText = '<%:Update successful%>';
|
||||
var clickToUpdateText = '<%:Click to update%>';
|
||||
var inProgressText = '<%:Updating...%>';
|
||||
var unexpectedErrorText = '<%:Unexpected error%>';
|
||||
var updateInProgressNotice = '<%:Updating, are you sure to close?%>';
|
||||
var downloadingText = '<%:Downloading...%>';
|
||||
var decompressioningText = '<%:Unpacking...%>';
|
||||
var movingText = '<%:Moving...%>';
|
||||
|
||||
window.onload = function() {
|
||||
var v2rayCheckBtn = document.getElementById('_v2ray-check_btn');
|
||||
var v2rayDetailElm = document.getElementById('_v2ray-check_btn-detail');
|
||||
};
|
||||
|
||||
function addPageNotice_v2ray() {
|
||||
window.onbeforeunload = function(e) {
|
||||
e.returnValue = updateInProgressNotice;
|
||||
return updateInProgressNotice;
|
||||
};
|
||||
}
|
||||
|
||||
function removePageNotice_v2ray() {
|
||||
window.onbeforeunload = undefined;
|
||||
}
|
||||
|
||||
function onUpdateSuccess_v2ray(btn) {
|
||||
alert(updateSuccessText);
|
||||
|
||||
if(btn) {
|
||||
btn.value = updateSuccessText;
|
||||
btn.placeholder = updateSuccessText;
|
||||
btn.disabled = true;
|
||||
}
|
||||
|
||||
window.setTimeout(function() {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function onRequestError_v2ray(btn, errorMessage) {
|
||||
btn.disabled = false;
|
||||
btn.value = manuallyUpdateText;
|
||||
|
||||
if(errorMessage) {
|
||||
alert(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
function onBtnClick_v2ray(btn) {
|
||||
if(v2rayInfo === undefined) {
|
||||
checkUpdate_v2ray(btn);
|
||||
} else {
|
||||
doUpdate_v2ray(btn);
|
||||
}
|
||||
}
|
||||
|
||||
function checkUpdate_v2ray(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = inProgressText;
|
||||
|
||||
addPageNotice_v2ray();
|
||||
|
||||
var ckeckDetailElm = document.getElementById(btn.id + '-detail');
|
||||
|
||||
XHR.get('<%=url([[admin]], [[services]], [[passwall]], [[v2ray_check]])%>', {
|
||||
token: tokenStr,
|
||||
arch: ''
|
||||
}, function(x,json) {
|
||||
removePageNotice_v2ray();
|
||||
|
||||
if(json.code) {
|
||||
v2rayInfo = undefined;
|
||||
onRequestError_v2ray(btn, json.error);
|
||||
} else {
|
||||
if(json.update) {
|
||||
v2rayInfo = json;
|
||||
btn.disabled = false;
|
||||
btn.value = clickToUpdateText;
|
||||
btn.placeholder = clickToUpdateText;
|
||||
|
||||
if(ckeckDetailElm) {
|
||||
var urlNode = '';
|
||||
if(json.version) {
|
||||
urlNode = '<em style="color:red;">最新版本号:' + json.version + '</em>';
|
||||
if(json.url && json.url.html) {
|
||||
urlNode = '<a href="' + json.url.html + '" target="_blank">' + urlNode + '</a>';
|
||||
}
|
||||
}
|
||||
ckeckDetailElm.innerHTML = urlNode;
|
||||
}
|
||||
} else {
|
||||
btn.disabled = true;
|
||||
btn.value = noUpdateText;
|
||||
}
|
||||
}
|
||||
},300);
|
||||
}
|
||||
|
||||
function doUpdate_v2ray(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = downloadingText;
|
||||
|
||||
addPageNotice_v2ray();
|
||||
|
||||
var v2rayUpdateUrl = '<%=url([[admin]], [[services]], [[passwall]], [[v2ray_update]])%>';
|
||||
// Download file
|
||||
XHR.get(v2rayUpdateUrl, {
|
||||
token: tokenStr,
|
||||
url: v2rayInfo ? v2rayInfo.url.download : ''
|
||||
}, function(x,json) {
|
||||
if(json.code) {
|
||||
removePageNotice_v2ray();
|
||||
onRequestError_v2ray(btn, json.error);
|
||||
} else {
|
||||
btn.value = decompressioningText;
|
||||
|
||||
// Extract file
|
||||
XHR.get(v2rayUpdateUrl, {
|
||||
token: tokenStr,
|
||||
task: 'extract',
|
||||
file: json.file,
|
||||
subfix: v2rayInfo ? v2rayInfo.type : ''
|
||||
}, function(x,json) {
|
||||
if(json.code) {
|
||||
removePageNotice_v2ray();
|
||||
onRequestError_v2ray(btn, json.error);
|
||||
} else {
|
||||
btn.value = movingText;
|
||||
|
||||
// Move file to target dir
|
||||
XHR.get(v2rayUpdateUrl, {
|
||||
token: tokenStr,
|
||||
task: 'move',
|
||||
file: json.file
|
||||
}, function(x,json) {
|
||||
removePageNotice_v2ray();
|
||||
if(json.code) {
|
||||
onRequestError_v2ray(btn, json.error);
|
||||
} else {
|
||||
onUpdateSuccess_v2ray(btn);
|
||||
}
|
||||
},300)
|
||||
}
|
||||
},300)
|
||||
}
|
||||
},300)
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title">V2ray
|
||||
<%:Version%>
|
||||
</label>
|
||||
<div class="cbi-value-field">
|
||||
<div class="cbi-value-description">
|
||||
<span>【 <%=v2ray_version%> 】</span>
|
||||
<input class="cbi-button cbi-input-apply" type="button" id="_v2ray-check_btn" onclick="onBtnClick_v2ray(this);" value="<%:Manually update%>" />
|
||||
<span id="_v2ray-check_btn-detail"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -1,8 +1,6 @@
|
||||
<%+cbi/valueheader%>
|
||||
<%
|
||||
local dsp = require "luci.dispatcher"
|
||||
local api = require "luci.model.cbi.passwall.api.api"
|
||||
|
||||
-%>
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
function padright(str, cnt, pad) {
|
||||
@ -314,6 +312,8 @@ local api = require "luci.model.cbi.passwall.api.api"
|
||||
if (ploc > 0) {
|
||||
url0 = sstr.substr(0, ploc);
|
||||
param = sstr.substr(ploc + 2);
|
||||
} else {
|
||||
var url0 = sstr;
|
||||
}
|
||||
console.log(param);
|
||||
var ssm = url0.match(/^(.+):([^:]+):([^:]*):([^:]+):([^:]*):([^:]+)/);
|
||||
@ -556,10 +556,7 @@ local api = require "luci.model.cbi.passwall.api.api"
|
||||
} else if (ssu[0] === "vmess") {
|
||||
var sstr = b64DecodeUnicode(ssu[1]);
|
||||
var ploc = sstr.indexOf("/?");
|
||||
opt.set('type', "V2ray");
|
||||
<% if api.is_finded("xray") then -%>
|
||||
opt.set('type', "Xray");
|
||||
<% end -%>
|
||||
opt.set('type', "Xray");
|
||||
opt.get('type').dispatchEvent(event);
|
||||
var url0, param = "";
|
||||
if (ploc > 0) {
|
||||
|
||||
@ -160,12 +160,18 @@ msgstr "自定义DNS"
|
||||
msgid "IP:Port mode ecceptable for specify other filtered name services."
|
||||
msgstr "定义接受 IP:Port 形式的输入,以指定其它域名服务的过滤服务。"
|
||||
|
||||
msgid "Resolver For Local/WhiteList Domains"
|
||||
msgstr "解析本地和白名单域名"
|
||||
msgid "Local DNS"
|
||||
msgstr "本地DNS"
|
||||
|
||||
msgid "Remote DNS"
|
||||
msgstr "远程DNS"
|
||||
|
||||
msgid "IP:Port mode acceptable, multi value split with english comma."
|
||||
msgstr "接受 IP:Port 形式的输入,多个以英文逗号分隔。"
|
||||
|
||||
msgid "If you use dns2socks, only the first one is valid."
|
||||
msgstr "如果使用dns2socks,只有第一个生效。"
|
||||
|
||||
msgid "When the selection is not the default, this DNS is forced to be set to dnsmasq upstream DNS."
|
||||
msgstr "当选择的不是默认,则将此DNS强制设置为dnsmasq上游DNS。"
|
||||
|
||||
@ -214,9 +220,6 @@ msgstr "请确保此Socks服务可用。"
|
||||
msgid "ChinaDNS-NG Fair Mode"
|
||||
msgstr "ChinaDNS-NG 公平模式"
|
||||
|
||||
msgid "Filtered DNS(For Proxied Domains)"
|
||||
msgstr "域名过滤服务(用于被代理的域名)"
|
||||
|
||||
msgid "Format must be:"
|
||||
msgstr "格式必须为:"
|
||||
|
||||
@ -229,9 +232,6 @@ msgstr "DoH Bootstrap DNS"
|
||||
msgid "The Bootstrap DNS server is used to resolve the IP address of the DoH resolver you specify as the upstream."
|
||||
msgstr "Bootstrap DNS 服务器用于解析您指定为上游的 DoH 解析器的 IP 地址。"
|
||||
|
||||
msgid "IP:Port mode acceptable, the 1st for 'dns2socks' if split with english comma."
|
||||
msgstr "接受 IP:Port 形式的输入,多个以英文逗号分隔 ,'dns2socks' 模式下仅首个有效。"
|
||||
|
||||
msgid "Cache Resolved"
|
||||
msgstr "缓存解析结果"
|
||||
|
||||
@ -412,6 +412,9 @@ msgstr "前置代理"
|
||||
msgid "Use the default node for the transit."
|
||||
msgstr "使用默认节点代理转发。"
|
||||
|
||||
msgid "Use the under node for the transit."
|
||||
msgstr "使用下面的节点代理转发。"
|
||||
|
||||
msgid "No shunt rules? Click me to go to add."
|
||||
msgstr "没有分流规则?点我前往去添加。"
|
||||
|
||||
|
||||
@ -6,14 +6,12 @@ config global
|
||||
option udp_node 'nil'
|
||||
option dns_mode 'pdnsd'
|
||||
option up_china_dns 'default'
|
||||
option dns_forward '8.8.4.4'
|
||||
option use_chnlist '0'
|
||||
option use_tcp_node_resolve_dns '1'
|
||||
option dns_forward '8.8.8.8'
|
||||
option tcp_proxy_mode 'chnroute'
|
||||
option udp_proxy_mode 'chnroute'
|
||||
option localhost_tcp_proxy_mode 'gfwlist'
|
||||
option localhost_udp_proxy_mode 'gfwlist'
|
||||
option socks_server '0.0.0.0:1080'
|
||||
option localhost_tcp_proxy_mode 'chnroute'
|
||||
option localhost_udp_proxy_mode 'chnroute'
|
||||
option socks_server '127.0.0.1:9050'
|
||||
option close_log_tcp '1'
|
||||
option close_log_udp '1'
|
||||
option loglevel 'warning'
|
||||
@ -52,7 +50,6 @@ config global_rules
|
||||
|
||||
config global_app
|
||||
option xray_file '/usr/bin/xray'
|
||||
option v2ray_file '/usr/bin/v2ray'
|
||||
option trojan_go_file '/usr/bin/trojan-go'
|
||||
option kcptun_client_file '/usr/bin/kcptun-client'
|
||||
option brook_file '/usr/bin/brook'
|
||||
|
||||
@ -298,7 +298,6 @@ load_config() {
|
||||
DNS_MODE=$(config_t_get global dns_mode pdnsd)
|
||||
DNS_FORWARD=$(config_t_get global dns_forward 8.8.4.4:53 | sed 's/:/#/g')
|
||||
DNS_CACHE=$(config_t_get global dns_cache 1)
|
||||
USE_CHNLIST=$(config_t_get global use_chnlist 0)
|
||||
process=1
|
||||
if [ "$(config_t_get global_forwarding process 0)" = "0" ]; then
|
||||
process=$(cat /proc/cpuinfo | grep 'processor' | wc -l)
|
||||
@ -318,13 +317,13 @@ load_config() {
|
||||
}
|
||||
|
||||
run_socks() {
|
||||
local node=$1
|
||||
local bind=$2
|
||||
local socks_port=$3
|
||||
local config_file=$4
|
||||
local http_port=$5
|
||||
local http_config_file=$6
|
||||
local id=$7
|
||||
local flag=$1
|
||||
local node=$2
|
||||
local bind=$3
|
||||
local socks_port=$4
|
||||
local config_file=$5
|
||||
local http_port=$6
|
||||
local http_config_file=$7
|
||||
local relay_port=$8
|
||||
local log_file="/dev/null"
|
||||
local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
|
||||
@ -345,7 +344,7 @@ run_socks() {
|
||||
msg="某种原因,此 Socks 服务的相关配置已失联,启动中止!"
|
||||
fi
|
||||
|
||||
if [ "$type" == "xray" -o "$type" == "v2ray" ] && ([ -n "$(config_n_get $node balancing_node)" ] || [ "$(config_n_get $node default_node)" != "nil" ]); then
|
||||
if [ "$type" == "xray" ] && ([ -n "$(config_n_get $node balancing_node)" ] || [ "$(config_n_get $node default_node)" != "nil" ]); then
|
||||
unset msg
|
||||
fi
|
||||
|
||||
@ -356,20 +355,15 @@ run_socks() {
|
||||
[ "$bind" != "127.0.0.1" ] && echolog " - 启动 ${bind}:${socks_port} - 节点:$remarks${tmp}"
|
||||
|
||||
case "$type" in
|
||||
socks)
|
||||
_username=$(config_n_get $node username)
|
||||
_password=$(config_n_get $node password)
|
||||
[ -n "$_username" ] && [ -n "$_password" ] && local _auth="--uname $_username --passwd $_password"
|
||||
ln_start_bin "$(first_type ssocks)" ssocks_SOCKS_$id $log_file --listen $socks_port --socks $server_host:$port $_auth
|
||||
;;
|
||||
socks|\
|
||||
xray)
|
||||
lua $API_GEN_XRAY -node $node -socks_proxy_port $socks_port > $config_file
|
||||
[ "$http_port" != "0" ] && {
|
||||
local extra_param="-http_proxy_port $http_port"
|
||||
config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g")
|
||||
}
|
||||
lua $API_GEN_XRAY -node $node -socks_proxy_port $socks_port $extra_param > $config_file
|
||||
ln_start_bin "$(first_type $(config_t_get global_app xray_file) xray)" xray $log_file -config="$config_file"
|
||||
;;
|
||||
v2ray)
|
||||
lua $API_GEN_XRAY -node $node -socks_proxy_port $socks_port > $config_file
|
||||
ln_start_bin "$(first_type $(config_t_get global_app v2ray_file) v2ray)" v2ray $log_file -config="$config_file"
|
||||
;;
|
||||
trojan-go)
|
||||
lua $API_GEN_TROJAN -node $node -run_type client -local_addr $bind -local_port $socks_port -server_host $server_host -server_port $port > $config_file
|
||||
ln_start_bin "$(first_type $(config_t_get global_app trojan_go_file) trojan-go)" trojan-go $log_file -config "$config_file"
|
||||
@ -388,21 +382,20 @@ run_socks() {
|
||||
[ "$protocol" == "wsclient" ] && {
|
||||
[ "$brook_tls" == "1" ] && server_host="wss://${server_host}" || server_host="ws://${server_host}"
|
||||
}
|
||||
ln_start_bin "$(first_type $(config_t_get global_app brook_file) brook)" "brook_SOCKS_$id" $log_file "$protocol" --socks5 "$bind:$socks_port" -s "$server_host:$port" -p "$(config_n_get $node password)"
|
||||
ln_start_bin "$(first_type $(config_t_get global_app brook_file) brook)" "brook_SOCKS_${flag}" $log_file "$protocol" --socks5 "$bind:$socks_port" -s "$server_host:$port" -p "$(config_n_get $node password)"
|
||||
;;
|
||||
ss|ssr)
|
||||
lua $API_GEN_SS -node $node -local_addr "0.0.0.0" -local_port $socks_port -server_host $server_host -server_port $port > $config_file
|
||||
ln_start_bin "$(first_type ${type}-local)" "${type}-local" $log_file -c "$config_file" -b "$bind" -u
|
||||
ln_start_bin "$(first_type ${type}-local)" "${type}-local" $log_file -c "$config_file" -b "$bind" -u -v
|
||||
;;
|
||||
esac
|
||||
|
||||
# socks to http
|
||||
[ "$http_port" != "0" ] && [ "$http_config_file" != "nil" ] && {
|
||||
[ "$type" != "xray" ] && [ "$type" != "socks" ] && [ "$http_port" != "0" ] && [ "$http_config_file" != "nil" ] && {
|
||||
lua $API_GEN_XRAY_PROTO -local_proto http -local_address "0.0.0.0" -local_port $http_port -server_proto socks -server_address "127.0.0.1" -server_port $socks_port -server_username $_username -server_password $_password > $http_config_file
|
||||
echo lua $API_GEN_XRAY_PROTO -local_proto http -local_address "0.0.0.0" -local_port $http_port -server_proto socks -server_address "127.0.0.1" -server_port $socks_port -server_username $_username -server_password $_password
|
||||
ln_start_bin "$(first_type $(config_t_get global_app xray_file) xray)" xray $log_file -config="$http_config_file"
|
||||
}
|
||||
unset _username _password _auth
|
||||
}
|
||||
|
||||
run_redir() {
|
||||
@ -443,18 +436,13 @@ run_redir() {
|
||||
local server_username=$(config_n_get $node username)
|
||||
local server_password=$(config_n_get $node password)
|
||||
eval port=\$UDP_REDIR_PORT
|
||||
ln_start_bin "$(first_type ipt2socks)" "ipt2socks_udp" $log_file -U -l "$port" -b 0.0.0.0 -s "$node_address" -p "$node_port" -R
|
||||
ln_start_bin "$(first_type ipt2socks)" "ipt2socks_udp" $log_file -U -l "$port" -b 0.0.0.0 -s "$node_address" -p "$node_port" -R -v
|
||||
;;
|
||||
xray)
|
||||
local loglevel=$(config_t_get global loglevel "warning")
|
||||
lua $API_GEN_XRAY -node $node -proto udp -redir_port $local_port -loglevel $loglevel > $config_file
|
||||
ln_start_bin "$(first_type $(config_t_get global_app xray_file) xray)" xray $log_file -config="$config_file"
|
||||
;;
|
||||
v2ray)
|
||||
local loglevel=$(config_t_get global loglevel "warning")
|
||||
lua $API_GEN_XRAY -node $node -proto udp -redir_port $local_port -loglevel $loglevel > $config_file
|
||||
ln_start_bin "$(first_type $(config_t_get global_app v2ray_file) v2ray)" v2ray $log_file -config="$config_file"
|
||||
;;
|
||||
trojan-go)
|
||||
local loglevel=$(config_t_get global trojan_loglevel "2")
|
||||
lua $API_GEN_TROJAN -node $node -run_type nat -local_addr "0.0.0.0" -local_port $local_port -loglevel $loglevel > $config_file
|
||||
@ -478,7 +466,7 @@ run_redir() {
|
||||
;;
|
||||
ss|ssr)
|
||||
lua $API_GEN_SS -node $node -local_addr "0.0.0.0" -local_port $local_port > $config_file
|
||||
ln_start_bin "$(first_type ${type}-redir)" "${type}-redir" $log_file -c "$config_file" -U
|
||||
ln_start_bin "$(first_type ${type}-redir)" "${type}-redir" $log_file -c "$config_file" -U -v
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
@ -512,18 +500,20 @@ run_redir() {
|
||||
;;
|
||||
xray)
|
||||
local loglevel=$(config_t_get global loglevel "warning")
|
||||
local extra_param="tcp"
|
||||
[ "$UDP_NODE" == "tcp" ] && extra_param="tcp,udp"
|
||||
lua $API_GEN_XRAY -node $node -proto $extra_param -redir_port $local_port -loglevel $loglevel > $config_file
|
||||
local proto="-proto tcp"
|
||||
[ "$UDP_NODE" == "tcp" ] && proto="-proto tcp,udp"
|
||||
local extra_param="${proto}"
|
||||
[ "$(config_t_get global tcp_node_socks 0)" = "1" ] && {
|
||||
local socks_param="-socks_proxy_port $(config_t_get global tcp_node_socks_port 1080)"
|
||||
extra_param="${extra_param} ${socks_param}"
|
||||
}
|
||||
[ "$(config_t_get global tcp_node_http 0)" = "1" ] && {
|
||||
local http_param="-http_proxy_port $(config_t_get global tcp_node_http_port 1180)"
|
||||
extra_param="${extra_param} ${http_param}"
|
||||
}
|
||||
lua $API_GEN_XRAY -node $node -redir_port $local_port -loglevel $loglevel $extra_param > $config_file
|
||||
ln_start_bin "$(first_type $(config_t_get global_app xray_file) xray)" xray $log_file -config="$config_file"
|
||||
;;
|
||||
v2ray)
|
||||
local loglevel=$(config_t_get global loglevel "warning")
|
||||
local extra_param="tcp"
|
||||
[ "$UDP_NODE" == "tcp" ] && extra_param="tcp,udp"
|
||||
lua $API_GEN_XRAY -node $node -proto $extra_param -redir_port $local_port -loglevel $loglevel > $config_file
|
||||
ln_start_bin "$(first_type $(config_t_get global_app v2ray_file) v2ray)" v2ray $log_file -config="$config_file"
|
||||
;;
|
||||
trojan-go)
|
||||
local loglevel=$(config_t_get global trojan_loglevel "2")
|
||||
lua $API_GEN_TROJAN -node $node -run_type nat -local_addr "0.0.0.0" -local_port $local_port -loglevel $loglevel > $config_file
|
||||
@ -571,14 +561,14 @@ run_redir() {
|
||||
[ "$UDP_NODE" == "tcp" ] && extra_param="-u"
|
||||
fi
|
||||
for k in $(seq 1 $process); do
|
||||
ln_start_bin "$(first_type ${type}-redir)" "${type}-redir" $log_file -c "$config_file" $extra_param
|
||||
ln_start_bin "$(first_type ${type}-redir)" "${type}-redir" $log_file -c "$config_file" -v $extra_param
|
||||
done
|
||||
;;
|
||||
esac
|
||||
if [ -n "$_socks_flag" ]; then
|
||||
local extra_param="-T"
|
||||
[ "$UDP_NODE" == "tcp" ] && extra_param=""
|
||||
ln_start_bin "$(first_type ipt2socks)" "ipt2socks_tcp" $log_file -l "$local_port" -b 0.0.0.0 -s "$_socks_address" -p "$_socks_port" -R $extra_param
|
||||
ln_start_bin "$(first_type ipt2socks)" "ipt2socks_tcp" $log_file -l "$local_port" -b 0.0.0.0 -s "$_socks_address" -p "$_socks_port" -R -v $extra_param
|
||||
fi
|
||||
unset _socks_flag _socks_address _socks_port _socks_username _socks_password
|
||||
;;
|
||||
@ -620,22 +610,32 @@ start_redir() {
|
||||
}
|
||||
|
||||
start_socks() {
|
||||
[ "$(config_n_get $TCP_NODE type nil)" != "xray" ] && {
|
||||
[ "$(config_t_get global tcp_node_socks 0)" = "1" ] && {
|
||||
local port=$(config_t_get global tcp_node_socks_port 1080)
|
||||
local config_file=$TMP_PATH/SOCKS_TCP.json
|
||||
local log_file=$TMP_PATH/SOCKS_TCP.log
|
||||
}
|
||||
local http_port=0
|
||||
local http_config_file=$TMP_PATH/HTTP2SOCKS_TCP.json
|
||||
[ "$(config_t_get global tcp_node_http 0)" = "1" ] && {
|
||||
http_port=$(config_t_get global tcp_node_http_port 1180)
|
||||
}
|
||||
run_socks TCP $TCP_NODE "0.0.0.0" $port $config_file $http_port $http_config_file
|
||||
}
|
||||
local ids=$(uci show $CONFIG | grep "=socks" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}')
|
||||
echolog "分析 Socks 服务的节点配置..."
|
||||
for id in $ids; do
|
||||
local enabled=$(config_n_get $id enabled 0)
|
||||
[ "$enabled" == "0" ] && continue
|
||||
local node=$(config_n_get $id node nil)
|
||||
if [ "$(echo $node | grep ^tcp)" ]; then
|
||||
eval node=\$TCP_NODE
|
||||
fi
|
||||
[ "$node" == "nil" ] && continue
|
||||
local port=$(config_n_get $id port)
|
||||
local config_file=$TMP_PATH/SOCKS_${id}.json
|
||||
local log_file=$TMP_PATH/SOCKS_${id}.log
|
||||
local http_port=$(config_n_get $id http_port 0)
|
||||
local http_config_file=$TMP_PATH/SOCKS2HTTP_${id}.json
|
||||
run_socks $node "0.0.0.0" $port $config_file $http_port $http_config_file $id
|
||||
local http_config_file=$TMP_PATH/HTTP2SOCKS_${id}.json
|
||||
run_socks $id $node "0.0.0.0" $port $config_file $http_port $http_config_file
|
||||
done
|
||||
}
|
||||
|
||||
@ -718,16 +718,20 @@ stop_crontab() {
|
||||
}
|
||||
|
||||
start_dns() {
|
||||
if [ "${LOCAL_DNS}" = "https-dns-proxy" ]; then
|
||||
_doh=$(config_t_get global up_china_dns_doh "https://dns.alidns.com/dns-query,223.5.5.5,223.6.6.6,2400:3200::1,2400:3200:baba::1")
|
||||
if [ "${LOCAL_DNS}" = "xray_doh" ]; then
|
||||
_doh=$(config_t_get global up_china_dns_doh "https://dns.alidns.com/dns-query,223.5.5.5")
|
||||
_doh_url=$(echo $_doh | awk -F ',' '{print $1}')
|
||||
_doh_host_port=$(echo $_doh_url | sed "s/https:\/\///g" | awk -F '/' '{print $1}')
|
||||
_doh_host=$(echo $_doh_host_port | awk -F ':' '{print $1}')
|
||||
_doh_port=$(echo $_doh_host_port | awk -F ':' '{print $2}')
|
||||
_doh_bootstrap=$(echo $_doh | cut -d ',' -sf 2-)
|
||||
ln_start_bin "$(first_type https-dns-proxy)" https-dns-proxy "/dev/null" -a 127.0.0.1 -p "${LOCAL_DOH_PORT}" -b "${_doh_bootstrap}" -r "${_doh_url}" -4
|
||||
lua $API_GEN_XRAY -dns_listen_port "${LOCAL_DOH_PORT}" -dns_server "${_doh_bootstrap}" -doh_url "${_doh_url}" -doh_host "${_doh_host}" > $TMP_PATH/DNS1.json
|
||||
ln_start_bin "$(first_type $(config_t_get global_app xray_file) xray)" xray $TMP_PATH/DNS1.log -config="$TMP_PATH/DNS1.json"
|
||||
LOCAL_DNS="127.0.0.1#${LOCAL_DOH_PORT}"
|
||||
unset _doh _doh_url _doh_bootstrap
|
||||
fi
|
||||
|
||||
local pdnsd_forward other_port up_trust_pdnsd_dns msg
|
||||
local pdnsd_forward other_port msg
|
||||
local global chnlist returnhome china_ng_chn china_ng_gfw chnlist_param gfwlist_param extra_mode
|
||||
dns_listen_port=${DNS_PORT}
|
||||
pdnsd_forward=${DNS_FORWARD}
|
||||
@ -741,6 +745,12 @@ start_dns() {
|
||||
sed -n 's/^ipset=\/\.\?\([^/]*\).*$/\1/p' "${RULES_PATH}/gfwlist.conf" | sort -u > "${TMP_PATH}/gfwlist.txt"
|
||||
echolog "过滤服务配置:准备接管域名解析[$?]..."
|
||||
|
||||
USE_CHNLIST=1
|
||||
if [ ! -f "${RULES_PATH}/chnlist" ]; then
|
||||
USE_CHNLIST=0
|
||||
else
|
||||
cp -a "${RULES_PATH}/chnlist" "${TMP_PATH}/chnlist"
|
||||
fi
|
||||
[ "$CHINADNS_NG" = "1" ] && {
|
||||
echolog " | - (chinadns-ng) 只支持2~4级的域名过滤..."
|
||||
[ -z "${global}${chnlist}" ] && echolog " | - (chinadns-ng) 此模式下,列表外的域名查询会同时发送给本地DNS(可切换到Pdnsd + TCP节点模式解决)..."
|
||||
@ -752,8 +762,8 @@ start_dns() {
|
||||
elif [ "$DNS_MODE" = "dns2socks" ]; then
|
||||
#[ -n "${global}${chnlist}" ] && TUN_DNS=${china_ng_gfw}
|
||||
msg="dns2socks"
|
||||
elif [ "$DNS_MODE" = "https-dns-proxy" ]; then
|
||||
msg="https-dns-proxy(DoH)"
|
||||
elif [ "$DNS_MODE" = "xray_doh" ]; then
|
||||
msg="Xray DNS(DoH)"
|
||||
elif [ "$DNS_MODE" = "udp" ]; then
|
||||
use_udp_node_resolve_dns=1
|
||||
if [ -z "${returnhome}" ]; then
|
||||
@ -767,27 +777,27 @@ start_dns() {
|
||||
china_ng_gfw="$(echo ${custom_dns} | sed 's/:/#/g')"
|
||||
msg="自定义DNS"
|
||||
fi
|
||||
chnlist_param=
|
||||
[ "$USE_CHNLIST" = "1" ] && {
|
||||
cp -a "${RULES_PATH}/chnlist" "${TMP_PATH}/chnlist"
|
||||
if [ -z "${returnhome}" ]; then
|
||||
cat "${RULES_PATH}/direct_host" >> "${TMP_PATH}/chnlist"
|
||||
echolog " | - [$?](chinadns-ng) 域名白名单合并到中国域名表"
|
||||
cat "${RULES_PATH}/proxy_host" >> "${TMP_PATH}/gfwlist.txt"
|
||||
[ -f "${RULES_PATH}/proxy_host2" ] && cat "${RULES_PATH}/proxy_host2" >> "${TMP_PATH}/gfwlist.txt"
|
||||
[ -f "${RULES_PATH}/proxy_host3" ] && cat "${RULES_PATH}/proxy_host3" >> "${TMP_PATH}/gfwlist.txt"
|
||||
echolog " | - [$?](chinadns-ng) 代理域名表合并到防火墙域名表"
|
||||
gfwlist_param="${TMP_PATH}/gfwlist.txt"
|
||||
else
|
||||
echolog " | - (chinadns-ng) 白名单不与中国域名表合并"
|
||||
cat "${RULES_PATH}/proxy_host" >> "${TMP_PATH}/chnlist"
|
||||
[ -f "${RULES_PATH}/proxy_host2" ] && cat "${RULES_PATH}/proxy_host2" >> "${TMP_PATH}/chnlist"
|
||||
[ -f "${RULES_PATH}/proxy_host3" ] && cat "${RULES_PATH}/proxy_host3" >> "${TMP_PATH}/chnlist"
|
||||
|
||||
chnlist_param="${TMP_PATH}/chnlist"
|
||||
if [ -n "${returnhome}" ]; then
|
||||
echolog " | - (chinadns-ng) 白名单不与中国域名表合并"
|
||||
[ -f "${RULES_PATH}/proxy_host" ] && {
|
||||
cat "${RULES_PATH}/proxy_host" >> "${chnlist_param}"
|
||||
echolog " | - [$?](chinadns-ng) 忽略防火墙域名表,代理域名表合并到中国域名表"
|
||||
fi
|
||||
chnlist_param="${TMP_PATH}/chnlist"
|
||||
chnlist_param=${chnlist_param:+-m "${chnlist_param}" -M}
|
||||
}
|
||||
}
|
||||
else
|
||||
[ -f "${RULES_PATH}/direct_host" ] && {
|
||||
cat "${RULES_PATH}/direct_host" >> "${chnlist_param}"
|
||||
echolog " | - [$?](chinadns-ng) 域名白名单合并到中国域名表"
|
||||
}
|
||||
[ -f "${RULES_PATH}/proxy_host" ] && {
|
||||
gfwlist_param="${TMP_PATH}/gfwlist.txt"
|
||||
cat "${RULES_PATH}/proxy_host" >> "${gfwlist_param}"
|
||||
echolog " | - [$?](chinadns-ng) 代理域名表合并到防火墙域名表"
|
||||
}
|
||||
fi
|
||||
chnlist_param=${chnlist_param:+-m "${chnlist_param}" -M}
|
||||
|
||||
[ "$(config_t_get global fair_mode 1)" = "1" ] && extra_mode="-f"
|
||||
ln_start_bin "$(first_type chinadns-ng)" chinadns-ng "/dev/null" -l "${dns_listen_port}" ${china_ng_chn:+-c "${china_ng_chn}"} ${chnlist_param} ${china_ng_gfw:+-t "${china_ng_gfw}"} ${gfwlist_param:+-g "${gfwlist_param}"} $extra_mode
|
||||
echolog " + 过滤服务:ChinaDNS-NG(:${dns_listen_port}${extra_mode}) + ${msg}:中国域名列表:${china_ng_chn:-D114.114.114.114},防火墙域名列表:${china_ng_gfw:-D8.8.8.8}"
|
||||
@ -801,9 +811,14 @@ start_dns() {
|
||||
TUN_DNS=""
|
||||
;;
|
||||
dns2socks)
|
||||
local dns2socks_socks_server=$(echo $(config_t_get global socks_server 127.0.0.1:9050) | sed "s/#/:/g")
|
||||
local dns2socks_forward=$(get_first_dns DNS_FORWARD 53 | sed 's/#/:/g')
|
||||
[ "$DNS_CACHE" == "0" ] && local dns2sock_cache="/d"
|
||||
ln_start_bin "$(first_type dns2socks)" dns2socks "/dev/null" "$dns2socks_socks_server" "$dns2socks_forward" "127.0.0.1:$dns_listen_port" $dns2sock_cache
|
||||
echolog " - dns2sock(127.0.0.1:${dns_listen_port}${dns2sock_cache}),${dns2socks_socks_server:-127.0.0.1:9050} -> ${dns2socks_forward-D8.8.8.8:53}"
|
||||
echolog " - 域名解析:dns2socks..."
|
||||
;;
|
||||
https-dns-proxy)
|
||||
xray_doh)
|
||||
up_trust_doh_dns=$(config_t_get global up_trust_doh_dns "tcp")
|
||||
if [ "$up_trust_doh_dns" = "socks" ]; then
|
||||
use_tcp_node_resolve_dns=0
|
||||
@ -812,17 +827,38 @@ start_dns() {
|
||||
use_tcp_node_resolve_dns=1
|
||||
msg="TCP节点"
|
||||
fi
|
||||
echolog " - 域名解析 https-dns-proxy(DOH)..."
|
||||
up_trust_doh=$(config_t_get global up_trust_doh "https://dns.google/dns-query,8.8.4.4")
|
||||
_doh_url=$(echo $up_trust_doh | awk -F ',' '{print $1}')
|
||||
_doh_host_port=$(echo $_doh_url | sed "s/https:\/\///g" | awk -F '/' '{print $1}')
|
||||
_doh_host=$(echo $_doh_host_port | awk -F ':' '{print $1}')
|
||||
_doh_port=$(echo $_doh_host_port | awk -F ':' '{print $2}')
|
||||
_doh_bootstrap=$(echo $up_trust_doh | cut -d ',' -sf 2-)
|
||||
|
||||
up_trust_doh_dns=$(config_t_get global up_trust_doh_dns "tcp")
|
||||
if [ "$up_trust_doh_dns" = "socks" ]; then
|
||||
socks_server=$(echo $(config_t_get global socks_server 127.0.0.1:9050) | sed "s/#/:/g")
|
||||
socks_address=$(echo $socks_server | awk -F ':' '{print $1}')
|
||||
socks_port=$(echo $socks_server | awk -F ':' '{print $2}')
|
||||
lua $API_GEN_XRAY -dns_listen_port "${dns_listen_port}" -dns_server "${_doh_bootstrap}" -doh_url "${_doh_url}" -doh_host "${_doh_host}" -doh_socks_address "${socks_address}" -doh_socks_port "${socks_port}" > $TMP_PATH/DNS.json
|
||||
ln_start_bin "$(first_type $(config_t_get global_app xray_file) xray)" xray $TMP_PATH/DNS.log -config="$TMP_PATH/DNS.json"
|
||||
elif [ "${up_trust_doh_dns}" = "tcp" ]; then
|
||||
DNS_FORWARD=""
|
||||
_doh_bootstrap_dns=$(echo $_doh_bootstrap | sed "s/,/ /g")
|
||||
for _dns in $_doh_bootstrap_dns; do
|
||||
_dns=$(echo $_dns | awk -F ':' '{print $1}'):${_doh_port:-443}
|
||||
[ -n "$DNS_FORWARD" ] && DNS_FORWARD=${DNS_FORWARD},${_dns} || DNS_FORWARD=${_dns}
|
||||
done
|
||||
lua $API_GEN_XRAY -dns_listen_port "${dns_listen_port}" -dns_server "${_doh_bootstrap}" -doh_url "${_doh_url}" -doh_host "${_doh_host}" > $TMP_PATH/DNS.json
|
||||
ln_start_bin "$(first_type $(config_t_get global_app xray_file) xray)" xray $TMP_PATH/DNS.log -config="$TMP_PATH/DNS.json"
|
||||
unset _dns _doh_bootstrap_dns
|
||||
fi
|
||||
unset _doh_url _doh_port _doh_bootstrap
|
||||
echolog " - 域名解析 Xray DNS(DOH)..."
|
||||
;;
|
||||
pdnsd)
|
||||
up_trust_pdnsd_dns=$(config_t_get global up_trust_pdnsd_dns "nil")
|
||||
if [ "$up_trust_pdnsd_dns" = "udp" ]; then
|
||||
use_udp_node_resolve_dns=1
|
||||
msg="UDP节点"
|
||||
elif [ "${up_trust_pdnsd_dns}" = "nil" ]; then
|
||||
msg="TCP节点"
|
||||
fi
|
||||
echolog " - 域名解析:pdnsd + 使用(${msg})解析域名..."
|
||||
gen_pdnsd_config "${dns_listen_port}" "${pdnsd_forward}"
|
||||
ln_start_bin "$(first_type pdnsd)" pdnsd "/dev/null" --daemon -c "${TMP_PATH}/pdnsd/pdnsd.conf" -d
|
||||
echolog " - 域名解析:pdnsd + 使用(TCP节点)解析域名..."
|
||||
;;
|
||||
udp)
|
||||
use_udp_node_resolve_dns=1
|
||||
@ -837,40 +873,7 @@ start_dns() {
|
||||
}
|
||||
;;
|
||||
esac
|
||||
if [ -n "$(echo ${DNS_MODE} | grep pdnsd)" ]; then
|
||||
gen_pdnsd_config "${dns_listen_port}" "${pdnsd_forward}"
|
||||
ln_start_bin "$(first_type pdnsd)" pdnsd "/dev/null" --daemon -c "${TMP_PATH}/pdnsd/pdnsd.conf" -d
|
||||
fi
|
||||
if [ -n "$(echo ${DNS_MODE} | grep 'https-dns-proxy')" ]; then
|
||||
up_trust_doh=$(config_t_get global up_trust_doh "https://dns.google/dns-query,8.8.8.8,8.8.4.4")
|
||||
_doh_url=$(echo $up_trust_doh | awk -F ',' '{print $1}')
|
||||
_doh_port=$(echo $_doh_url | sed "s/:\/\///g" | awk -F ':' '{print $2}'| awk -F '/' '{print $1}')
|
||||
_doh_bootstrap=$(echo $up_trust_doh | cut -d ',' -sf 2-)
|
||||
|
||||
up_trust_doh_dns=$(config_t_get global up_trust_doh_dns "tcp")
|
||||
if [ "$up_trust_doh_dns" = "socks" ]; then
|
||||
socks_server=$(echo $(config_t_get global socks_server 127.0.0.1:9050) | sed "s/#/:/g")
|
||||
ln_start_bin "$(first_type https-dns-proxy)" https-dns-proxy "/dev/null" -a 127.0.0.1 -p "${dns_listen_port}" -b "${_doh_bootstrap}" -r "${_doh_url}" -4 -t socks5h://${socks_server}
|
||||
elif [ "${up_trust_doh_dns}" = "tcp" ]; then
|
||||
DNS_FORWARD=""
|
||||
_doh_bootstrap_dns=$(echo $_doh_bootstrap | sed "s/,/ /g")
|
||||
for _dns in $_doh_bootstrap_dns; do
|
||||
_dns=$(echo $_dns | awk -F ':' '{print $1}'):${_doh_port:-443}
|
||||
[ -n "$DNS_FORWARD" ] && DNS_FORWARD=${DNS_FORWARD},${_dns} || DNS_FORWARD=${_dns}
|
||||
done
|
||||
ln_start_bin "$(first_type https-dns-proxy)" https-dns-proxy "/dev/null" -a 127.0.0.1 -p "${dns_listen_port}" -b "${_doh_bootstrap}" -r "${_doh_url}" -4
|
||||
unset _dns _doh_bootstrap_dns
|
||||
fi
|
||||
unset _doh_url _doh_port _doh_bootstrap
|
||||
fi
|
||||
if [ -n "$(echo ${DNS_MODE}${up_trust_pdnsd_dns} | grep dns2socks)" ]; then
|
||||
local dns2socks_socks_server=$(echo $(config_t_get global socks_server 127.0.0.1:9050) | sed "s/#/:/g")
|
||||
local dns2socks_forward=$(get_first_dns DNS_FORWARD 53 | sed 's/#/:/g')
|
||||
[ "$DNS_CACHE" == "0" ] && local dns2sock_cache="/d"
|
||||
ln_start_bin "$(first_type dns2socks)" dns2socks "/dev/null" "$dns2socks_socks_server" "$dns2socks_forward" "127.0.0.1:$dns_listen_port" $dns2sock_cache
|
||||
echolog " - dns2sock(127.0.0.1:${dns_listen_port}${dns2sock_cache}),${dns2socks_socks_server:-127.0.0.1:9050} -> ${dns2socks_forward-D46.182.19.48:53}"
|
||||
#[ "$CHINADNS_NG" = "1" ] && [ -n "${global}${chnlist}" ] && [ -z "${returnhome}" ] && TUN_DNS=$(echo "${dns_listen_port}" | sed 's/:/#/g')
|
||||
fi
|
||||
|
||||
[ "${use_udp_node_resolve_dns}" = "1" ] && echolog " * 要求代理 DNS 请求,如上游 DNS 非直连地址,确保 UDP 代理打开,并且已经正确转发!"
|
||||
[ "${use_tcp_node_resolve_dns}" = "1" ] && echolog " * 请确认上游 DNS 支持 TCP 查询,如非直连地址,确保 TCP 代理打开,并且已经正确转发!"
|
||||
}
|
||||
@ -904,10 +907,6 @@ add_dnsmasq() {
|
||||
|
||||
#始终用国内DNS解析直连(白名单)列表
|
||||
fwd_dns="${LOCAL_DNS}"
|
||||
#如果使用ChinaDNS-NG则直接交给它处理
|
||||
[ "$CHINADNS_NG" = "1" ] && unset fwd_dns
|
||||
#如果没使用chnlist直接使用默认DNS
|
||||
[ "${USE_CHNLIST}" = "0" ] && unset fwd_dns
|
||||
sort -u "${RULES_PATH}/direct_host" | gen_dnsmasq_items "whitelist" "${fwd_dns}" "${TMP_DNSMASQ_PATH}/00-direct_host.conf"
|
||||
echolog " - [$?]域名白名单(whitelist):${fwd_dns:-默认}"
|
||||
|
||||
|
||||
@ -35,7 +35,8 @@ dst() {
|
||||
}
|
||||
|
||||
comment() {
|
||||
echo "-m comment --comment '$1'"
|
||||
local name=$(echo $1 | sed 's/ /_/g')
|
||||
echo "-m comment --comment '$name'"
|
||||
}
|
||||
|
||||
RULE_LAST_INDEX() {
|
||||
@ -222,7 +223,7 @@ load_acl() {
|
||||
[ "$UDP_NO_REDIR_PORTS" != "disable" ] && $ipt_m -A PSW $(comment "默认") -p udp -m multiport --dport $UDP_NO_REDIR_PORTS -j RETURN
|
||||
[ "$UDP_NODE" != "nil" ] && {
|
||||
msg="UDP默认代理:使用UDP节点 [$(get_action_chain_name $UDP_PROXY_MODE)](TPROXY:${UDP_REDIR_PORT})代理"
|
||||
[ "$UDP_NO_REDIR_PORTS" != "disable" ] && msg="${msg}除${TCP_NO_REDIR_PORTS}外的"
|
||||
[ "$UDP_NO_REDIR_PORTS" != "disable" ] && msg="${msg}除${UDP_NO_REDIR_PORTS}外的"
|
||||
msg="${msg}所有端口"
|
||||
$ipt_m -A PSW $(comment "默认") -p udp $(factor $UDP_REDIR_PORTS "-m multiport --dport") $(dst $IPSET_SHUNTLIST) $(REDIRECT $UDP_REDIR_PORT TPROXY)
|
||||
$ipt_m -A PSW $(comment "默认") -p udp $(factor $UDP_REDIR_PORTS "-m multiport --dport") $(dst $IPSET_BLACKLIST) $(REDIRECT $UDP_REDIR_PORT TPROXY)
|
||||
@ -311,14 +312,21 @@ filter_node() {
|
||||
elif [ "$proxy_protocol" == "_shunt" ]; then
|
||||
#echolog " - 按请求目的地址分流(${proxy_type})..."
|
||||
local default_node=$(config_n_get $proxy_node default_node nil)
|
||||
filter_rules $default_node $stream
|
||||
local default_proxy=$(config_n_get $proxy_node default_proxy 0)
|
||||
if [ "$default_proxy" == 1 ]; then
|
||||
local main_node=$(config_n_get $proxy_node main_node nil)
|
||||
filter_rules $main_node $stream
|
||||
else
|
||||
filter_rules $default_node $stream
|
||||
fi
|
||||
:<<!
|
||||
local default_node_address=$(get_host_ip ipv4 $(config_n_get $default_node address) 1)
|
||||
local default_node_port=$(config_n_get $default_node port)
|
||||
|
||||
local shunt_ids=$(uci show $CONFIG | grep "=shunt_rules" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}')
|
||||
for shunt_id in $shunt_ids; do
|
||||
local shunt_proxy=$(config_n_get $proxy_node "${shunt_id}_proxy" 0)
|
||||
#local shunt_proxy=$(config_n_get $proxy_node "${shunt_id}_proxy" 0)
|
||||
local shunt_proxy=0
|
||||
local shunt_node=$(config_n_get $proxy_node "${shunt_id}" nil)
|
||||
[ "$shunt_node" != "nil" ] && {
|
||||
[ "$shunt_proxy" == 1 ] && {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -426,6 +426,8 @@
|
||||
43.228.148.0/22
|
||||
43.228.152.0/22
|
||||
43.228.188.0/22
|
||||
43.228.204.0/22
|
||||
43.228.240.0/22
|
||||
43.229.40.0/22
|
||||
43.229.48.0/22
|
||||
43.229.56.0/22
|
||||
@ -2538,6 +2540,7 @@
|
||||
103.41.0.0/22
|
||||
103.41.16.0/22
|
||||
103.41.52.0/22
|
||||
103.41.116.0/22
|
||||
103.41.140.0/22
|
||||
103.41.148.0/22
|
||||
103.41.152.0/22
|
||||
@ -2818,6 +2821,8 @@
|
||||
103.56.60.0/22
|
||||
103.56.72.0/22
|
||||
103.56.76.0/22
|
||||
103.56.100.0/22
|
||||
103.56.104.0/22
|
||||
103.56.140.0/22
|
||||
103.56.152.0/22
|
||||
103.56.184.0/22
|
||||
@ -3916,7 +3921,6 @@
|
||||
103.142.96.0/23
|
||||
103.142.102.0/23
|
||||
103.142.122.0/23
|
||||
103.142.126.0/24
|
||||
103.142.128.0/23
|
||||
103.142.140.0/23
|
||||
103.142.154.0/23
|
||||
@ -4116,6 +4120,9 @@
|
||||
103.161.14.0/23
|
||||
103.161.102.0/23
|
||||
103.161.138.0/23
|
||||
103.161.208.0/23
|
||||
103.161.220.0/23
|
||||
103.161.254.0/23
|
||||
103.192.0.0/22
|
||||
103.192.4.0/22
|
||||
103.192.8.0/22
|
||||
|
||||
@ -34,7 +34,6 @@
|
||||
2001:df0:d180::/48
|
||||
2001:df0:d880::/48
|
||||
2001:df1:c80::/48
|
||||
2001:df1:4180::/48
|
||||
2001:df1:4580::/48
|
||||
2001:df1:5280::/48
|
||||
2001:df1:5b80::/48
|
||||
@ -1895,6 +1894,7 @@
|
||||
2409:8000::/20
|
||||
240a:2000::/24
|
||||
240a:4000::/21
|
||||
240a:6000::/24
|
||||
240a:8000::/21
|
||||
240a:c000::/20
|
||||
240b:8000::/21
|
||||
|
||||
@ -163,6 +163,20 @@ do
|
||||
ucic2:set(application, node_id, "default_node", server)
|
||||
end
|
||||
}
|
||||
|
||||
local main_node_id = node.main_node
|
||||
local main_node
|
||||
if main_node_id then
|
||||
main_node = ucic2:get_all(application, main_node_id)
|
||||
end
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
log = false,
|
||||
currentNode = main_node,
|
||||
remarks = "分流默认前置代理节点",
|
||||
set = function(server)
|
||||
ucic2:set(application, node_id, "main_node", server)
|
||||
end
|
||||
}
|
||||
elseif node.protocol and node.protocol == '_balancing' then
|
||||
local node_id = node[".name"]
|
||||
local nodes = {}
|
||||
@ -340,10 +354,7 @@ local function processData(szType, content, add_mode)
|
||||
result.remarks = base64Decode(params.remarks)
|
||||
elseif szType == 'vmess' then
|
||||
local info = jsonParse(content)
|
||||
result.type = 'V2ray'
|
||||
if api.is_finded("xray") then
|
||||
result.type = 'Xray'
|
||||
end
|
||||
result.type = 'Xray'
|
||||
result.address = info.add
|
||||
result.port = info.port
|
||||
result.protocol = 'vmess'
|
||||
|
||||
@ -83,7 +83,7 @@ test_auto_switch() {
|
||||
[ -n "$node_address" ] && [ -n "$node_port" ] && local curlx="socks5h://$node_address:$node_port"
|
||||
else
|
||||
local tmp_port=$(/usr/share/passwall/app.sh get_new_port 61080 tcp)
|
||||
/usr/share/passwall/app.sh run_socks "$main_node" "127.0.0.1" "$tmp_port" "/var/etc/passwall/auto_switch.json" "10"
|
||||
/usr/share/passwall/app.sh run_socks "auto_switch" "$main_node" "127.0.0.1" "$tmp_port" "/var/etc/passwall/auto_switch.json"
|
||||
local curlx="socks5h://127.0.0.1:$tmp_port"
|
||||
fi
|
||||
sleep 10s
|
||||
|
||||
@ -11,11 +11,13 @@ Subject: [PATCH] add filter-aaaa option
|
||||
|
||||
--- a/src/dnsmasq.h
|
||||
+++ b/src/dnsmasq.h
|
||||
@@ -270,6 +270,7 @@ struct event_desc {
|
||||
@@ -269,7 +269,8 @@
|
||||
#define OPT_IGNORE_CLID 59
|
||||
#define OPT_SINGLE_PORT 60
|
||||
#define OPT_LEASE_RENEW 61
|
||||
#define OPT_LAST 62
|
||||
+#define OPT_FILTER_AAAA 63
|
||||
-#define OPT_LAST 62
|
||||
+#define OPT_FILTER_AAAA 62
|
||||
+#define OPT_LAST 63
|
||||
|
||||
#define OPTION_BITS (sizeof(unsigned int)*8)
|
||||
#define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) )
|
||||
|
||||
@ -1,57 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2007-2010 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=iperf
|
||||
PKG_VERSION:=2.0.13
|
||||
PKG_RELEASE:=2
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_HASH:=c88adec966096a81136dda91b4bd19c27aae06df4d45a7f547a8e50d723778ad
|
||||
PKG_SOURCE_URL:=@SF/iperf2
|
||||
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
PKG_LICENSE:=BSD-3-Clause
|
||||
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
|
||||
PKG_CONFIG_DEPENDS:=CONFIG_IPERF_ENABLE_MULTICAST
|
||||
|
||||
include $(INCLUDE_DIR)/uclibc++.mk
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/iperf
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
DEPENDS:= $(CXX_DEPENDS) +libpthread
|
||||
TITLE:=Internet Protocol bandwidth measuring tool
|
||||
URL:=http://sourceforge.net/projects/iperf2/
|
||||
endef
|
||||
|
||||
define Package/iperf/description
|
||||
Iperf is a modern alternative for measuring TCP and UDP bandwidth
|
||||
performance, allowing the tuning of various parameters and
|
||||
characteristics.
|
||||
endef
|
||||
|
||||
TARGET_CFLAGS += -D_GNU_SOURCE
|
||||
CONFIGURE_ARGS += --disable-multicast
|
||||
|
||||
ifeq ($(CONFIG_IPV6),)
|
||||
CONFIGURE_ARGS += --disable-ipv6
|
||||
endif
|
||||
|
||||
CONFIGURE_VARS += CXXFLAGS="$$$$CXXFLAGS -fno-rtti"
|
||||
CONFIGURE_VARS += LIBS="-lpthread -lm"
|
||||
|
||||
define Package/iperf/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/iperf $(1)/usr/bin/iperf
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,iperf))
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user