Merge Mainline

This commit is contained in:
CN_SZTL 2020-07-20 00:06:48 +08:00
commit ab3b31991a
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
50 changed files with 16258 additions and 10858 deletions

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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")

View File

@ -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'

View File

@ -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();

View File

@ -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

View 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

View 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

View File

@ -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
---

View 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>

View 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 "这是一款支持在ssd13060.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 "屏保"

View 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 "這是壹款支持在ssd13060.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 "屏保"

View 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'

View 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
}

View 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

View 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

View 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();
}
}
}
}

View 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);
}
}

View 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);

View 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;
}

View 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_ */

View 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.

View 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

View 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 :)

File diff suppressed because it is too large Load Diff

View File

@ -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_ */

View File

@ -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_

View File

@ -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
}

View File

@ -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

View File

@ -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
}

View File

@ -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 \

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 "流量分载"

View File

@ -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)

View File

@ -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

View File

@ -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 = {

View File

@ -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")
--]]

View File

@ -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",

View File

@ -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
}
}
},
-- 传出连接

View File

@ -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

View File

@ -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>

View File

@ -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%>

View File

@ -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 "加密"

View File

@ -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)