luci-app-jd-dailybonus: bump version

This commit is contained in:
lean 2021-01-22 11:27:27 +08:00
parent f15b61b9b8
commit 95dfd326ad
13 changed files with 922 additions and 477 deletions

View File

@ -7,8 +7,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-jd-dailybonus
LUCI_PKGARCH:=all
PKG_VERSION:=0.8.9
PKG_RELEASE:=20201230
PKG_VERSION:=1.0.0
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk

View File

@ -1,82 +1,112 @@
-- Copyright (C) 2020 jerrykuku <jerrykuku@gmail.com>
-- Licensed to the public under the GNU General Public License v3.
module("luci.controller.jd-dailybonus", package.seeall)
function index()
if not nixio.fs.access("/etc/config/jd-dailybonus") then
return
module('luci.controller.jd-dailybonus', package.seeall)
package.path = package.path .. ';/usr/share/jd-dailybonus/?.lua'
function index()
if not nixio.fs.access('/etc/config/jd-dailybonus') then
return
end
entry({"admin", "services", "jd-dailybonus"}, alias("admin", "services", "jd-dailybonus", "client"), _("JD-DailyBonus"), 10).dependent = true -- 首页
entry({"admin", "services", "jd-dailybonus", "client"}, cbi("jd-dailybonus/client"),_("Client"), 10).leaf = true -- 基本设置
entry({"admin", "services", "jd-dailybonus", "log"},form("jd-dailybonus/log"),_("Log"), 30).leaf = true -- 日志页面
entry({"admin", "services", "jd-dailybonus", "script"},form("jd-dailybonus/script"),_("Script"), 20).leaf = true -- 直接配置脚本
entry({"admin", "services", "jd-dailybonus", "run"}, call("run")) -- 执行程序
entry({"admin", "services", "jd-dailybonus", "update"}, call("update")) -- 执行更新
entry({"admin", "services", "jd-dailybonus", "check_update"}, call("check_update")) -- 检查更新
entry({'admin', 'services', 'jd-dailybonus'}, alias('admin', 'services', 'jd-dailybonus', 'client'), _('京东签到服务'), 10).dependent = true -- 首页
entry({'admin', 'services', 'jd-dailybonus', 'client'}, cbi('jd-dailybonus/client', {hidesavebtn = true, hideresetbtn = true}), _('客户端'), 10).leaf = true -- 基本设置
entry({'admin', 'services', 'jd-dailybonus', 'log'}, form('jd-dailybonus/log'), _('日志'), 30).leaf = true -- 日志页面
entry({'admin', 'services', 'jd-dailybonus', 'script'}, form('jd-dailybonus/script'), _('脚本查看'), 20).leaf = true -- 直接配置脚本
entry({'admin', 'services', 'jd-dailybonus', 'run'}, call('run')) -- 执行程序
entry({'admin', 'services', 'jd-dailybonus', 'update'}, call('update')) -- 执行更新
entry({'admin', 'services', 'jd-dailybonus', 'check_update'}, call('check_update')) -- 检查更新
entry({'admin', 'services', 'jd-dailybonus', 'qrcode'}, call('qrcode')) -- 获取二维码
entry({'admin', 'services', 'jd-dailybonus', 'check_login'}, call('check_login')) -- 获取二维码
end
-- 写入配置
function write_json(file, content)
local json = require 'luci.jsonc'
local f = assert(io.open(file, 'w'))
f:write(json.stringify(content, 1))
f:close()
end
-- 执行程序
function run()
local e = {}
local uci = luci.model.uci.cursor()
local cookie = luci.http.formvalue("cookies")
local cookie2 = luci.http.formvalue("cookies2")
local auto_update = luci.http.formvalue("auto_update")
local auto_update_time = luci.http.formvalue("auto_update_time")
local auto_run = luci.http.formvalue("auto_run")
local auto_run_time = luci.http.formvalue("auto_run_time")
local stop = luci.http.formvalue("stop")
local serverchan = luci.http.formvalue("serverchan")
local failed = luci.http.formvalue("failed")
local name = ""
uci:foreach("vssr", "global", function(s) name = s[".name"] end)
local data = luci.http.formvalue()
if cookie ~= " " then
uci:set("jd-dailybonus", '@global[0]', 'auto_update', auto_update)
uci:set("jd-dailybonus", '@global[0]', 'auto_update_time', auto_update_time)
uci:set("jd-dailybonus", '@global[0]', 'auto_run', auto_run)
uci:set("jd-dailybonus", '@global[0]', 'auto_run_time', auto_run_time)
uci:set("jd-dailybonus", '@global[0]', 'stop', stop)
uci:set("jd-dailybonus", '@global[0]', 'cookie', cookie)
uci:set("jd-dailybonus", '@global[0]', 'cookie2', cookie2)
uci:set("jd-dailybonus", '@global[0]', 'serverchan', serverchan)
uci:set("jd-dailybonus", '@global[0]', 'failed', failed)
uci:save("jd-dailybonus")
uci:commit("jd-dailybonus")
luci.sys.call("/usr/share/jd-dailybonus/newapp.sh -r")
luci.sys.call("/usr/share/jd-dailybonus/newapp.sh -a")
e.error = 0
else
e.error = 1
end
data.auto_run = data.auto_run ~= nil and data.auto_run or 0
data.auto_update = data.auto_update ~= nil and data.auto_update or 0
uci:tset('jd-dailybonus', '@global[0]', data)
uci:commit('jd-dailybonus')
local json_data = {
CookieJD = data.cookie,
CookieJD2 = data.cookie2:len() == 0 and nil or data.cookie2,
JD_DailyBonusDelay = data.stop,
JD_DailyBonusTimeOut = data.out
}
write_json('/root/CookieSet.json', json_data)
write_json('/www/CookieSet.json', json_data)
luci.sys.call('/usr/share/jd-dailybonus/newapp.sh -r')
luci.sys.call('/usr/share/jd-dailybonus/newapp.sh -a')
e.error = 0
luci.http.prepare_content("application/json")
luci.http.prepare_content('application/json')
luci.http.write_json(e)
end
--检查更新
function check_update()
local jd = "jd-dailybonus"
local jd = 'jd-dailybonus'
local e = {}
local new_version = luci.sys.exec("/usr/share/jd-dailybonus/newapp.sh -n")
local new_version = luci.sys.exec('/usr/share/jd-dailybonus/newapp.sh -n')
e.new_version = new_version
e.error = 0
luci.http.prepare_content("application/json")
luci.http.prepare_content('application/json')
luci.http.write_json(e)
end
--执行更新
function update()
local jd = "jd-dailybonus"
local jd = 'jd-dailybonus'
local e = {}
local uci = luci.model.uci.cursor()
local version = luci.http.formvalue("version")
local version = luci.http.formvalue('version')
--下载脚本
local code = luci.sys.exec("/usr/share/jd-dailybonus/newapp.sh -u")
local code = luci.sys.exec('/usr/share/jd-dailybonus/newapp.sh -u')
e.error = code
luci.http.prepare_content("application/json")
luci.http.prepare_content('application/json')
luci.http.write_json(e)
end
end
--获取二维码
function qrcode()
local jd_cookie = require 'jd_cookie'
local e = {}
e.error = 0
e.data = jd_cookie.get_qrcode()
luci.http.prepare_content('application/json')
luci.http.write_json(e)
end
--检测登录
function check_login()
local jd_cookie = require 'jd_cookie'
local uci = luci.model.uci.cursor()
local data = luci.http.formvalue()
local id = data.id
local e = jd_cookie.checkLogin(data.check_url, data.cookies)
if e.error == 0 then
local cookieStr = 'pt_key=' .. e.cookie.pt_key .. ';pt_pin=' .. e.cookie.pt_pin .. ';'
uci:set('jd-dailybonus', '@global[0]', id, cookieStr)
local json_data = {
CookieJD = uci:get('jd-dailybonus', '@global[0]', 'cookie'),
CookieJD2 = uci:get('jd-dailybonus', '@global[0]', 'cookie2'),
JD_DailyBonusDelay = uci:get('jd-dailybonus', '@global[0]', 'stop'),
JD_DailyBonusTimeOut = uci:get('jd-dailybonus', '@global[0]', 'out')
}
write_json('/root/CookieSet.json', json_data)
write_json('/www/CookieSet.json', json_data)
uci:commit('jd-dailybonus')
e.cstr = cookieStr
end
luci.http.prepare_content('application/json')
luci.http.write_json(e)
end

View File

