Merge Mainline
This commit is contained in:
commit
ab3b31991a
@ -54,7 +54,8 @@ luci-theme-Butterfly-dark source: [Leo-Jo-My/luci-theme-Butterfly-dark](https://
|
||||
luci-theme-argon-mod source: [Leo-Jo-My/luci-theme-argon-mod](https://github.com/Leo-Jo-My/luci-theme-argon-mod).<br/>
|
||||
node-request source: [jerrykuku/node-request](https://github.com/jerrykuku/node-request).<br/>
|
||||
luci-app-jd-dailybonus source: [jerrykuku/luci-app-jd-dailybonus](https://github.com/jerrykuku/luci-app-jd-dailybonus).<br/>
|
||||
luci-theme-btmod source: [siropboy/luci-theme-btmod](https://github.com/siropboy/luci-theme-btmod).
|
||||
luci-theme-btmod source: [siropboy/luci-theme-btmod](https://github.com/siropboy/luci-theme-btmod).<br/>
|
||||
luci-app-oled source: [NateLol/luci-app-oled](https://github.com/NateLol/luci-app-oled).
|
||||
|
||||
## License
|
||||
### Depending on their own License.
|
||||
### Depend on their own License.
|
||||
|
||||
@ -7,8 +7,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
PKG_NAME:=luci-app-jd-dailybonus
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_VERSION:=0.8.1
|
||||
PKG_RELEASE:=20200716
|
||||
PKG_VERSION:=0.8.2
|
||||
PKG_RELEASE:=20200719
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
|
||||
@ -2,14 +2,12 @@ local fs = require "nixio.fs"
|
||||
local jd = "jd-dailybonus"
|
||||
local conffile = "/www/JD_DailyBonus.htm"
|
||||
|
||||
f = SimpleForm("logview")
|
||||
m = Map(jd)
|
||||
-- [[ 基本设置 ]]--
|
||||
log = SimpleForm("logview")
|
||||
log.submit = false
|
||||
log.reset = false
|
||||
|
||||
s = m:section(TypedSection, "global")
|
||||
s.anonymous = true
|
||||
|
||||
t = s:option(TextValue, "1", nil)
|
||||
-- [[ 日志显示 ]]--
|
||||
t = log:field(TextValue, "1", nil)
|
||||
t.rmempty = true
|
||||
t.rows = 30
|
||||
function t.cfgvalue()
|
||||
@ -17,4 +15,4 @@ function t.cfgvalue()
|
||||
end
|
||||
t.readonly="readonly"
|
||||
|
||||
return m
|
||||
return log
|
||||
@ -1,13 +1,5 @@
|
||||
local fs = require "nixio.fs"
|
||||
local jd = "jd-dailybonus"
|
||||
local uci = luci.model.uci.cursor()
|
||||
|
||||
function sync_value_to_file(value, file)
|
||||
value = value:gsub("\r\n?", "\n")
|
||||
local old_value = nixio.fs.readfile(file)
|
||||
if value ~= old_value then nixio.fs.writefile(file, value) end
|
||||
|
||||
end
|
||||
|
||||
s = SimpleForm("scriptview")
|
||||
|
||||
@ -15,8 +7,14 @@ view_cfg = s:field(TextValue, "conf")
|
||||
view_cfg.rmempty = false
|
||||
view_cfg.rows = 43
|
||||
|
||||
function sync_value_to_file(value, file)
|
||||
value = value:gsub("\r\n?", "\n")
|
||||
local old_value = fs.readfile(file)
|
||||
if value ~= old_value then fs.writefile(file, value) end
|
||||
end
|
||||
|
||||
function view_cfg.cfgvalue()
|
||||
return nixio.fs.readfile("/usr/share/jd-dailybonus/JD_DailyBonus.js") or ""
|
||||
return fs.readfile("/usr/share/jd-dailybonus/JD_DailyBonus.js") or ""
|
||||
end
|
||||
function view_cfg.write(self, section, value)
|
||||
sync_value_to_file(value, "/usr/share/jd-dailybonus/JD_DailyBonus.js")
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
config global
|
||||
option version '1.27'
|
||||
option version '1.29'
|
||||
option auto_run_time '1'
|
||||
option auto_run '1'
|
||||
option auto_update_time '1'
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
京东多合一签到脚本
|
||||
|
||||
更新时间: 2020.7.10 0:10 v1.27
|
||||
更新时间: 2020.7.18 17:20 v1.29
|
||||
有效接口: 24+
|
||||
脚本兼容: QuantumultX, Surge, Loon, JSBox, Node.js
|
||||
电报频道: @NobyDa
|
||||
@ -34,6 +34,8 @@ var DualKey = ''; //如需双账号签到,此处单引号内填写抓取的"账
|
||||
由于cookie的有效性(经测试网页Cookie有效周期最长31天),如果脚本后续弹出cookie无效的通知,则需要重复上述步骤。
|
||||
签到脚本将在每天的凌晨0:05执行, 您可以修改执行时间。 因部分接口京豆限量领取, 建议调整为凌晨签到。
|
||||
|
||||
BoxJs订阅地址: https://raw.githubusercontent.com/NobyDa/Script/master/NobyDa_BoxJs.json
|
||||
|
||||
*************************
|
||||
【 配置双京东账号签到说明 】 :
|
||||
*************************
|
||||
@ -87,39 +89,14 @@ hostname = api.m.jd.com
|
||||
|
||||
var LogDetails = false; //是否开启响应日志, true则开启
|
||||
|
||||
var stop = 0; //自定义延迟签到,单位毫秒. 默认分批并发无延迟. (延迟作用于每个签到接口, 如填入延迟则切换顺序签到. Surge用户请注意在UI界面调整脚本超时) 注: QX用户将强制使用顺序签到 (即默认stop=1)
|
||||
var stop = 0; //自定义延迟签到,单位毫秒. 默认分批并发无延迟. 延迟作用于每个签到接口, 如填入延迟则切换顺序签到(耗时较长), VPN重启或越狱用户建议填写1, Surge用户请注意在SurgeUI界面调整脚本超时
|
||||
|
||||
var DeleteCookie = false; //是否清除Cookie, true则开启
|
||||
|
||||
var out = 6000; //接口超时退出, 用于可能发生的网络不稳定. 建议不少于3000毫秒, 0则关闭.
|
||||
var out = 0; //接口超时退出, 用于可能发生的网络不稳定, 0则关闭. 如QX日志出现大量"JS Context timeout"后脚本中断时, 建议填写6000
|
||||
|
||||
var $nobyda = nobyda();
|
||||
|
||||
let acData = {
|
||||
// 京东商城-超市
|
||||
JDGStore: 'aNCM6yrzD6qp1Vvh5YTzeJtk7cM',
|
||||
// 京东商城-宠物
|
||||
JDPet: '37ta5sh5ocrMZF3Fz5UMJbTsL42',
|
||||
// 京东商城-图书
|
||||
JDBook: '3SC6rw5iBg66qrXPGmZMqFDwcyXi',
|
||||
// 京东拍拍-二手
|
||||
JDShand: '3S28janPLYmtFxypu37AYAGgivfp',
|
||||
// 京东商城-美妆
|
||||
JDMakeup: '2smCxzLNuam5L14zNJHYu43ovbAP',
|
||||
// 京东商城-清洁
|
||||
JDClean: '2Tjm6ay1ZbZ3v7UbriTj6kHy9dn6',
|
||||
// 京东商城-女装
|
||||
JDWomen: 'DpSh7ma8JV7QAxSE2gJNro8Q2h9',
|
||||
// 京东商城-个护
|
||||
JDCare: 'NJ1kd1PJWhwvhtim73VPsD1HwY3',
|
||||
// 京东商城-美食
|
||||
JDFood: '4PzvVmLSBq5K63oq4oxKcDtFtzJo',
|
||||
// 京东商城-珠宝
|
||||
JDJewels: 'zHUHpTHNTaztSRfNBFNVZscyFZU',
|
||||
// 京东商城-菜场
|
||||
JDVege: 'Wcu2LVCFMkBP3HraRvb7pgSpt64'
|
||||
};
|
||||
|
||||
async function all() {
|
||||
if (stop == 0) {
|
||||
await Promise.all([
|
||||
@ -132,9 +109,7 @@ async function all() {
|
||||
JDFlashSale(stop), //京东闪购
|
||||
JDOverseas(stop), //京东国际
|
||||
JingDongCash(stop), //京东现金红包
|
||||
// JingRSeeAds(stop), //金融看广告
|
||||
// JingRongGame(stop), //金融游戏大厅
|
||||
// JDMagicCube(stop), //京东小魔方
|
||||
JDMagicCube(stop), //京东小魔方
|
||||
JingDongPrize(stop), //京东抽大奖
|
||||
JingDongSubsidy(stop), //京东金贴
|
||||
JingDongShake(stop) //京东摇一摇
|
||||
@ -145,9 +120,7 @@ async function all() {
|
||||
JDUserSignPre(stop, 'JDClean', '京东商城-清洁'), //京东清洁馆
|
||||
JDUserSignPre(stop, 'JDCare', '京东商城-个护'), //京东个人护理馆
|
||||
JDUserSignPre(stop, 'JDJewels', '京东商城-珠宝'), //京东珠宝馆
|
||||
JDUserSignPre(stop, 'JDShand', '京东拍拍-二手') //京东拍拍二手
|
||||
]);
|
||||
await Promise.all([
|
||||
JDUserSignPre(stop, 'JDShand', '京东拍拍-二手'), //京东拍拍二手
|
||||
JDUserSignPre(stop, 'JDWomen', '京东商城-女装'), //京东女装馆
|
||||
JDUserSignPre(stop, 'JDGStore', '京东商城-超市'), //京东超市
|
||||
JDUserSignPre(stop, 'JDPet', '京东商城-宠物'), //京东宠物馆
|
||||
@ -172,12 +145,10 @@ async function all() {
|
||||
await JDUserSignPre(stop, 'JDVege', '京东商城-菜场'); //京东菜场
|
||||
await JingDongCash(stop); //京东现金红包
|
||||
await JDUserSignPre(stop, 'JDFood', '京东商城-美食'); //京东美食馆
|
||||
// await JingRSeeAds(stop); //金融看广告
|
||||
// await JingRongGame(stop); //金融游戏大厅
|
||||
await JDUserSignPre(stop, 'JDClean', '京东商城-清洁'); //京东清洁馆
|
||||
await JDUserSignPre(stop, 'JDCare', '京东商城-个护'); //京东个人护理馆
|
||||
await JDUserSignPre(stop, 'JDJewels', '京东商城-珠宝'); //京东珠宝馆
|
||||
// await JDMagicCube(stop); //京东小魔方
|
||||
await JDMagicCube(stop); //京东小魔方
|
||||
await JingDongPrize(stop); //京东抽大奖
|
||||
await JingDongSubsidy(stop); //京东金贴
|
||||
await JingDongShake(stop) //京东摇一摇
|
||||
@ -208,7 +179,7 @@ function notify() {
|
||||
}
|
||||
var Cash = merge.JDCash.TCash ? merge.JDCash.TCash + "红包" : ""
|
||||
var Steel = merge.JRSteel.TSteel ? merge.JRSteel.TSteel + "钢镚" + (Cash ? ", " : "") : ""
|
||||
var beans = merge.JDShake.Qbear ? merge.JDShake.Qbear + "京豆" + (Steel || Cash ? ", " : "" ) : ""
|
||||
var beans = merge.JDShake.Qbear ? merge.JDShake.Qbear + "京豆" + (Steel || Cash ? ", " : "") : ""
|
||||
var bsc = beans ? "\n" : Steel ? "\n" : Cash ? "\n" : "获取失败\n"
|
||||
var Tbean = bean ? bean + "京豆" + (steel || merge.JDCash.Cash ? ", " : "") : ""
|
||||
var TSteel = steel ? steel + "钢镚" + (merge.JDCash.Cash ? ", " : "") : ""
|
||||
@ -239,9 +210,9 @@ function notify() {
|
||||
$nobyda.time();
|
||||
$nobyda.done();
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("通知模块 " + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
});
|
||||
@ -250,7 +221,6 @@ function notify() {
|
||||
function ReadCookie() {
|
||||
initial()
|
||||
DualAccount = true;
|
||||
if ($nobyda.isQuanX && stop === 0) stop = 1;
|
||||
if (DeleteCookie) {
|
||||
if ($nobyda.isJSBox) {
|
||||
if ($file.exists("shared://JD_Cookie.txt")) {
|
||||
@ -303,6 +273,9 @@ function ReadCookie() {
|
||||
} else if (Key || $nobyda.read("CookieJD")) {
|
||||
add = DualKey || $nobyda.read("CookieJD2") ? true : false
|
||||
KEY = Key ? Key : $nobyda.read("CookieJD")
|
||||
out = $nobyda.read("JD_DailyBonusTimeOut") || out
|
||||
stop = $nobyda.read("JD_DailyBonusDelay") || stop
|
||||
LogDetails = $nobyda.read("JD_DailyBonusLog") === "true" ? true : false || LogDetails
|
||||
all()
|
||||
} else {
|
||||
$nobyda.notify("京东签到", "", "脚本终止, 未获取Cookie ‼️")
|
||||
@ -332,6 +305,7 @@ function double() {
|
||||
|
||||
function JingDongBean(s) {
|
||||
return new Promise(resolve => {
|
||||
if (disable("JDBean")) return resolve()
|
||||
setTimeout(() => {
|
||||
const JDBUrl = {
|
||||
url: 'https://api.m.jd.com/client.action?functionId=signBeanIndex&appid=ld',
|
||||
@ -393,9 +367,9 @@ function JingDongBean(s) {
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京东商城-京豆" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -406,6 +380,7 @@ function JingDongBean(s) {
|
||||
|
||||
function JingDongTurn(s) {
|
||||
return new Promise(resolve => {
|
||||
if (disable("JDTurn")) return resolve()
|
||||
setTimeout(() => {
|
||||
const JDTUrl = {
|
||||
url: 'https://api.m.jd.com/client.action?functionId=lotteryDraw&body=%7B%22actId%22%3A%22jgpqtzjhvaoym%22%2C%22appSource%22%3A%22jdhome%22%2C%22lotteryCode%22%3A%224wwzdq7wkqx2usx4g5i2nu5ho4auto4qxylblkxacm7jqdsltsepmgpn3b2hgyd7hiawzpccizuck%22%7D&appid=ld',
|
||||
@ -460,9 +435,9 @@ function JingDongTurn(s) {
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京东商城-转盘" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -473,6 +448,7 @@ function JingDongTurn(s) {
|
||||
|
||||
function JingRongBean(s) {
|
||||
return new Promise(resolve => {
|
||||
if (disable("JRBean")) return resolve()
|
||||
setTimeout(() => {
|
||||
const login = {
|
||||
url: 'https://ms.jr.jd.com/gw/generic/zc/h5/m/signRecords',
|
||||
@ -504,9 +480,9 @@ function JingRongBean(s) {
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京东金融-京豆登录" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -561,9 +537,9 @@ function JRBeanCheckin(s) {
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京东金融-京豆" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -574,6 +550,7 @@ function JRBeanCheckin(s) {
|
||||
|
||||
function JingRongSteel(s) {
|
||||
return new Promise(resolve => {
|
||||
if (disable("JRSteel")) return resolve()
|
||||
setTimeout(() => {
|
||||
const JRSUrl = {
|
||||
url: 'https://ms.jr.jd.com/gw/generic/gry/h5/m/signIn',
|
||||
@ -624,9 +601,9 @@ function JingRongSteel(s) {
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京东金融-钢镚" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -637,6 +614,7 @@ function JingRongSteel(s) {
|
||||
|
||||
function JRDoubleSign(s) {
|
||||
return new Promise(resolve => {
|
||||
if (disable("JRDSign")) return resolve()
|
||||
setTimeout(() => {
|
||||
const JRDSUrl = {
|
||||
url: 'https://nu.jr.jd.com/gw/generic/jrm/h5/m/process?',
|
||||
@ -680,9 +658,9 @@ function JRDoubleSign(s) {
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京东金融-双签" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -693,6 +671,7 @@ function JRDoubleSign(s) {
|
||||
|
||||
function JingDongShake(s) {
|
||||
return new Promise(resolve => {
|
||||
if (disable("JDShake")) return resolve()
|
||||
setTimeout(() => {
|
||||
const JDSh = {
|
||||
url: 'https://api.m.jd.com/client.action?appid=vip_h5&functionId=vvipclub_shaking',
|
||||
@ -748,9 +727,9 @@ function JingDongShake(s) {
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京东商城-摇摇" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -762,7 +741,7 @@ function JingDongShake(s) {
|
||||
function JDUserSignPre(s, key, title) {
|
||||
if ($nobyda.isNode) {
|
||||
return JDUserSignPre1(s, key, title);
|
||||
} else if (key == 'JDWomen' || key == 'JDJewels'|| $nobyda.isJSBox) {
|
||||
} else if (key == 'JDWomen' || key == 'JDJewels' || $nobyda.isJSBox) {
|
||||
return JDUserSignPre2(s, key, title);
|
||||
} else {
|
||||
return JDUserSignPre1(s, key, title);
|
||||
@ -771,93 +750,97 @@ function JDUserSignPre(s, key, title) {
|
||||
|
||||
function JDUserSignPre1(s, key, title) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (disable(key)) return reject()
|
||||
//setTimeout(() => {
|
||||
const JDUrl = {
|
||||
url: 'https://api.m.jd.com/?client=wh5&functionId=qryH5BabelFloors',
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
Cookie: KEY,
|
||||
},
|
||||
body: `body={"activityId":"${acData[key]}"}`
|
||||
};
|
||||
$nobyda.post(JDUrl, function(error, response, data) {
|
||||
try {
|
||||
if (error) {
|
||||
merge[key].notify = `${title}: 签到活动获取失败 ‼️‼️`
|
||||
merge[key].fail = 1
|
||||
} else {
|
||||
if (data.match(/enActK/)) { // 含有签到活动数据
|
||||
const od = JSON.parse(data);
|
||||
let params = (od.floatLayerList || []).filter(o=>o.params && o.params.match(/enActK/)).map(o=>o.params).pop();
|
||||
if(!params){ // 第一处找到签到所需数据
|
||||
// floatLayerList未找到签到所需数据,从floorList中查找
|
||||
let signInfo = (od.floorList || []).filter(o=>o.template=='signIn' && o.signInfos && o.signInfos.params && o.signInfos.params.match(/enActK/))
|
||||
.map(o=>o.signInfos).pop();
|
||||
if(signInfo){
|
||||
if(signInfo.signStat=='1'){
|
||||
merge[key].notify = `${title}: 失败, 原因: 已签过 ⚠️`
|
||||
merge[key].fail = 1
|
||||
reject();
|
||||
return;
|
||||
} else {
|
||||
params = signInfo.params;
|
||||
}
|
||||
const JDUrl = {
|
||||
url: 'https://api.m.jd.com/?client=wh5&functionId=qryH5BabelFloors',
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
Cookie: KEY,
|
||||
},
|
||||
body: `body={"activityId":"${acData[key]}"}`
|
||||
};
|
||||
$nobyda.post(JDUrl, function(error, response, data) {
|
||||
try {
|
||||
if (error) {
|
||||
merge[key].notify = `${title}: 签到活动获取失败 ‼️‼️`
|
||||
merge[key].fail = 1
|
||||
} else {
|
||||
if (data.match(/enActK/)) { // 含有签到活动数据
|
||||
const od = JSON.parse(data);
|
||||
let params = (od.floatLayerList || []).filter(o => o.params && o.params.match(/enActK/)).map(o => o.params).pop();
|
||||
if (!params) { // 第一处找到签到所需数据
|
||||
// floatLayerList未找到签到所需数据,从floorList中查找
|
||||
let signInfo = (od.floorList || []).filter(o => o.template == 'signIn' && o.signInfos && o.signInfos.params && o.signInfos.params.match(/enActK/))
|
||||
.map(o => o.signInfos).pop();
|
||||
if (signInfo) {
|
||||
if (signInfo.signStat == '1') {
|
||||
merge[key].notify = `${title}: 失败, 原因: 已签过 ⚠️`
|
||||
merge[key].fail = 1
|
||||
reject();
|
||||
return;
|
||||
} else {
|
||||
params = signInfo.params;
|
||||
}
|
||||
}
|
||||
if(params){
|
||||
resolve({params: params}); // 执行签到处理
|
||||
return;
|
||||
}
|
||||
}
|
||||
merge[key].notify = `${title}: 失败, 原因: 不含活动数据 ⚠️`
|
||||
merge[key].fail = 1
|
||||
if (params) {
|
||||
resolve({
|
||||
params: params
|
||||
}); // 执行签到处理
|
||||
return;
|
||||
}
|
||||
}
|
||||
reject()
|
||||
} catch (eor) {
|
||||
$nobyda.notify(`${title}${eor.name} ‼️`, JSON.stringify(eor), eor.message)
|
||||
reject()
|
||||
merge[key].notify = `${title}: 失败, 原因: 不含活动数据 ⚠️`
|
||||
merge[key].fail = 1
|
||||
}
|
||||
})
|
||||
} catch (eor) {
|
||||
$nobyda.notify(`${title}${eor.name} ‼️`, JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
reject()
|
||||
}
|
||||
})
|
||||
//}, s)
|
||||
if (out) setTimeout(reject, out + s)
|
||||
}).then(data=>{
|
||||
}).then(data => {
|
||||
return JDUserSign(s, key, title, encodeURIComponent(JSON.stringify(data)));
|
||||
},()=>{});
|
||||
}, () => {});
|
||||
}
|
||||
|
||||
function JDUserSignPre2(s, key, title) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (disable(key)) return reject()
|
||||
//setTimeout(() => {
|
||||
const JDUrl = {
|
||||
url: `https://pro.m.jd.com/mall/active/${acData[key]}/index.html`,
|
||||
headers: {
|
||||
Cookie: KEY,
|
||||
}
|
||||
};
|
||||
$nobyda.get(JDUrl, function(error, response, data) {
|
||||
try {
|
||||
if (error) {
|
||||
merge[key].notify = `${title}: 签到活动获取失败 ‼️‼️`
|
||||
merge[key].fail = 1
|
||||
} else {
|
||||
if (data.match(/"params":"{\\"enActK\\".*?\\"}"/)) { // 含有签到活动数据
|
||||
resolve(`{${data.match(/"params":"{\\"enActK\\".*?\\"}"/)}}`); // 执行签到处理
|
||||
return;
|
||||
}
|
||||
merge[key].notify = `${title}: 失败, 原因: 不含活动数据 ⚠️`
|
||||
merge[key].fail = 1
|
||||
const JDUrl = {
|
||||
url: `https://pro.m.jd.com/mall/active/${acData[key]}/index.html`,
|
||||
headers: {
|
||||
Cookie: KEY,
|
||||
}
|
||||
};
|
||||
$nobyda.get(JDUrl, function(error, response, data) {
|
||||
try {
|
||||
if (error) {
|
||||
merge[key].notify = `${title}: 签到活动获取失败 ‼️‼️`
|
||||
merge[key].fail = 1
|
||||
} else {
|
||||
if (data.match(/"params":"{\\"enActK\\".*?\\"}"/)) { // 含有签到活动数据
|
||||
resolve(`{${data.match(/"params":"{\\"enActK\\".*?\\"}"/)}}`); // 执行签到处理
|
||||
return;
|
||||
}
|
||||
reject()
|
||||
} catch (eor) {
|
||||
$nobyda.notify(`${title}${eor.name} ‼️`, JSON.stringify(eor), eor.message)
|
||||
reject()
|
||||
merge[key].notify = `${title}: 失败, 原因: 不含活动数据 ⚠️`
|
||||
merge[key].fail = 1
|
||||
}
|
||||
})
|
||||
} catch (eor) {
|
||||
$nobyda.notify(`${title}${eor.name} ‼️`, JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
reject()
|
||||
}
|
||||
})
|
||||
//}, s)
|
||||
if (out) setTimeout(reject, out + s)
|
||||
}).then(data=>{
|
||||
}).then(data => {
|
||||
return JDUserSign(s, key, title, encodeURIComponent(data));
|
||||
},()=>{});
|
||||
}, () => {});
|
||||
}
|
||||
|
||||
function JDUserSign(s, key, title, body) {
|
||||
@ -911,9 +894,9 @@ function JDUserSign(s, key, title, body) {
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify(`${title}${eor.name} ‼️`, JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -924,6 +907,7 @@ function JDUserSign(s, key, title, body) {
|
||||
|
||||
function JDFlashSale(s) {
|
||||
return new Promise(resolve => {
|
||||
if (disable("JDFSale")) return resolve()
|
||||
setTimeout(() => {
|
||||
const JDPETUrl = {
|
||||
url: 'https://api.m.jd.com/client.action?functionId=partitionJdSgin',
|
||||
@ -973,9 +957,9 @@ function JDFlashSale(s) {
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京东商城-闪购" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -1034,9 +1018,9 @@ function FlashSaleDivide(s) {
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京东闪购-瓜分" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -1047,6 +1031,7 @@ function FlashSaleDivide(s) {
|
||||
|
||||
function JingDongCash(s) {
|
||||
return new Promise(resolve => {
|
||||
if (disable("JDCash")) return resolve()
|
||||
setTimeout(() => {
|
||||
const JDCAUrl = {
|
||||
url: 'https://api.m.jd.com/client.action?functionId=ccSignInNew',
|
||||
@ -1095,172 +1080,9 @@ function JingDongCash(s) {
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京东现金-红包" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}, s)
|
||||
if (out) setTimeout(resolve, out + s)
|
||||
});
|
||||
}
|
||||
|
||||
function JingRSeeAds(s) {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
const JRAdsUrl = {
|
||||
url: 'https://ms.jr.jd.com/gw/generic/jrm/h5/m/sendAdGb',
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
Cookie: KEY,
|
||||
},
|
||||
body: "reqData=%7B%22clientType%22%3A%22ios%22%2C%22actKey%22%3A%22176696%22%2C%22userDeviceInfo%22%3A%7B%22adId%22%3A9999999%7D%2C%22deviceInfoParam%22%3A%7B%22macAddress%22%3A%2202%3A00%3A00%3A00%3A00%3A00%22%2C%22channelInfo%22%3A%22appstore%22%2C%22IPAddress1%22%3A%22%22%2C%22OpenUDID%22%3A%22%22%2C%22clientVersion%22%3A%225.3.30%22%2C%22terminalType%22%3A%2202%22%2C%22osVersion%22%3A%22%22%2C%22appId%22%3A%22com.jd.jinrong%22%2C%22deviceType%22%3A%22iPhone8%2C2%22%2C%22networkType%22%3A%22%22%2C%22startNo%22%3A212%2C%22UUID%22%3A%22%22%2C%22IPAddress%22%3A%22%22%2C%22deviceId%22%3A%22%22%2C%22IDFA%22%3A%22%22%2C%22resolution%22%3A%22%22%2C%22osPlatform%22%3A%22iOS%22%7D%2C%22bussource%22%3A%22%22%7D"
|
||||
};
|
||||
$nobyda.post(JRAdsUrl, function(error, response, data) {
|
||||
try {
|
||||
if (error) {
|
||||
merge.JRSeeAds.notify = "京东金融-广告: 签到接口请求失败 ‼️‼️"
|
||||
merge.JRSeeAds.fail = 1
|
||||
} else {
|
||||
const Details = LogDetails ? "response:\n" + data : '';
|
||||
const cc = JSON.parse(data)
|
||||
if (data.match(/(\"canGetGb\":true)/)) {
|
||||
console.log("\n" + "京东金融-广告签到成功 " + Details)
|
||||
if (data.match(/(\"volumn\"|\"volume\")/)) {
|
||||
merge.JRSeeAds.notify = "京东金融-广告: 成功, 明细: " + cc.resultData.data.volumn + "京豆 🐶"
|
||||
merge.JRSeeAds.bean = cc.resultData.data.volumn
|
||||
merge.JRSeeAds.success = 1
|
||||
} else {
|
||||
merge.JRSeeAds.notify = "京东金融-广告: 成功, 明细: 无京豆 🐶"
|
||||
merge.JRSeeAds.success = 1
|
||||
}
|
||||
} else {
|
||||
console.log("\n" + "京东金融-广告签到失败 " + Details)
|
||||
if (data.match(/(已经发完|已签到|已领取|\"code\":\"2000\")/)) {
|
||||
merge.JRSeeAds.notify = "京东金融-广告: 失败, 原因: 已签过 ⚠️"
|
||||
merge.JRSeeAds.fail = 1
|
||||
} else {
|
||||
if (data.match(/(不存在|已结束|未找到)/)) {
|
||||
merge.JRSeeAds.notify = "京东金融-广告: 失败, 原因: 活动已结束 ⚠️"
|
||||
merge.JRSeeAds.fail = 1
|
||||
} else {
|
||||
if (data.match(/(\"resultCode\":3|先登录)/)) {
|
||||
merge.JRSeeAds.notify = "京东金融-广告: 失败, 原因: Cookie失效‼️"
|
||||
merge.JRSeeAds.fail = 1
|
||||
} else {
|
||||
merge.JRSeeAds.notify = "京东金融-广告: 失败, 原因: 未开始 ⚠️"
|
||||
merge.JRSeeAds.fail = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京东金融-广告" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}, s)
|
||||
if (out) setTimeout(resolve, out + s)
|
||||
});
|
||||
}
|
||||
|
||||
function JingRongGame(s) {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
const JRGamelogin = {
|
||||
url: 'https://ylc.m.jd.com/sign/signGiftDays',
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
Cookie: KEY,
|
||||
},
|
||||
body: "channelId=1"
|
||||
};
|
||||
$nobyda.post(JRGamelogin, async function(error, response, data) {
|
||||
try {
|
||||
if (error) {
|
||||
merge.JRGame.notify = "京东金融-游戏: 登录接口请求失败 ‼️‼️"
|
||||
merge.JRGame.fail = 1
|
||||
} else {
|
||||
const Details = LogDetails ? "response:\n" + data : '';
|
||||
if (data.match(/(未登录)/)) {
|
||||
console.log("\n" + "京东金融-游戏登录失败 " + Details)
|
||||
merge.JRGame.notify = "京东游戏-登录: 失败, 原因: Cookie失效‼️"
|
||||
merge.JRGame.fail = 1
|
||||
} else if (data.match(/(成功)/)) {
|
||||
console.log("\n" + "京东金融-游戏登录成功 " + Details)
|
||||
await JRGameCheckin(0)
|
||||
} else {
|
||||
merge.JRGame.notify = "京东游戏-登录: 失败, 原因: 未知 ⚠️"
|
||||
merge.JRGame.fail = 1
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京东游戏-登录" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}, s)
|
||||
if (out) setTimeout(resolve, out + s)
|
||||
});
|
||||
}
|
||||
|
||||
function JRGameCheckin(s) {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
const JRGameUrl = {
|
||||
url: 'https://ylc.m.jd.com/sign/signDone',
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
Cookie: KEY,
|
||||
},
|
||||
body: "channelId=1"
|
||||
};
|
||||
$nobyda.post(JRGameUrl, function(error, response, data) {
|
||||
try {
|
||||
if (error) {
|
||||
merge.JRGame.notify = "京东金融-游戏: 签到接口请求失败 ‼️‼️"
|
||||
merge.JRGame.fail = 1
|
||||
} else {
|
||||
const Details = LogDetails ? "response:\n" + data : '';
|
||||
const cc = JSON.parse(data)
|
||||
if (data.match(/(\"code\":200)/)) {
|
||||
console.log("\n" + "京东金融-游戏签到成功 " + Details)
|
||||
if (data.match(/(\"rewardAmount\":\d+)/)) {
|
||||
merge.JRGame.notify = "京东金融-游戏: 成功, 明细: " + cc.data.rewardAmount + "京豆 🐶"
|
||||
merge.JRGame.bean = cc.data.rewardAmount
|
||||
merge.JRGame.success = 1
|
||||
} else {
|
||||
merge.JRGame.notify = "京东金融-游戏: 成功, 明细: 无京豆 🐶"
|
||||
merge.JRGame.success = 1
|
||||
}
|
||||
} else {
|
||||
console.log("\n" + "京东金融-游戏签到失败 " + Details)
|
||||
if (data.match(/(用户重复|重复点击|\"code\":301|\"code\":303)/)) {
|
||||
merge.JRGame.notify = "京东金融-游戏: 失败, 原因: 已签过 ⚠️"
|
||||
merge.JRGame.fail = 1
|
||||
} else {
|
||||
if (data.match(/(不存在|已结束|未找到)/)) {
|
||||
merge.JRGame.notify = "京东金融-游戏: 失败, 原因: 活动已结束 ⚠️"
|
||||
merge.JRGame.fail = 1
|
||||
} else {
|
||||
if (data.match(/(\"code\":202|未登录)/)) {
|
||||
merge.JRGame.notify = "京东金融-游戏: 失败, 原因: Cookie失效‼️"
|
||||
merge.JRGame.fail = 1
|
||||
} else {
|
||||
merge.JRGame.notify = "京东金融-游戏: 失败, 原因: 未知 ⚠️"
|
||||
merge.JRGame.fail = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京东金融-游戏" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -1271,6 +1093,7 @@ function JRGameCheckin(s) {
|
||||
|
||||
function JDMagicCube(s) {
|
||||
return new Promise(resolve => {
|
||||
if (disable("JDCube")) return resolve()
|
||||
setTimeout(() => {
|
||||
const JDMCUrl = {
|
||||
url: 'https://api.m.jd.com/client.action?functionId=getNewsInteractionLotteryInfo&appid=smfe',
|
||||
@ -1317,9 +1140,9 @@ function JDMagicCube(s) {
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京东商城-魔方" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -1330,6 +1153,7 @@ function JDMagicCube(s) {
|
||||
|
||||
function JingDongPrize(s) {
|
||||
return new Promise(resolve => {
|
||||
if (disable("JDPrize")) return resolve()
|
||||
setTimeout(() => {
|
||||
const JDkey = {
|
||||
url: 'https://api.m.jd.com/client.action?functionId=vvipscdp_raffleAct_index&client=apple&clientVersion=8.1.0&appid=member_benefit_m',
|
||||
@ -1366,9 +1190,9 @@ function JingDongPrize(s) {
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京东商城-大奖查询KEY" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -1432,9 +1256,9 @@ function JDPrizeCheckin(s) {
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京东商城-大奖签到" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -1445,6 +1269,7 @@ function JDPrizeCheckin(s) {
|
||||
|
||||
function JingDongSpeedUp(s, id) {
|
||||
return new Promise(resolve => {
|
||||
if (disable("SpeedUp")) return resolve()
|
||||
setTimeout(() => {
|
||||
const GameUrl = {
|
||||
url: 'https://api.m.jd.com/?appid=memberTaskCenter&functionId=flyTask_' + (id ? 'start&body=%7B%22source%22%3A%22game%22%2C%22source_id%22%3A' + id + '%7D' : 'state&body=%7B%22source%22%3A%22game%22%7D'),
|
||||
@ -1505,9 +1330,9 @@ function JingDongSpeedUp(s, id) {
|
||||
console.log("\n" + "天天加速-判断状态失败")
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京东天天-加速" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -1550,9 +1375,9 @@ function JDQueryTask(s) {
|
||||
console.log("\n天天加速-查询无道具" + Details)
|
||||
}
|
||||
}
|
||||
resolve(TaskID)
|
||||
} catch (eor) {
|
||||
$nobyda.notify("天天加速-查询道具" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve(TaskID)
|
||||
}
|
||||
})
|
||||
@ -1575,9 +1400,9 @@ function JDReceiveTask(s, CID) {
|
||||
Cookie: KEY
|
||||
}
|
||||
};
|
||||
count += 1
|
||||
$nobyda.get(TUrl, function(error, response, data) {
|
||||
try {
|
||||
count += 1
|
||||
if (error) {
|
||||
console.log("\n天天加速-领取道具请求失败 ‼️‼️")
|
||||
} else {
|
||||
@ -1588,13 +1413,14 @@ function JDReceiveTask(s, CID) {
|
||||
NumTask += 1
|
||||
}
|
||||
}
|
||||
|
||||
} catch (eor) {
|
||||
$nobyda.notify("天天加速-领取道具" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
if (CID.length == count) {
|
||||
console.log("\n天天加速-已成功领取" + NumTask + "个道具")
|
||||
resolve(NumTask)
|
||||
}
|
||||
} catch (eor) {
|
||||
$nobyda.notify("天天加速-领取道具" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
resolve(NumTask)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -1641,9 +1467,9 @@ function JDQueryTaskID(s, EID) {
|
||||
console.log("\n天天加速-查询无道具ID" + Details)
|
||||
}
|
||||
}
|
||||
resolve(TaskCID)
|
||||
} catch (eor) {
|
||||
$nobyda.notify("天天加速-道具ID" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve(TaskCID)
|
||||
}
|
||||
})
|
||||
@ -1669,9 +1495,9 @@ function JDUseProps(s, PropID) {
|
||||
Cookie: KEY
|
||||
}
|
||||
};
|
||||
PropCount += 1
|
||||
$nobyda.get(PropUrl, function(error, response, data) {
|
||||
try {
|
||||
PropCount += 1
|
||||
if (error) {
|
||||
console.log("\n天天加速-使用道具请求失败 ‼️‼️")
|
||||
} else {
|
||||
@ -1682,13 +1508,14 @@ function JDUseProps(s, PropID) {
|
||||
PropNumTask += 1
|
||||
}
|
||||
}
|
||||
|
||||
} catch (eor) {
|
||||
$nobyda.notify("天天加速-使用道具" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
if (PropID.length == PropCount) {
|
||||
console.log("\n天天加速-已成功使用" + PropNumTask + "个道具")
|
||||
resolve()
|
||||
}
|
||||
} catch (eor) {
|
||||
$nobyda.notify("天天加速-使用道具" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -1702,6 +1529,7 @@ function JDUseProps(s, PropID) {
|
||||
|
||||
function JingDongSubsidy(s) {
|
||||
return new Promise(resolve => {
|
||||
if (disable("subsidy")) return resolve()
|
||||
setTimeout(() => {
|
||||
const subsidyUrl = {
|
||||
url: 'https://ms.jr.jd.com/gw/generic/uc/h5/m/signIn7',
|
||||
@ -1738,9 +1566,9 @@ function JingDongSubsidy(s) {
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京东商城-金贴" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -1751,6 +1579,7 @@ function JingDongSubsidy(s) {
|
||||
|
||||
function JingRongDoll(s, type, num) {
|
||||
return new Promise(resolve => {
|
||||
if (disable("JRDoll")) return resolve()
|
||||
setTimeout(() => {
|
||||
const DollUrl = {
|
||||
url: "https://nu.jr.jd.com/gw/generic/jrm/h5/m/process",
|
||||
@ -1804,9 +1633,9 @@ function JingRongDoll(s, type, num) {
|
||||
merge.JRDoll.fail = 1;
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京东金融-娃娃" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -1817,6 +1646,7 @@ function JingRongDoll(s, type, num) {
|
||||
|
||||
function JDOverseas(s) {
|
||||
return new Promise(resolve => {
|
||||
if (disable("Overseas")) return resolve()
|
||||
setTimeout(() => {
|
||||
const OverseasUrl = {
|
||||
url: 'https://api.m.jd.com/client.action?functionId=checkin',
|
||||
@ -1854,9 +1684,9 @@ function JDOverseas(s) {
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京东商城-国际" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -1867,6 +1697,7 @@ function JDOverseas(s) {
|
||||
|
||||
function TotalSteel() {
|
||||
return new Promise(resolve => {
|
||||
if (disable("TSteel")) return resolve()
|
||||
const SteelUrl = {
|
||||
url: 'https://coin.jd.com/m/gb/getBaseInfo.html',
|
||||
headers: {
|
||||
@ -1887,9 +1718,9 @@ function TotalSteel() {
|
||||
} else {
|
||||
console.log("\n" + "京东-总钢镚查询请求失败 ")
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("钢镚接口" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -1899,6 +1730,7 @@ function TotalSteel() {
|
||||
|
||||
function TotalBean() {
|
||||
return new Promise(resolve => {
|
||||
if (disable("Qbear")) return resolve()
|
||||
const BeanUrl = {
|
||||
url: 'https://wq.jd.com/user/info/QueryJDUserInfo?sceneval=2',
|
||||
headers: {
|
||||
@ -1927,9 +1759,9 @@ function TotalBean() {
|
||||
} else {
|
||||
console.log("\n" + "京东-总京豆查询请求失败 ")
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("京豆接口" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -1939,6 +1771,7 @@ function TotalBean() {
|
||||
|
||||
function TotalCash() {
|
||||
return new Promise(resolve => {
|
||||
if (disable("TCash")) return resolve()
|
||||
const CashUrl = {
|
||||
url: 'https://api.m.jd.com/client.action?functionId=myhongbao_balance',
|
||||
headers: {
|
||||
@ -1961,9 +1794,9 @@ function TotalCash() {
|
||||
} else {
|
||||
console.log("\n" + "京东-总红包查询请求失败 ")
|
||||
}
|
||||
resolve()
|
||||
} catch (eor) {
|
||||
$nobyda.notify("红包接口" + eor.name + "‼️", JSON.stringify(eor), eor.message)
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
@ -1971,7 +1804,41 @@ function TotalCash() {
|
||||
});
|
||||
}
|
||||
|
||||
function disable(name) {
|
||||
const read = $nobyda.read("JD_DailyBonusDisable")
|
||||
if (read === "" || read && read.indexOf(name) == -1) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
function initial() {
|
||||
|
||||
acData = {
|
||||
// 京东商城-超市
|
||||
JDGStore: 'aNCM6yrzD6qp1Vvh5YTzeJtk7cM',
|
||||
// 京东商城-宠物
|
||||
JDPet: '37ta5sh5ocrMZF3Fz5UMJbTsL42',
|
||||
// 京东商城-图书
|
||||
JDBook: '3SC6rw5iBg66qrXPGmZMqFDwcyXi',
|
||||
// 京东拍拍-二手
|
||||
JDShand: '3S28janPLYmtFxypu37AYAGgivfp',
|
||||
// 京东商城-美妆
|
||||
JDMakeup: '2smCxzLNuam5L14zNJHYu43ovbAP',
|
||||
// 京东商城-清洁
|
||||
JDClean: '2Tjm6ay1ZbZ3v7UbriTj6kHy9dn6',
|
||||
// 京东商城-女装
|
||||
JDWomen: 'DpSh7ma8JV7QAxSE2gJNro8Q2h9',
|
||||
// 京东商城-个护
|
||||
JDCare: 'NJ1kd1PJWhwvhtim73VPsD1HwY3',
|
||||
// 京东商城-美食
|
||||
JDFood: '4PzvVmLSBq5K63oq4oxKcDtFtzJo',
|
||||
// 京东商城-珠宝
|
||||
JDJewels: 'zHUHpTHNTaztSRfNBFNVZscyFZU',
|
||||
// 京东商城-菜场
|
||||
JDVege: 'Wcu2LVCFMkBP3HraRvb7pgSpt64'
|
||||
};
|
||||
|
||||
merge = {
|
||||
SpeedUp: {},
|
||||
JDBean: {},
|
||||
@ -1987,8 +1854,6 @@ function initial() {
|
||||
JDMakeup: {},
|
||||
Overseas: {},
|
||||
JDWomen: {},
|
||||
JRGame: {},
|
||||
JRSeeAds: {},
|
||||
JDCare: {},
|
||||
JDFood: {},
|
||||
JDClean: {},
|
||||
@ -2052,6 +1917,8 @@ function GetCookie() {
|
||||
} else {
|
||||
$nobyda.notify("用户名: " + DecodeName, "", "更新京东" + CookieName + "Cookie成功 🎉");
|
||||
}
|
||||
} else {
|
||||
console.log("京东: \n与历史Cookie相同, 跳过写入")
|
||||
}
|
||||
} else {
|
||||
var cookie = $nobyda.write(CookieValue, CookieKey);
|
||||
@ -2212,4 +2079,4 @@ function nobyda() {
|
||||
done
|
||||
}
|
||||
};
|
||||
ReadCookie();
|
||||
ReadCookie();
|
||||
@ -140,7 +140,7 @@ update() {
|
||||
if [ $? -ne 0 ]; then
|
||||
cancel "501"
|
||||
fi
|
||||
if [ $(echo "$local_ver < $remote_ver" | bc) -eq 1 ]; then
|
||||
if [ $(expr $local_ver \< $remote_ver) -eq 1 ]; then
|
||||
cp -r $TEMP_SCRIPT $JD_SCRIPT
|
||||
fill_cookie
|
||||
uci set jd-dailybonus.@global[0].version=$remote_ver
|
||||
|
||||
22
package/ctcgfw/luci-app-oled/Makefile
Normal file
22
package/ctcgfw/luci-app-oled/Makefile
Normal file
@ -0,0 +1,22 @@
|
||||
#
|
||||
# Copyright (C) 2020 Nate Ding
|
||||
#
|
||||
# This is free software, licensed under the GUN General Public License v3.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
PKG_NAME:=luci-app-oled
|
||||
LUCI_Title:=LuCI support for ssd1306 0.91\' 138x32 display
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+i2c-tools +coreutils-nohup +libuci
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=1.0
|
||||
|
||||
PKG_LICENSE:=GPLv3
|
||||
PKG_LINCESE_FILES:=LICENSE
|
||||
PKF_MAINTAINER:=natelol <natelol@github.com>
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
17
package/ctcgfw/luci-app-oled/luasrc/controller/oled.lua
Normal file
17
package/ctcgfw/luci-app-oled/luasrc/controller/oled.lua
Normal file
@ -0,0 +1,17 @@
|
||||
module("luci.controller.oled", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/oled") then
|
||||
return
|
||||
end
|
||||
entry({"admin", "services", "oled"}, alias("admin", "services", "oled", "setting"),_("OLED"), 10).dependent = true
|
||||
entry({"admin", "services", "oled", "status"}, call("act_status"))
|
||||
entry({"admin", "services", "oled", "setting"}, cbi("oled/setting"),_("Setting"),30).leaf = true
|
||||
end
|
||||
|
||||
function act_status()
|
||||
local e={}
|
||||
e.running = luci.sys.call("pgrep -f /usr/bin/oled > /dev/null")==0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
@ -0,0 +1,83 @@
|
||||
m = Map("oled", translate("OLED"), translate("A LuCI app that helps you config your oled display (SSD1306, 0.91', 128X32) with screensavers! <br /> <br /> Any issues, please go to: ")..[[<a href="https://github.com/natelol/luci-app-oled" target="_blank">luci-app-oled</a>]])
|
||||
|
||||
--m.chain("luci")
|
||||
|
||||
m:section(SimpleSection).template="oled/status"
|
||||
|
||||
s = m:section(TypedSection, "oled", translate(""))
|
||||
s.anonymous=true
|
||||
s.addremove=false
|
||||
|
||||
--OPTIONS
|
||||
s:tab("info", translate("Info Display"))
|
||||
s:tab("screensaver", translate("screensaver"))
|
||||
|
||||
o = s:taboption("info", Flag, "enable", translate("Enable"))
|
||||
o.default=0
|
||||
--informtion options----
|
||||
o = s:taboption("info", Flag, "date", translate("Date"), translate('Format YYYY-MM-DD HH:MM:SS'))
|
||||
o.default=0
|
||||
o = s:taboption("info", Flag, "lanip", translate("IP"), translate("LAN IP address"))
|
||||
o.default=0
|
||||
o = s:taboption("info", Flag, "cputemp", translate("CPU temperature"))
|
||||
o.default=0
|
||||
o = s:taboption("info", Flag, "cpufreq", translate("CPU frequency"))
|
||||
o.default=0
|
||||
o = s:taboption("info", Flag, "netspeed", translate("Network speed"), translate("1Mbps(m/s)=1,000Kbps(k/s)=1,000,000bps(b/s)"))
|
||||
o.default=0
|
||||
o = s:taboption("info", ListValue, "netsource", translate("which eth to monitor"))
|
||||
o:value("eth0","eth0")
|
||||
o:value("eth1","eth1")
|
||||
o:depends("netspeed",'1')
|
||||
o.default='eth0'
|
||||
o = s:taboption("info", Value, "time", translate("Display interval(s)"), translate('Screensaver will activate in set seconds'))
|
||||
o.default=0
|
||||
|
||||
--screensaver options--
|
||||
o = s:taboption("screensaver", Flag, "scroll", translate("Scroll Text"))
|
||||
o.default=1
|
||||
o = s:taboption("screensaver", Value, "text", translate("Text you want to scroll"))
|
||||
o:depends("scroll",'1')
|
||||
o.default='OPENWRT'
|
||||
o = s:taboption("screensaver", Flag, "drawline", translate("Draw Many Lines"))
|
||||
o.default=0
|
||||
o = s:taboption("screensaver", Flag, "drawrect", translate("Draw Rectangles"))
|
||||
o.default=0
|
||||
o = s:taboption("screensaver", Flag, "fillrect", translate("Draw Multiple Rectangles"))
|
||||
o.default=0
|
||||
o = s:taboption("screensaver", Flag, "drawcircle", translate("Draw Multiple Circles"))
|
||||
o.default=0
|
||||
o = s:taboption("screensaver", Flag, "drawroundrect", translate("Draw a white circle, 10 pixel radius"))
|
||||
o.default=0
|
||||
o = s:taboption("screensaver", Flag, "fillroundrect", translate("Fill the Round Rectangles"))
|
||||
o.default=0
|
||||
o = s:taboption("screensaver", Flag, "drawtriangle", translate("Draw Triangles"))
|
||||
o.default=0
|
||||
o = s:taboption("screensaver", Flag, "filltriangle", translate("Fill Triangles"))
|
||||
o.default=0
|
||||
o = s:taboption("screensaver", Flag, "displaybitmap", translate("Display miniature bitmap"))
|
||||
o.default=0
|
||||
o = s:taboption("screensaver", Flag, "displayinvertnormal", translate("Invert Display Normalize it"))
|
||||
o.default=0
|
||||
o = s:taboption("screensaver", Flag, "drawbitmapeg", translate("Draw a bitmap and animate"))
|
||||
o.default=0
|
||||
|
||||
return m
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
22
package/ctcgfw/luci-app-oled/luasrc/view/oled/status.htm
Normal file
22
package/ctcgfw/luci-app-oled/luasrc/view/oled/status.htm
Normal file
@ -0,0 +1,22 @@
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(3, '<%=url([[admin]], [[services]], [[oled]], [[status]])%>', null,
|
||||
function(x, data) {
|
||||
var tb = document.getElementById('oled_status');
|
||||
if (data && tb) {
|
||||
if (data.running) {
|
||||
var links = '<em><b><font color=green>OLED <%:RUNNING%></font></b></em>';
|
||||
tb.innerHTML = links;
|
||||
} else {
|
||||
tb.innerHTML = '<em><b><font color=red>OLED <%:NOT RUNNING%></font></b></em>';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
|
||||
<fieldset class="cbi-section">
|
||||
<p id="oled_status">
|
||||
<em><%:Collecting data...%></em>
|
||||
</p>
|
||||
</fieldset>
|
||||
134
package/ctcgfw/luci-app-oled/po/zh-cn/oled.po
Normal file
134
package/ctcgfw/luci-app-oled/po/zh-cn/oled.po
Normal file
@ -0,0 +1,134 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:1
|
||||
msgid ""
|
||||
"A LuCI app that helps you config your oled display (SSD1306, 0.91', 128X32) "
|
||||
"with screensavers! <br /> <br /> Any issues, please go to:"
|
||||
msgstr "这是一款支持在ssd1306,0.91寸,128x32像素的oled显示屏上显示你要的信息,包含屏保的程序。<br /> <br />任何问题请到:"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:24
|
||||
msgid "CPU frequency"
|
||||
msgstr "CPU频率"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:22
|
||||
msgid "CPU temperature"
|
||||
msgstr "CPU温度"
|
||||
|
||||
msgid "Scroll Text"
|
||||
msgstr "文字滚动"
|
||||
|
||||
msgid "Text you want to scroll"
|
||||
msgstr "你想要显示的文字"
|
||||
|
||||
msgid "which eth to monitor"
|
||||
msgstr "选择监控哪个网口"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/view/oled/status.htm:20
|
||||
msgid "Collecting data..."
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:18
|
||||
msgid "Date"
|
||||
msgstr "时间"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:48
|
||||
msgid "Display miniature bitmap"
|
||||
msgstr "小图案"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:28
|
||||
msgid "Display interval(s)"
|
||||
msgstr "信息显示间隔(秒)"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:28
|
||||
msgid "Screensaver will activate in set seconds"
|
||||
msgstr "屏保每间隔设置的时间运行一次"
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:32
|
||||
msgid "Draw Many Lines"
|
||||
msgstr "直线"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:38
|
||||
msgid "Draw Multiple Circles"
|
||||
msgstr "多圆"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:36
|
||||
msgid "Draw Multiple Rectangles"
|
||||
msgstr "多方块"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:34
|
||||
msgid "Draw Rectangles"
|
||||
msgstr "方块"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:44
|
||||
msgid "Draw Triangles"
|
||||
msgstr "三角形"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:54
|
||||
msgid "Draw a bitmap and animate"
|
||||
msgstr "动图"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:52
|
||||
msgid "Draw a bitmap and animate movement"
|
||||
msgstr "变化图"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:40
|
||||
msgid "Draw a white circle, 10 pixel radius"
|
||||
msgstr "实心圆"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:15
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:46
|
||||
msgid "Fill Triangles"
|
||||
msgstr "三角填充"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:42
|
||||
msgid "Fill the Round Rectangles"
|
||||
msgstr "方形填充"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:18
|
||||
msgid "Format YYYY-MM-DD HH:MM:SS"
|
||||
msgstr "日期格式 YYYY-MM-DD HH:MM:SS"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:20
|
||||
msgid "IP"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:12
|
||||
msgid "Info Display"
|
||||
msgstr "显示信息"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:50
|
||||
msgid "Invert Display Normalize it"
|
||||
msgstr "反转"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:20
|
||||
msgid "LAN IP address"
|
||||
msgstr "LAN地址"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/view/oled/status.htm:10
|
||||
msgid "NOT RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:26
|
||||
msgid "Network speed"
|
||||
msgstr "网速"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/controller/oled.lua:7
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:1
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:7
|
||||
msgid "OLED"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/view/oled/status.htm:7
|
||||
msgid "RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/controller/oled.lua:9
|
||||
msgid "Setting"
|
||||
msgstr "设置"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:13
|
||||
msgid "screensaver"
|
||||
msgstr "屏保"
|
||||
135
package/ctcgfw/luci-app-oled/po/zh-tw/oled.po
Normal file
135
package/ctcgfw/luci-app-oled/po/zh-tw/oled.po
Normal file
@ -0,0 +1,135 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:1
|
||||
msgid ""
|
||||
"A LuCI app that helps you config your oled display (SSD1306, 0.91', 128X32) "
|
||||
"with screensavers! <br /> <br /> Any issues, please go to:"
|
||||
msgstr "這是壹款支持在ssd1306,0.91寸,128x32像素的oled顯示屏上顯示妳要的信息,包含屏保的程序。<br /> <br />任何問題請到:"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:24
|
||||
msgid "CPU frequency"
|
||||
msgstr "CPU頻率"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:22
|
||||
msgid "CPU temperature"
|
||||
msgstr "CPU溫度"
|
||||
|
||||
msgid "Scroll Text"
|
||||
msgstr "文字滾動"
|
||||
|
||||
msgid "Text you want to scroll"
|
||||
msgstr "妳想要顯示的文字"
|
||||
|
||||
msgid "which eth to monitor"
|
||||
msgstr "選擇監控哪個網口"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/view/oled/status.htm:20
|
||||
msgid "Collecting data..."
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:18
|
||||
msgid "Date"
|
||||
msgstr "時間"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:48
|
||||
msgid "Display miniature bitmap"
|
||||
msgstr "小圖案"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:28
|
||||
msgid "Display interval(s)"
|
||||
msgstr "信息顯示間隔(秒)"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:28
|
||||
msgid "Screensaver will activate in set seconds"
|
||||
msgstr "屏保每間隔設置的時間運行壹次"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:32
|
||||
msgid "Draw Many Lines"
|
||||
msgstr "直線"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:38
|
||||
msgid "Draw Multiple Circles"
|
||||
msgstr "多圓"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:36
|
||||
msgid "Draw Multiple Rectangles"
|
||||
msgstr "多方塊"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:34
|
||||
msgid "Draw Rectangles"
|
||||
msgstr "方塊"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:44
|
||||
msgid "Draw Triangles"
|
||||
msgstr "三角形"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:54
|
||||
msgid "Draw a bitmap and animate"
|
||||
msgstr "動圖"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:52
|
||||
msgid "Draw a bitmap and animate movement"
|
||||
msgstr "變化圖"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:40
|
||||
msgid "Draw a white circle, 10 pixel radius"
|
||||
msgstr "實心圓"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:15
|
||||
msgid "Enable"
|
||||
msgstr "啟用"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:46
|
||||
msgid "Fill Triangles"
|
||||
msgstr "三角填充"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:42
|
||||
msgid "Fill the Round Rectangles"
|
||||
msgstr "方形填充"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:18
|
||||
msgid "Format YYYY-MM-DD HH:MM:SS"
|
||||
msgstr "日期格式 YYYY-MM-DD HH:MM:SS"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:20
|
||||
msgid "IP"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:12
|
||||
msgid "Info Display"
|
||||
msgstr "顯示信息"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:50
|
||||
msgid "Invert Display Normalize it"
|
||||
msgstr "反轉"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:20
|
||||
msgid "LAN IP address"
|
||||
msgstr "LAN地址"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/view/oled/status.htm:10
|
||||
msgid "NOT RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:26
|
||||
msgid "Network speed"
|
||||
msgstr "網速"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/controller/oled.lua:7
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:1
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:7
|
||||
msgid "OLED"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/view/oled/status.htm:7
|
||||
msgid "RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/controller/oled.lua:9
|
||||
msgid "Setting"
|
||||
msgstr "設置"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:13
|
||||
msgid "screensaver"
|
||||
msgstr "屏保"
|
||||
20
package/ctcgfw/luci-app-oled/root/etc/config/oled
Normal file
20
package/ctcgfw/luci-app-oled/root/etc/config/oled
Normal file
@ -0,0 +1,20 @@
|
||||
config oled
|
||||
option drawline '0'
|
||||
option drawrect '0'
|
||||
option fillrect '0'
|
||||
option drawcircle '0'
|
||||
option drawroundrect '0'
|
||||
option fillroundrect '0'
|
||||
option drawtriangle '0'
|
||||
option filltriangle '0'
|
||||
option displaybitmap '0'
|
||||
option displayinvertnormal '0'
|
||||
option drawbitmapeg '0'
|
||||
option date '1'
|
||||
option netspeed '0'
|
||||
option lanip '1'
|
||||
option cpufreq '1'
|
||||
option cputemp '1'
|
||||
option time '60'
|
||||
option enable '0'
|
||||
|
||||
74
package/ctcgfw/luci-app-oled/root/etc/init.d/oled
Executable file
74
package/ctcgfw/luci-app-oled/root/etc/init.d/oled
Executable file
@ -0,0 +1,74 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
START=1OO
|
||||
|
||||
PROG=/usr/bin/oled
|
||||
|
||||
start() {
|
||||
enabled=$(uci get oled.@oled[0].enable)
|
||||
if [ $enabled -eq 0 ]; then
|
||||
exit 0
|
||||
fi
|
||||
#crontab daemon
|
||||
cat /etc/crontabs/root | grep oled > /dev/null
|
||||
if [ $? -eq 1 ]; then
|
||||
echo "*/15 * * * * /etc/init.d/oled restart &>/dev/null 2>&1" >> /etc/crontabs/root
|
||||
fi
|
||||
|
||||
date=$(uci get oled.@oled[0].date)
|
||||
lanip=$(uci get oled.@oled[0].lanip)
|
||||
cputemp=$(uci get oled.@oled[0].cputemp)
|
||||
cpufreq=$(uci get oled.@oled[0].cpufreq)
|
||||
netspeed=$(uci get oled.@oled[0].netspeed)
|
||||
time=$(uci get oled.@oled[0].time)
|
||||
drawline=$(uci get oled.@oled[0].drawline)
|
||||
drawrect=$(uci get oled.@oled[0].drawrect)
|
||||
fillrect=$(uci get oled.@oled[0].fillrect)
|
||||
drawcircle=$(uci get oled.@oled[0].drawcircle)
|
||||
drawroundrect=$(uci get oled.@oled[0].drawroundrect)
|
||||
fillroundrect=$(uci get oled.@oled[0].fillroundrect)
|
||||
drawtriangle=$(uci get oled.@oled[0].drawtriangle)
|
||||
filltriangle=$(uci get oled.@oled[0].filltriangle)
|
||||
displaybitmap=$(uci get oled.@oled[0].displaybitmap)
|
||||
displayinvertnormal=$(uci get oled.@oled[0].displayinvertnormal)
|
||||
drawbitmapeg=$(uci get oled.@oled[0].drawbitmapeg)
|
||||
scroll=$(uci get oled.@oled[0].scroll)
|
||||
text=$(uci get oled.@oled[0].text)
|
||||
netsource=$(uci get oled.@oled[0].netsource)
|
||||
if [ ${netspeed} -eq 1 ]; then
|
||||
nohup /usr/sbin/netspeed ${netsource} >/dev/null 2>&1 &
|
||||
else
|
||||
ps|grep netspeed|grep -v grep|awk '{print $1}'|xargs kill -9
|
||||
rm -f /tmp/netspeed
|
||||
fi
|
||||
nohup ${PROG} ${date} ${lanip} ${cputemp} ${cpufreq} ${netspeed} ${time} ${drawline} ${drawrect} ${fillrect} ${drawcircle} ${drawroundrect} ${fillroundrect} ${drawtriangle} ${filltriangle} ${displaybitmap} ${displayinvertnormal} ${drawbitmapeg} ${scroll} "${text}" "${netsource}" > /dev/null 2>&1 &
|
||||
}
|
||||
|
||||
|
||||
stop() {
|
||||
kill `pgrep /usr/bin/oled`
|
||||
sleep 1
|
||||
ps|grep netspeed|grep -v grep|awk '{print $1}'|xargs kill -9
|
||||
sleep 1
|
||||
echo "oled exit..."
|
||||
}
|
||||
|
||||
restart(){
|
||||
enabled=$(uci get oled.@oled[0].enable)
|
||||
pgrep -f ${PROG} >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
if [ $enabled -eq 1 ]; then
|
||||
stop
|
||||
sleep 1
|
||||
start
|
||||
else
|
||||
stop
|
||||
fi
|
||||
|
||||
else
|
||||
if [ $enabled -eq 1 ]; then
|
||||
start
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
}
|
||||
11
package/ctcgfw/luci-app-oled/root/etc/uci-defaults/oled
Normal file
11
package/ctcgfw/luci-app-oled/root/etc/uci-defaults/oled
Normal file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@oled[-1]
|
||||
add ucitrack oled
|
||||
set ucitrack.@oled[-1].init=oled
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
rm -rf /tmp/luci-*
|
||||
exit 0
|
||||
20
package/ctcgfw/luci-app-oled/root/usr/sbin/netspeed
Executable file
20
package/ctcgfw/luci-app-oled/root/usr/sbin/netspeed
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/ash
|
||||
IF=$1
|
||||
if [ -z "$IF" ]; then
|
||||
IF=`ls -1 /sys/class/net/ | head -1`
|
||||
fi
|
||||
RXPREV=-1
|
||||
TXPREV=-1
|
||||
echo "Listening $IF..."
|
||||
while [ 1 == 1 ] ; do
|
||||
RX=`cat /sys/class/net/${IF}/statistics/rx_bytes`
|
||||
TX=`cat /sys/class/net/${IF}/statistics/tx_bytes`
|
||||
if [ $RXPREV -ne -1 ] ; then
|
||||
let BWRX=$RX-$RXPREV
|
||||
let BWTX=$TX-$TXPREV
|
||||
echo "$BWRX $BWTX">/tmp/netspeed
|
||||
fi
|
||||
RXPREV=$RX
|
||||
TXPREV=$TX
|
||||
sleep 1
|
||||
done
|
||||
232
package/ctcgfw/luci-app-oled/src/Example_Code/Main.c
Normal file
232
package/ctcgfw/luci-app-oled/src/Example_Code/Main.c
Normal file
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Main.c
|
||||
*
|
||||
* Created on : Sep 6, 2017
|
||||
* Author : Vinay Divakar
|
||||
* Description : Example usage of the SSD1306 Driver API's
|
||||
* Website : www.deeplyembedded.org
|
||||
*/
|
||||
|
||||
/* Lib Includes */
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
/* Header Files */
|
||||
#include "I2C.h"
|
||||
#include "SSD1306_OLED.h"
|
||||
#include "example_app.h"
|
||||
|
||||
/* Oh Compiler-Please leave me as is */
|
||||
volatile unsigned char flag = 0;
|
||||
|
||||
/* Alarm Signal Handler */
|
||||
void ALARMhandler(int sig)
|
||||
{
|
||||
/* Set flag */
|
||||
flag = 5;
|
||||
}
|
||||
|
||||
void BreakDeal(int sig)
|
||||
{
|
||||
clearDisplay();
|
||||
usleep(1000000);
|
||||
Display();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int date=atoi(argv[1]);
|
||||
int lanip=atoi(argv[2]);
|
||||
int cputemp=atoi(argv[3]);
|
||||
int cpufreq=atoi(argv[4]);
|
||||
int netspeed=atoi(argv[5]);
|
||||
int time=atoi(argv[6]);
|
||||
int drawline=atoi(argv[7]);
|
||||
int drawrect=atoi(argv[8]);
|
||||
int fillrect=atoi(argv[9]);
|
||||
int drawcircle=atoi(argv[10]);
|
||||
int drawroundcircle=atoi(argv[11]);
|
||||
int fillroundcircle=atoi(argv[12]);
|
||||
int drawtriangle=atoi(argv[13]);
|
||||
int filltriangle=atoi(argv[14]);
|
||||
int displaybitmap=atoi(argv[15]);
|
||||
int displayinvertnormal=atoi(argv[16]);
|
||||
int drawbitmapeg=atoi(argv[17]);
|
||||
int scroll=atoi(argv[18]);
|
||||
char *text=argv[19];
|
||||
char *eth = argv[20];
|
||||
|
||||
|
||||
|
||||
/* Initialize I2C bus and connect to the I2C Device */
|
||||
if(init_i2c_dev(I2C_DEV0_PATH, SSD1306_OLED_ADDR) == 0)
|
||||
{
|
||||
printf("(Main)i2c-2: Bus Connected to SSD1306\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("(Main)i2c-2: OOPS! Something Went Wrong\r\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Register the Alarm Handler */
|
||||
signal(SIGALRM, ALARMhandler);
|
||||
signal(SIGINT, BreakDeal);
|
||||
signal(SIGTERM, BreakDeal);
|
||||
/* Run SDD1306 Initialization Sequence */
|
||||
display_Init_seq();
|
||||
|
||||
/* Clear display */
|
||||
clearDisplay();
|
||||
|
||||
// draw a single pixel
|
||||
// drawPixel(0, 1, WHITE);
|
||||
// Display();
|
||||
// usleep(1000000);
|
||||
// clearDisplay();
|
||||
|
||||
// draw many lines
|
||||
while(1){
|
||||
|
||||
if(scroll){
|
||||
testscrolltext(text);
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
|
||||
if(drawline){
|
||||
testdrawline();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
|
||||
|
||||
// draw rectangles
|
||||
if(drawrect){
|
||||
testdrawrect();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
|
||||
// draw multiple rectangles
|
||||
if(fillrect){
|
||||
testfillrect();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
|
||||
// draw mulitple circles
|
||||
if(drawcircle){
|
||||
testdrawcircle();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
|
||||
|
||||
// draw a white circle, 10 pixel radius
|
||||
if(drawroundcircle){
|
||||
testdrawroundrect();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
|
||||
|
||||
// Fill the round rectangle
|
||||
if(fillroundcircle){
|
||||
testfillroundrect();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
|
||||
// Draw triangles
|
||||
if(drawtriangle){
|
||||
testdrawtriangle();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
// Fill triangles
|
||||
if(filltriangle){
|
||||
testfilltriangle();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
|
||||
// Display miniature bitmap
|
||||
if(displaybitmap){
|
||||
display_bitmap();
|
||||
Display();
|
||||
usleep(1000000);
|
||||
};
|
||||
// Display Inverted image and normalize it back
|
||||
if(displayinvertnormal){
|
||||
display_invert_normal();
|
||||
clearDisplay();
|
||||
usleep(1000000);
|
||||
Display();
|
||||
|
||||
}
|
||||
|
||||
// Generate Signal after 20 Seconds
|
||||
|
||||
// draw a bitmap icon and 'animate' movement
|
||||
if(drawbitmapeg){
|
||||
alarm(10);
|
||||
flag=0;
|
||||
testdrawbitmap_eg();
|
||||
clearDisplay();
|
||||
usleep(1000000);
|
||||
Display();
|
||||
}
|
||||
|
||||
|
||||
//setCursor(0,0);
|
||||
setTextColor(WHITE);
|
||||
// info display
|
||||
int sum = date+lanip+cpufreq+cputemp+netspeed;
|
||||
if (sum == 0) {clearDisplay(); return 0;}
|
||||
for(int i = 1; i < time; i++){
|
||||
if (sum == 1){//only one item for display
|
||||
if (date) testdate(CENTER, 8);
|
||||
if (lanip) testlanip(CENTER, 8);
|
||||
if (cpufreq) testcpufreq(CENTER, 8);
|
||||
if (cputemp) testcputemp(CENTER, 8);
|
||||
if (netspeed) testnetspeed(SPLIT,0);
|
||||
Display();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}else if (sum == 2){//two items for display
|
||||
if(date) {testdate(CENTER, 16*(date-1));}
|
||||
if(lanip) {testlanip(CENTER, 16*(date+lanip-1));}
|
||||
if(cpufreq) {testcpufreq(CENTER, 16*(date+lanip+cpufreq-1));}
|
||||
if(cputemp) {testcputemp(CENTER, 16*(date+lanip+cpufreq+cputemp-1));}
|
||||
if(netspeed) {testnetspeed(MERGE, 16*(date+lanip+cpufreq+cputemp+netspeed-1));}
|
||||
Display();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
else{//more than two items for display
|
||||
if(date) {testdate(FULL, 8*(date-1));}
|
||||
if(lanip) {testlanip(FULL, 8*(date+lanip-1));}
|
||||
if(cpufreq && cputemp) {
|
||||
testcpu(8*(date+lanip));
|
||||
if(netspeed) {testnetspeed(FULL, 8*(date+lanip+1+netspeed-1));}
|
||||
}
|
||||
else{
|
||||
if(cpufreq) {testcpufreq(FULL, 8*(date+lanip+cpufreq-1));}
|
||||
if(cputemp) {testcputemp(FULL, 8*(date+lanip+cpufreq+cputemp-1));}
|
||||
if(netspeed) {testnetspeed(FULL, 8*(date+lanip+cpufreq+cputemp+netspeed-1));}
|
||||
}
|
||||
|
||||
Display();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
650
package/ctcgfw/luci-app-oled/src/Example_Code/example_app.c
Normal file
650
package/ctcgfw/luci-app-oled/src/Example_Code/example_app.c
Normal file
@ -0,0 +1,650 @@
|
||||
/*
|
||||
* MIT License
|
||||
|
||||
Copyright (c) 2017 DeeplyEmbedded
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
* example_app.c
|
||||
*
|
||||
* Created on : Sep 6, 2017
|
||||
* Author : Vinay Divakar
|
||||
* Website : www.deeplyembedded.org
|
||||
*/
|
||||
|
||||
/* Lib Includes */
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include "SSD1306_OLED.h"
|
||||
#include "example_app.h"
|
||||
|
||||
#define BUFMAX SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT
|
||||
|
||||
/* MACRO's */
|
||||
#define LOGO16_GLCD_HEIGHT 16
|
||||
#define LOGO16_GLCD_WIDTH 16
|
||||
#define NUMFLAKES 10
|
||||
#define XPOS 0
|
||||
#define YPOS 1
|
||||
#define DELTAY 2
|
||||
|
||||
|
||||
|
||||
#define TIMESIZE 64
|
||||
//temperature
|
||||
#define TEMPPATH "/sys/class/thermal/thermal_zone0/temp"
|
||||
#define TEMPSIZE 5
|
||||
//cpu
|
||||
#define FREQSIZE 8
|
||||
#define FREQPATH "cat /sys/devices/system/cpu/cpu[04]/cpufreq/cpuinfo_cur_freq"
|
||||
//ip
|
||||
#define IPPATH "ifconfig br-lan|grep 'inet addr:'|cut -d: -f2|awk '{print $1}'"
|
||||
#define IPSIZE 20
|
||||
//netspeed
|
||||
#define NETPATH "cat /tmp/netspeed"
|
||||
|
||||
/* Extern volatile */
|
||||
extern volatile unsigned char flag;
|
||||
|
||||
/* Bit Map - Taken from Adafruit SSD1306 OLED Library */
|
||||
static const unsigned char logo16_glcd_bmp[] =
|
||||
{
|
||||
0b00000000, 0b11000000,
|
||||
0b00000001, 0b11000000,
|
||||
0b00000001, 0b11000000,
|
||||
0b00000011, 0b11100000,
|
||||
0b11110011, 0b11100000,
|
||||
0b11111110, 0b11111000,
|
||||
0b01111110, 0b11111111,
|
||||
0b00110011, 0b10011111,
|
||||
0b00011111, 0b11111100,
|
||||
0b00001101, 0b01110000,
|
||||
0b00011011, 0b10100000,
|
||||
0b00111111, 0b11100000,
|
||||
0b00111111, 0b11110000,
|
||||
0b01111100, 0b11110000,
|
||||
0b01110000, 0b01110000,
|
||||
0b00000000, 0b00110000
|
||||
};
|
||||
|
||||
FILE *fp;
|
||||
char content_buff[BUFMAX];
|
||||
char buf[BUFMAX];
|
||||
int display_offset =7;
|
||||
/* draw many lines */
|
||||
void testdrawline()
|
||||
{
|
||||
short i = 0;
|
||||
for (i=0; i<SSD1306_LCDWIDTH; i+=4)
|
||||
{
|
||||
drawLine(0, 0, i, SSD1306_LCDHEIGHT-1, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
for (i=0; i<SSD1306_LCDHEIGHT; i+=4)
|
||||
{
|
||||
drawLine(0, 0, SSD1306_LCDWIDTH-1, i, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
usleep(250000);
|
||||
|
||||
clearDisplay();
|
||||
for (i=0; i<SSD1306_LCDWIDTH; i+=4)
|
||||
{
|
||||
drawLine(0, SSD1306_LCDHEIGHT-1, i, 0, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
for (i=SSD1306_LCDHEIGHT-1; i>=0; i-=4)
|
||||
{
|
||||
drawLine(0, SSD1306_LCDHEIGHT-1, SSD1306_LCDWIDTH-1, i, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
usleep(250000);
|
||||
|
||||
clearDisplay();
|
||||
for (i=SSD1306_LCDWIDTH-1; i>=0; i-=4)
|
||||
{
|
||||
drawLine(SSD1306_LCDWIDTH-1, SSD1306_LCDHEIGHT-1, i, 0, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
for (i=SSD1306_LCDHEIGHT-1; i>=0; i-=4)
|
||||
{
|
||||
drawLine(SSD1306_LCDWIDTH-1, SSD1306_LCDHEIGHT-1, 0, i, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
usleep(250000);
|
||||
|
||||
clearDisplay();
|
||||
for (i=0; i<SSD1306_LCDHEIGHT; i+=4)
|
||||
{
|
||||
drawLine(SSD1306_LCDWIDTH-1, 0, 0, i, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
for (i=0; i<SSD1306_LCDWIDTH; i+=4) {
|
||||
drawLine(SSD1306_LCDWIDTH-1, 0, i, SSD1306_LCDHEIGHT-1, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
usleep(250000);
|
||||
}
|
||||
|
||||
/* draw rectangles */
|
||||
void testdrawrect()
|
||||
{
|
||||
short i = 0;
|
||||
for (i=0; i<SSD1306_LCDHEIGHT/2; i+=2)
|
||||
{
|
||||
drawRect(i, i,SSD1306_LCDWIDTH-2*i, SSD1306_LCDHEIGHT-2*i, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
/* draw multiple rectangles */
|
||||
void testfillrect()
|
||||
{
|
||||
unsigned char color = 1;
|
||||
short i = 0;
|
||||
for (i=0; i<SSD1306_LCDHEIGHT/2; i+=3)
|
||||
{
|
||||
// alternate colors
|
||||
fillRect(i, i, SSD1306_LCDWIDTH-i*2, SSD1306_LCDHEIGHT-i*2, color%2);
|
||||
Display();
|
||||
usleep(1000);
|
||||
color++;
|
||||
}
|
||||
}
|
||||
|
||||
/* draw mulitple circles */
|
||||
void testdrawcircle()
|
||||
{
|
||||
short i = 0;
|
||||
for (i=0; i<SSD1306_LCDHEIGHT; i+=2)
|
||||
{
|
||||
drawCircle(SSD1306_LCDWIDTH/2,SSD1306_LCDHEIGHT/2, i, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
/*draw a white circle, 10 pixel radius */
|
||||
void testdrawroundrect()
|
||||
{
|
||||
short i = 0;
|
||||
for (i=0; i<SSD1306_LCDHEIGHT/2-2; i+=2) {
|
||||
drawRoundRect(i, i,SSD1306_LCDWIDTH-2*i, SSD1306_LCDHEIGHT-2*i, SSD1306_LCDHEIGHT/4, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill the round rectangle */
|
||||
void testfillroundrect()
|
||||
{
|
||||
short color = WHITE,i = 0;
|
||||
for (i=0; i<SSD1306_LCDHEIGHT/2-2; i+=2)
|
||||
{
|
||||
fillRoundRect(i, i, SSD1306_LCDWIDTH-2*i, SSD1306_LCDHEIGHT-2*i, SSD1306_LCDHEIGHT/4, color);
|
||||
if (color == WHITE)
|
||||
color = BLACK;
|
||||
else
|
||||
color = WHITE;
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw triangles */
|
||||
void testdrawtriangle()
|
||||
{
|
||||
short i = 0;
|
||||
for (i=0; i<MIN(SSD1306_LCDWIDTH,SSD1306_LCDHEIGHT)/2; i+=5)
|
||||
{
|
||||
drawTriangle(SSD1306_LCDWIDTH/2, SSD1306_LCDHEIGHT/2-i,
|
||||
SSD1306_LCDWIDTH/2-i,SSD1306_LCDHEIGHT /2+i,
|
||||
SSD1306_LCDWIDTH/2+i, SSD1306_LCDHEIGHT/2+i, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill triangles */
|
||||
void testfilltriangle()
|
||||
{
|
||||
unsigned char color = WHITE;
|
||||
short i = 0;
|
||||
for (i=MIN(SSD1306_LCDWIDTH,SSD1306_LCDHEIGHT)/2; i>0; i-=5)
|
||||
{
|
||||
fillTriangle(SSD1306_LCDWIDTH/2, SSD1306_LCDHEIGHT/2-i,
|
||||
SSD1306_LCDWIDTH/2-i, SSD1306_LCDHEIGHT/2+i,
|
||||
SSD1306_LCDWIDTH/2+i, SSD1306_LCDHEIGHT/2+i, WHITE);
|
||||
if (color == WHITE)
|
||||
color = BLACK;
|
||||
else
|
||||
color = WHITE;
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
/* Display a bunch of characters and emoticons */
|
||||
void testdrawchar()
|
||||
{
|
||||
unsigned char i = 0;
|
||||
setTextSize(1);
|
||||
setTextColor(WHITE);
|
||||
setCursor(0,0);
|
||||
|
||||
for (i=0; i < 168; i++)
|
||||
{
|
||||
if (i == '\n')
|
||||
continue;
|
||||
oled_write(i);
|
||||
if ((i > 0) && (i % 21 == 0))
|
||||
println();
|
||||
}
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
|
||||
/* Display "scroll" and scroll around */
|
||||
void testscrolltext(char* str)
|
||||
{
|
||||
setTextSize(2);
|
||||
setTextColor(WHITE);
|
||||
setCursor(10,8);
|
||||
sprintf(buf,"%s",str);
|
||||
print_strln(buf);
|
||||
Display();
|
||||
usleep(1000);
|
||||
startscrollright(0x00, 0x0F);
|
||||
usleep(5000000);
|
||||
stopscroll();
|
||||
usleep(1000000);
|
||||
startscrollleft(0x00, 0x0F);
|
||||
usleep(5000000);
|
||||
stopscroll();
|
||||
usleep(1000000);
|
||||
startscrolldiagright(0x00, 0x07);
|
||||
usleep(5000000);
|
||||
startscrolldiagleft(0x00, 0x07);
|
||||
usleep(5000000);
|
||||
stopscroll();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Display Texts */
|
||||
void display_texts()
|
||||
{
|
||||
setTextSize(1);
|
||||
setTextColor(WHITE);
|
||||
setCursor(10,0);
|
||||
print_str("HELLO FELLAS!");
|
||||
println();
|
||||
printFloat_ln(3.141592, 4); //Print 4 No's after the decimal Pt.
|
||||
printNumber_L_ln(-1234, DEC);
|
||||
printNumber_UC_ln(170, BIN);
|
||||
setTextSize(2);
|
||||
setTextColor(WHITE);
|
||||
print_str("0x");
|
||||
printNumber_UL_ln(0xDEADBEEF, HEX);
|
||||
}
|
||||
|
||||
/* Display miniature bitmap */
|
||||
void display_bitmap()
|
||||
{
|
||||
drawBitmap(30, 16, logo16_glcd_bmp, 16, 16, 1);
|
||||
}
|
||||
|
||||
/* Invert Display and Normalize it */
|
||||
void display_invert_normal()
|
||||
{
|
||||
invertDisplay(SSD1306_INVERT_DISPLAY);
|
||||
usleep(1000000);
|
||||
invertDisplay(SSD1306_NORMALIZE_DISPLAY);
|
||||
usleep(1000000);
|
||||
}
|
||||
|
||||
/* Draw a bitmap and 'animate' movement */
|
||||
void testdrawbitmap(const unsigned char *bitmap, unsigned char w, unsigned char h)
|
||||
{
|
||||
unsigned char icons[NUMFLAKES][3], f = 0;
|
||||
|
||||
// initialize
|
||||
for (f=0; f< NUMFLAKES; f++)
|
||||
{
|
||||
icons[f][XPOS] = rand() % SSD1306_LCDWIDTH;
|
||||
icons[f][YPOS] = 0;
|
||||
icons[f][DELTAY] = (rand() % 5) + 1;
|
||||
|
||||
/* Looks kinna ugly to me - Un-Comment if you need it */
|
||||
//print_str("x: ");
|
||||
//printNumber_UC(icons[f][XPOS], DEC);
|
||||
//print_str("y: ");
|
||||
//printNumber_UC(icons[f][YPOS], DEC);
|
||||
//print_str("dy: ");
|
||||
//printNumber_UC(icons[f][DELTAY], DEC);
|
||||
}
|
||||
|
||||
while (flag != 5)
|
||||
{
|
||||
// draw each icon
|
||||
for (f=0; f< NUMFLAKES; f++)
|
||||
{
|
||||
drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);
|
||||
}
|
||||
Display();
|
||||
usleep(200000);
|
||||
|
||||
// then erase it + move it
|
||||
for (f=0; f< NUMFLAKES; f++)
|
||||
{
|
||||
drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, BLACK);
|
||||
|
||||
// move it
|
||||
icons[f][YPOS] += icons[f][DELTAY];
|
||||
|
||||
// if its gone, reinit
|
||||
if (icons[f][YPOS] > SSD1306_LCDHEIGHT)
|
||||
{
|
||||
icons[f][XPOS] = rand() % SSD1306_LCDWIDTH;
|
||||
icons[f][YPOS] = 0;
|
||||
icons[f][DELTAY] = (rand() % 5) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw bitmap and animate */
|
||||
void testdrawbitmap_eg()
|
||||
{
|
||||
setTextSize(1);
|
||||
setTextColor(WHITE);
|
||||
setCursor(10,0);
|
||||
testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH);
|
||||
}
|
||||
|
||||
/* Intro */
|
||||
void deeplyembedded_credits()
|
||||
{
|
||||
setTextSize(1);
|
||||
setTextColor(WHITE);
|
||||
setCursor(1,0);
|
||||
print_strln("deeplyembedded.org");
|
||||
println();
|
||||
print_strln("Author:Vinay Divakar");
|
||||
println();
|
||||
println();
|
||||
print_strln("THANK YOU");
|
||||
}
|
||||
|
||||
|
||||
void testdate(int mode, int y)
|
||||
{
|
||||
time_t rawtime;
|
||||
time_t curtime;
|
||||
uint8_t timebuff[TIMESIZE];
|
||||
curtime = time(NULL);
|
||||
time(&rawtime);
|
||||
switch (mode)
|
||||
{
|
||||
case CENTER:
|
||||
setTextSize(2);
|
||||
strftime(timebuff,80,"%H:%M",localtime(&rawtime));
|
||||
sprintf(buf,"%s",timebuff);
|
||||
setCursor((127-strlen(buf)*11)/2-4, y);
|
||||
break;
|
||||
case FULL:
|
||||
setTextSize(1);
|
||||
strftime(timebuff,80,"%Y-%m-%d %H:%M:%S",localtime(&rawtime));
|
||||
sprintf(buf,"%s",timebuff);
|
||||
setCursor(display_offset, y);
|
||||
}
|
||||
print_strln(buf);
|
||||
}
|
||||
|
||||
|
||||
void testlanip(int mode, int y)
|
||||
{
|
||||
setTextSize(1);
|
||||
if((fp=popen(IPPATH,"r"))!=NULL)
|
||||
{
|
||||
fscanf(fp,"%s",content_buff);
|
||||
fclose(fp);
|
||||
//ipbuff[strlen(ipbuff)-1]=32;
|
||||
switch(mode)
|
||||
{
|
||||
case CENTER:
|
||||
setTextSize(1);
|
||||
sprintf(buf,"%s",content_buff);
|
||||
setCursor((127-strlen(buf)*6)/2, y+4);
|
||||
break;
|
||||
|
||||
case FULL:
|
||||
setTextSize(1);
|
||||
sprintf(buf,"IP:%s",content_buff);
|
||||
setCursor(display_offset, y);
|
||||
}
|
||||
print_strln(buf);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void testcputemp(int mode, int y)
|
||||
{
|
||||
if((fp=fopen(TEMPPATH,"r"))!=NULL)
|
||||
{
|
||||
fgets(content_buff,TEMPSIZE,fp);
|
||||
fclose(fp);
|
||||
switch (mode)
|
||||
{
|
||||
case CENTER:
|
||||
setTextSize(2);
|
||||
sprintf(buf, "%.2f",atoi(content_buff)/100.0);
|
||||
setCursor((127-(strlen(buf)+2)*11)/2-4, y);
|
||||
print_str(buf);
|
||||
oled_write(0);
|
||||
oled_write(67);
|
||||
drawCircle(getCursorX()-16, getCursorY()+3, 2, WHITE);
|
||||
break;
|
||||
case FULL:
|
||||
setTextSize(1);
|
||||
sprintf(buf,"CPU TEMP:%.2f",atoi(content_buff)/100.0);
|
||||
setCursor(display_offset, y);
|
||||
print_str(buf);
|
||||
oled_write(0);
|
||||
oled_write(67);
|
||||
drawCircle(getCursorX()-8, getCursorY()+1, 1, WHITE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void testcpufreq(int mode, int y)
|
||||
{
|
||||
if((fp=popen(FREQPATH,"r")) != NULL)
|
||||
{
|
||||
fgets(content_buff,FREQSIZE,fp);
|
||||
fclose(fp);
|
||||
switch(mode)
|
||||
{
|
||||
case CENTER:
|
||||
setTextSize(2);
|
||||
sprintf(buf,"%4dMHz",atoi(content_buff)/1000);
|
||||
setCursor((127-strlen(buf)*11)/2-4, y);
|
||||
break;
|
||||
case FULL:
|
||||
setTextSize(1);
|
||||
sprintf(buf,"CPU FREQ:%4dMHz",atoi(content_buff)/1000);
|
||||
setCursor(display_offset, y);
|
||||
}
|
||||
print_strln(buf);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void testnetspeed(int mode, int y)
|
||||
{
|
||||
int in,out;
|
||||
if((fp=popen(NETPATH,"r")) != NULL)
|
||||
{
|
||||
|
||||
fscanf(fp,"%d %d", &in, &out);
|
||||
fclose(fp);
|
||||
in = in;
|
||||
out = out;
|
||||
switch(mode)
|
||||
{
|
||||
case SPLIT:
|
||||
setTextSize(2);
|
||||
if (in < 1000) sprintf(buf, "%03dB", in);
|
||||
else if (in > 1000000) sprintf(buf, "%03dM", in/1000000);
|
||||
else sprintf(buf, "%03dK", in/1000);
|
||||
setCursor((127-(strlen(buf)+1)*11)/2,0);
|
||||
oled_write(24);
|
||||
print_str(buf);
|
||||
|
||||
if (out < 1000) sprintf(buf, "%03dB", out);
|
||||
else if (out > 1000000) sprintf(buf, "%03dM", out/1000000);
|
||||
else sprintf(buf, "%03dK", out/1000);
|
||||
setCursor((127-(strlen(buf)+1)*11)/2,16);
|
||||
oled_write(25);
|
||||
print_str(buf);
|
||||
break;
|
||||
case MERGE:
|
||||
setTextSize(1);
|
||||
if (in < 1000) sprintf(buf, "%03dB ", in);
|
||||
else if (in > 1000000) sprintf(buf, "%03dM", in/1000000);
|
||||
else sprintf(buf, "%03dK ", in/1000);
|
||||
setCursor((127-(2*strlen(buf)-1)*6)/2-4, y+4);
|
||||
oled_write(24);
|
||||
print_str(buf);
|
||||
if (out < 1000) sprintf(buf, "%03dB", out);
|
||||
else if (out > 1000000) sprintf(buf, "%03dM", out/1000000);
|
||||
else sprintf(buf, "%03dK", out/1000);
|
||||
oled_write(25);
|
||||
print_str(buf);
|
||||
break;
|
||||
case FULL:
|
||||
setTextSize(1);
|
||||
setCursor(display_offset, y);
|
||||
oled_write(24);
|
||||
if (in < 1000) sprintf(buf, "%03dB ", in);
|
||||
else if (in > 1000000) sprintf(buf, "%03dM", in/1000000);
|
||||
else sprintf(buf, "%03dK ", in/1000);
|
||||
print_str(buf);
|
||||
oled_write(25);
|
||||
if (out < 1000) sprintf(buf, "%03dB", out);
|
||||
else if (out > 1000000) sprintf(buf, "%03dM", out/1000000);
|
||||
else sprintf(buf, "%03dK", out/1000);
|
||||
print_str(buf);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void testcpu(int y)
|
||||
{
|
||||
//freq
|
||||
setTextSize(1);
|
||||
setCursor(display_offset, y);
|
||||
if((fp=popen(FREQPATH,"r")) != NULL)
|
||||
{
|
||||
fgets(content_buff,FREQSIZE,fp);
|
||||
fclose(fp);
|
||||
sprintf(buf,"CPU:%4dMHz ", atoi(content_buff)/1000);
|
||||
print_str(buf);
|
||||
}
|
||||
|
||||
|
||||
//temp
|
||||
if((fp=fopen(TEMPPATH,"r"))!=NULL)
|
||||
{
|
||||
fgets(content_buff,TEMPSIZE,fp);
|
||||
fclose(fp);
|
||||
sprintf(buf, "%.2f",atoi(content_buff)/100.0);
|
||||
print_str(buf);
|
||||
oled_write(0);
|
||||
oled_write(67);
|
||||
drawCircle(getCursorX()-8, getCursorY()+1, 1, WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
void testprintinfo()
|
||||
{
|
||||
setTextSize(1);
|
||||
setTextColor(WHITE);
|
||||
setCursor(0,0);
|
||||
//DATE
|
||||
|
||||
time_t rawtime;
|
||||
time_t curtime;
|
||||
uint8_t timebuff[TIMESIZE];
|
||||
curtime = time(NULL);
|
||||
time(&rawtime);
|
||||
strftime(timebuff,80,"%Y-%m-%d_%w %H:%M:%S",localtime(&rawtime));
|
||||
sprintf(buf,"%s",timebuff);
|
||||
print_strln(buf);
|
||||
|
||||
//br-lan ip
|
||||
if((fp=popen(IPPATH,"r"))!=NULL)
|
||||
{
|
||||
fscanf(fp,"%s",content_buff);
|
||||
fclose(fp);
|
||||
//ipbuff[strlen(ipbuff)-1]=32;
|
||||
sprintf(buf,"IP:%s",content_buff);
|
||||
print_strln(buf);
|
||||
}
|
||||
|
||||
//CPU temp
|
||||
if((fp=popen(FREQPATH,"r")) != NULL)
|
||||
{
|
||||
fgets(content_buff,FREQSIZE,fp);
|
||||
fclose(fp);
|
||||
sprintf(buf,"CPU freq:%d MHz ",atoi(content_buff)/1000);
|
||||
print_strln(buf);
|
||||
}
|
||||
|
||||
//cpu freq
|
||||
if((fp=fopen(TEMPPATH,"r"))!=NULL)
|
||||
{
|
||||
fgets(content_buff,TEMPSIZE,fp);
|
||||
fclose(fp);
|
||||
sprintf(buf,"CPU temp:%.2f C",atoi(content_buff)/100.0);
|
||||
print_strln(buf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
30
package/ctcgfw/luci-app-oled/src/Example_Code/example_app.h
Normal file
30
package/ctcgfw/luci-app-oled/src/Example_Code/example_app.h
Normal file
@ -0,0 +1,30 @@
|
||||
#define CENTER 0 //single item display
|
||||
#define SPLIT 1 //two items
|
||||
#define MERGE 2
|
||||
#define FULL 3
|
||||
|
||||
void testdrawline();
|
||||
void testdrawrect();
|
||||
void testfillrect();
|
||||
void testdrawcircle();
|
||||
void testdrawroundrect();
|
||||
void testfillroundrect();
|
||||
void testdrawtriangle();
|
||||
void testfilltriangle();
|
||||
void testdrawchar();
|
||||
void testscrolltext(char *str);
|
||||
void display_texts();
|
||||
void display_bitmap();
|
||||
void display_invert_normal();
|
||||
void testdrawbitmap(const unsigned char *bitmap, unsigned char w, unsigned char h);
|
||||
void testdrawbitmap_eg();
|
||||
void deeplyembedded_credits();
|
||||
void testprintinfo();
|
||||
void testdate(int mode, int y);
|
||||
void testlanip(int mode, int y);
|
||||
void testcpufreq(int mode, int y);
|
||||
void testcputemp(int mode, int y);
|
||||
void testnetspeed(int mode, int y);
|
||||
void testcpu(int y);
|
||||
|
||||
|
||||
281
package/ctcgfw/luci-app-oled/src/I2C_Library/I2C.c
Normal file
281
package/ctcgfw/luci-app-oled/src/I2C_Library/I2C.c
Normal file
@ -0,0 +1,281 @@
|
||||
/*
|
||||
* MIT License
|
||||
|
||||
Copyright (c) 2017 DeeplyEmbedded
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
* I2C.c
|
||||
*
|
||||
* Created on : September 19, 2017
|
||||
* Author : Vinay Divakar
|
||||
* Description : This is an I2C Library for the BeagleBone that consists of the API's to support the standard
|
||||
* I2C operations.
|
||||
* Website : www.deeplyembedded.org
|
||||
*/
|
||||
|
||||
/*Libs Includes*/
|
||||
#include<stdio.h>
|
||||
#include<fcntl.h>
|
||||
#include<sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
// heuristic to guess what version of i2c-dev.h we have:
|
||||
// the one installed with `apt-get install libi2c-dev`
|
||||
// would conflict with linux/i2c.h, while the stock
|
||||
// one requires linus/i2c.h
|
||||
#ifndef I2C_SMBUS_BLOCK_MAX
|
||||
// If this is not defined, we have the "stock" i2c-dev.h
|
||||
// so we include linux/i2c.h
|
||||
#include <linux/i2c.h>
|
||||
typedef unsigned char i2c_char_t;
|
||||
#else
|
||||
typedef char i2c_char_t;
|
||||
#endif
|
||||
|
||||
/* Header Files */
|
||||
#include "I2C.h"
|
||||
|
||||
|
||||
/* Exposed objects for i2c-x */
|
||||
I2C_DeviceT I2C_DEV_2;
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : Open_device
|
||||
* Description : Opens the I2C device to use
|
||||
* Returns : 0 on success, -1 on failure
|
||||
* Params @i2c_dev_path: Path to the I2C device
|
||||
* @fd: Variable to store the file handler
|
||||
****************************************************************/
|
||||
int Open_device(char *i2c_dev_path, int *fd)
|
||||
{
|
||||
if((*fd = open(i2c_dev_path, O_RDWR))<0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : Close_device
|
||||
* Description : Closes the I2C device in use
|
||||
* Returns : 0 on success, -1 on failure
|
||||
* Params : @fd: file descriptor
|
||||
****************************************************************/
|
||||
int Close_device(int fd)
|
||||
{
|
||||
if(close(fd) == -1)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : Set_slave_addr
|
||||
* Description : Connect to the Slave device
|
||||
* Returns : 0 on success, -1 on failure
|
||||
* Params @fd: File descriptor
|
||||
* @slave_addr: Address of the slave device to
|
||||
* talk to.
|
||||
****************************************************************/
|
||||
int Set_slave_addr(int fd, unsigned char slave_addr)
|
||||
{
|
||||
if(ioctl(fd, I2C_SLAVE, slave_addr) < 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : i2c_write
|
||||
* Description : Write a byte on SDA
|
||||
* Returns : No. of bytes written on success, -1 on failure
|
||||
* Params @fd: File descriptor
|
||||
* @data: data to write on SDA
|
||||
****************************************************************/
|
||||
int i2c_write(int fd, unsigned char data)
|
||||
{
|
||||
int ret = 0;
|
||||
ret = write(fd, &data, I2C_ONE_BYTE);
|
||||
if((ret == -1) || (ret != 1))
|
||||
return -1;
|
||||
else
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : i2c_read
|
||||
* Description : Read a byte on SDA
|
||||
* Returns : No. of bytes read on success, -1 on failure
|
||||
* Params @fd: File descriptor
|
||||
* @read_data: Points to the variable that stores
|
||||
* the read data byte
|
||||
****************************************************************/
|
||||
int i2c_read(int fd, unsigned char *read_data)
|
||||
{
|
||||
int ret = 0;
|
||||
ret = read(fd, &read_data, I2C_ONE_BYTE);
|
||||
if(ret == -1)
|
||||
perror("I2C: Failed to read |");
|
||||
if(ret == 0)
|
||||
perror("I2C: End of FILE |");
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : i2c_read_register
|
||||
* Description : Read a single register of the slave device
|
||||
* Returns : No. of bytes read on success, -1 on failure
|
||||
* Params @fd: File descriptor
|
||||
* @read_addr: Register address to be read
|
||||
* @read_data: Points to the variable that stores
|
||||
* the read data byte
|
||||
****************************************************************/
|
||||
int i2c_read_register(int fd, unsigned char read_addr, unsigned char *read_data)
|
||||
{
|
||||
int ret = 0;
|
||||
if(i2c_write(fd, read_addr) == -1)
|
||||
{
|
||||
perror("I2C: Failed to write |");
|
||||
return -1;
|
||||
}
|
||||
ret = read(fd, &read_data, I2C_ONE_BYTE);
|
||||
if(ret == -1)
|
||||
perror("I2C: Failed to read |");
|
||||
if(ret == 0)
|
||||
perror("I2C: End of FILE |");
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : i2c_read_registers
|
||||
* Description : Read a multiple registers on the slave device
|
||||
* from starting address
|
||||
* Returns : No. of bytes read on success, -1 on failure
|
||||
* Params @fd: File descriptor
|
||||
* @num: Number of registers/bytes to read from.
|
||||
* @starting_addr: Starting address to read from
|
||||
* @buff_Ptr: Buffer to store the read bytes
|
||||
****************************************************************/
|
||||
int i2c_read_registers(int fd, int num, unsigned char starting_addr,
|
||||
unsigned char *buff_Ptr)
|
||||
{
|
||||
int ret = 0;
|
||||
if(i2c_write(fd, starting_addr) == -1)
|
||||
{
|
||||
perror("I2C: Failed to write |");
|
||||
return -1;
|
||||
}
|
||||
ret = read(fd, buff_Ptr, num);
|
||||
if(ret == -1)
|
||||
perror("I2C: Failed to read |");
|
||||
if(ret == 0)
|
||||
perror("I2C: End of FILE |");
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : i2c_multiple_writes
|
||||
* Description : Write multiple bytes on SDA
|
||||
* Returns : No. of bytes written on success, -1 on failure
|
||||
* Params @fd: file descriptor
|
||||
* @num: No. of bytes to write
|
||||
* @Ptr_buff: Pointer to the buffer containing the
|
||||
* bytes to be written on the SDA
|
||||
****************************************************************/
|
||||
int i2c_multiple_writes(int fd, int num, unsigned char *Ptr_buff)
|
||||
{
|
||||
int ret = 0;
|
||||
ret = write(fd, Ptr_buff, num);
|
||||
if((ret == -1) || (ret != num))
|
||||
return -1;
|
||||
else
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : i2c_write_register
|
||||
* Description : Write a control byte or byte to a register
|
||||
* Returns : No. of bytes written on success, -1 on failure
|
||||
* Params @fd: file descriptor
|
||||
* @reg_addr_or_cntrl: Control byte or Register
|
||||
* address to be written
|
||||
* @val: Command or value to be written in the
|
||||
* addressed register
|
||||
****************************************************************/
|
||||
int i2c_write_register(int fd, unsigned char reg_addr_or_cntrl, unsigned char val)
|
||||
{
|
||||
unsigned char buff[2];
|
||||
int ret = 0;
|
||||
buff[0] = reg_addr_or_cntrl;
|
||||
buff[1] = val;
|
||||
ret = write(fd, buff, I2C_TWO_BYTES);
|
||||
if((ret == -1) || (ret != I2C_TWO_BYTES))
|
||||
return -1;
|
||||
else
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : config_i2c_struct
|
||||
* Description : Initialize the I2C device structure
|
||||
* Returns : NONE
|
||||
* Params @i2c_dev_path: Device path
|
||||
* @slave_addr: Slave device address
|
||||
* @i2c_dev: Pointer to the device structure
|
||||
****************************************************************/
|
||||
void config_i2c_struct(char *i2c_dev_path, unsigned char slave_addr, I2C_DevicePtr i2c_dev)
|
||||
{
|
||||
i2c_dev->i2c_dev_path = i2c_dev_path;
|
||||
i2c_dev->fd_i2c = 0;
|
||||
i2c_dev->i2c_slave_addr = slave_addr;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : init_i2c_dev
|
||||
* Description : Connect the i2c bus to the slave device
|
||||
* Returns : 0 on success, -1 on failure
|
||||
* Params @i2c_path: the path to the device
|
||||
* @slave_addr: Slave device address
|
||||
****************************************************************/
|
||||
int init_i2c_dev(const char* i2c_path, unsigned char slave_address)
|
||||
{
|
||||
config_i2c_struct((char*)i2c_path, slave_address, &I2C_DEV_2);
|
||||
if(Open_device(I2C_DEV_2.i2c_dev_path, &I2C_DEV_2.fd_i2c) == -1)
|
||||
{
|
||||
perror("I2C: Failed to open device |");
|
||||
return -1;
|
||||
}
|
||||
if(Set_slave_addr(I2C_DEV_2.fd_i2c, I2C_DEV_2.i2c_slave_addr) == -1)
|
||||
{
|
||||
perror("I2C: Failed to connect to slave device |");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
69
package/ctcgfw/luci-app-oled/src/I2C_Library/I2C.h
Normal file
69
package/ctcgfw/luci-app-oled/src/I2C_Library/I2C.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* MIT License
|
||||
|
||||
Copyright (c) 2017 DeeplyEmbedded
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
* I2C.h
|
||||
*
|
||||
* Created on : Sep 4, 2017
|
||||
* Author : Vinay Divakar
|
||||
* Website : www.deeplyembedded.org
|
||||
*/
|
||||
|
||||
#ifndef I2C_H_
|
||||
#define I2C_H_
|
||||
|
||||
#include<stdint.h>
|
||||
|
||||
/* No. of bytes per transaction */
|
||||
#define I2C_ONE_BYTE 1
|
||||
#define I2C_TWO_BYTES 2
|
||||
#define I2C_THREE_BYTES 3
|
||||
|
||||
/*Definitions specific to i2c-x */
|
||||
#define I2C_DEV0_PATH "/dev/i2c-0"
|
||||
#define I2C_DEV1_PATH "/dev/i2c-1"
|
||||
#define I2C_DEV2_PATH "/dev/i2c-2"
|
||||
|
||||
/*I2C device configuration structure*/
|
||||
typedef struct{
|
||||
char* i2c_dev_path;
|
||||
int fd_i2c;
|
||||
unsigned char i2c_slave_addr;
|
||||
}I2C_DeviceT, *I2C_DevicePtr;
|
||||
|
||||
/* Exposed Generic I2C Functions */
|
||||
extern int Open_device(char *i2c_dev_path, int *fd);
|
||||
extern int Close_device(int fd);
|
||||
extern int Set_slave_addr(int fd, unsigned char slave_addr);
|
||||
extern int i2c_write(int fd, unsigned char data);
|
||||
extern int i2c_read(int fd, unsigned char *read_data);
|
||||
extern int i2c_read_register(int fd, unsigned char read_addr, unsigned char *read_data);
|
||||
extern int i2c_read_registers(int fd, int num, unsigned char starting_addr,
|
||||
unsigned char *buff_Ptr);
|
||||
extern void config_i2c_struct(char *i2c_dev_path, unsigned char slave_addr, I2C_DevicePtr i2c_dev);
|
||||
extern int i2c_multiple_writes(int fd, int num, unsigned char *Ptr_buff);
|
||||
extern int i2c_write_register(int fd, unsigned char reg_addr_or_cntrl, unsigned char val);
|
||||
|
||||
/* Exposed I2C-x Specific Functions */
|
||||
extern int init_i2c_dev(const char* i2c_path, unsigned char slave_address);
|
||||
|
||||
#endif /* I2C_H_ */
|
||||
21
package/ctcgfw/luci-app-oled/src/LICENSE
Normal file
21
package/ctcgfw/luci-app-oled/src/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 DeeplyEmbedded
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
19
package/ctcgfw/luci-app-oled/src/Makefile
Normal file
19
package/ctcgfw/luci-app-oled/src/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
CC = gcc
|
||||
LD = gcc
|
||||
|
||||
SOURCES = SSD1306_OLED_Library/SSD1306_OLED.c Example_Code/Main.c Example_Code/example_app.c I2C_Library/I2C.c
|
||||
OBJS := $(SOURCES:.c=.o)
|
||||
CPPFLAGS := -I SSD1306_OLED_Library -I I2C_Library
|
||||
CFLAGS := -g
|
||||
|
||||
oled: $(OBJS)
|
||||
$(CC) $^ -o $@
|
||||
|
||||
clean:
|
||||
rm -rf oled $(OBJS)
|
||||
|
||||
compile: oled
|
||||
|
||||
install: compile
|
||||
mkdir -p $(DESTDIR)/usr/bin
|
||||
cp oled $(DESTDIR)/usr/bin/oled
|
||||
21
package/ctcgfw/luci-app-oled/src/README.md
Normal file
21
package/ctcgfw/luci-app-oled/src/README.md
Normal file
@ -0,0 +1,21 @@
|
||||
# SSD1306-OLED-display-driver-for-BeagleBone
|
||||
This is a SSD1306 OLED Display Library fully compatible with the BeagleBone.
|
||||
|
||||
The Library has 3 components:
|
||||
1. I2C component for enabling communication between the BeagleBone and display.
|
||||
2. Control component for sending I2C commands to configure and control the display.
|
||||
3. Graphics component for drawing geometrical figures, bitmaps, texts, characters, emoticons and numbers.
|
||||
|
||||
Author: Vinay Divakar
|
||||
|
||||
References:
|
||||
1. https://github.com/adafruit/Adafruit_SSD1306
|
||||
2. https://github.com/adafruit/Adafruit-GFX-Library
|
||||
|
||||
Youtube demo: https://youtu.be/sDKf6zW6Pyg
|
||||
|
||||
MIT license, check LICENSE file for more information
|
||||
|
||||
This Library is written in C. To use it, just include the I2C and SSD1306 Libraries in your project.
|
||||
|
||||
Enjoy :)
|
||||
2713
package/ctcgfw/luci-app-oled/src/SSD1306_OLED_Library/SSD1306_OLED.c
Normal file
2713
package/ctcgfw/luci-app-oled/src/SSD1306_OLED_Library/SSD1306_OLED.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,202 @@
|
||||
/*
|
||||
* MIT License
|
||||
|
||||
Copyright (c) 2017 DeeplyEmbedded
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
* SSD1306_OLED.h
|
||||
*
|
||||
* Created on : Sep 21, 2017
|
||||
* Author : Vinay Divakar
|
||||
* Website : www.deeplyembedded.org
|
||||
*/
|
||||
|
||||
#ifndef SSD1306_OLED_H_
|
||||
#define SSD1306_OLED_H_
|
||||
|
||||
/* Lib's */
|
||||
#include <stdbool.h>
|
||||
|
||||
/* Find Min and Max - MACROS */
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
|
||||
/* I2C Address of SSD1306 */
|
||||
#define SSD1306_OLED_ADDR 0x3C
|
||||
#define DISPLAY_BUFF_SIZE (SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8)
|
||||
|
||||
/* COLOR MACROS */
|
||||
#define WHITE 1
|
||||
#define BLACK 0
|
||||
#define INVERSE 2
|
||||
|
||||
/* Number output format */
|
||||
#define DEC 10
|
||||
#define HEX 16
|
||||
#define OCT 8
|
||||
#define BIN 2
|
||||
#define DEFAULT 0
|
||||
|
||||
/*D/C# bit is '0' indicating that following
|
||||
* byte is a command. '1' is for data
|
||||
*/
|
||||
#define SSD1306_CNTRL_CMD 0x00
|
||||
#define SSD1306_CNTRL_DATA 0x40
|
||||
|
||||
|
||||
/*-----------------------Enable the WxL of the Display ---------------------------*/
|
||||
//#define SSD1306_128_64
|
||||
#define SSD1306_128_32
|
||||
//#define SSD1306_96_16
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/* LCD HxW i.e. 64x128 || WxL i.e. 128x64 */
|
||||
#if defined SSD1306_128_64
|
||||
#define SSD1306_LCDWIDTH 128
|
||||
#define SSD1306_LCDHEIGHT 64
|
||||
#endif
|
||||
#if defined SSD1306_128_32
|
||||
#define SSD1306_LCDWIDTH 128
|
||||
#define SSD1306_LCDHEIGHT 32
|
||||
#endif
|
||||
#if defined SSD1306_96_16
|
||||
#define SSD1306_LCDWIDTH 96
|
||||
#define SSD1306_LCDHEIGHT 16
|
||||
#endif
|
||||
|
||||
/* SSD1306 Commands */
|
||||
#define SSD1306_DISPLAY_OFF 0xAE
|
||||
#define SSD1306_SET_DISP_CLK 0xD5
|
||||
#define SSD1306_SET_MULTIPLEX 0xA8
|
||||
#define SSD1306_SET_DISP_OFFSET 0xD3
|
||||
#define SSD1306_SET_DISP_START_LINE 0x40// | 0x00)
|
||||
#define SSD1306_CONFIG_CHARGE_PUMP 0x8D
|
||||
#define SSD1306_SET_MEM_ADDR_MODE 0x20
|
||||
#define SSD1306_SEG_REMAP (0xA0 | 0x01) //Rotate 180 Degrees
|
||||
#define SSD1306_SET_COMSCANDEC 0xC8
|
||||
#define SSD1306_SET_COMPINS 0xDA
|
||||
#define SSD1306_SET_CONTRAST 0x81
|
||||
#define SSD1306_SET_PRECHARGE 0xD9
|
||||
#define SSD1306_SET_VCOMDETECT 0xDB
|
||||
#define SSD1306_DISPLAYALLON_RESUME 0xA4
|
||||
#define SSD1306_NORMAL_DISPLAY 0xA6
|
||||
#define SSD1306_DISPLAYON 0xAF
|
||||
#define SSD1306_SET_COL_ADDR 0x21
|
||||
#define SSD1306_PAGEADDR 0x22
|
||||
#define SSD1306_INVERT_DISPLAY 0x01
|
||||
#define SSD1306_NORMALIZE_DISPLAY 0x00
|
||||
|
||||
/* SDD1306 Scroll Commands */
|
||||
#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3
|
||||
#define SSD1306_ACTIVATE_SCROLL 0x2F
|
||||
#define SSD1306_DEACTIVATE_SCROLL 0x2E
|
||||
#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26
|
||||
#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27
|
||||
#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29
|
||||
#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
|
||||
#define SSD1306_INVERTDISPLAY 0xA7
|
||||
|
||||
/* SSD1306 Configuration Commands */
|
||||
#define SSD1306_DISPCLK_DIV 0x80
|
||||
#if defined SSD1306_128_64
|
||||
#define SSD1306_MULT_64 0x3F
|
||||
#endif
|
||||
#if defined SSD1306_128_32
|
||||
#define SSD1306_MULT_64 0x1F
|
||||
#endif
|
||||
#define SSD1306_MULT_64 0x1F
|
||||
#define SSD1306_DISP_OFFSET_VAL 0x00
|
||||
#define SSD1306_COL_START_ADDR 0x00 //Reset to = 0
|
||||
#define SSD1306_COL_END_ADDR (SSD1306_LCDWIDTH - 1) //Reset to = 127
|
||||
#define SSD1306_PG_START_ADDR 0x00
|
||||
#define SSD1306_PG_END_ADDR 7
|
||||
#define SSD1306_CHARGE_PUMP_EN 0x14
|
||||
#if defined SSD1306_128_64
|
||||
#define SSD1306_CONFIG_COM_PINS 0x12
|
||||
#endif
|
||||
#if defined SSD1306_128_32
|
||||
#define SSD1306_CONFIG_COM_PINS 0x02
|
||||
#endif
|
||||
#define SSD1306_CONTRAST_VAL 0xCF //207
|
||||
#define SSD1306_PRECHARGE_VAL 0xF1
|
||||
#define SSD1306_VCOMH_VAL 0x40
|
||||
#define SSD1306_MULT_DAT (SSD1306_LCDHEIGHT - 1)
|
||||
#define SSD1306_HOR_MM 0x00
|
||||
|
||||
/*SSD1306 Display API's */
|
||||
extern void clearDisplay();
|
||||
extern void display_Init_seq();
|
||||
extern void Display();
|
||||
extern void Init_Col_PG_addrs(unsigned char col_start_addr, unsigned char col_end_addr,
|
||||
unsigned char pg_start_addr, unsigned char pg_end_addr);
|
||||
extern void setRotation(unsigned char x);
|
||||
extern void startscrollright(unsigned char start, unsigned char stop);
|
||||
extern void startscrollleft(unsigned char start, unsigned char stop);
|
||||
extern void startscrolldiagright(unsigned char start, unsigned char stop);
|
||||
extern void startscrolldiagleft(unsigned char start, unsigned char stop);
|
||||
extern void stopscroll();
|
||||
extern void setCursor(short x, short y);
|
||||
extern short getCursorX();
|
||||
extern short getCursorY();
|
||||
extern unsigned char getRotation();
|
||||
extern void invertDisplay(unsigned char i);
|
||||
|
||||
/*SSD1306 Graphics Handling API's */
|
||||
extern signed char drawPixel(short x, short y, short color);
|
||||
extern void writeLine(short x0, short y0, short x1, short y1, short color);
|
||||
extern void drawCircleHelper( short x0, short y0, short r, unsigned char cornername, short color);
|
||||
extern void drawLine(short x0, short y0, short x1, short y1, short color);
|
||||
extern void drawRect(short x, short y, short w, short h, short color);
|
||||
extern void fillRect(short x, short y, short w, short h, short color);
|
||||
extern void drawCircle(short x0, short y0, short r, short color);
|
||||
extern void fillCircleHelper(short x0, short y0, short r, unsigned char cornername, short delta, short color);
|
||||
extern void fillCircle(short x0, short y0, short r, short color);
|
||||
extern void drawTriangle(short x0, short y0, short x1, short y1, short x2, short y2, short color);
|
||||
extern void fillTriangle(short x0, short y0, short x1, short y1, short x2, short y2, short color);
|
||||
extern void drawRoundRect(short x, short y, short w, short h, short r, short color);
|
||||
extern void fillRoundRect(short x, short y, short w, short h, short r, short color);
|
||||
extern void drawBitmap(short x, short y, const unsigned char bitmap[], short w, short h, short color);
|
||||
extern short oled_write(unsigned char c);
|
||||
|
||||
/*SSD1306 Text and Character Handling API's */
|
||||
extern void setTextSize(unsigned char s);
|
||||
extern void setTextColor(short c);
|
||||
extern void setTextWrap(bool w);
|
||||
extern void drawChar(short x, short y, unsigned char c, short color, short bg, unsigned char size);
|
||||
extern short print_str(const unsigned char *strPtr);
|
||||
extern short println();
|
||||
extern short print_strln(const unsigned char *strPtr);
|
||||
|
||||
/*SSD1306 Number Handling API's */
|
||||
extern short printNumber(unsigned long n, unsigned char base);
|
||||
extern short printNumber_UL(unsigned long n, int base);
|
||||
extern short printNumber_UL_ln(unsigned long num, int base);
|
||||
extern short printNumber_UI(unsigned int n, int base);
|
||||
extern short printNumber_UI_ln(unsigned int n, int base);
|
||||
extern short printNumber_UC(unsigned char b, int base);
|
||||
extern short printNumber_UC_ln(unsigned char b, int base);
|
||||
extern short printNumber_L(long n, int base);
|
||||
extern short printNumber_L_ln(long num, int base);
|
||||
extern short printNumber_I(int n, int base);
|
||||
extern short printNumber_I_ln(int n, int base);
|
||||
extern short printFloat(double number, unsigned char digits);
|
||||
extern short printFloat_ln(double num, int digits);
|
||||
#endif /* SSD1306_OLED_H_ */
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
#ifndef _GFXFONT_H_
|
||||
#define _GFXFONT_H_
|
||||
|
||||
typedef struct { // Data stored PER GLYPH
|
||||
unsigned short bitmapOffset; // Pointer into GFXfont->bitmap
|
||||
unsigned char width, height; // Bitmap dimensions in pixels
|
||||
unsigned char xAdvance; // Distance to advance cursor (x axis)
|
||||
char xOffset, yOffset; // Dist from cursor pos to UL corner
|
||||
} GFXglyphT, *GFXglyphPtr;
|
||||
|
||||
typedef struct { // Data stored for FONT AS A WHOLE:
|
||||
unsigned char *bitmap; // Glyph bitmaps, concatenated
|
||||
GFXglyphPtr glyph; // Glyph array
|
||||
unsigned char first, last; // ASCII extents
|
||||
unsigned char yAdvance; // Newline distance (y axis)
|
||||
} GFXfontT, *GFXfontPtr;
|
||||
|
||||
#endif // _GFXFONT_H_
|
||||
@ -4,12 +4,49 @@ START=99
|
||||
USE_PROCD=1
|
||||
|
||||
BIN=/etc/subconverter/subconverter
|
||||
PID=""
|
||||
|
||||
getPid(){
|
||||
ps | grep subconverter > /tmp/_subconverter_pid
|
||||
sed -i '/grep/d' /tmp/_subconverter_pid
|
||||
sed -i '/bin\/sh/d' /tmp/_subconverter_pid
|
||||
sed -i "s/^[ \s]\{1,\}//g;s/[ \s]\{1,\}$//g" /tmp/_subconverter_pid
|
||||
local pid=$(cat /tmp/_subconverter_pid| cut -d ' ' -f1)
|
||||
PID=$pid
|
||||
#echo PID is $pid === $PID
|
||||
rm -rf /tmp/_subconverter_pid
|
||||
}
|
||||
|
||||
start_service() {
|
||||
[ ! -e /etc/subconverter/subconverter ] && ln -fs /usr/bin/subconverter /etc/subconverter/subconverter
|
||||
getPid
|
||||
local pid=$PID
|
||||
if [ ! -z "$pid" ]; then
|
||||
echo "Subconverter has already run, PID is "$pid
|
||||
return 0
|
||||
fi
|
||||
[ ! -e /etc/subconverter/subconverter ] && cp /usr/bin/subconverter /etc/subconverter/subconverter
|
||||
procd_open_instance
|
||||
procd_set_param command $BIN
|
||||
procd_set_param respawn
|
||||
procd_set_param stderr 1
|
||||
procd_close_instance
|
||||
echo Subconverter started.
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
getPid
|
||||
local pid=$PID
|
||||
if [ ! -z "$pid" ]; then
|
||||
echo Found subconverter process, which PID is $pid
|
||||
kill $pid
|
||||
echo Subconverter process has been terminated.
|
||||
else
|
||||
echo No subconverter process found.
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
@ -45,6 +45,7 @@ define Build/Configure
|
||||
$(RM) $(PKG_BUILD_DIR)/config/{subconverter,README.md,README-cn.md}
|
||||
$(RM) -r $(PKG_BUILD_DIR)/api/__pycache__
|
||||
$(SED) 's/root/etc/g;s/ -ef//g' $(PKG_BUILD_DIR)/subweb.sh
|
||||
$(SED) 's/10010/25500/g' $(PKG_BUILD_DIR)/api/aff.py
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
|
||||
@ -4,12 +4,49 @@ START=99
|
||||
USE_PROCD=1
|
||||
|
||||
BIN=/etc/subweb/subweb.sh
|
||||
PID=
|
||||
getPid(){
|
||||
local pid=$(ps| grep /etc/subweb/api.py | grep python3 | sed "s/^[ \s]\{1,\}//g;s/[ \s]\{1,\}$//g" | cut -d ' ' -f1)
|
||||
PID=$pid
|
||||
}
|
||||
|
||||
start_service() {
|
||||
getPid
|
||||
local pid=$PID
|
||||
if [ ! -z "$pid" ]; then
|
||||
echo "Subweb has already run, PID is "$pid
|
||||
return 0
|
||||
fi
|
||||
[ ! -e /etc/subweb/config/subconverter ] && ln -fs /usr/bin/subconverter /etc/subweb/config/subconverter
|
||||
local ipInConf=$(cat /etc/subweb/api/aff.py| grep apiip | cut -d "'" -f2 | cut -d ":" -f2 | cut -d "/" -f3)
|
||||
local ipOfLan=$(uci get network.lan.ipaddr)
|
||||
echo IP in conf is $ipInConf, LAN ip is $ipOfLan
|
||||
if [ "$ipOfLan" != "$ipInConf" ]; then
|
||||
echo IP mismatch. Change ip in /etc/subweb/api/aff.py
|
||||
sed -i 's/'$ipInConf'/'$ipOfLan'/' /etc/subweb/api/aff.py
|
||||
fi
|
||||
procd_open_instance
|
||||
procd_set_param command $BIN
|
||||
procd_set_param respawn
|
||||
procd_set_param stderr 1
|
||||
procd_close_instance
|
||||
echo Subweb started.
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
getPid
|
||||
local pid=$PID
|
||||
if [ ! -z "$pid" ]; then
|
||||
echo Found subweb process, which PID is $pid
|
||||
kill $pid
|
||||
echo Subweb process has been terminated.
|
||||
else
|
||||
echo No subweb process found.
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
@ -32,6 +32,14 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server
|
||||
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_Trojan \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Redsocks2 \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server
|
||||
|
||||
LUCI_TITLE:=SS/SSR/V2Ray/Trojan/Socks5/Tun LuCI interface
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+shadowsocksr-libev-alt +ipset +ip-full +iptables-mod-tproxy +dnsmasq-full +coreutils +coreutils-base64 +pdnsd-alt +wget +lua +libuci-lua \
|
||||
|
||||
@ -1065,7 +1065,6 @@
|
||||
45.114.52.0/22
|
||||
45.114.96.0/22
|
||||
45.114.104.0/22
|
||||
45.114.108.0/22
|
||||
45.114.124.0/22
|
||||
45.114.136.0/22
|
||||
45.114.196.0/22
|
||||
@ -2855,7 +2854,6 @@
|
||||
103.61.160.0/22
|
||||
103.61.172.0/22
|
||||
103.61.176.0/22
|
||||
103.61.184.0/22
|
||||
103.61.188.0/22
|
||||
103.62.24.0/22
|
||||
103.62.52.0/22
|
||||
@ -4056,6 +4054,13 @@
|
||||
103.152.190.0/23
|
||||
103.152.192.0/23
|
||||
103.152.200.0/23
|
||||
103.152.208.0/23
|
||||
103.152.224.0/23
|
||||
103.152.226.0/23
|
||||
103.152.246.0/23
|
||||
103.152.250.0/23
|
||||
103.153.4.0/23
|
||||
103.153.36.0/23
|
||||
103.192.0.0/22
|
||||
103.192.4.0/22
|
||||
103.192.8.0/22
|
||||
@ -5654,7 +5659,9 @@
|
||||
120.31.0.0/16
|
||||
120.32.0.0/13
|
||||
120.40.0.0/14
|
||||
120.44.0.0/14
|
||||
120.44.0.0/15
|
||||
120.46.0.0/16
|
||||
120.47.0.0/16
|
||||
120.48.0.0/15
|
||||
120.52.0.0/16
|
||||
120.53.0.0/16
|
||||
@ -6113,7 +6120,6 @@
|
||||
157.119.16.0/22
|
||||
157.119.28.0/22
|
||||
157.119.68.0/22
|
||||
157.119.112.0/22
|
||||
157.119.132.0/22
|
||||
157.119.136.0/22
|
||||
157.119.140.0/22
|
||||
|
||||
@ -1,108 +1,108 @@
|
||||
ipset=/.91smartyun.pt/gfwlist
|
||||
ipset=/.adobe.com/gfwlist
|
||||
ipset=/.amazonaws.com/gfwlist
|
||||
ipset=/.ampproject.org/gfwlist
|
||||
ipset=/.apple.news/gfwlist
|
||||
ipset=/.aws.amazon.com/gfwlist
|
||||
ipset=/.azureedge.net/gfwlist
|
||||
ipset=/.backpackers.com.tw/gfwlist
|
||||
ipset=/.bitfinex.com/gfwlist
|
||||
ipset=/.buzzfeed.com/gfwlist
|
||||
ipset=/.clockwise.ee/gfwlist
|
||||
ipset=/.cloudfront.net/gfwlist
|
||||
ipset=/.coindesk.com/gfwlist
|
||||
ipset=/.coinsquare.io/gfwlist
|
||||
ipset=/.cryptocompare.com/gfwlist
|
||||
ipset=/.dropboxstatic.com/gfwlist
|
||||
ipset=/.eurecom.fr/gfwlist
|
||||
ipset=/.gdax.com/gfwlist
|
||||
ipset=/.github.com/gfwlist
|
||||
ipset=/.kknews.cc/gfwlist
|
||||
ipset=/.nutaq.com/gfwlist
|
||||
ipset=/.openairinterface.org/gfwlist
|
||||
ipset=/.skype.com/gfwlist
|
||||
ipset=/.sublimetext.com/gfwlist
|
||||
ipset=/.textnow.com/gfwlist
|
||||
ipset=/.textnow.me/gfwlist
|
||||
ipset=/.trouter.io/gfwlist
|
||||
ipset=/.t66y.com/gfwlist
|
||||
ipset=/.uploaded.net/gfwlist
|
||||
ipset=/.whatsapp.com/gfwlist
|
||||
ipset=/.whatsapp.net/gfwlist
|
||||
ipset=/.wsj.net/gfwlist
|
||||
ipset=/.google.com/gfwlist
|
||||
ipset=/.google.com.hk/gfwlist
|
||||
ipset=/.gstatic.com/gfwlist
|
||||
ipset=/.googleusercontent.com/gfwlist
|
||||
ipset=/.googlepages.com/gfwlist
|
||||
ipset=/.googlevideo.com/gfwlist
|
||||
ipset=/.googlecode.com/gfwlist
|
||||
ipset=/.googleapis.com/gfwlist
|
||||
ipset=/.googlesource.com/gfwlist
|
||||
ipset=/.googledrive.com/gfwlist
|
||||
ipset=/.ggpht.com/gfwlist
|
||||
ipset=/.youtube.com/gfwlist
|
||||
ipset=/.youtu.be/gfwlist
|
||||
ipset=/.ytimg.com/gfwlist
|
||||
ipset=/.twitter.com/gfwlist
|
||||
ipset=/.facebook.com/gfwlist
|
||||
ipset=/.fastly.net/gfwlist
|
||||
ipset=/.akamai.net/gfwlist
|
||||
ipset=/.akamaiedge.net/gfwlist
|
||||
ipset=/.akamaihd.net/gfwlist
|
||||
ipset=/.edgesuite.net/gfwlist
|
||||
ipset=/.edgekey.net/gfwlist
|
||||
server=/.91smartyun.pt/127.0.0.1#5335
|
||||
server=/.adobe.com/127.0.0.1#5335
|
||||
server=/.amazonaws.com/127.0.0.1#5335
|
||||
server=/.ampproject.org/127.0.0.1#5335
|
||||
server=/.apple.news/127.0.0.1#5335
|
||||
server=/.aws.amazon.com/127.0.0.1#5335
|
||||
server=/.azureedge.net/127.0.0.1#5335
|
||||
server=/.backpackers.com.tw/127.0.0.1#5335
|
||||
server=/.bitfinex.com/127.0.0.1#5335
|
||||
server=/.buzzfeed.com/127.0.0.1#5335
|
||||
server=/.clockwise.ee/127.0.0.1#5335
|
||||
server=/.cloudfront.net/127.0.0.1#5335
|
||||
server=/.coindesk.com/127.0.0.1#5335
|
||||
server=/.coinsquare.io/127.0.0.1#5335
|
||||
server=/.cryptocompare.com/127.0.0.1#5335
|
||||
server=/.dropboxstatic.com/127.0.0.1#5335
|
||||
server=/.eurecom.fr/127.0.0.1#5335
|
||||
server=/.gdax.com/127.0.0.1#5335
|
||||
server=/.github.com/127.0.0.1#5335
|
||||
server=/.kknews.cc/127.0.0.1#5335
|
||||
server=/.nutaq.com/127.0.0.1#5335
|
||||
server=/.openairinterface.org/127.0.0.1#5335
|
||||
server=/.skype.com/127.0.0.1#5335
|
||||
server=/.sublimetext.com/127.0.0.1#5335
|
||||
server=/.textnow.com/127.0.0.1#5335
|
||||
server=/.textnow.me/127.0.0.1#5335
|
||||
server=/.trouter.io/127.0.0.1#5335
|
||||
server=/.t66y.com/127.0.0.1#5335
|
||||
server=/.uploaded.net/127.0.0.1#5335
|
||||
server=/.whatsapp.com/127.0.0.1#5335
|
||||
server=/.whatsapp.net/127.0.0.1#5335
|
||||
server=/.wsj.net/127.0.0.1#5335
|
||||
server=/.google.com/127.0.0.1#5335
|
||||
server=/.google.com.hk/127.0.0.1#5335
|
||||
server=/.gstatic.com/127.0.0.1#5335
|
||||
server=/.googleusercontent.com/127.0.0.1#5335
|
||||
server=/.googlepages.com/127.0.0.1#5335
|
||||
server=/.googlevideo.com/127.0.0.1#5335
|
||||
server=/.googlecode.com/127.0.0.1#5335
|
||||
server=/.googleapis.com/127.0.0.1#5335
|
||||
server=/.googlesource.com/127.0.0.1#5335
|
||||
server=/.googledrive.com/127.0.0.1#5335
|
||||
server=/.ggpht.com/127.0.0.1#5335
|
||||
server=/.youtube.com/127.0.0.1#5335
|
||||
server=/.youtu.be/127.0.0.1#5335
|
||||
server=/.ytimg.com/127.0.0.1#5335
|
||||
server=/.twitter.com/127.0.0.1#5335
|
||||
server=/.facebook.com/127.0.0.1#5335
|
||||
server=/.fastly.net/127.0.0.1#5335
|
||||
server=/.akamai.net/127.0.0.1#5335
|
||||
server=/.akamaiedge.net/127.0.0.1#5335
|
||||
server=/.akamaihd.net/127.0.0.1#5335
|
||||
server=/.edgesuite.net/127.0.0.1#5335
|
||||
server=/.edgekey.net/127.0.0.1#5335
|
||||
ipset=/91smartyun.pt/gfwlist
|
||||
ipset=/adobe.com/gfwlist
|
||||
ipset=/amazonaws.com/gfwlist
|
||||
ipset=/ampproject.org/gfwlist
|
||||
ipset=/apple.news/gfwlist
|
||||
ipset=/aws.amazon.com/gfwlist
|
||||
ipset=/azureedge.net/gfwlist
|
||||
ipset=/backpackers.com.tw/gfwlist
|
||||
ipset=/bitfinex.com/gfwlist
|
||||
ipset=/buzzfeed.com/gfwlist
|
||||
ipset=/clockwise.ee/gfwlist
|
||||
ipset=/cloudfront.net/gfwlist
|
||||
ipset=/coindesk.com/gfwlist
|
||||
ipset=/coinsquare.io/gfwlist
|
||||
ipset=/cryptocompare.com/gfwlist
|
||||
ipset=/dropboxstatic.com/gfwlist
|
||||
ipset=/eurecom.fr/gfwlist
|
||||
ipset=/gdax.com/gfwlist
|
||||
ipset=/github.com/gfwlist
|
||||
ipset=/kknews.cc/gfwlist
|
||||
ipset=/nutaq.com/gfwlist
|
||||
ipset=/openairinterface.org/gfwlist
|
||||
ipset=/skype.com/gfwlist
|
||||
ipset=/sublimetext.com/gfwlist
|
||||
ipset=/textnow.com/gfwlist
|
||||
ipset=/textnow.me/gfwlist
|
||||
ipset=/trouter.io/gfwlist
|
||||
ipset=/t66y.com/gfwlist
|
||||
ipset=/uploaded.net/gfwlist
|
||||
ipset=/whatsapp.com/gfwlist
|
||||
ipset=/whatsapp.net/gfwlist
|
||||
ipset=/wsj.net/gfwlist
|
||||
ipset=/google.com/gfwlist
|
||||
ipset=/google.com.hk/gfwlist
|
||||
ipset=/gstatic.com/gfwlist
|
||||
ipset=/googleusercontent.com/gfwlist
|
||||
ipset=/googlepages.com/gfwlist
|
||||
ipset=/googlevideo.com/gfwlist
|
||||
ipset=/googlecode.com/gfwlist
|
||||
ipset=/googleapis.com/gfwlist
|
||||
ipset=/googlesource.com/gfwlist
|
||||
ipset=/googledrive.com/gfwlist
|
||||
ipset=/ggpht.com/gfwlist
|
||||
ipset=/youtube.com/gfwlist
|
||||
ipset=/youtu.be/gfwlist
|
||||
ipset=/ytimg.com/gfwlist
|
||||
ipset=/twitter.com/gfwlist
|
||||
ipset=/facebook.com/gfwlist
|
||||
ipset=/fastly.net/gfwlist
|
||||
ipset=/akamai.net/gfwlist
|
||||
ipset=/akamaiedge.net/gfwlist
|
||||
ipset=/akamaihd.net/gfwlist
|
||||
ipset=/edgesuite.net/gfwlist
|
||||
ipset=/edgekey.net/gfwlist
|
||||
server=/91smartyun.pt/127.0.0.1#5335
|
||||
server=/adobe.com/127.0.0.1#5335
|
||||
server=/amazonaws.com/127.0.0.1#5335
|
||||
server=/ampproject.org/127.0.0.1#5335
|
||||
server=/apple.news/127.0.0.1#5335
|
||||
server=/aws.amazon.com/127.0.0.1#5335
|
||||
server=/azureedge.net/127.0.0.1#5335
|
||||
server=/backpackers.com.tw/127.0.0.1#5335
|
||||
server=/bitfinex.com/127.0.0.1#5335
|
||||
server=/buzzfeed.com/127.0.0.1#5335
|
||||
server=/clockwise.ee/127.0.0.1#5335
|
||||
server=/cloudfront.net/127.0.0.1#5335
|
||||
server=/coindesk.com/127.0.0.1#5335
|
||||
server=/coinsquare.io/127.0.0.1#5335
|
||||
server=/cryptocompare.com/127.0.0.1#5335
|
||||
server=/dropboxstatic.com/127.0.0.1#5335
|
||||
server=/eurecom.fr/127.0.0.1#5335
|
||||
server=/gdax.com/127.0.0.1#5335
|
||||
server=/github.com/127.0.0.1#5335
|
||||
server=/kknews.cc/127.0.0.1#5335
|
||||
server=/nutaq.com/127.0.0.1#5335
|
||||
server=/openairinterface.org/127.0.0.1#5335
|
||||
server=/skype.com/127.0.0.1#5335
|
||||
server=/sublimetext.com/127.0.0.1#5335
|
||||
server=/textnow.com/127.0.0.1#5335
|
||||
server=/textnow.me/127.0.0.1#5335
|
||||
server=/trouter.io/127.0.0.1#5335
|
||||
server=/t66y.com/127.0.0.1#5335
|
||||
server=/uploaded.net/127.0.0.1#5335
|
||||
server=/whatsapp.com/127.0.0.1#5335
|
||||
server=/whatsapp.net/127.0.0.1#5335
|
||||
server=/wsj.net/127.0.0.1#5335
|
||||
server=/google.com/127.0.0.1#5335
|
||||
server=/google.com.hk/127.0.0.1#5335
|
||||
server=/gstatic.com/127.0.0.1#5335
|
||||
server=/googleusercontent.com/127.0.0.1#5335
|
||||
server=/googlepages.com/127.0.0.1#5335
|
||||
server=/googlevideo.com/127.0.0.1#5335
|
||||
server=/googlecode.com/127.0.0.1#5335
|
||||
server=/googleapis.com/127.0.0.1#5335
|
||||
server=/googlesource.com/127.0.0.1#5335
|
||||
server=/googledrive.com/127.0.0.1#5335
|
||||
server=/ggpht.com/127.0.0.1#5335
|
||||
server=/youtube.com/127.0.0.1#5335
|
||||
server=/youtu.be/127.0.0.1#5335
|
||||
server=/ytimg.com/127.0.0.1#5335
|
||||
server=/twitter.com/127.0.0.1#5335
|
||||
server=/facebook.com/127.0.0.1#5335
|
||||
server=/fastly.net/127.0.0.1#5335
|
||||
server=/akamai.net/127.0.0.1#5335
|
||||
server=/akamaiedge.net/127.0.0.1#5335
|
||||
server=/akamaihd.net/127.0.0.1#5335
|
||||
server=/edgesuite.net/127.0.0.1#5335
|
||||
server=/edgekey.net/127.0.0.1#5335
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,15 +1,15 @@
|
||||
8.41.4.0/24
|
||||
23.246.0.0/18
|
||||
37.77.184.0/21
|
||||
38.72.126.0/24
|
||||
45.57.0.0/17
|
||||
64.120.128.0/17
|
||||
66.197.128.0/17
|
||||
69.53.224.0/19
|
||||
103.87.204.0/22
|
||||
108.175.32.0/20
|
||||
185.2.220.0/22
|
||||
185.9.188.0/22
|
||||
192.173.64.0/18
|
||||
198.38.96.0/19
|
||||
198.45.48.0/20
|
||||
207.45.72.0/22
|
||||
208.75.76.0/22
|
||||
208.75.76.0/22
|
||||
|
||||
@ -19,5 +19,5 @@ prev = cur;
|
||||
}
|
||||
generate_china_banned /tmp/ssr-update.$1 >/tmp/gfw.txt
|
||||
rm -f /tmp/gfwlist.txt
|
||||
sed '/.*/s/.*/server=\/\.&\/127.0.0.1#5335\nipset=\/\.&\/gfwlist/' /tmp/gfw.txt >/tmp/ssr-update.$1
|
||||
sed '/.*/s/.*/server=\/&\/127.0.0.1#5335\nipset=\/&\/gfwlist/' /tmp/gfw.txt >/tmp/ssr-update.$1
|
||||
rm -f /tmp/gfw.txt
|
||||
|
||||
@ -9,7 +9,7 @@ NETFLIX_SERVER=$(uci_get_by_type global netflix_server nil)
|
||||
[ "$NETFLIX_SERVER" == "same" ] && NETFLIX_SERVER=$GLOBAL_SERVER
|
||||
if [ "$NETFLIX_SERVER" != "nil" ]; then
|
||||
netflix() {
|
||||
if [ -f "tmp/dnsmasq.ssr/gfw_list.conf" ]; then
|
||||
if [ -f "/tmp/dnsmasq.ssr/gfw_list.conf" ]; then
|
||||
for line in $(cat /etc/ssr/netflix.list); do sed -i "/$line/d" /tmp/dnsmasq.ssr/gfw_list.conf; done
|
||||
fi
|
||||
awk '!/^$/&&!/^#/{printf("ipset=/.%s/'"netflix"'\n",$0)}' /etc/ssr/netflix.list >/tmp/dnsmasq.ssr/netflix_forward.conf
|
||||
|
||||
@ -91,6 +91,9 @@ msgstr "多个上游 IPv6 DNS 服务器请用 ',' 分隔(注意用英文逗号
|
||||
msgid "AdGuardHome login username/password: AdGuardHome/AdGuardHome"
|
||||
msgstr "AdGuardHome 登录账号/密码:AdGuardHome/AdGuardHome"
|
||||
|
||||
msgid "Running Status"
|
||||
msgstr "运行状态"
|
||||
|
||||
msgid "Flow Offloading"
|
||||
msgstr "流量分载"
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall
|
||||
PKG_VERSION:=3.9
|
||||
PKG_RELEASE:=18
|
||||
PKG_RELEASE:=19
|
||||
PKG_DATE:=20200717
|
||||
|
||||
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
|
||||
@ -37,6 +37,9 @@ function index()
|
||||
entry({"admin", "vpn", "passwall", "server_user_status"}, call("server_user_status")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "server_get_log"}, call("server_get_log")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "server_clear_log"}, call("server_clear_log")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "link_append_temp"}, call("link_append_temp")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "link_load_temp"}, call("link_load_temp")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "link_clear_temp"}, call("link_clear_temp")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "link_add_node"}, call("link_add_node")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "get_log"}, call("get_log")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "clear_log"}, call("clear_log")).leaf = true
|
||||
@ -82,9 +85,38 @@ function hide_menu()
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin", "status", "overview"))
|
||||
end
|
||||
|
||||
function link_add_node()
|
||||
function link_append_temp()
|
||||
local link = luci.http.formvalue("link")
|
||||
luci.sys.call('rm -f /tmp/links.conf && echo "' .. link .. '" >> /tmp/links.conf')
|
||||
local lfile = "/tmp/links.conf"
|
||||
local ret, ldata="empty", {}
|
||||
luci.sys.call('touch ' .. lfile .. ' && echo \'' .. link .. '\' >> ' .. lfile)
|
||||
ret = luci.sys.exec([[awk -F'://' 'BEGIN{ all=0 } /.{2,9}:\/\/.{4,}$/ {gsub(/:\/\/.*$/,""); arr[$0]++; all++ } END { for(typ in arr) { printf("%s: %d, ", typ, arr[typ]) }; printf("\ntotal: %d", all) }' ]] .. lfile)
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json({counter = ret})
|
||||
end
|
||||
|
||||
function link_load_temp()
|
||||
local lfile = "/tmp/links.conf"
|
||||
local ret, ldata="empty", {}
|
||||
ldata[#ldata+1] = nixio.fs.readfile(lfile) or "_nofile_"
|
||||
if ldata[1] == "" then
|
||||
ldata[1] = "_nodata_"
|
||||
else
|
||||
ret = luci.sys.exec([[awk -F'://' 'BEGIN{ all=0 } /.{2,9}:\/\/.{4,}$/ {gsub(/:\/\/.*$/,""); arr[$0]++; all++ } END { for(typ in arr) { printf("%s: %d, ", typ, arr[typ]) }; printf("\ntotal: %d", all) }' ]] .. lfile)
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json({counter = ret, data = ldata})
|
||||
end
|
||||
|
||||
function link_clear_temp()
|
||||
local lfile = "/tmp/links.conf"
|
||||
luci.sys.call('cat /dev/null > ' .. lfile)
|
||||
end
|
||||
|
||||
function link_add_node()
|
||||
local lfile = "/tmp/links.conf"
|
||||
local link = luci.http.formvalue("link")
|
||||
luci.sys.call('echo \'' .. link .. '\' >> ' .. lfile)
|
||||
luci.sys.call("lua /usr/share/passwall/subscribe.lua add log")
|
||||
end
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ local function gen_outbound(node, tag)
|
||||
concurrency = (node.mux_concurrency) and tonumber(node.mux_concurrency) or 8
|
||||
},
|
||||
-- 底层传输配置
|
||||
streamSettings = (node.protocol == "vmess") and {
|
||||
streamSettings = (node.protocol == "vmess" or node.protocol == "socks" or node.protocol == "shadowsocks") and {
|
||||
network = node.transport,
|
||||
security = node.stream_security,
|
||||
tlsSettings = (node.stream_security == "tls") and {
|
||||
@ -56,8 +56,7 @@ local function gen_outbound(node, tag)
|
||||
serverName = node.tls_serverName,
|
||||
allowInsecure = (node.tls_allowInsecure == "1") and true or false
|
||||
} or nil,
|
||||
tcpSettings = (node.transport == "tcp" and
|
||||
node.protocol ~= "socks") and {
|
||||
tcpSettings = (node.transport == "tcp" and node.protocol ~= "socks") and {
|
||||
header = {
|
||||
type = node.tcp_guise,
|
||||
request = {
|
||||
|
||||
@ -10,8 +10,7 @@ local function get_customed_path(e)
|
||||
end
|
||||
|
||||
local function is_finded(e)
|
||||
return luci.sys.exec("find /usr/*bin %s -iname %s -type f" %
|
||||
{get_customed_path(e), e}) ~= "" and true or false
|
||||
return luci.sys.exec("find /usr/*bin %s -iname %s -type f" % {get_customed_path(e), e}) ~= "" and true or false
|
||||
end
|
||||
|
||||
local function is_installed(e) return ipkg.installed(e) end
|
||||
@ -73,13 +72,17 @@ s = m:section(NamedSection, arg[1], "nodes", "")
|
||||
s.addremove = false
|
||||
s.dynamic = false
|
||||
|
||||
share = s:option(DummyValue, "share_url", translate("Share Current"))
|
||||
share.rawhtml = true
|
||||
share.template = "passwall/node_list/link_share_man"
|
||||
share.value = arg[1]
|
||||
|
||||
remarks = s:option(Value, "remarks", translate("Node Remarks"))
|
||||
remarks.default = translate("Remarks")
|
||||
remarks.rmempty = false
|
||||
|
||||
type = s:option(ListValue, "type", translate("Type"))
|
||||
if ((is_installed("redsocks2") or is_finded("redsocks2")) or
|
||||
(is_installed("ipt2socks") or is_finded("ipt2socks"))) then
|
||||
if is_installed("ipt2socks") or is_finded("ipt2socks") then
|
||||
type:value("Socks", translate("Socks"))
|
||||
end
|
||||
if is_finded("ss-redir") then
|
||||
@ -145,8 +148,7 @@ for k, v in pairs(nodes_table) do default_node:value(v.id, v.remarks) end
|
||||
default_node:depends("protocol", "_shunt")
|
||||
|
||||
-- Brook协议
|
||||
brook_protocol = s:option(ListValue, "brook_protocol",
|
||||
translate("Brook Protocol"))
|
||||
brook_protocol = s:option(ListValue, "brook_protocol", translate("Brook Protocol"))
|
||||
brook_protocol:value("client", translate("Brook"))
|
||||
brook_protocol:value("wsclient", translate("WebSocket"))
|
||||
brook_protocol:depends("type", "Brook")
|
||||
@ -213,28 +215,23 @@ password:depends("protocol", "http")
|
||||
password:depends("protocol", "socks")
|
||||
password:depends("protocol", "shadowsocks")
|
||||
|
||||
ss_encrypt_method = s:option(ListValue, "ss_encrypt_method",
|
||||
translate("Encrypt Method"))
|
||||
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
|
||||
ss_encrypt_method:depends("type", "SS")
|
||||
|
||||
ssr_encrypt_method = s:option(ListValue, "ssr_encrypt_method",
|
||||
translate("Encrypt Method"))
|
||||
ssr_encrypt_method = s:option(ListValue, "ssr_encrypt_method", translate("Encrypt Method"))
|
||||
for a, t in ipairs(ssr_encrypt_method_list) do ssr_encrypt_method:value(t) end
|
||||
ssr_encrypt_method:depends("type", "SSR")
|
||||
|
||||
security = s:option(ListValue, "security",
|
||||
translate("Encrypt Method"))
|
||||
security = s:option(ListValue, "security", translate("Encrypt Method"))
|
||||
for a, t in ipairs(security_list) do security:value(t) end
|
||||
security:depends("protocol", "vmess")
|
||||
|
||||
v_ss_encrypt_method = s:option(ListValue, "v_ss_encrypt_method",
|
||||
translate("Encrypt Method"))
|
||||
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("protocol", "shadowsocks")
|
||||
|
||||
ss_ota = s:option(Flag, "ss_ota", translate("OTA"), translate(
|
||||
"When OTA is enabled, V2Ray will reject connections that are not OTA enabled. This option is invalid when using AEAD encryption."))
|
||||
ss_ota = s:option(Flag, "ss_ota", translate("OTA"), translate("When OTA is enabled, V2Ray will reject connections that are not OTA enabled. This option is invalid when using AEAD encryption."))
|
||||
ss_ota.default = "0"
|
||||
ss_ota:depends("protocol", "shadowsocks")
|
||||
|
||||
@ -258,8 +255,7 @@ timeout.default = 300
|
||||
timeout:depends("type", "SS")
|
||||
timeout:depends("type", "SSR")
|
||||
|
||||
tcp_fast_open = s:option(ListValue, "tcp_fast_open", translate("TCP Fast Open"),
|
||||
translate("Need node support required"))
|
||||
tcp_fast_open = s:option(ListValue, "tcp_fast_open", translate("TCP Fast Open"), translate("Need node support required"))
|
||||
tcp_fast_open:value("false")
|
||||
tcp_fast_open:value("true")
|
||||
tcp_fast_open:depends("type", "SS")
|
||||
@ -278,9 +274,7 @@ ss_plugin_opts:depends("ss_plugin", "v2ray-plugin")
|
||||
ss_plugin_opts:depends("ss_plugin", "obfs-local")
|
||||
|
||||
use_kcp = s:option(Flag, "use_kcp", translate("Use Kcptun"),
|
||||
"<span style='color:red'>" .. translate(
|
||||
"Please confirm whether the Kcptun is installed. If not, please go to Rule Update download installation.") ..
|
||||
"</span>")
|
||||
"<span style='color:red'>" .. translate("Please confirm whether the Kcptun is installed. If not, please go to Rule Update download installation.") .. "</span>")
|
||||
use_kcp.default = 0
|
||||
use_kcp:depends("type", "SS")
|
||||
use_kcp:depends("type", "SSR")
|
||||
@ -294,34 +288,27 @@ kcp_port = s:option(Value, "kcp_port", translate("Kcptun Port"))
|
||||
kcp_port.datatype = "port"
|
||||
kcp_port:depends("use_kcp", "1")
|
||||
|
||||
kcp_opts = s:option(TextValue, "kcp_opts", translate("Kcptun Config"),
|
||||
translate(
|
||||
"--crypt aes192 --key abc123 --mtu 1350 --sndwnd 128 --rcvwnd 1024 --mode fast"))
|
||||
kcp_opts.placeholder =
|
||||
"--crypt aes192 --key abc123 --mtu 1350 --sndwnd 128 --rcvwnd 1024 --mode fast"
|
||||
kcp_opts = s:option(TextValue, "kcp_opts", translate("Kcptun Config"), translate("--crypt aes192 --key abc123 --mtu 1350 --sndwnd 128 --rcvwnd 1024 --mode fast"))
|
||||
kcp_opts.placeholder = "--crypt aes192 --key abc123 --mtu 1350 --sndwnd 128 --rcvwnd 1024 --mode fast"
|
||||
kcp_opts:depends("use_kcp", "1")
|
||||
|
||||
vmess_id = s:option(Value, "vmess_id", translate("ID"))
|
||||
vmess_id.password = true
|
||||
vmess_id:depends("protocol", "vmess")
|
||||
|
||||
alter_id = s:option(Value, "alter_id",
|
||||
translate("Alter ID"))
|
||||
alter_id = s:option(Value, "alter_id", translate("Alter ID"))
|
||||
alter_id:depends("protocol", "vmess")
|
||||
|
||||
vmess_level =
|
||||
s:option(Value, "vmess_level", translate("User Level"))
|
||||
vmess_level = s:option(Value, "vmess_level", translate("User Level"))
|
||||
vmess_level.default = 1
|
||||
vmess_level:depends("protocol", "vmess")
|
||||
|
||||
stream_security = s:option(ListValue, "stream_security",
|
||||
translate("Transport Layer Encryption"),
|
||||
translate(
|
||||
'Whether or not transport layer encryption is enabled, the supported options are "none" for unencrypted (default) and "TLS" for using TLS.'))
|
||||
stream_security = s:option(ListValue, "stream_security", translate("Transport Layer Encryption"), translate('Whether or not transport layer encryption is enabled, the supported options are "none" for unencrypted (default) and "TLS" for using TLS.'))
|
||||
stream_security:value("none", "none")
|
||||
stream_security:value("tls", "tls")
|
||||
stream_security.default = "tls"
|
||||
stream_security:depends("protocol", "vmess")
|
||||
stream_security:depends("protocol", "socks")
|
||||
stream_security:depends("protocol", "shadowsocks")
|
||||
stream_security:depends("type", "Trojan")
|
||||
stream_security:depends("type", "Trojan-Go")
|
||||
@ -333,13 +320,11 @@ stream_security.validate = function(self, value)
|
||||
end
|
||||
|
||||
-- [[ TLS部分 ]] --
|
||||
|
||||
tls_sessionTicket = s:option(Flag, "tls_sessionTicket", translate("Session Ticket"))
|
||||
tls_sessionTicket.default = "0"
|
||||
tls_sessionTicket:depends("stream_security", "tls")
|
||||
|
||||
-- [[ Trojan TLS ]]--
|
||||
|
||||
trojan_force_fp = s:option(ListValue, "fingerprint", translate("Finger Print"))
|
||||
for a, t in ipairs(force_fp) do trojan_force_fp:value(t) end
|
||||
trojan_force_fp.default = "firefox"
|
||||
@ -348,13 +333,11 @@ trojan_force_fp:depends({ type = "Trojan-Go", stream_security = "tls" })
|
||||
tls_serverName = s:option(Value, "tls_serverName", translate("Domain"))
|
||||
tls_serverName:depends("stream_security", "tls")
|
||||
|
||||
tls_allowInsecure = s:option(Flag, "tls_allowInsecure", translate("allowInsecure"), translate(
|
||||
"Whether unsafe connections are allowed. When checked, V2Ray does not check the validity of the TLS certificate provided by the remote host."))
|
||||
tls_allowInsecure = s:option(Flag, "tls_allowInsecure", translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, V2Ray does not check the validity of the TLS certificate provided by the remote host."))
|
||||
tls_allowInsecure.default = "0"
|
||||
tls_allowInsecure:depends("stream_security", "tls")
|
||||
|
||||
-- [[ Trojan Cert ]]--
|
||||
|
||||
trojan_cert_path = s:option(Value, "trojan_cert_path", translate("Trojan Cert Path"))
|
||||
trojan_cert_path.default = ""
|
||||
trojan_cert_path:depends({ stream_security = "tls", tls_allowInsecure = false })
|
||||
@ -397,12 +380,13 @@ transport:value("h2", "HTTP/2")
|
||||
transport:value("ds", "DomainSocket")
|
||||
transport:value("quic", "QUIC")
|
||||
transport:depends("protocol", "vmess")
|
||||
transport:depends("protocol", "socks")
|
||||
transport:depends("protocol", "shadowsocks")
|
||||
|
||||
--[[
|
||||
ss_transport = s:option(ListValue, "ss_transport", translate("Transport"))
|
||||
ss_transport:value("ws", "WebSocket")
|
||||
ss_transport:value("h2", "HTTP/2")
|
||||
ss_transport:value("ws", "WebSocket")
|
||||
ss_transport:value("h2+ws", "HTTP/2 & WebSocket")
|
||||
ss_transport:depends("protocol", "shadowsocks")
|
||||
]]--
|
||||
@ -410,27 +394,22 @@ ss_transport:depends("protocol", "shadowsocks")
|
||||
-- [[ TCP部分 ]]--
|
||||
|
||||
-- TCP伪装
|
||||
tcp_guise = s:option(ListValue, "tcp_guise",
|
||||
translate("Camouflage Type"))
|
||||
tcp_guise = s:option(ListValue, "tcp_guise", translate("Camouflage Type"))
|
||||
tcp_guise:value("none", "none")
|
||||
tcp_guise:value("http", "http")
|
||||
tcp_guise:depends("transport", "tcp")
|
||||
|
||||
-- HTTP域名
|
||||
tcp_guise_http_host = s:option(DynamicList, "tcp_guise_http_host",
|
||||
translate("HTTP Host"))
|
||||
tcp_guise_http_host = s:option(DynamicList, "tcp_guise_http_host", translate("HTTP Host"))
|
||||
tcp_guise_http_host:depends("tcp_guise", "http")
|
||||
|
||||
-- HTTP路径
|
||||
tcp_guise_http_path = s:option(DynamicList, "tcp_guise_http_path",
|
||||
translate("HTTP Path"))
|
||||
tcp_guise_http_path = s:option(DynamicList, "tcp_guise_http_path", translate("HTTP Path"))
|
||||
tcp_guise_http_path:depends("tcp_guise", "http")
|
||||
|
||||
-- [[ mKCP部分 ]]--
|
||||
|
||||
mkcp_guise = s:option(ListValue, "mkcp_guise",
|
||||
translate("Camouflage Type"), translate(
|
||||
'<br />none: default, no masquerade, data sent is packets with no characteristics.<br />srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).<br />utp: packets disguised as uTP will be recognized as bittorrent downloaded data.<br />wechat-video: packets disguised as WeChat video calls.<br />dtls: disguised as DTLS 1.2 packet.<br />wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)'))
|
||||
mkcp_guise = s:option(ListValue, "mkcp_guise", translate("Camouflage Type"), translate('<br />none: default, no masquerade, data sent is packets with no characteristics.<br />srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).<br />utp: packets disguised as uTP will be recognized as bittorrent downloaded data.<br />wechat-video: packets disguised as WeChat video calls.<br />dtls: disguised as DTLS 1.2 packet.<br />wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)'))
|
||||
for a, t in ipairs(header_type_list) do mkcp_guise:value(t) end
|
||||
mkcp_guise:depends("transport", "mkcp")
|
||||
|
||||
@ -440,28 +419,22 @@ mkcp_mtu:depends("transport", "mkcp")
|
||||
mkcp_tti = s:option(Value, "mkcp_tti", translate("KCP TTI"))
|
||||
mkcp_tti:depends("transport", "mkcp")
|
||||
|
||||
mkcp_uplinkCapacity = s:option(Value, "mkcp_uplinkCapacity",
|
||||
translate("KCP uplinkCapacity"))
|
||||
mkcp_uplinkCapacity = s:option(Value, "mkcp_uplinkCapacity", translate("KCP uplinkCapacity"))
|
||||
mkcp_uplinkCapacity:depends("transport", "mkcp")
|
||||
|
||||
mkcp_downlinkCapacity = s:option(Value, "mkcp_downlinkCapacity",
|
||||
translate("KCP downlinkCapacity"))
|
||||
mkcp_downlinkCapacity = s:option(Value, "mkcp_downlinkCapacity", translate("KCP downlinkCapacity"))
|
||||
mkcp_downlinkCapacity:depends("transport", "mkcp")
|
||||
|
||||
mkcp_congestion = s:option(Flag, "mkcp_congestion",
|
||||
translate("KCP Congestion"))
|
||||
mkcp_congestion = s:option(Flag, "mkcp_congestion", translate("KCP Congestion"))
|
||||
mkcp_congestion:depends("transport", "mkcp")
|
||||
|
||||
mkcp_readBufferSize = s:option(Value, "mkcp_readBufferSize",
|
||||
translate("KCP readBufferSize"))
|
||||
mkcp_readBufferSize = s:option(Value, "mkcp_readBufferSize", translate("KCP readBufferSize"))
|
||||
mkcp_readBufferSize:depends("transport", "mkcp")
|
||||
|
||||
mkcp_writeBufferSize = s:option(Value, "mkcp_writeBufferSize",
|
||||
translate("KCP writeBufferSize"))
|
||||
mkcp_writeBufferSize = s:option(Value, "mkcp_writeBufferSize", translate("KCP writeBufferSize"))
|
||||
mkcp_writeBufferSize:depends("transport", "mkcp")
|
||||
|
||||
-- [[ WebSocket部分 ]]--
|
||||
|
||||
ws_host = s:option(Value, "ws_host", translate("WebSocket Host"))
|
||||
ws_host:depends("transport", "ws")
|
||||
ws_host:depends("ss_transport", "ws")
|
||||
@ -475,7 +448,6 @@ ws_path:depends("trojan_transport", "h2+ws")
|
||||
ws_path:depends("trojan_transport", "ws")
|
||||
|
||||
-- [[ HTTP/2部分 ]]--
|
||||
|
||||
h2_host = s:option(Value, "h2_host", translate("HTTP/2 Host"))
|
||||
h2_host:depends("transport", "h2")
|
||||
h2_host:depends("ss_transport", "h2")
|
||||
@ -489,30 +461,24 @@ h2_path:depends("trojan_transport", "h2+ws")
|
||||
h2_path:depends("trojan_transport", "h2")
|
||||
|
||||
-- [[ DomainSocket部分 ]]--
|
||||
|
||||
ds_path = s:option(Value, "ds_path", "Path", translate(
|
||||
"A legal file path. This file must not exist before running V2Ray."))
|
||||
ds_path = s:option(Value, "ds_path", "Path", translate("A legal file path. This file must not exist before running V2Ray."))
|
||||
ds_path:depends("transport", "ds")
|
||||
|
||||
-- [[ QUIC部分 ]]--
|
||||
quic_security = s:option(ListValue, "quic_security",
|
||||
translate("Encrypt Method"))
|
||||
quic_security = s:option(ListValue, "quic_security", translate("Encrypt Method"))
|
||||
quic_security:value("none")
|
||||
quic_security:value("aes-128-gcm")
|
||||
quic_security:value("chacha20-poly1305")
|
||||
quic_security:depends("transport", "quic")
|
||||
|
||||
quic_key = s:option(Value, "quic_key",
|
||||
translate("Encrypt Method") .. translate("Key"))
|
||||
quic_key = s:option(Value, "quic_key", translate("Encrypt Method") .. translate("Key"))
|
||||
quic_key:depends("transport", "quic")
|
||||
|
||||
quic_guise = s:option(ListValue, "quic_guise",
|
||||
translate("Camouflage Type"))
|
||||
quic_guise = s:option(ListValue, "quic_guise", translate("Camouflage Type"))
|
||||
for a, t in ipairs(header_type_list) do quic_guise:value(t) end
|
||||
quic_guise:depends("transport", "quic")
|
||||
|
||||
-- [[ Trojan-Go Shadowsocks2 ]] --
|
||||
|
||||
ss_aead = s:option(Flag, "ss_aead", translate("Shadowsocks2"))
|
||||
ss_aead:depends("type", "Trojan-Go")
|
||||
ss_aead.default = "0"
|
||||
@ -540,33 +506,24 @@ mux_concurrency:depends("mux", "1")
|
||||
|
||||
-- [[ 当作为TCP节点时,是否同时开启socks代理 ]]--
|
||||
--[[
|
||||
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 = 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", "V2ray")
|
||||
|
||||
tcp_socks_port = s:option(Value, "tcp_socks_port",
|
||||
"Socks " .. translate("Port"),
|
||||
translate("Do not conflict with other ports"))
|
||||
tcp_socks_port = s:option(Value, "tcp_socks_port", "Socks " .. translate("Port"), translate("Do not conflict with other ports"))
|
||||
tcp_socks_port.datatype = "port"
|
||||
tcp_socks_port.default = 1080
|
||||
tcp_socks_port:depends("tcp_socks", "1")
|
||||
|
||||
tcp_socks_auth = s:option(ListValue, "tcp_socks_auth",
|
||||
translate("Socks for authentication"),
|
||||
translate(
|
||||
'Socks protocol authentication, support anonymous and password.'))
|
||||
tcp_socks_auth = s:option(ListValue, "tcp_socks_auth", translate("Socks for authentication"), translate('Socks protocol authentication, support anonymous and password.'))
|
||||
tcp_socks_auth:value("noauth", translate("anonymous"))
|
||||
tcp_socks_auth:value("password", translate("User Password"))
|
||||
tcp_socks_auth:depends("tcp_socks", "1")
|
||||
|
||||
tcp_socks_auth_username = s:option(Value, "tcp_socks_auth_username",
|
||||
"Socks " .. translate("Username"))
|
||||
tcp_socks_auth_username = s:option(Value, "tcp_socks_auth_username", "Socks " .. translate("Username"))
|
||||
tcp_socks_auth_username:depends("tcp_socks_auth", "password")
|
||||
|
||||
tcp_socks_auth_password = s:option(Value, "tcp_socks_auth_password",
|
||||
"Socks " .. translate("Password"))
|
||||
tcp_socks_auth_password = s:option(Value, "tcp_socks_auth_password", "Socks " .. translate("Password"))
|
||||
tcp_socks_auth_password:depends("tcp_socks_auth", "password")
|
||||
--]]
|
||||
|
||||
|
||||
@ -30,11 +30,6 @@ function gen_config(user)
|
||||
udp_timeout = 60,
|
||||
disable_http_check = true,
|
||||
tcp = {
|
||||
mux = (user.mux == "1") and {
|
||||
enabled = true,
|
||||
concurrency = tonumber(user.mux_concurrency),
|
||||
idle_timeout = 60,
|
||||
} or nil,
|
||||
transport_plugin = user.stream_security == "none" and user.trojan_transport == "original" and {
|
||||
enabled = user.plugin_type ~= nil,
|
||||
type = user.plugin_type or "plaintext",
|
||||
|
||||
@ -14,7 +14,7 @@ function gen_config(user)
|
||||
for i = 1, #user.vmess_id do
|
||||
clients[i] = {
|
||||
id = user.vmess_id[i],
|
||||
level = tonumber(user.vmess_level),
|
||||
level = tonumber(user.level),
|
||||
alterId = tonumber(user.alter_id)
|
||||
}
|
||||
end
|
||||
@ -42,12 +42,21 @@ function gen_config(user)
|
||||
}
|
||||
elseif user.protocol == "shadowsocks" then
|
||||
settings = {
|
||||
method = user.ss_encrypt_method,
|
||||
method = user.v_ss_encrypt_method,
|
||||
password = user.password,
|
||||
level = tonumber(user.vmess_level) or 1,
|
||||
level = tonumber(user.level) or 1,
|
||||
network = user.ss_network or "TCP,UDP",
|
||||
ota = (user.ss_ota == '1') and true or false
|
||||
}
|
||||
elseif user.protocol == "mtproto" then
|
||||
settings = {
|
||||
users = {
|
||||
{
|
||||
level = tonumber(user.level) or 1,
|
||||
secret = (user.password == nil) and "" or user.password
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
if user.accept_lan == nil or user.accept_lan == "0" then
|
||||
@ -74,7 +83,7 @@ function gen_config(user)
|
||||
concurrency = (node.mux_concurrency) and tonumber(node.mux_concurrency) or 8
|
||||
},
|
||||
-- 底层传输配置
|
||||
streamSettings = (node.protocol == "vmess") and {
|
||||
streamSettings = {
|
||||
network = node.transport,
|
||||
security = node.stream_security,
|
||||
tlsSettings = (node.stream_security == "tls") and {
|
||||
@ -122,7 +131,7 @@ function gen_config(user)
|
||||
key = node.quic_key,
|
||||
header = {type = node.quic_guise}
|
||||
} or nil
|
||||
} or nil,
|
||||
},
|
||||
settings = {
|
||||
vnext = (node.protocol == "vmess") and {
|
||||
{
|
||||
@ -132,7 +141,7 @@ function gen_config(user)
|
||||
{
|
||||
id = node.vmess_id,
|
||||
alterId = tonumber(node.alter_id),
|
||||
level = tonumber(node.vmess_level),
|
||||
level = tonumber(node.level),
|
||||
security = node.security
|
||||
}
|
||||
}
|
||||
@ -162,7 +171,7 @@ function gen_config(user)
|
||||
|
||||
local config = {
|
||||
log = {
|
||||
-- error = "/var/log/v2ray.log",
|
||||
-- error = "/var/etc/passwall_server/log/" .. user[".name"] .. ".log",
|
||||
loglevel = "warning"
|
||||
},
|
||||
-- 传入连接
|
||||
@ -171,14 +180,12 @@ function gen_config(user)
|
||||
listen = (user.bind_local == "1") and "127.0.0.1" or nil,
|
||||
port = tonumber(user.port),
|
||||
protocol = user.protocol,
|
||||
-- 底层传输配置
|
||||
settings = settings,
|
||||
streamSettings = (user.protocol == "vmess") and {
|
||||
streamSettings = {
|
||||
network = user.transport,
|
||||
security = (user.stream_security == 'tls') and "tls" or "none",
|
||||
tlsSettings = (user.stream_security == 'tls') and {
|
||||
disableSessionResumption = user.sessionTicket ~= "1" and true or false,
|
||||
-- serverName = (user.tls_serverName),
|
||||
allowInsecure = false,
|
||||
disableSystemRoot = false,
|
||||
certificates = {
|
||||
@ -209,22 +216,22 @@ function gen_config(user)
|
||||
writeBufferSize = tonumber(user.mkcp_writeBufferSize),
|
||||
header = {type = user.mkcp_guise}
|
||||
} or nil,
|
||||
wsSettings = (user.transport == "ws") and
|
||||
{
|
||||
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,
|
||||
wsSettings = (user.transport == "ws") and {
|
||||
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
|
||||
} or nil
|
||||
}
|
||||
}
|
||||
},
|
||||
-- 传出连接
|
||||
|
||||
@ -82,17 +82,17 @@ if is_installed("trojan-go") or is_finded("trojan-go") then
|
||||
end
|
||||
|
||||
protocol = s:option(ListValue, "protocol", translate("Protocol"))
|
||||
protocol:value("vmess", translate("Vmess"))
|
||||
protocol:value("http", translate("HTTP"))
|
||||
protocol:value("socks", translate("Socks"))
|
||||
protocol:value("shadowsocks", translate("Shadowsocks"))
|
||||
protocol:value("vmess", "Vmess")
|
||||
protocol:value("http", "HTTP")
|
||||
protocol:value("socks", "Socks")
|
||||
protocol:value("shadowsocks", "Shadowsocks")
|
||||
protocol:value("mtproto", "MTProto")
|
||||
protocol:depends("type", "V2ray")
|
||||
|
||||
-- Brook协议
|
||||
brook_protocol = s:option(ListValue, "brook_protocol",
|
||||
translate("Brook Protocol"))
|
||||
brook_protocol:value("server", translate("Brook"))
|
||||
brook_protocol:value("wsserver", translate("WebSocket"))
|
||||
brook_protocol = s:option(ListValue, "brook_protocol", translate("Brook Protocol"))
|
||||
brook_protocol:value("server", "Brook")
|
||||
brook_protocol:value("wsserver", "WebSocket")
|
||||
brook_protocol:depends("type", "Brook")
|
||||
|
||||
brook_tls = s:option(Flag, "brook_tls", translate("Use TLS"))
|
||||
@ -101,14 +101,6 @@ brook_tls:depends("brook_protocol", "wsserver")
|
||||
port = s:option(Value, "port", translate("Port"))
|
||||
port.datatype = "port"
|
||||
port.rmempty = false
|
||||
port:depends("type", "SSR")
|
||||
port:depends({ type = "V2ray", protocol = "vmess" })
|
||||
port:depends({ type = "V2ray", protocol = "http" })
|
||||
port:depends({ type = "V2ray", protocol = "socks" })
|
||||
port:depends({ type = "V2ray", protocol = "shadowsocks" })
|
||||
port:depends("type", "Brook")
|
||||
port:depends("type", "Trojan")
|
||||
port:depends("type", "Trojan-Go")
|
||||
|
||||
username = s:option(Value, "username", translate("Username"))
|
||||
username:depends("protocol", "http")
|
||||
@ -123,6 +115,7 @@ password:depends("type", "Trojan-Go")
|
||||
password:depends({ type = "V2ray", protocol = "http" })
|
||||
password:depends({ type = "V2ray", protocol = "socks" })
|
||||
password:depends({ type = "V2ray", protocol = "shadowsocks" })
|
||||
password:depends({ type = "V2ray", protocol = "mtproto" })
|
||||
|
||||
ssr_encrypt_method = s:option(ListValue, "ssr_encrypt_method", translate("Encrypt Method"))
|
||||
for a, t in ipairs(ssr_encrypt_method_list) do ssr_encrypt_method:value(t) end
|
||||
@ -185,21 +178,20 @@ alter_id = s:option(Value, "alter_id", translate("Alter ID"))
|
||||
alter_id.default = 16
|
||||
alter_id:depends({ type = "V2ray", protocol = "vmess" })
|
||||
|
||||
vmess_level = s:option(Value, "vmess_level", translate("User Level"))
|
||||
vmess_level.default = 1
|
||||
vmess_level:depends({ type = "V2ray", protocol = "vmess" })
|
||||
vmess_level:depends({ type = "V2ray", protocol = "shadowsocks" })
|
||||
level = s:option(Value, "level", translate("User Level"))
|
||||
level.default = 1
|
||||
level:depends({ type = "V2ray", protocol = "vmess" })
|
||||
level:depends({ type = "V2ray", protocol = "shadowsocks" })
|
||||
level:depends({ type = "V2ray", protocol = "mtproto" })
|
||||
|
||||
stream_security = s:option(ListValue, "stream_security",
|
||||
translate("Transport Layer Encryption"),
|
||||
translate(
|
||||
'Whether or not transport layer encryption is enabled, the supported options are "none" for unencrypted (default) and "TLS" for using TLS.'))
|
||||
stream_security = s:option(ListValue, "stream_security", translate("Transport Layer Encryption"), translate('Whether or not transport layer encryption is enabled, the supported options are "none" for unencrypted (default) and "TLS" for using TLS.'))
|
||||
stream_security:value("none", "none")
|
||||
stream_security:value("tls", "tls")
|
||||
stream_security.default = "tls"
|
||||
stream_security:depends({ type = "V2ray", protocol = "vmess", transport = "ws" })
|
||||
stream_security:depends({ type = "V2ray", protocol = "vmess", transport = "h2" })
|
||||
stream_security:depends("protocol", "shadowsocks")
|
||||
stream_security:depends({ type = "V2ray", protocol = "socks" })
|
||||
stream_security:depends({ type = "V2ray", protocol = "shadowsocks" })
|
||||
stream_security:depends("type", "Trojan-Go")
|
||||
|
||||
-- [[ TLS部分 ]] --
|
||||
@ -221,7 +213,9 @@ transport:value("ws", "WebSocket")
|
||||
transport:value("h2", "HTTP/2")
|
||||
transport:value("ds", "DomainSocket")
|
||||
transport:value("quic", "QUIC")
|
||||
transport:depends("protocol", "vmess")
|
||||
stream_security:depends({ type = "V2ray", protocol = "vmess" })
|
||||
stream_security:depends({ type = "V2ray", protocol = "socks" })
|
||||
stream_security:depends({ type = "V2ray", protocol = "shadowsocks" })
|
||||
|
||||
trojan_transport = s:option(ListValue, "trojan_transport", translate("Transport"))
|
||||
trojan_transport:value("original", "Original")
|
||||
@ -343,7 +337,7 @@ quic_guise = s:option(ListValue, "quic_guise", translate("Camouflage Type"))
|
||||
for a, t in ipairs(header_type_list) do quic_guise:value(t) end
|
||||
quic_guise:depends("transport", "quic")
|
||||
|
||||
remote_enable = s:option(Flag, "remote_enable", translate("Enable Remote"),translate("You can forward to Nginx/Caddy/V2ray WebSocket and more."))
|
||||
remote_enable = s:option(Flag, "remote_enable", translate("Enable Remote"), translate("You can forward to Nginx/Caddy/V2ray WebSocket and more."))
|
||||
remote_enable.default = "1"
|
||||
remote_enable.rmempty = false
|
||||
remote_enable:depends("type", "Trojan")
|
||||
@ -372,14 +366,6 @@ ss_aead_pwd.password = true
|
||||
ss_aead_pwd.rmempty = false
|
||||
ss_aead_pwd:depends("ss_aead", "1")
|
||||
|
||||
-- [[ Mux ]]--
|
||||
mux = s:option(Flag, "mux", translate("Mux"))
|
||||
|
||||
mux_concurrency = s:option(Value, "mux_concurrency",
|
||||
translate("Mux Concurrency"))
|
||||
mux_concurrency.default = 8
|
||||
mux_concurrency:depends("mux", "1")
|
||||
|
||||
local nodes_table = {}
|
||||
uci:foreach("passwall", "nodes", function(e)
|
||||
if e.type and e.type == "V2ray" and e.remarks and e.address and e.port then
|
||||
|
||||
@ -23,6 +23,41 @@ local dsp = require "luci.dispatcher"
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function link_clear_temp() {
|
||||
if (confirm('<%:Are you sure to clear all cached links?%>') == true){
|
||||
XHR.get('<%=dsp.build_url("admin/vpn/passwall/link_clear_temp")%>', null,
|
||||
function(x, data) {
|
||||
if(x && x.status == 200) {
|
||||
window.location.href = '<%=dsp.build_url("admin/vpn/passwall/node_list")%>';
|
||||
}
|
||||
else {
|
||||
alert("<%:Error%>");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function link_load_temp() {
|
||||
var inputer = document.getElementById("nodes_link");
|
||||
XHR.get('<%=dsp.build_url("admin/vpn/passwall/link_load_temp")%>', null,
|
||||
function(x, data) {
|
||||
if(x.readyState === 4 && x.status === 200) {
|
||||
try {
|
||||
res = JSON.parse(x.responseText);
|
||||
}
|
||||
catch(e) {
|
||||
res = null;
|
||||
}
|
||||
if(res !== null && typeof(res) === "object") {
|
||||
alert(res.counter);
|
||||
if(res.data) inputer.value = res.data;
|
||||
}
|
||||
} else {
|
||||
alert("<%:Error%>");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function ajax_add_node(link) {
|
||||
if (link) {
|
||||
XHR.get('<%=dsp.build_url("admin/vpn/passwall/link_add_node")%>', {
|
||||
@ -51,7 +86,7 @@ local dsp = require "luci.dispatcher"
|
||||
function add_node() {
|
||||
var nodes_link = document.getElementById("nodes_link").value;
|
||||
if (nodes_link.trim() != "") {
|
||||
if (nodes_link.indexOf("ss://") == 0 || nodes_link.indexOf("ssr://") == 0 || nodes_link.indexOf("vmess://") == 0 || nodes_link.indexOf("trojan://") == 0) {
|
||||
if (nodes_link.indexOf("ss://") == 0 || nodes_link.indexOf("ssr://") == 0 || nodes_link.indexOf("vmess://") == 0 || nodes_link.indexOf("trojan://") == 0 || nodes_link.indexOf("trojan-go://") == 0) {
|
||||
ajax_add_node(nodes_link);
|
||||
}
|
||||
else {
|
||||
@ -88,9 +123,10 @@ local dsp = require "luci.dispatcher"
|
||||
</div>
|
||||
</div>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"></label>
|
||||
<div class="cbi-value-field">
|
||||
<input class="cbi-button cbi-button-add" type="button" onclick="add_node()" value="<%:Add%>" />
|
||||
<input class="cbi-button cbi-button-apply" type="button" onclick="link_load_temp()" value="<%:Load %><%:Cached%>" />
|
||||
<input class="cbi-button cbi-button-refresh" type="button" onclick="link_clear_temp()" value="<%:Clear %><%:Cached%>" />
|
||||
<input class="cbi-button cbi-button-remove" type="button" onclick="close_add_link_div()" value="<%:Close%>" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -0,0 +1,604 @@
|
||||
<%+cbi/valueheader%>
|
||||
<%
|
||||
local dsp = require "luci.dispatcher"
|
||||
-%>
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
function padright(str, cnt, pad) {
|
||||
return str + Array(cnt + 1).join(pad);
|
||||
}
|
||||
|
||||
function b64EncodeUnicode(str) {
|
||||
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
|
||||
return String.fromCharCode('0x' + p1);
|
||||
}));
|
||||
}
|
||||
|
||||
function b64encutf8safe(str) {
|
||||
return b64EncodeUnicode(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '');
|
||||
}
|
||||
|
||||
function b64DecodeUnicode(str) {
|
||||
return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) {
|
||||
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||
}).join(''));
|
||||
}
|
||||
|
||||
function b64decutf8safe(str) {
|
||||
var l;
|
||||
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
||||
l = str.length;
|
||||
l = (4 - l % 4) % 4;
|
||||
if (l)
|
||||
str = padright(str, l, "=");
|
||||
return b64DecodeUnicode(str);
|
||||
}
|
||||
|
||||
function b64encsafe(str) {
|
||||
return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '')
|
||||
}
|
||||
|
||||
function b64decsafe(str) {
|
||||
var l;
|
||||
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
||||
l = str.length;
|
||||
l = (4 - l % 4) % 4;
|
||||
if (l)
|
||||
str = padright(str, l, "=");
|
||||
return atob(str);
|
||||
}
|
||||
|
||||
function dictvalue(d, key) {
|
||||
var v = d[key];
|
||||
if (typeof(v) === 'undefined' || v === '')
|
||||
return '';
|
||||
return b64decsafe(v);
|
||||
}
|
||||
function parseNodeUrl(url) {
|
||||
var m = url.match(/^(([^:\/?#]+:)?(?:\/\/((?:([^\/?#:]*)([^\/?#:]*)@)?([^\/?#:]*)(?::([^\/?#:]*))?)))?([^?#]*)(\?[^#]*)?(#.*)?$/),
|
||||
r = {
|
||||
hash: m[10] || "", // #asd
|
||||
host: m[3] || "", // localhost:257
|
||||
hostname: m[6] || "", // localhost
|
||||
href: m[0] || "", // http://username:password@localhost:257/deploy/?asd=asd#asd
|
||||
origin: m[1] || "", // http://username:password@localhost:257
|
||||
pathname: m[8] || (m[1] ? "/" : ""), // /deploy/
|
||||
port: m[7] || "", // 257
|
||||
protocol: m[2] || "", // http:
|
||||
search: m[9] || "", // ?asd=asd
|
||||
passwd: m[4] || "", // username
|
||||
removed: m[5] || "" // password
|
||||
};
|
||||
if (r.protocol.length === 2) {
|
||||
r.protocol = "file:///" + r.protocol.toUpperCase();
|
||||
r.origin = r.protocol + "//" + r.host;
|
||||
}
|
||||
r.href = r.origin + r.pathname + r.search + r.hash;
|
||||
return m && r;
|
||||
}
|
||||
|
||||
function link_append_temp(link) {
|
||||
XHR.get('<%=dsp.build_url("admin/vpn/passwall/link_append_temp")%>', {
|
||||
'link': link
|
||||
},
|
||||
function(x, data) {
|
||||
if(x.readyState === 4 && x.status === 200) {
|
||||
try {
|
||||
res = JSON.parse(x.responseText);
|
||||
}
|
||||
catch(e) {
|
||||
res = null;
|
||||
}
|
||||
if(res !== null && typeof(res) === "object") {
|
||||
alert(res.counter);
|
||||
}
|
||||
} else {
|
||||
alert("<%:Error%>");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function buildUrl(btn, urlname, sid) {
|
||||
var opt = {
|
||||
base: "cbid.passwall",
|
||||
fallback: "dummy",
|
||||
get: function(opt) {
|
||||
var id = this.base + "." + opt;
|
||||
var obj = document.getElementsByName(id) || document.getElementById(id);
|
||||
if (obj) {
|
||||
if (obj.length === 1) obj = obj[0];
|
||||
return obj;
|
||||
} else {
|
||||
alert("<%:Faltal on get option, please help in debug: %>" + opt);
|
||||
return document.getElementById(this.fallback);
|
||||
}
|
||||
},
|
||||
getlist: function(opt) {
|
||||
var id = this.base + "." + opt;
|
||||
var objs = document.getElementsByName(id) || document.getElementsByClassName(id);
|
||||
var ret = [];
|
||||
if (objs) {
|
||||
for (var i = 0; i < objs.length; i++) {
|
||||
ret[i] = objs[i].value;
|
||||
}
|
||||
} else {
|
||||
alert("<%:Faltal on get option, please help in debug: %>" + opt);
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
query: function(param, src, tval = "1", fval = "0") {
|
||||
var ret = "&" + param + "=";
|
||||
var obj = this.get(src);
|
||||
if (obj) {
|
||||
if (obj.type === "checkbox") {
|
||||
return ret + (obj.checked === true ? tval : fval);
|
||||
} else {
|
||||
return ret + encodeURIComponent(obj.value);
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
var s = document.getElementById(urlname + "-status");
|
||||
if (!s) {
|
||||
alert("Never");
|
||||
return false;
|
||||
}
|
||||
opt.base = "cbid.passwall." + sid;
|
||||
opt.fallback = urlname + "-dummy";
|
||||
var v_type = opt.get("type").value;
|
||||
var v_alias = opt.get("remarks");
|
||||
var url = null;
|
||||
if (v_type === "SSR") {
|
||||
var v_server = opt.get("address");
|
||||
var v_port = opt.get("port");
|
||||
var v_protocol = opt.get("ssr_protocol");
|
||||
var v_method = opt.get("ssr_encrypt_method");
|
||||
var v_obfs = opt.get("obfs");
|
||||
var v_password = opt.get("password");
|
||||
var v_obfs_param = opt.get("obfs_param");
|
||||
var v_protocol_param = opt.get("protocol_param");
|
||||
var ssr_str = v_server.value + ":" +
|
||||
v_port.value + ":" +
|
||||
v_protocol.value + ":" +
|
||||
v_method.value + ":" +
|
||||
v_obfs.value + ":" +
|
||||
b64encsafe(v_password.value) +
|
||||
"/?obfsparam=" + b64encsafe(v_obfs_param.value) +
|
||||
"&protoparam=" + b64encsafe(v_protocol_param.value) +
|
||||
"&remarks=" + b64encutf8safe(v_alias.value);
|
||||
url = b64encsafe(ssr_str);
|
||||
} else if (v_type === "Trojan" || v_type === "Trojan-Go") {
|
||||
var v_password = opt.get("password");
|
||||
var v_server = opt.get("address");
|
||||
var v_port = opt.get("port");
|
||||
url = encodeURIComponent(v_password.value) +
|
||||
"@" + v_server.value +
|
||||
":" + v_port.value + "/?";
|
||||
if (opt.get("stream_security").value === "tls") {
|
||||
url += "tls=1";
|
||||
url += opt.query("sni", "tls_serverName");
|
||||
url += opt.query("allowinsecure", "tls_allowInsecure");
|
||||
} else if (v_type === "Trojan-Go") {
|
||||
url += "tls=0";
|
||||
}
|
||||
if (v_type === "Trojan-Go") {
|
||||
if (opt.get("stream_security").value === "none" && opt.get("trojan_transport").value === "original") {
|
||||
var plugin = {};
|
||||
plugin.type = opt.get("plugin_type").value;
|
||||
if (plugin.type !== "plaintext") {
|
||||
plugin.command = opt.get("plugin_cmd").value;
|
||||
plugin.option = opt.get("plugin_option").value;
|
||||
plugin.arg = opt.getlist("plugin_arg");
|
||||
}
|
||||
url += "&plugin=" + encodeURIComponent(JSON.stringify(plugin));
|
||||
}
|
||||
url += opt.query("type", "trojan_transport");
|
||||
var ws = (opt.get("trojan_transport").value.indexOf("ws") !== -1);
|
||||
var h2 = (opt.get("trojan_transport").value.indexOf("h2") !== -1);
|
||||
if (ws) {
|
||||
url += opt.query("host", "ws_host");
|
||||
url += opt.query("path", "ws_path");
|
||||
} else if (h2) {
|
||||
url += opt.query("host", "h2_host");
|
||||
url += opt.query("path", "h2_path");
|
||||
}
|
||||
var enc = "none";
|
||||
if (opt.get("ss_aead").checked === true) {
|
||||
enc = "ss;" +
|
||||
opt.get("ss_aead_method").value +
|
||||
":" + opt.get("ss_aead_pwd").value;
|
||||
}
|
||||
url += "&encryption=" + encodeURIComponent(enc);
|
||||
url += opt.query("mux", "mux");
|
||||
}
|
||||
url += "#" + encodeURI(v_alias.value);
|
||||
}
|
||||
if (url) {
|
||||
url = v_type.toLowerCase() + "://" + url;
|
||||
link_append_temp(url);
|
||||
var textarea = document.createElement("textarea");
|
||||
textarea.textContent = url;
|
||||
textarea.style.position = "fixed";
|
||||
document.body.appendChild(textarea);
|
||||
textarea.select();
|
||||
try {
|
||||
document.execCommand("copy"); // Security exception may be thrown by some browsers.
|
||||
s.innerHTML = "<font color='green'><%:Share to clipboard successfully, copy to batch mode still: %></font>";
|
||||
} catch (ex) {
|
||||
s.innerHTML = "<font color='red'><%:Unable share to clipboard, copy to batch mode still: %></font>";
|
||||
} finally {
|
||||
document.body.removeChild(textarea);
|
||||
}
|
||||
} else {
|
||||
alert("<%:Not a supported scheme:%> " + v_type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function fromUrl(btn, urlname, sid) {
|
||||
var opt = {
|
||||
base: 'cbid.passwall',
|
||||
fallback: 'dummy',
|
||||
get: function(opt) {
|
||||
var obj;
|
||||
var id = this.base + '.' + opt;
|
||||
obj = document.getElementsByName(id)[0] || document.getElementById(id);
|
||||
if (obj) {
|
||||
return obj;
|
||||
} else {
|
||||
alert('<%:Faltal on get option, please help in debug: %>' + opt);
|
||||
return document.getElementById(this.fallback);
|
||||
}
|
||||
},
|
||||
set: function(opt, val) {
|
||||
var obj;
|
||||
obj = this.get(opt)
|
||||
if (obj) {
|
||||
if (obj.type === 'checkbox') {
|
||||
var event = document.createEvent("HTMLEvents");
|
||||
event.initEvent("change", true, true);
|
||||
obj.checked = val;
|
||||
obj.dispatchEvent(event);
|
||||
} else {
|
||||
obj.value = val;
|
||||
}
|
||||
} else {
|
||||
alert('<%:Faltal on set option, please help in debug: %>' + opt + ' = ' + val);
|
||||
}
|
||||
},
|
||||
setlist: function(opt, vlist) {
|
||||
var id = this.base + "." + opt;
|
||||
var objs = document.getElementsByName(id) || document.getElementsByClassName(id);
|
||||
if (objs) {
|
||||
var values = "";
|
||||
for (var i = 0; i < vlist.length; i++) {
|
||||
values += vlist[i] + ", ";
|
||||
}
|
||||
alert("Manually input the option:\n" + opt + "s:\n[" + values + "]");
|
||||
} else {
|
||||
alert("<%:Faltal on set option, please help in debug: %>" + opt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var s = document.getElementById(urlname + '-status');
|
||||
if (!s) {
|
||||
alert("Never");
|
||||
return false;
|
||||
}
|
||||
opt.base = 'cbid.passwall.' + sid
|
||||
opt.fallback = urlname + '-dummy';
|
||||
var ssrurl = prompt('<%:Paste Share URL Here%>', '');
|
||||
if (ssrurl === null || ssrurl === "") {
|
||||
s.innerHTML = "<font color='red'><%:User cancelled%></font>";
|
||||
return false;
|
||||
}
|
||||
s.innerHTML = "";
|
||||
var ssu = ssrurl.split('://');
|
||||
var event = document.createEvent("HTMLEvents");
|
||||
event.initEvent("change", true, true);
|
||||
if (ssu[0] === "ssr") {
|
||||
//var b64c = ssu[1].match(/([A-Za-z0-9_-]+)/);
|
||||
var sstr = b64decsafe(ssu[1]);
|
||||
var ploc = sstr.indexOf("/?");
|
||||
var url0 = "", param = "";
|
||||
if (ploc > 0) {
|
||||
url0 = sstr.substr(0, ploc);
|
||||
param = sstr.substr(ploc + 2);
|
||||
}
|
||||
console.log(param);
|
||||
var ssm = url0.match(/^(.+):([^:]+):([^:]*):([^:]+):([^:]*):([^:]+)/);
|
||||
if (!ssm || ssm.length < 7) {
|
||||
s.innerHTML = "<font color='red'><%:Invalid Share URL Format%></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] || '');
|
||||
}
|
||||
}
|
||||
opt.set('type', "SSR");
|
||||
opt.get('type').dispatchEvent(event);
|
||||
opt.set('address', ssm[1]);
|
||||
opt.set('port', ssm[2]);
|
||||
opt.set('ssr_protocol', ssm[3]);
|
||||
opt.set('ssr_encrypt_method', ssm[4]);
|
||||
opt.set('obfs', ssm[5]);
|
||||
opt.set('password', b64decsafe(ssm[6]));
|
||||
opt.set('obfs_param', dictvalue(pdict, 'obfsparam'));
|
||||
opt.set('protocol_param', dictvalue(pdict, 'protoparam'));
|
||||
var rem = pdict['remarks'];
|
||||
if (typeof(rem) !== 'undefined' && rem !== '' && rem.length > 0)
|
||||
opt.set('remark', b64decutf8safe(rem));
|
||||
} 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];
|
||||
}
|
||||
console.log(param);
|
||||
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 userInfoSplitIndex = userInfo.indexOf(":");
|
||||
if (userInfoSplitIndex !== -1) {
|
||||
method = userInfo.substr(0, userInfoSplitIndex);
|
||||
password = userInfo.substr(userInfoSplitIndex + 1);
|
||||
}
|
||||
opt.set('type', "SS");
|
||||
opt.get('type').dispatchEvent(event);
|
||||
opt.set('address', server);
|
||||
opt.set('port', port);
|
||||
opt.set('password', password || "");
|
||||
opt.set('ss_encrypt_method', method || "");
|
||||
opt.set('ss_plugin', plugin || "");
|
||||
opt.set('ss_plugin_opts', pluginOpts || "");
|
||||
if (param !== undefined) {
|
||||
opt.set('remark', decodeURI(param));
|
||||
}
|
||||
} else {
|
||||
var sstr = b64decsafe(url0);
|
||||
var team = sstr.split('@');
|
||||
opt.set('type', "SS");
|
||||
opt.get('type').dispatchEvent(event);
|
||||
var part1 = team[0].split(':');
|
||||
var part2 = team[1].split(':');
|
||||
opt.set('address', part2[0]);
|
||||
opt.set('port', part2[1]);
|
||||
opt.set('password', part1[1]);
|
||||
opt.set('ss_encrypt_method', part1[0]);
|
||||
opt.set('ss_plugin', "");
|
||||
opt.set('ss_plugin_opts', "");
|
||||
if (param !== undefined) {
|
||||
opt.set('remark', decodeURI(param));
|
||||
}
|
||||
}
|
||||
} else if (ssu[0] === "trojan") {
|
||||
var stype = "Trojan";
|
||||
var m = parseNodeUrl(ssrurl);
|
||||
console.log(m.search);
|
||||
var password = m.passwd;
|
||||
if (password === "") {
|
||||
s.innerHTML = "<font color='red'><%:Invalid Share URL Format%></font>";
|
||||
return false;
|
||||
}
|
||||
var queryParam = {};
|
||||
if (m.search.length > 1) {
|
||||
var query = m.search.split('?');
|
||||
var queryParams = query[1];
|
||||
var queryArray = queryParams.split('&');
|
||||
var params;
|
||||
for (i = 0; i < queryArray.length; i++) {
|
||||
params = queryArray[i].split('=');
|
||||
queryParam[decodeURIComponent(params[0]).toLowerCase()] = decodeURIComponent(params[1] || '');
|
||||
}
|
||||
}
|
||||
if (queryParam.mux || queryParam.ws || queryParam.h2 || queryParam.ss || queryParam.plugin) {
|
||||
stype = "Trojan-Go";
|
||||
}
|
||||
opt.set('type', stype);
|
||||
opt.get('type').dispatchEvent(event);
|
||||
opt.set('address', m.hostname);
|
||||
opt.set('port', m.port || "443");
|
||||
opt.set('password', decodeURIComponent(password));
|
||||
var tls = true;
|
||||
if (stype === "Trojan-Go") {
|
||||
tls = queryParam.plugin === undefined;
|
||||
}
|
||||
if (tls === false) { alert("TODO: plugin params for trojan-go."); }
|
||||
opt.set('stream_security', tls ? "tls" : "none");
|
||||
opt.get('stream_security').dispatchEvent(event);
|
||||
if (tls) {
|
||||
opt.set('tls_serverName', queryParam.peer || queryParam.sni || '');
|
||||
opt.set('tls_allowInsecure', queryParam.allowinsecure === '1');
|
||||
}
|
||||
var tran = 'original';
|
||||
var ws = queryParam.type.indexOf('ws') !== -1;
|
||||
var h2 = queryParam.type.indexOf('h2') !== -1;
|
||||
if (ws && h2) {
|
||||
tran = 'h2+ws'
|
||||
} else {
|
||||
if (ws) tran = 'ws';
|
||||
if (h2) tran = 'h2';
|
||||
}
|
||||
opt.set('trojan_transport', 'tran');
|
||||
opt.get('trojan_transport').dispatchEvent(event);
|
||||
if (ws) {
|
||||
opt.set('ws_host', queryParam.wshost || '');
|
||||
opt.set('ws_path', queryParam.wspath || '/');
|
||||
}
|
||||
if (h2) {
|
||||
opt.set('h2_host', queryParam.h2host || '');
|
||||
opt.set('h2_path', queryParam.h2path || '/');
|
||||
}
|
||||
var ss = queryParam.ss === '1';
|
||||
opt.set('ss_aead', ss);
|
||||
if (ss) {
|
||||
opt.set('ss_aead_method', queryParam.ssmethod.toUpperCase() || '');
|
||||
opt.set('ss_aead_pwd', queryParam.sspasswd || '');
|
||||
}
|
||||
opt.set('mux', queryParam.mux === '1');
|
||||
if (m.hash) {
|
||||
opt.set('remark', decodeURI(m.hash.substr(1)));
|
||||
}
|
||||
} else if (ssu[0] === "trojan-go") {
|
||||
var m = parseNodeUrl(ssrurl);
|
||||
console.log(m.search);
|
||||
var password = m.passwd;
|
||||
if (password === "") {
|
||||
s.innerHTML = "<font color='red'><%:Invalid Share URL Format%></font>";
|
||||
return false;
|
||||
}
|
||||
var queryParam = {};
|
||||
if (m.search.length > 1) {
|
||||
var query = m.search.split('?');
|
||||
var queryParams = query[1];
|
||||
var queryArray = queryParams.split('&');
|
||||
for (i = 0; i < queryArray.length; i++) {
|
||||
var params = queryArray[i].split('=');
|
||||
queryParam[decodeURIComponent(params[0]).toLowerCase()] = decodeURIComponent(params[1] || '');
|
||||
}
|
||||
}
|
||||
opt.set('type', 'Trojan-Go');
|
||||
opt.get('type').dispatchEvent(event);
|
||||
opt.set('address', m.hostname);
|
||||
opt.set('port', m.port || "443");
|
||||
opt.set('password', decodeURIComponent(password));
|
||||
opt.set('stream_security', (queryParam.tls && queryParam.tls === '1') ? 'tls' : 'none');
|
||||
opt.get('stream_security').dispatchEvent(event);
|
||||
var plugin = queryParam.plugin !== undefined;
|
||||
if (plugin) {
|
||||
opt.set('trojan_transport', 'original');
|
||||
opt.get('trojan_transport').dispatchEvent(event);
|
||||
var plugin = JSON.parse(queryParam.plugin);
|
||||
if (plugin) {
|
||||
opt.set('plugin_type', plugin.type);
|
||||
opt.get('plugin_type').dispatchEvent(event);
|
||||
if (plugin.type !== "plaintext") {
|
||||
opt.set('plugin_cmd', plugin.command);
|
||||
opt.set('plugin_option', plugin.option);
|
||||
opt.setlist('plugin_arg', plugin.arg);
|
||||
}
|
||||
} else
|
||||
alert(queryParam.plugin);
|
||||
}
|
||||
var tls = !plugin && queryParam.tls === '1';
|
||||
opt.set('stream_security', tls ? "tls" : "none");
|
||||
opt.get('stream_security').dispatchEvent(event);
|
||||
if (tls) {
|
||||
opt.set('tls_serverName', queryParam.peer || queryParam.sni || '');
|
||||
opt.set('tls_allowInsecure', queryParam.allowinsecure === '1');
|
||||
}
|
||||
var tran = 'original';
|
||||
var or = queryParam.type === undefined || queryParam.type === 'original';
|
||||
var ws = queryParam.type.indexOf('ws') !== -1;
|
||||
var h2 = queryParam.type.indexOf('h2') !== -1;
|
||||
if (ws && h2) {
|
||||
tran = 'h2+ws'
|
||||
} else {
|
||||
if (ws) tran = 'ws';
|
||||
if (h2) tran = 'h2';
|
||||
}
|
||||
opt.set('trojan_transport', tran);
|
||||
opt.get('trojan_transport').dispatchEvent(event);
|
||||
if (ws) {
|
||||
opt.set('ws_host', queryParam.host || '');
|
||||
opt.set('ws_path', queryParam.path || '/');
|
||||
}
|
||||
if (h2){
|
||||
opt.set('h2_host', queryParam.host || '');
|
||||
opt.set('h2_path', queryParam.path || '/');
|
||||
}
|
||||
var enc = {};
|
||||
var ss = false;
|
||||
if (queryParam.encryption) {
|
||||
var r = queryParam.encryption.match(/^(ss);([^;:]*)[;:](.*)$/),
|
||||
enc = {type: r[1], method: r[2], password: r[3]};
|
||||
}
|
||||
ss = enc.type === 'ss';
|
||||
opt.set('ss_aead', ss);
|
||||
if (ss) {
|
||||
opt.set('ss_aead_method', enc.method.toUpperCase() || '');
|
||||
opt.set('ss_aead_pwd', enc.password || '');
|
||||
}
|
||||
opt.set('mux', queryParam.mux === '1');
|
||||
if (m.hash) {
|
||||
opt.set('remark', decodeURI(m.hash));
|
||||
}
|
||||
} else if (ssu[0] === "vmess") {
|
||||
var sstr = b64DecodeUnicode(ssu[1]);
|
||||
var ploc = sstr.indexOf("/?");
|
||||
opt.set('type', "V2ray");
|
||||
opt.get('type').dispatchEvent(event);
|
||||
var url0, param = "";
|
||||
if (ploc > 0) {
|
||||
url0 = sstr.substr(0, ploc);
|
||||
param = sstr.substr(ploc + 2);
|
||||
}
|
||||
var ssm = JSON.parse(sstr);
|
||||
opt.set('remark', ssm.ps);
|
||||
opt.set('address', ssm.add);
|
||||
opt.set('port', ssm.port);
|
||||
opt.set('alter_id', ssm.aid);
|
||||
opt.set('vmess_id', ssm.id);
|
||||
opt.set('stream_security', ssm.tls === "tls" ? "tls" : "none");
|
||||
opt.get('stream_security').dispatchEvent(event);
|
||||
if (ssm.tls === "tls") {
|
||||
opt.set('tls_serverName', ssm.host);
|
||||
}
|
||||
opt.set('transport', ssm.net);
|
||||
opt.get('transport').dispatchEvent(event);
|
||||
if (ssm.net === "tcp") {
|
||||
opt.set('tcp_guise', (ssm.host && ssm.path) ? "http" : "none");
|
||||
opt.get('tcp_guise').dispatchEvent(event);
|
||||
if (ssm.host && ssm.path) {
|
||||
opt.set('tcp_guise_http_host', ssm.host);
|
||||
opt.set('tcp_guise_http_path', ssm.path);
|
||||
}
|
||||
} else if (ssm.net === "ws") {
|
||||
opt.set('ws_host', ssm.host);
|
||||
opt.set('ws_path', ssm.path);
|
||||
} else if (ssm.net === "h2") {
|
||||
opt.set('h2_host', ssm.host);
|
||||
opt.set('h2_path', ssm.path);
|
||||
} else if (ssm.net === "quic") {
|
||||
opt.set('quic_security', ssm.securty);
|
||||
opt.set('quic_key', ssm.key);
|
||||
} else if (ssm.net === "kcp") {
|
||||
opt.set('mkcp_guise', ssm.type);
|
||||
opt.get('mkcp_guise').dispatchEvent(event);
|
||||
}
|
||||
} else {
|
||||
s.innerHTML = "<font color='red'><%:Invalid Share URL Format%></font>: " + ssu[0];
|
||||
return false;
|
||||
}
|
||||
s.innerHTML = "<font color='green'><%:Import Finished %></font>";
|
||||
return false;
|
||||
}
|
||||
|
||||
//]]></script>
|
||||
<input type="test" class="hidden" id='<%=self.option%>-dummy' value="-dummy-" />
|
||||
<input type="button" class="cbi-button cbi-button-apply" value='<%:From Share URL%>' onclick="return fromUrl(this, '<%=self.option%>', '<%=self.value%>')" />
|
||||
<input type="button" class="cbi-button cbi-button-apply" value='<%:Build Share URL%>' onclick="return buildUrl(this, '<%=self.option%>', '<%=self.value%>')" />
|
||||
<span id="<%=self.option%>-status"></span>
|
||||
<%+cbi/valuefooter%>
|
||||
@ -370,6 +370,42 @@ msgstr "负载均衡节点列表"
|
||||
msgid "Load balancing node list, <a target='_blank' href='https://toutyrater.github.io/routing/balance2.html'>document</a>"
|
||||
msgstr "负载均衡节点列表,<a target='_blank' href='https://toutyrater.github.io/routing/balance2.html'>文档原理</a>"
|
||||
|
||||
msgid "Share Current"
|
||||
msgstr "所见即所得"
|
||||
|
||||
msgid "From Share URL"
|
||||
msgstr "导入配置信息"
|
||||
|
||||
msgid "Build Share URL"
|
||||
msgstr "导出配置信息"
|
||||
|
||||
msgid "Import Finished"
|
||||
msgstr "导入完成:"
|
||||
|
||||
msgid "Not a supported scheme:"
|
||||
msgstr "不支持这种样式的:"
|
||||
|
||||
msgid "Invalid Share URL Format"
|
||||
msgstr "无效的分享信息"
|
||||
|
||||
msgid "User cancelled"
|
||||
msgstr "用户已取消"
|
||||
|
||||
msgid "Paste Share URL Here"
|
||||
msgstr "在此处粘贴分享信息"
|
||||
|
||||
msgid "Unable share to clipboard, copy to batch mode still:"
|
||||
msgstr "无法分享网址到剪贴板,复制到批量导入临时输入:"
|
||||
|
||||
msgid "Share to clipboard successfully, copy to batch mode still:"
|
||||
msgstr "成功复制分享网址到剪贴板和批量导入临时输入:"
|
||||
|
||||
msgid "Faltal on get option, please help in debug:"
|
||||
msgstr "代码错误,请协助捉虫:"
|
||||
|
||||
msgid "Faltal on set option, please help in debug:"
|
||||
msgstr "代码错误,请协助捉虫:"
|
||||
|
||||
msgid "Address"
|
||||
msgstr "地址"
|
||||
|
||||
@ -386,7 +422,7 @@ msgid "Finger Print"
|
||||
msgstr "指纹伪造"
|
||||
|
||||
msgid "Shadowsocks2"
|
||||
msgstr "双重加密"
|
||||
msgstr "二次加密"
|
||||
|
||||
msgid "Encrypt Method"
|
||||
msgstr "加密"
|
||||
|
||||
@ -6,12 +6,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=trojan-go
|
||||
PKG_VERSION:=0.7.8
|
||||
PKG_VERSION:=0.8.1
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/p4gefau1t/trojan-go.git
|
||||
PKG_SOURCE_VERSION:=9866c030058870bf18d60f1d3677c6d4ed9de35d
|
||||
PKG_SOURCE_VERSION:=c010e7dda15142a633f43ce74bf8a822f37cd84f
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user