@ -1,75 +1,100 @@
local jd = "jd-dailybonus"
local jd = 'jd-dailybonus'
local uci = luci.model.uci.cursor()
local sys = require "luci.sys"
local sys = require 'luci.sys'
m = Map(jd)
-- [[ 基本设置 ]]--
s = m:section(TypedSection, "global",
translate("Base Config"))
s = m:section(TypedSection, 'global', translate('基本设置'))
s.anonymous = true
o = s:option(DummyValue, "", "")
o = s:option(DummyValue, '', '')
o.rawhtml = true
o.template = "jd-dailybonus/cookie_tools"
o.template = 'jd-dailybonus/cookie_tools'
o = s:option(ListValue, "remote_url", translate("Source Update Url"))
o:value("https://cdn.jsdelivr.net/gh/NobyDa/Script/JD-DailyBonus/JD_DailyBonus.js", translate("GitHub"))
o:value("https://gitee.com/jerrykuku/staff/raw/master/JD_DailyBonus.js", translate("Gitee"))
o.default = "nil"
o.rmempty = false
o.description = translate('当GitHub源无法更新时,可以选择使用国内Gitee源')
o = s:option(Value, "cookie", translate("First Cookie"))
o = s:option(Value, 'cookie', translate('第一账号Cookie'))
o.rmempty = false
o = s:option(Value, "cookie2", translate("Second Cookie"))
o = s:option(Value, 'cookie2', translate('第二账号Cookie'))
o.rmempty = true
o.description = translate('双账号用户抓取"账号1"Cookie后, 请勿点击退出账号(可能会导致Cookie失效), 需清除浏览器资料或更换浏览器登录"账号2"抓取.')
o = s:option(Value, "stop", translate("Execute Delay"))
o = s:option(Value, 'stop', translate('延迟签到'))
o.rmempty = false
o.default = 0
o.datatype = integer
o.description = translate("自定义延迟签到,单位毫秒. 默认分批并发无延迟. (延迟作用于每个签到接口, 如填入延迟则切换顺序签到. ) ")
o.description = translate('自定义延迟签到,单位毫秒. 默认分批并发无延迟. (延迟作用于每个签到接口, 如填入延迟则切换顺序签到. ) ')
o = s:option(ListValue, "serverurl", translate("ServerURL"))
o:value("scu", translate("SCU"))
o:value("sct", translate("SCT"))
o.default = "scu"
o = s:option(Value, 'out', translate('接口超时'))
o.rmempty = false
o.default = 0
o.datatype = integer
o.description = translate('接口超时退出,单位毫秒 用于可能发生的网络不稳定, 0则关闭.')
-- server chan
o = s:option(ListValue, 'serverurl', translate('Server酱的推送接口地址'))
o:value('scu', translate('SCU'))
o:value('sct', translate('SCT'))
o.default = 'scu'
o.rmempty = false
o.description = translate('选择Server酱的推送接口')
o = s:option(Value, "serverchan", translate("ServerChan SCKEY"))
o = s:option(Value, 'serverchan', translate('Server酱 SCKEY'))
o.rmempty = true
o.description = translate("微信推送基于Server酱服务请自行登录 http://sc.ftqq.com/ 绑定并获取 SCKEY (仅在自动签到时推送)")
o.description = translate('微信推送基于Server酱服务请自行登录 http://sc.ftqq.com/ 绑定并获取 SCKEY。')
o = s:option(Flag, "failed", translate("Failed Push"))
-- telegram
o = s:option(Value, 'tg_token', translate('Telegram Bot Token'))
o.rmempty = true
o.description = translate('首先在Telegram上搜索BotFather机器人创建一个属于自己的通知机器人并获取Token。')
o = s:option(Value, 'tg_userid', translate('Telegram UserID'))
o.rmempty = true
o.description = translate('在Telegram上搜索getuserIDbot机器人获取UserID。')
--Auto Run Script Service
o = s:option(Flag, 'auto_run', translate('自动签到'))
o.rmempty = false
o.description = translate("仅当cookie失效时推送")
o = s:option(Flag, "auto_update", translate("Auto Update"))
o.rmempty = false
o.description = translate("Auto Update Script Service")
o =s:option(ListValue, "auto_update_time", translate("Update time (every day)"))
for t = 0, 23 do o:value(t, t .. ":01") end
o = s:option(ListValue, 'auto_run_time_h', translate('每天签到时间(小时)'))
for t = 0, 23 do
o:value(t, t)
end
o.default = 1
o.rmempty = true
o:depends("auto_update", "1")
o = s:option(Flag, "auto_run", translate("Auto Run"))
o.rmempty = false
o.description = translate("Auto Run Script Service")
o =s:option(ListValue, "auto_run_time", translate("Run time (every day)"))
for t = 0, 23 do o:value(t, t .. ":05") end
o:depends('auto_run', '1')
o = s:option(ListValue, 'auto_run_time_m', translate('每天签到时间(分钟)'))
for t = 0, 59 do
o:value(t, t)
end
o.default = 1
o.rmempty = true
o:depends("auto_run", "1")
o:depends('auto_run', '1')
o = s:option(DummyValue, "", "")
-- Auto Update Script Service
o = s:option(Flag, 'auto_update', translate('自动更新'))
o.rmempty = false
o = s:option(ListValue, 'auto_update_time', translate('每天更新时间'))
for t = 0, 23 do
o:value(t, t .. ':01')
end
o.default = 1
o.rmempty = true
o:depends('auto_update', '1')
o = s:option(ListValue, 'remote_url', translate('更新源地址'))
o:value('https://raw.githubusercontent.com/NobyDa/Script/master/JD-DailyBonus/JD_DailyBonus.js', translate('GitHub'))
o:value('https://gitee.com/jerrykuku/staff/raw/master/JD_DailyBonus.js', translate('Gitee'))
o.default = 'nil'
o.rmempty = false
o.description = translate('当GitHub源无法更新时,可以选择使用国内Gitee源')
o = s:option(DummyValue, '', '')
o.rawhtml = true
o.version = sys.exec('uci get jd-dailybonus.@global[0].version')
o.template = "jd-dailybonus/update_service"
o.template = 'jd-dailybonus/update_service'
return m

View File

@ -1,25 +1,13 @@
<%+cbi/valueheader%>
<label class="cbi-value-title"><%= translate("Cookie Tools") %></label>
<label class="cbi-value-title"><%= translate("获取Cookie") %></label>
<div class="cbi-value-field">
<input type="button" class="cbi-button cbi-input-reload" value="<%= translate('JDCookie Tools') %>" onclick="javascript:window.open('/jd-dailybonus/JDCookie.zip','target');" />
<input type="button" data-rel="1" class="cbi-button cbi-input-reload cookie-button" value="<%= translate('获取第一Cookie') %>" />
<input type="button" data-rel="2" class="cbi-button cbi-input-reload cookie-button" value="<%= translate('获取第二Cookie') %>" />
<br>
<div class="cbi-value-description">
<span class="cbi-value-helpicon"><img src="/luci-static/resources/cbi/help.gif" alt="帮助"></span>
<%= translate("Click to download the JDCookie.zip,unzip it,and use load Unpacked extensions to install.link:[chrome://extensions/]")%>
</div>
</div>
<%+cbi/valuefooter%>
<%+cbi/valueheader%>
<label class="cbi-value-title"><%= translate("JD Url") %></label>
<div class="cbi-value-field">
<input type="button" class="cbi-button cbi-input-reload" value="bean.m.jd.com" onclick="javascript:window.open('https://bean.m.jd.com','target');" />
<br>
<div class="cbi-value-description">
<span class="cbi-value-helpicon"><img src="/luci-static/resources/cbi/help.gif" alt="帮助"></span>
<%= translate("Sign in ,then click JDCookie button.you will copy JD cookies, paste the cookie below.")%>
<%= translate("点击上面按钮使用京东手机app扫码获取Cookie")%>
</div>
</div>

View File

@ -1,5 +1,9 @@
<%+cbi/valueheader%>
<script src="/jd-dailybonus/jquery.min.js"></script>
<script src="/jd-dailybonus/qrcode.min.js"></script>
<script type="text/javascript">
var jq=$.noConflict();
</script>
<style>
.modals-bg {
position: fixed;
@ -9,7 +13,8 @@
left: 0;
top: 0;
background: rgba(255, 255, 255, 0.8);
display: none;
transition: all 0.3s ease-in-out;
transform: scale(1);
}
.modals {
@ -29,7 +34,22 @@
/* Firefox */
-webkit-box-sizing: border-box;
/* Safari */
transition: all 0.3s ease-in-out;
transform: scale(1);
}
.modals-bg.hide {
visibility: hidden;
opacity: 0;
}
.modals.hide {
visibility: hidden;
opacity: 0;
transform: scale(0.5);
}
.modals h2 {
color: #fff;
@ -72,6 +92,70 @@
text-align: left;
display: table-cell;
}
#qrcontainer {
position: fixed;
width: 100%;
height: 100%;
left: 0;
top: 0;
z-index: 5000;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, .8);
text-align: center;
transition: all 0.3s;
}
#qrcontainer.hidden{
opacity: 0;
visibility: hidden;
}
#qrcontainer .qframe {
background-color: #ffffff;
padding: 1rem;
border-radius: 0.5rem;
border: #6D8A88 1px solid;
-webkit-box-shadow: 0px 0px 7px 3px rgba(0, 0, 0, 0.2);
box-shadow: 0px 0px 7px 3px rgba(0, 0, 0, 0.2);
position: relative;
}
#qrcontainer .qframe #refresh_qrcode{
width: 256px;
height: 256px;
position: absolute;
background-color: rgba(0, 0, 0, 0.5);
left: 1rem;
top: 1rem;
color: #ffffff;
display: flex;
justify-content: center;
align-items: center;
}
#qrcontainer .qframe #refresh_qrcode.hidden{
opacity: 0;
visibility: hidden;
}
#qrcontainer .qframe #refresh_qrcode h3{
font-weight: normal;
}
#qrcontainer .qframe #refresh_qrcode .refresh{
display: block;
background: #e4393c;
width: 80px;
height: 30px;
margin: 0 auto;
line-height: 30px;
opacity: 1;
z-index: 19;
color: #fbfbfb;
text-decoration: none;
cursor: pointer;
}
#qrcontainer .qframe .info {
padding: 1rem 0 0 0;
}
@media screen and (max-width: 1024px) {
.modals {
@ -104,48 +188,54 @@
}
</style>
<label class="cbi-value-title"><%= translate("Run") %></label>
<label class="cbi-value-title"><%= translate("执行") %></label>
<div class="cbi-value-field">
<input class="cbi-button cbi-button-reload" id="update_service" type="button" size="0"
value="<%= translate("Save Cookies And Run Service") %>">
value="<%= translate("保存Cookie,并马上进行签到") %>">
</div>
<%+cbi/valuefooter%>
<%+cbi/valueheader%>
<label class="cbi-value-title"><%= translate("Current Script Version") %></label>
<div class="cbi-value-field">
<div class="cbi-value-version">
v<%=self.version%>
</div>
</div>
<%+cbi/valuefooter%>
<%+cbi/valueheader%>
<label class="cbi-value-title"><%= translate("Update Script") %></label>
<label class="cbi-value-title"><%= translate("更新脚本") %></label>
<div class="cbi-value-field">
<input class="cbi-button cbi-button-reload" id="update_script" type="button" size="0"
value="<%= translate("Check Script Version") %>">
value="<%= translate("手动检查脚本更新当前版本v")..self.version %>">
</div>
<%+cbi/valuefooter%>
<div id="qrcontainer" class="hidden">
<div class="qframe">
<div id="refresh_qrcode" class="hidden">
<div>
<h3>二维码已失效</h3>
<div class="refresh">刷新</div>
</div>
</div>
<div id="qrcode"></div>
<div class="info">请使用京东手机APP扫码</div>
</div>
</div>
<script type="text/javascript">
const SAVE_URL = '<%=luci.dispatcher.build_url("admin", "services", "jd-dailybonus","run")%>';
const CHECK_URL = '<%=luci.dispatcher.build_url("admin", "services", "jd-dailybonus","check_update")%>';
const QRCODE_URL = '<%=luci.dispatcher.build_url("admin", "services", "jd-dailybonus","qrcode")%>';
const CHECK_LOGIN_URL = '<%=luci.dispatcher.build_url("admin", "services", "jd-dailybonus","check_login")%>';
const UPDATE_URL = '<%=luci.dispatcher.build_url("admin", "services", "jd-dailybonus","update")%>';
const CHECKING_TEXT = '<%= translate("Checking the New Version ...") %>';
const UPDATING_TEXT = '<%= translate("Updating script,please wait ...") %>';
const NEW_VERSION = '<%= translate("Is currently the latest version") %>';
const UPDATE_TEXT = '<%= translate("There is a new version, click to update") %>';
const CHECKING_TEXT = '<%= translate("正在检查是否存在新的版本 ...") %>';
const UPDATING_TEXT = '<%= translate("正在更新脚本,请稍候 ...") %>';
const NEW_VERSION = '<%= translate("当前已是最新版本。") %>';
const UPDATE_TEXT = '<%= translate("有新的版本,请点击更新") %>';
var needUpdate = false;
var newVersion;
var _responseLen;
var noChange = 0;
var modal = '<div class="modals-bg">' +
'<div class="modals">' +
var ckid = 0;
var modal = '<div class="modals-bg hide">' +
'<div class="modals hide">' +
'<h2><%:Sign in info%></h2>' +
'<h3 style="margin-left:0;"><%:Service is running,Please do not refresh!%></h3>' +
'<textarea cols="63" rows="28" wrap="on" readonly="readonly" id="log_content3" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"></textarea>' +
@ -154,52 +244,38 @@
//显示并开始刷新订阅
function update_service() {
$("body").append(modal);
$(".modals-bg").show();
setTimeout("get_realtime_log();", 500);
jq("body").append(modal);
jq(".modals-bg").removeClass("hide");
setTimeout(function(){
jq(".modals").removeClass("hide");
}, 100);
setTimeout("get_realtime_log();", 500);
}
//保存订阅按钮
$("#update_service").click(function () {
prefix_array = $("#cbi-jd-dailybonus-global .cbi-section-node").attr("id").split("-");
prefix = prefix_array[prefix_array.length - 1];
//console.log(prefix);
if ($("[name='cbid.jd-dailybonus." + prefix + ".auto_update']").is(":checked")) {
var auto_update = "1";
var auto_update_time = $("[name='cbid.jd-dailybonus." + prefix + ".auto_update_time']").val();
} else {
var auto_update = "0";
var auto_update_time = "0";
}
if ($("[name='cbid.jd-dailybonus." + prefix + ".auto_run']").is(":checked")) {
var auto_run = "1";
var auto_run_time = $("[name='cbid.jd-dailybonus." + prefix + ".auto_run_time']").val();
} else {
var auto_run = "0";
var auto_run_time = "0";
}
var stop = $("[name='cbid.jd-dailybonus." + prefix + ".stop']").val();
var cookies = $("[name='cbid.jd-dailybonus." + prefix + ".cookie']").val();
var cookies2 = $("[name='cbid.jd-dailybonus." + prefix + ".cookie2']").val();
var failed=($("[name='cbid.jd-dailybonus." + prefix + ".failed']").is(":checked"))?"1":"0";
var serverchan = $("[name='cbid.jd-dailybonus." + prefix + ".serverchan']").val();
var data = {
auto_update: auto_update,
auto_update_time: auto_update_time,
auto_run: auto_run,
auto_run_time: auto_run_time,
cookies: cookies,
cookies2: cookies2,
stop: stop,
serverchan: serverchan,
failed: failed
}
//console.log(data);
$.ajax({
jq("#update_service").click(function () {
let prefix_array = jq(".cbi-input-text").eq(0).attr("id").split(".");
prefix_array.pop()
var prefix = prefix_array.join(".")+".";
let array = jq("form[name*='cbi'").serializeArray()
var json = {};
jq.each(array, function () {
if(this.name.indexOf(prefix) != -1){
let aname = this.name.replace(prefix, "");
if (json[aname]) {
if (!json[aname].push) {
json[aname] = [json[aname]];
}
json[aname].push(this.value || '');
} else {
json[aname] = this.value || '';
}
}
});
jq.ajax({
type: "post",
url: SAVE_URL,
dataType: "json",
data: data,
data: json,
success: function (d) {
if (d.error == 0) {
update_service();
@ -212,29 +288,29 @@
});
//更新脚本
$("#update_script").click(function () {
jq("#update_script").click(function () {
check_version()
return false;
});
function updateS(){
$("#update_script").attr("disabled", true);
$("#update_script").val(UPDATING_TEXT);
jq("#update_script").attr("disabled", true);
jq("#update_script").val(UPDATING_TEXT);
//console.log(data);
var data = {
version: $("#update_script").attr("data-version")
version: jq("#update_script").attr("data-version")
}
$.ajax({
jq.ajax({
type: "post",
url: UPDATE_URL,
dataType: "json",
data: data,
success: function (d) {
if (d.error == 0) {
$("#update_script").val(NEW_VERSION);
$(".cbi-value-version").text("v" + newVersion);
jq("#update_script").val(NEW_VERSION);
jq(".cbi-value-version").text("v" + newVersion);
} else {
$("#update_script").attr("disabled", false);
jq("#update_script").attr("disabled", false);
alert("更新错误请重试");
}
}
@ -243,7 +319,7 @@
function get_realtime_log() {
$.ajax({
jq.ajax({
url: '/JD_DailyBonus.htm?v=' + parseInt(Math.random() * 100000000),
dataType: 'html',
error: function (xhr) {
@ -272,9 +348,9 @@
}
function check_version() {
$("#update_script").attr("disabled", true);
$("#update_script").val(CHECKING_TEXT);
$.ajax({
jq("#update_script").attr("disabled", true);
jq("#update_script").val(CHECKING_TEXT);
jq.ajax({
url: CHECK_URL,
dataType: 'json',
error: function (xhr) {
@ -282,20 +358,94 @@
},
success: function (data) {
if(data.new_version == 501){
$("#update_script").attr("disabled", false);
$("#update_script").val("无法获取新版本,请重试!");
jq("#update_script").attr("disabled", false);
jq("#update_script").val("无法获取新版本,请重试!");
}else if (data.new_version > <%= self.version %>) {
$("#update_script").attr("disabled", false);
$("#update_script").val(UPDATE_TEXT + " v" + data.new_version);
$("#update_script").attr("data-version", data.new_version);
jq("#update_script").attr("disabled", false);
jq("#update_script").val(UPDATE_TEXT + " v" + data.new_version);
jq("#update_script").attr("data-version", data.new_version);
newVersion = data.new_version;
updateS();
} else {
$("#update_script").val(NEW_VERSION + " v" + data.new_version);
updateS();
jq("#update_script").val(NEW_VERSION + " v" + data.new_version);
}
}
}
});
}
qrcode = new QRCode(document.getElementById("qrcode"),
{
text: "sample",
correctLevel: QRCode.CorrectLevel.L
});
//获取二维码
function get_code() {
let timeStamp = (new Date()).getTime()
$.get('/qrcode?t='+timeStamp, function (data) {
if (data.err == 0) {
jq("#qrcontainer").removeClass("hidden")
jq("#refresh_qrcode").addClass("hidden")
qrcode.clear();
qrcode.makeCode(data.qrcode);
checkLogin();
} else {
Swal.fire({
text: data.msg,
icon: "error"
})
}
});
}
jq(".cookie-button").click(function(){
ckid = jq(this).attr("data-rel");
get_code()
return false;
})
jq('.refresh').click(get_code);
function get_code(){
let timeStamp = (new Date()).getTime()
jq.ajax({
url: QRCODE_URL+"?t="+timeStamp,
dataType: 'json',
success: function (data) {
if(data.error == 0){
jq("#qrcontainer").removeClass("hidden")
jq("#refresh_qrcode").addClass("hidden")
console.log(data.data.qrcode_url)
qrcode.clear();
qrcode.makeCode(data.data.qrcode_url);
checkLogin(data.data.check_url,data.data.cookies);
} else {
alert("出错了请重试。")
}
}
});
return false;
}
function checkLogin(check_url,cookies){
var timeId = setInterval(() => {
let cname = ckid == 1?"cookie":"cookie2"
jq.post( CHECK_LOGIN_URL, { check_url:check_url,cookies: cookies ,id: cname}, function( data ) {
if (data.error == 0) {
clearInterval(timeId)
jq("#qrcontainer").addClass("hidden")
jq("#refresh_qrcode").addClass("hidden")
let prefix_array = jq(".cbi-input-text").eq(0).attr("id").split(".");
prefix_array.pop()
let prefix = prefix_array.join(".")+".";
console.log("."+prefix+cname,data.cstr);
document.getElementById(prefix+cname).value =data.cstr
} else if (data.error == 21 || data.error == 261) {
clearInterval(timeId)
jq("#refresh_qrcode").removeClass("hidden")
}
}, "json");
}, 3000)
}
</script>

View File

@ -1,111 +0,0 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8\n"
msgid "JD-DailyBonus"
msgstr "京东签到服务"
msgid "Enable"
msgstr "启用"
msgid "Disable"
msgstr "停用"
msgid "Log"
msgstr "日志"
msgid "Script"
msgstr "脚本"
msgid "Base Config"
msgstr "基本设置"
msgid "Cookie Tools"
msgstr "Cookie 工具"
msgid "JDCookie Tools"
msgstr "获取京东cookie扩展工具"
msgid "Source Update Url"
msgstr "更新源地址"
msgid "First Cookie"
msgstr "主账号Cookie"
msgid "Second Cookie"
msgstr "第二账号Cookie"
msgid "Click to download the JDCookie.zip,unzip it,and use load Unpacked extensions to install.link:[chrome://extensions/]")"
msgstr "点击上面的按钮安装下载JDCookie.zip获取京东cookie扩展工具解压后在[chrome://extensions/]中使用加载已解压的扩展程序进行安装。 "
msgid "JD Url"
msgstr "京东链接"
msgid "Sign in ,then click JDCookie button.you will copy JD cookies, paste the cookie below."
msgstr "登录后点击JDCookie 扩展工具复制cookie然后粘贴到下面输入框中。请使用F12调试工具进入模拟手机浏览器模式"
msgid "Auto Update Script Service"
msgstr "自动更新脚本服务"
msgid "Update time (every day)"
msgstr "更新时间 (每天)"
msgid "Update Script"
msgstr "更新脚本"
msgid "Execute Delay"
msgstr "延迟签到"
msgid "ServerChan SCKEY"
msgstr "Server酱 SCKEY"
msgid "ServerURL"
msgstr "Server酱的推送接口地址"
msgid "SCT"
msgstr "测试版推送接口地址"
msgid "SCU"
msgstr "原版推送接口地址"
msgid "Failed Push"
msgstr "失效时推送"
msgid "Auto Run"
msgstr "自动签到"
msgid "Run"
msgstr "执行"
msgid "Auto Run Script Service"
msgstr "自动签到服务"
msgid "Run time (every day)"
msgstr "签到时间 (每天)"
msgid "Save Cookies And Run Service"
msgstr "保存Cookie并签到"
msgid "Sign in info"
msgstr "签到信息"
msgid "Service is running,Please do not refresh!"
msgstr "服务正在执行中,请勿刷新!"
msgid "Updating script,please wait ..."
msgstr "正在更新脚本,请稍候 ..."
msgid "Is currently the latest version"
msgstr "当前已是最新版本。"
msgid "There is a new version, click to update"
msgstr "有新的版本,请点击更新"
msgid "Checking the New Version ..."
msgstr "正在检查是否存在新的版本 ..."
msgid "Check Script Version"
msgstr "手动检查脚本更新"
msgid "Current Script Version"
msgstr "当前脚本版本"

View File

@ -1,9 +1,14 @@
config global
option version '1.87'
option auto_run_time '1'
option auto_run '1'
option auto_update_time '1'
option version '1.90'
option out '0'
option stop '100'
option serverchan ''
option remote_url 'https://raw.githubusercontent.com/NobyDa/Script/master/JD-DailyBonus/JD_DailyBonus.js'
option serverurl 'scu'
option auto_update '1'
option stop '0'
option failed '0'
option remote_url 'https://cdn.jsdelivr.net/gh/NobyDa/Script/JD-DailyBonus/JD_DailyBonus.js'
option auto_update_time '23'
option auto_run '1'
option auto_run_time '0'
option auto_run_time_m '1'
option auto_run_time_h '1'
option cookie ''

View File

@ -2,7 +2,7 @@
京东多合一签到脚本
更新时间: 2020.12.25 17:50 v1.89
更新时间: 2021.01.07 17:00 v1.90
有效接口: 40+
脚本兼容: QuantumultX, Surge, Loon, JSBox, Node.js
电报频道: @NobyDa
@ -13,7 +13,7 @@
JSbox, Node.js 说明 :
*************************
开启抓包app后, Safari浏览器登录 https://bean.m.jd.com 点击签到并且出现签到日历后, 返回抓包app搜索关键字 functionId=signBean 复制请求头Cookie填入以下Key处的单引号内即可 */
开启抓包app后, Safari浏览器登录 https://bean.m.jd.com/bean/signIndex.action 点击签到并且出现签到日历后, 返回抓包app搜索关键字 functionId=signBean 复制请求头Cookie填入以下Key处的单引号内即可 */
var Key = ''; //单引号内自行填写您抓取的Cookie
@ -30,7 +30,7 @@ var DualKey = ''; //如需双账号签到,此处单引号内填写抓取的"账
QX, Surge, Loon 说明 :
*************************
初次使用时, app配置文件添加脚本配置,并启用Mitm后, Safari浏览器打开登录 https://bean.m.jd.com ,点击签到并且出现签到日历后, 如果通知获得cookie成功, 则可以使用此签到脚本。 注: 请勿在京东APP内获取!!!
初次使用时, app配置文件添加脚本配置,并启用Mitm后, Safari浏览器打开登录 https://bean.m.jd.com/bean/signIndex.action ,点击签到并且出现签到日历后, 如果通知获得cookie成功, 则可以使用此签到脚本。 注: 请勿在京东APP内获取!!!
由于cookie的有效性(经测试网页Cookie有效周期最长31天)如果脚本后续弹出cookie无效的通知则需要重复上述步骤
签到脚本将在每天的凌晨0:05执行, 您可以修改执行时间 因部分接口京豆限量领取, 建议调整为凌晨签到
@ -108,14 +108,12 @@ async function all() {
case 0:
await Promise.all([
JingDongBean(stop), //京东京豆
JDTakeaLook(stop), //京东发现-看一看
JingDongStore(stop), //京东超市
JingDongWebcasts(stop), //京东直播
JingRongBean(stop), //金融简单赚钱
JingRongSteel(stop), //金融钢镚
JingDongTurn(stop), //京东转盘
JDFlashSale(stop), //京东闪购
JDOverseas(stop), //京东国际
JingDongCash(stop), //京东现金红包
JDMagicCube(stop, 2), //京东小魔方
JingDongSubsidy(stop), //京东金贴
@ -131,15 +129,13 @@ async function all() {
JingRongDoll(stop, 'JRFiveDoll', '京东金融-签伍', '1D06AA3B0F')
]);
await Promise.all([
JDUserSignPre(stop, 'JDClothing', '京东商城-服饰', '4RBT3H9jmgYg1k2kBnHF8NAHm7m8'), //京东服饰
JDUserSignPre(stop, 'JDUnderwear', '京东商城-内衣', '4PgpL1xqPSW1sVXCJ3xopDbB1f69'), //京东内衣馆
JDUserSignPre(stop, 'JDShoes', '京东商城-鞋靴', '4RXyb1W4Y986LJW8ToqMK14BdTD'), //京东鞋靴
JDUserSignPre(stop, 'JDCalendar', '京东日历-翻牌', '36V2Qw59VPNsuLxY84vCFtxFzrFs'), //京东日历翻牌
JDUserSignPre(stop, 'JDChild', '京东商城-童装', '3Af6mZNcf5m795T8dtDVfDwWVNhJ'), //京东童装馆
JDUserSignPre(stop, 'JDBaby', '京东商城-母婴', '3BbAVGQPDd6vTyHYjmAutXrKAos6'), //京东母婴馆
JDUserSignPre(stop, 'JD3C', '京东商城-数码', '4SWjnZSCTHPYjE5T7j35rxxuMTb6'), //京东数码电器馆
JDUserSignPre(stop, 'JDSubsidy', '京东晚市-补贴', 'xK148m4kWj5hBcTPuJUNNXH3AkJ'), //京东晚市补贴金
JDUserSignPre(stop, 'JDDrug', '京东商城-医药', '3tqTG5sF1xCUyC6vgEF5CLCxGn7w'), //京东医药馆
// JDUserSignPre(stop, 'JDSubsidy', '京东晚市-补贴', 'xK148m4kWj5hBcTPuJUNNXH3AkJ'), //京东晚市补贴金
// JDUserSignPre(stop, 'JDDrug', '京东商城-医药', '3tqTG5sF1xCUyC6vgEF5CLCxGn7w'), //京东医药馆
JDUserSignPre(stop, 'JDWomen', '京东商城-女装', 'DpSh7ma8JV7QAxSE2gJNro8Q2h9'), //京东女装馆
JDUserSignPre(stop, 'JDFineWine', '京东商城-酒饮', 'zGwAUzL3pVGjptBBGeYfpKjYdtX'), //京东酒饮馆
JDUserSignPre(stop, 'JDBook', '京东商城-图书', '3SC6rw5iBg66qrXPGmZMqFDwcyXi'), //京东图书
@ -147,15 +143,17 @@ async function all() {
JingRongDoll(stop, 'XJDouble', '金融现金-双签', 'F68B2C3E71', '', '', '', 'xianjin') //京东金融 现金双签
]);
await Promise.all([
JDUserSignPre(stop, 'JDClothing', '京东商城-服饰', '4RBT3H9jmgYg1k2kBnHF8NAHm7m8'), //京东服饰
JDUserSignPre(stop, 'JDUnderwear', '京东商城-内衣', '4PgpL1xqPSW1sVXCJ3xopDbB1f69'), //京东内衣馆
JDUserSignPre(stop, 'JDSuitcase', '京东商城-箱包', 'ZrH7gGAcEkY2gH8wXqyAPoQgk6t'), //京东箱包馆
JDUserSignPre(stop, 'JDSchool', '京东商城-校园', '4812pn2PAcUyfNdWr7Cvpww5MCyW'), //京东校园
JDUserSignPre(stop, 'JDHealth', '京东商城-健康', 'w2oeK5yLdHqHvwef7SMMy4PL8LF'), //京东健康
JDUserSignPre(stop, 'JDPet', '京东商城-宠物', '37ta5sh5ocrMZF3Fz5UMJbTsL42'), //京东宠物馆
JDUserSignPre(stop, 'JDShand', '京东拍拍-二手', '3S28janPLYmtFxypu37AYAGgivfp'), //京东拍拍二手
// JDUserSignPre(stop, 'JDPet', '京东商城-宠物', '37ta5sh5ocrMZF3Fz5UMJbTsL42'), //京东宠物馆
// JDUserSignPre(stop, 'JDShand', '京东拍拍-二手', '3S28janPLYmtFxypu37AYAGgivfp'), //京东拍拍二手
JDUserSignPre(stop, 'JDClean', '京东商城-清洁', '2Tjm6ay1ZbZ3v7UbriTj6kHy9dn6'), //京东清洁馆
JDUserSignPre(stop, 'JDCare', '京东商城-个护', 'NJ1kd1PJWhwvhtim73VPsD1HwY3'), //京东个人护理馆
JDUserSignPre(stop, 'JDJewels', '京东商城-珠宝', 'zHUHpTHNTaztSRfNBFNVZscyFZU'), //京东珠宝馆
JDUserSignPre(stop, 'JDClocks', '京东商城-钟表', '2BcJPCVVzMEtMUynXkPscCSsx68W'), //京东钟表馆
// JDUserSignPre(stop, 'JDClocks', '京东商城-钟表', '2BcJPCVVzMEtMUynXkPscCSsx68W'), //京东钟表馆
JDUserSignPre(stop, 'JDMakeup', '京东商城-美妆', '2smCxzLNuam5L14zNJHYu43ovbAP'), //京东美妆馆
JDUserSignPre(stop, 'JDVege', '京东商城-菜场', 'Wcu2LVCFMkBP3HraRvb7pgSpt64') //京东菜场
]);
@ -164,14 +162,12 @@ async function all() {
break;
default:
await JingDongBean(stop); //京东京豆
await JDTakeaLook(stop); //京东发现-看一看
await JingDongStore(stop); //京东超市
await JingDongWebcasts(stop); //京东直播
await JingRongBean(stop); //金融简单赚钱
await JingRongSteel(stop); //金融钢镚
await JingDongTurn(stop); //京东转盘
await JDFlashSale(stop); //京东闪购
await JDOverseas(stop); //京东国际
await JingDongCash(stop); //京东现金红包
await JDMagicCube(stop, 2); //京东小魔方
await JingDongGetCash(stop); //京东领现金
@ -197,13 +193,13 @@ async function all() {
await JDUserSignPre(stop, 'JDChild', '京东商城-童装', '3Af6mZNcf5m795T8dtDVfDwWVNhJ'); //京东童装馆
await JDUserSignPre(stop, 'JDBaby', '京东商城-母婴', '3BbAVGQPDd6vTyHYjmAutXrKAos6'); //京东母婴馆
await JDUserSignPre(stop, 'JD3C', '京东商城-数码', '4SWjnZSCTHPYjE5T7j35rxxuMTb6'); //京东数码电器馆
await JDUserSignPre(stop, 'JDSubsidy', '京东晚市-补贴', 'xK148m4kWj5hBcTPuJUNNXH3AkJ'); //京东晚市补贴金
await JDUserSignPre(stop, 'JDClocks', '京东商城-钟表', '2BcJPCVVzMEtMUynXkPscCSsx68W'); //京东钟表馆
await JDUserSignPre(stop, 'JDDrug', '京东商城-医药', '3tqTG5sF1xCUyC6vgEF5CLCxGn7w'); //京东医药馆
// await JDUserSignPre(stop, 'JDSubsidy', '京东晚市-补贴', 'xK148m4kWj5hBcTPuJUNNXH3AkJ'); //京东晚市补贴金
// await JDUserSignPre(stop, 'JDClocks', '京东商城-钟表', '2BcJPCVVzMEtMUynXkPscCSsx68W'); //京东钟表馆
// await JDUserSignPre(stop, 'JDDrug', '京东商城-医药', '3tqTG5sF1xCUyC6vgEF5CLCxGn7w'); //京东医药馆
await JDUserSignPre(stop, 'JDWomen', '京东商城-女装', 'DpSh7ma8JV7QAxSE2gJNro8Q2h9'); //京东女装馆
await JDUserSignPre(stop, 'JDPet', '京东商城-宠物', '37ta5sh5ocrMZF3Fz5UMJbTsL42'); //京东宠物馆
// await JDUserSignPre(stop, 'JDPet', '京东商城-宠物', '37ta5sh5ocrMZF3Fz5UMJbTsL42'); //京东宠物馆
await JDUserSignPre(stop, 'JDBook', '京东商城-图书', '3SC6rw5iBg66qrXPGmZMqFDwcyXi'); //京东图书
await JDUserSignPre(stop, 'JDShand', '京东拍拍-二手', '3S28janPLYmtFxypu37AYAGgivfp'); //京东拍拍二手
// await JDUserSignPre(stop, 'JDShand', '京东拍拍-二手', '3S28janPLYmtFxypu37AYAGgivfp'); //京东拍拍二手
await JDUserSignPre(stop, 'JDMakeup', '京东商城-美妆', '2smCxzLNuam5L14zNJHYu43ovbAP'); //京东美妆馆
await JDUserSignPre(stop, 'JDFineWine', '京东商城-酒饮', 'zGwAUzL3pVGjptBBGeYfpKjYdtX'); //京东酒饮馆
await JDUserSignPre(stop, 'JDVege', '京东商城-菜场', 'Wcu2LVCFMkBP3HraRvb7pgSpt64'); //京东菜场
@ -1700,56 +1696,6 @@ function JingRongDoll(s, key, title, code, type, num, award, belong) {
});
}
function JDOverseas(s) {
merge.Overseas = {};
return new Promise(resolve => {
if (disable("Overseas")) return resolve()
setTimeout(() => {
const OverseasUrl = {
url: 'https://api.m.jd.com/client.action?functionId=checkin',
headers: {
Cookie: KEY
},
body: "body=%7B%7D&build=167237&client=apple&clientVersion=9.0.0&openudid=1fce88cd05c42fe2b054e846f11bdf33f016d676&partner=apple&scope=11&sign=e27f8b904040a0e3c99b87fc27e09c87&st=1591730990449&sv=101"
};
$nobyda.post(OverseasUrl, function(error, response, data) {
try {
if (error) {
throw new Error(error)
} else {
const Details = LogDetails ? "response:\n" + data : '';
if (data.match(/\"type\":\d+?,/)) {
console.log("\n" + "京东商城-国际签到成功 " + Details)
merge.Overseas.success = 1
if (data.match(/\"jdBeanAmount\":[1-9]+/)) {
merge.Overseas.bean = data.match(/\"jdBeanAmount\":(\d+)/)[1]
merge.Overseas.notify = "京东商城-国际: 成功, 明细: " + merge.Overseas.bean + "京豆 🐶"
} else {
merge.Overseas.notify = "京东商城-国际: 成功, 明细: 无京豆 🐶"
}
} else {
console.log("\n" + "京东商城-国际签到失败 " + Details)
merge.Overseas.fail = 1
if (data.match(/(\"code\":\"13\"|重复签到)/)) {
merge.Overseas.notify = "京东商城-国际: 失败, 原因: 已签过 ⚠️"
} else if (data.match(/\"code\":\"(-1|3)\"/)) {
merge.Overseas.notify = "京东商城-国际: 失败, 原因: Cookie失效‼"
} else {
merge.Overseas.notify = "京东商城-国际: 失败, 原因: 未知 ⚠️"
}
}
}
} catch (eor) {
$nobyda.AnError("京东商城-国际", "Overseas", eor, response, data)
} finally {
resolve()
}
})
}, s)
if (out) setTimeout(resolve, out + s)
});
}
function JingDongGetCash(s) {
merge.JDGetCash = {};
return new Promise(resolve => {
@ -1834,45 +1780,6 @@ function JingDongWebcasts(s) {
});
}
function JDTakeaLook(s) {
merge.TakeaLook = {};
return new Promise(resolve => {
if (disable("TakeaLook")) return resolve()
setTimeout(() => {
$nobyda.get({
url: 'https://api.m.jd.com/client.action?functionId=discTaskList&body=%7B%22bizType%22%3A1%2C%22referPageId%22%3A%22discRecommend%22%7D&client=apple&clientVersion=9.1.6&openudid=1fce88cd05c42fe2b054e846f11bdf33f016d676&sign=17061147fe8e0eb10edfe8d9968b6d66&st=1601138337675&sv=102',
headers: {
Cookie: KEY
}
}, (error, response, data) => {
try {
if (error) throw new Error(error);
const cc = JSON.parse(data);
const Details = LogDetails ? "response:\n" + data : '';
const tm = parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000
if (data.match(/签到成功/) && !data.match(tm)) {
console.log(`\n京东发现-看看签到成功 ${Details}`)
const aw = data.match(/\"签到成功,获得(\d+)京豆\"/)
merge.TakeaLook.success = 1
merge.TakeaLook.bean = aw ? aw[1] : 0
merge.TakeaLook.notify = `京东发现-看看: 成功, 明细: ${merge.TakeaLook.bean||``}京豆 🐶`
} else {
console.log(`\n京东发现-看看签到失败 ${Details}`)
const tp = data.match(tm) ? `已签过` : cc.busiCode == 2001 ? `Cookie失效` : `${cc.message||`未知`}`
merge.TakeaLook.notify = `京东发现-看看: 失败, 原因: ${tp}${cc.busiCode==2001?`‼️`:` ⚠️`}`
merge.TakeaLook.fail = 1
}
} catch (eor) {
$nobyda.AnError("京东发现-看看", "TakeaLook", eor, response, data)
} finally {
resolve()
}
})
}, s)
if (out) setTimeout(resolve, out + s)
});
}
function JingDongStore(s) {
merge.JDGStore = {};
return new Promise(resolve => {

View File

@ -0,0 +1,168 @@
-- Copyright (C) 2021 jerrykuku <jerrykuku@gmail.com>
-- Licensed to the public under the GNU General Public License v3.
local uci = require 'luci.model.uci'.cursor()
local config = 'jd-dailybonus'
package.path = package.path .. ';/usr/share/jd-dailybonus/?.lua'
local requests = require 'requests'
local socket = require 'socket'
local tinsert = table.insert
local ssub, slen, schar, sbyte, sformat, sgsub = string.sub, string.len, string.char, string.byte, string.format, string.gsub
local User_Agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36'
local Host = 'plogin.m.jd.com'
local jd_cookie = {}
--打印table
function print_r(t)
local print_r_cache = {}
local function sub_print_r(t, indent)
if (print_r_cache[tostring(t)]) then
print(indent .. '*' .. tostring(t))
else
print_r_cache[tostring(t)] = true
if (type(t) == 'table') then
for pos, val in pairs(t) do
if (type(val) == 'table') then
print(indent .. '[' .. pos .. '] => ' .. tostring(t) .. ' {')
sub_print_r(val, indent .. string.rep(' ', string.len(pos) + 8))
print(indent .. string.rep(' ', string.len(pos) + 6) .. '}')
elseif (type(val) == 'string') then
print(indent .. '[' .. pos .. '] => "' .. val .. '"')
else
print(indent .. '[' .. pos .. '] => ' .. tostring(val))
end
end
else
print(indent .. tostring(t))
end
end
end
if (type(t) == 'table') then
print(tostring(t) .. ' {')
sub_print_r(t, ' ')
print('}')
else
sub_print_r(t, ' ')
end
print()
end
-- 分割字符串
local function split(full, sep)
full = full:gsub('%z', '') -- 这里不是很清楚 有时候结尾带个\0
local off, result = 1, {}
while true do
local nStart, nEnd = full:find(sep, off)
if not nEnd then
local res = ssub(full, off, slen(full))
if #res > 0 then -- 过滤掉 \0
tinsert(result, res)
end
break
else
tinsert(result, ssub(full, off, nStart - 1))
off = nEnd + 1
end
end
return result
end
--获取unix时间戳
function jd_cookie.timestamp()
return math.floor(socket.gettime() * 1000)
end
--延时函数
function sleep(n)
os.execute('sleep ' .. n)
end
--解析cookie
function praseSetCookies(rcookie)
local tbl = {}
for k, v in rcookie:gmatch('([^;%s]+)=([^;]+)') do
tbl[k] = v
end
return tbl
end
--获取二维码链接和检测URL
function jd_cookie.get_qrcode()
local timeStamp = jd_cookie.timestamp()
local url =
'https://plogin.m.jd.com/cgi-bin/mm/new_login_entrance?lang=chs&appid=300&returnurl=https://wq.jd.com/passport/LoginRedirect?state=' ..
timeStamp .. '&returnurl=https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport'
local xformHeaders = {
['Content-Type'] = 'application/x-www-form-urlencoded',
['Connection'] = 'Keep-Alive',
['Accept'] = 'application/json, text/plain, */*',
['Accept-Language'] = 'zh-cn',
['Referer'] = 'https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wq.jd.com/passport/LoginRedirect?state=' ..
timeStamp .. '&returnurl=https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport',
['User-Agent'] = User_Agent,
['Host'] = Host
}
local response = requests.get {url, headers = xformHeaders}
local s_token = response.json().s_token
local dat = split(string.gsub(response.headers['set-cookie'], ' DOMAIN=.plogin.m.jd.com', ''), ';')
local cookies = string.gsub(dat[1] .. dat[4] .. dat[6] .. dat[8], ',', ';') .. ';'
local timeStamp = jd_cookie.timestamp()
local url = 'https://plogin.m.jd.com/cgi-bin/m/tmauthreflogurl?s_token=' .. s_token .. '&v=' .. timeStamp .. '&remember=true'
local xformHeaders = {
['Content-Type'] = 'application/x-www-form-urlencoded',
['Connection'] = 'Keep-Alive',
['Accept'] = 'application/json, text/plain, */*',
['Accept-Language'] = 'zh-cn',
['Referer'] = 'https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wq.jd.com/passport/LoginRedirect?state=' ..
timeStamp .. '&returnurl=https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport',
['User-Agent'] = User_Agent,
['Host'] = Host
}
local response = requests.post {url, cookies = cookies, headers = xformHeaders}
local json_body, error = response.json()
local token = json_body['token']
local ou_state = json_body['ou_state']
local okl_token = praseSetCookies(response.headers['set-cookie']).okl_token
local return_json = {
qrcode_url = 'https://plogin.m.jd.com/cgi-bin/m/tmauth?appid=300&client_type=m&token=' .. token,
check_url = 'https://plogin.m.jd.com/cgi-bin/m/tmauthchecktoken?&token=' .. token .. '&ou_state=' .. ou_state .. '&okl_token=' .. okl_token,
cookies = cookies
}
return return_json
end
--检测扫码状态 并返回cookie
function jd_cookie.checkLogin(url, cookies)
local xformHeaders = {
['Content-Type'] = 'application/x-www-form-urlencoded',
['Connection'] = 'Keep-Alive',
['Accept'] = 'application/json, text/plain, */*',
['Accept-Language'] = 'zh-cn',
['Referer'] = 'https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wqlogin2.jd.com/passport/LoginRedirect?state=',
['User-Agent'] = User_Agent,
['Host'] = Host
}
local data =
'lang=chs&appid=300&source=wq_passport&returnurl=https://wqlogin2.jd.com/passport/LoginRedirect?state=1100399130787&returnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action'
local response = requests.post {url, data = data, cookies = cookies, headers = xformHeaders}
--local cookie = jd_cookie.praseSetCookies(response.headers['set-cookie'])
local json = response.json()
local return_json = {}
if json.errcode == 0 then
local ucookie = praseSetCookies(response.headers['set-cookie'])
return_json = {
error = 0,
cookie = ucookie
}
else
return_json = {
error = json.errcode,
msg = json.message
}
end
return return_json
end
return jd_cookie

View File

@ -49,78 +49,58 @@ cancel() {
exit 1
}
fill_cookie() {
cookie1=$(uci_get_by_type global cookie)
if [ ! "$cookie1" = "" ]; then
varb="var Key = '$cookie1';"
a=$(sed -n '/var Key =/=' $JD_SCRIPT)
b=$((a-1))
sed -i "${a}d" $JD_SCRIPT
sed -i "${b}a ${varb}" $JD_SCRIPT
fi
cookie2=$(uci_get_by_type global cookie2)
if [ ! "$cookie2" = "" ]; then
varb2="var DualKey = '$cookie2';"
aa=$(sed -n '/var DualKey =/=' $JD_SCRIPT)
bb=$((aa-1))
sed -i "${aa}d" $JD_SCRIPT
sed -i "${bb}a ${varb2}" $JD_SCRIPT
fi
stop=$(uci_get_by_type global stop)
if [ ! "$stop" = "" ]; then
varb3="var stop = $stop;"
sed -i "s/^var stop =.*/$varb3/g" $JD_SCRIPT
fi
}
add_cron() {
sed -i '/jd-dailybonus/d' $CRON_FILE
[ $(uci_get_by_type global auto_run 0) -eq 1 ] && echo '5 '$(uci_get_by_type global auto_run_time)' * * * sleep '$(expr $(head -n 128 /dev/urandom | tr -dc "0123456789" | head -c4) % 180)'s; /usr/share/jd-dailybonus/newapp.sh -w' >>$CRON_FILE
[ $(uci_get_by_type global auto_run 0) -eq 1 ] && echo $(uci_get_by_type global auto_run_time_m)' '$(uci_get_by_type global auto_run_time_h)' * * * /usr/share/jd-dailybonus/newapp.sh -w' >>$CRON_FILE
[ $(uci_get_by_type global auto_update 0) -eq 1 ] && echo '1 '$(uci_get_by_type global auto_update_time)' * * * /usr/share/jd-dailybonus/newapp.sh -u' >>$CRON_FILE
crontab $CRON_FILE
/etc/init.d/cron restart
}
# Run Script
serverchan() {
sckey=$(uci_get_by_type global serverchan)
failed=$(uci_get_by_type global failed)
desc=$(cat /www/JD_DailyBonus.htm | grep -E '签到号|签到概览|签到奖励|其他奖励|账号总计|其他总计' | sed 's/$/&\n/g')
serverurlflag=$(uci_get_by_type global serverurl)
serverurl=https://sc.ftqq.com/
if [ "$serverurlflag" = "sct" ]; then
serverurl=https://sctapi.ftqq.com/
fi
if [ $failed -eq 1 ]; then
grep "Cookie失效" /www/JD_DailyBonus.htm > /dev/null
if [ $? -eq 0 ]; then
title="$(date '+%Y年%m月%d日') 京东签到 Cookie 失效"
wget-ssl -q --output-document=/dev/null --post-data="text=$title~&desp=$desc" $serverurl$sckey.send
fi
notify() {
grep "Cookie失效" /www/JD_DailyBonus.htm >/dev/null
if [ $? -eq 0 ]; then
title="$(date '+%Y年%m月%d日') 京东签到 Cookie 失效"
else
title="$(date '+%Y年%m月%d日') 京东签到"
fi
desc=$(cat /www/JD_DailyBonus.htm | grep -E '签到号|签到概览|签到奖励|其他奖励|账号总计|其他总计' | sed 's/$/&\n/g')
#serverchan
sckey=$(uci_get_by_type global serverchan)
if [ ! -z $sckey ]; then
serverurlflag=$(uci_get_by_type global serverurl)
serverurl=https://sc.ftqq.com/
if [ "$serverurlflag" = "sct" ]; then
serverurl=https://sctapi.ftqq.com/
fi
wget-ssl -q --output-document=/dev/null --post-data="text=$title~&desp=$desc" $serverurl$sckey.send
fi
#telegram
TG_BOT_TOKEN=$(uci_get_by_type global tg_token)
TG_USER_ID=$(uci_get_by_type global tg_userid)
API_URL="https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage"
if [ ! -z $TG_BOT_TOKEN ] && [ ! -z $TG_USER_ID ]; then
text="*$title*
\`\`\`
"$desc"
====================================
本消息来自京东签到插件 jd-dailybonus
\`\`\`"
wget-ssl -q --output-document=/dev/null --post-data="chat_id=$TG_USER_ID&text=$text&parse_mode=markdownv2" $API_URL
fi
}
run() {
fill_cookie
echo -e $(date '+%Y-%m-%d %H:%M:%S %A') >$LOG_HTM 2>/dev/null
[ ! -f "/usr/bin/node" ] && echo -e "未安装node.js,请安装后再试!\nNode.js is not installed, please try again after installation!">>$LOG_HTM && exit 1
node $JD_SCRIPT >>$LOG_HTM 2>/dev/null
}
back_run() {
run
sleep 1s
serverchan
[ ! -f "/usr/bin/node" ] && echo -e "未安装node.js,请安装后再试!\nNode.js is not installed, please try again after installation!" >>$LOG_HTM && exit 1
node $JD_SCRIPT >>$LOG_HTM 2>/dev/null && notify &
}
save() {
fill_cookie
add_cron
}
@ -156,7 +136,6 @@ update() {
fi
remote_ver=$(get_ver $TEMP_SCRIPT)
cp -r $TEMP_SCRIPT $JD_SCRIPT
fill_cookie
uci set jd-dailybonus.@global[0].version=$remote_ver
uci commit jd-dailybonus
cancel "0"
@ -169,7 +148,7 @@ while getopts ":alnruswh" arg; do
exit 0
;;
l)
serverchan
notify
exit 0
;;
n)
@ -189,7 +168,7 @@ while getopts ":alnruswh" arg; do
exit 0
;;
w)
back_run
run
exit 0
;;
h)

View File

@ -0,0 +1,303 @@
-- Lua Requests library for http ease
local http_socket = require('socket.http')
local https_socket = require('ssl.https')
local url_parser = require('socket.url')
local ltn12 = require('ltn12')
local json = require('cjson.safe')
local md5sum = require('md5') -- TODO: Make modular?
local mime = require('mime')
local requests = {
_DESCRIPTION = 'Http requests made simpler',
http_socket = http_socket,
https_socket = https_socket
}
local _requests = {}
--User facing function the make a request use Digest Authentication
--TODO: Determine what else should live in authentication
function requests.HTTPDigestAuth(user, password)
return { _type = 'digest', user = user, password = password}
end
--User facing function the make a request use Basic Authentication
--TODO: Determine what else should live in authentication
function requests.HTTPBasicAuth(user, password)
return { _type = 'basic', user = user, password = password}
end
function requests.post(url, args)
return requests.request("POST", url, args)
end
function requests.get(url, args)
return requests.request("GET", url, args)
end
function requests.delete(url, args)
return requests.request("DELETE", url, args)
end
function requests.patch(url, args)
return requests.request("PATCH", url, args)
end
function requests.put(url, args)
return requests.request("PUT", url, args)
end
function requests.options(url, args)
return requests.request("OPTIONS", url, args)
end
function requests.head(url, args)
return requests.request("HEAD", url, args)
end
function requests.trace(url, args)
return requests.request("TRACE", url, args)
end
--Sets up all the data for a request and makes the request
function requests.request(method, url, args)
local request
if type(url) == "table" then
request = url
if not request.url and request[1] then
request.url = table.remove(request, 1)
end
else
request = args or {}
request.url = url
end
request.method = method
_requests.parse_args(request)
-- TODO: Find a better way to do this
if request.auth and request.auth._type == 'digest' then
local response = _requests.make_request(request)
return _requests.use_digest(response, request)
else
return _requests.make_request(request)
end
end
--Makes a request
function _requests.make_request(request)
local response_body = {}
local full_request = {
method = request.method,
url = request.url,
headers = request.headers,
sink = ltn12.sink.table(response_body),
redirect = request.allow_redirects,
proxy = request.proxy
}
if request.data then
full_request.source = ltn12.source.string(request.data)
end
local response = {}
local ok
local socket = string.find(full_request.url, '^https:') and not request.proxy and https_socket or http_socket
ok, response.status_code, response.headers, response.status = socket.request(full_request)
assert(ok, 'error in '..request.method..' request: '..response.status_code)
response.text = table.concat(response_body)
response.json = function () return json.decode(response.text) end
return response
end
--Parses through all the possible arguments for a request
function _requests.parse_args(request)
_requests.check_url(request)
_requests.check_data(request)
_requests.create_header(request)
_requests.check_timeout(request.timeout)
_requests.check_redirect(request.allow_redirects)
end
--Format the the url based on the params argument
function _requests.format_params(url, params) -- TODO: Clean
if not params or next(params) == nil then return url end
url = url..'?'
for key, value in pairs(params) do
if tostring(value) then
url = url..tostring(key)..'='
if type(value) == 'table' then
local val_string = ''
for _, val in ipairs(value) do
val_string = val_string..tostring(val)..','
end
url = url..val_string:sub(0, -2)
else
url = url..tostring(value)
end
url = url..'&'
end
end
return url:sub(0, -2)
end
--Check that there is a URL given and append to it if params are passed in.
function _requests.check_url(request)
assert(request.url, 'No url specified for request')
request.url = _requests.format_params(request.url, request.params)
end
-- Add to the HTTP header
function _requests.create_header(request)
request.headers = request.headers or {}
if request.data then
request.headers['Content-Length'] = request.data:len()
end
if request.cookies then
if request.headers.cookie then
request.headers.cookie = request.headers.cookie..'; '..request.cookies
else
request.headers.cookie = request.cookies
end
end
if request.auth then
_requests.add_auth_headers(request)
end
end
--Makes sure that the data is in a format that can be sent
function _requests.check_data(request)
if type(request.data) == "table" then
request.data = json.encode(request.data)
elseif request.data then
request.data = tostring(request.data)
end
end
--Set the timeout
function _requests.check_timeout(timeout)
http_socket.TIMEOUT = timeout or 5
https_socket.TIMEOUT = timeout or 5
end
--Checks is allow_redirects parameter is set correctly
function _requests.check_redirect(allow_redirects)
if allow_redirects and type(allow_redirects) ~= "boolean" then
error("allow_redirects expects a boolean value. received type = "..type(allow_redirects))
end
end
--Create the Authorization header for Basic Auth
function _requests.basic_auth_header(request)
local encoded = mime.b64(request.auth.user..':'..request.auth.password)
request.headers.Authorization = 'Basic '..encoded
end
-- Create digest authorization string for request header TODO: Could be better, but it should work
function _requests.digest_create_header_string(auth)
local authorization = 'Digest username="'..auth.user..'", realm="'..auth.realm..'", nonce="'..auth.nonce
authorization = authorization..'", uri="'..auth.uri..'", qop='..auth.qop..', nc='..auth.nc
authorization = authorization..', cnonce="'..auth.cnonce..'", response="'..auth.response..'"'
if auth.opaque then
authorization = authorization..', opaque="'..auth.opaque..'"'
end
return authorization
end
--MD5 hash all parameters
local function md5_hash(...)
return md5sum.sumhexa(table.concat({...}, ":"))
end
-- Creates response hash TODO: Add functionality
function _requests.digest_hash_response(auth_table)
return md5_hash(
md5_hash(auth_table.user, auth_table.realm, auth_table.password),
auth_table.nonce,
auth_table.nc,
auth_table.cnonce,
auth_table.qop,
md5_hash(auth_table.method, auth_table.uri)
)
end
-- Add digest authentication to the request header
function _requests.digest_auth_header(request)
if not request.auth.nonce then return end
request.auth.cnonce = request.auth.cnonce or string.format("%08x", os.time())
request.auth.nc_count = request.auth.nc_count or 0
request.auth.nc_count = request.auth.nc_count + 1
request.auth.nc = string.format("%08x", request.auth.nc_count)
local url = url_parser.parse(request.url)
request.auth.uri = url_parser.build{path = url.path, query = url.query}
request.auth.method = request.method
request.auth.qop = 'auth'
request.auth.response = _requests.digest_hash_response(request.auth)
request.headers.Authorization = _requests.digest_create_header_string(request.auth)
end
--Checks the resonse code and adds additional headers for Digest Auth
-- TODO: Rename this
function _requests.use_digest(response, request)
if response.status_code == 401 then
_requests.parse_digest_response_header(response,request)
_requests.create_header(request)
response = _requests.make_request(request)
response.auth = request.auth
response.cookies = request.headers.cookie
return response
else
response.auth = request.auth
response.cookies = request.headers.cookie
return response
end
end
--Parse the first response from the host to make the Authorization header
function _requests.parse_digest_response_header(response, request)
for key, value in response.headers['www-authenticate']:gmatch('(%w+)="(%S+)"') do
request.auth[key] = value
end
if request.headers.cookie then
request.headers.cookie = request.headers.cookie..'; '..response.headers['set-cookie']
else
request.headers.cookie = response.headers['set-cookie']
end
request.auth.nc_count = 0
end
-- Call the correct authentication header function
function _requests.add_auth_headers(request)
local auth_func = {
basic = _requests.basic_auth_header,
digest = _requests.digest_auth_header
}
auth_func[request.auth._type](request)
end
--Return public functions
requests._private = _requests
return requests

File diff suppressed because one or more lines are too long