Compare commits

...
7 Commits
Author SHA1 Message Date
shanmite 329e6931dd 更新readme 2021-07-18 23:55:49 +08:00
shanmite 309371fbd7 pref: 重构部分代码,优化提示 2021-07-18 23:37:27 +08:00
shanmite 6f81360d2a fix: 多账号状态清零 2021-07-18 22:27:48 +08:00
shanmite 4e377f1c41 cli: 更改颜色 2021-07-18 17:35:33 +08:00
shanmite 79c550db14 fix: 滤除过期官方抽奖 2021-07-18 17:24:11 +08:00
shanmite 28c2af93cf fix: 开奖时间过滤失效 2021-07-18 16:52:54 +08:00
shanmite 11aec87eed fix: 循环运行 2021-07-18 12:45:49 +08:00
14 changed files with 89 additions and 126 deletions
+3 -1
View File
@@ -79,7 +79,9 @@ Chrome浏览器:
2. `env.js`中填入`COOKIE`和推送参数
3. `my_config.js`中自定义设置
4. 在当前目录下打开终端运行可执行文件`lottery`
5. 运行截图
5. 输入`lottery start`启动抽奖|`lottery check`检测中奖|`lottery clear`清理动态
> 或者新建文本文档写入`lottery start`然后更改扩展名为.bat点击运行
6. 运行截图
![lottery_start](doc/pic/lottery_start.png)
#### 以源码方式运行
+1 -1
View File
@@ -1,5 +1,5 @@
const Ajax = require('./Ajax');
const { strToJson, log } = require('./Base');
const { strToJson, log } = require('./Util');
const GlobalVar = require('./GlobalVar');
/**
+1 -1
View File
@@ -1,6 +1,6 @@
const { createReadStream, createWriteStream } = require('fs')
const unzip = require('unzipper');
const { strToJson, tooltip } = require("./Base")
const { strToJson, tooltip } = require("./Util")
const { HttpRequest } = require("./HttpRequest")
const { GITHUB_REPOSITORY } = process.env;
+33 -27
View File
@@ -1,4 +1,4 @@
const Base = require('./Base');
const Util = require('./Util');
const BiliAPI = require('./BiliAPI');
const { sendNotify } = require('./sendNotify');
const eventBus = require('./eventBus');
@@ -6,7 +6,7 @@ const Public = require('./Public');
const GlobalVar = require("./GlobalVar");
const config = require("./config");
const MyStorage = require('./MyStorage');
const { log, hasEnv } = Base;
const { log, hasEnv } = Util;
/**
* 监视器
@@ -87,11 +87,17 @@ class Monitor extends Public {
let status = 0;
if (Lottery.isOfficialLottery) {
let { ts } = await BiliAPI.getLotteryNotice(Lottery.dyid);
const ts_10 = Date.now() / 1000;
if (ts < 0) {
return 51
}
if (ts > (Date.now() / 1000) + config.maxday * 864e5) {
log.info('过滤', '开奖时间晚于指定时间')
if (ts < ts_10) {
log.info('过滤', '已过开奖时间')
MyStorage.updateDyid(Lottery.dyid)
continue
}
if (ts > ts_10 + config.maxday * 86400) {
log.info('过滤', '超过指定开奖时间')
MyStorage.updateDyid(Lottery.dyid)
continue
}
@@ -111,6 +117,7 @@ class Monitor extends Public {
return status
}
MyStorage.updateDyid(Lottery.dyid);
await Util.delay(config.wait * (Math.random() + 0.5));
}
log.info('抽奖', '开始转发下一组动态');
return 0
@@ -172,7 +179,7 @@ class Monitor extends Public {
)
/* 检查动态是否满足要求 */
await Base.try_for_each(protoLotteryInfo, async function ({
await Util.try_for_each(protoLotteryInfo, async function ({
lottery_info_type, uids,
uname, dyid,
ctrl, rid, des, type,
@@ -230,7 +237,7 @@ class Monitor extends Public {
let
/**转发评语 */
RandomStr = Base.getRandomOne(config.relay),
RandomStr = Util.getRandomOne(config.relay),
/**控制字段 */
new_ctrl = [];
@@ -307,34 +314,36 @@ class Monitor extends Public {
log.info('NOT_GO_LOTTERY', 'ON');
return 0
}
let status = 1;
const { uid, dyid, type, rid, relay_chat, ctrl } = option;
/* 评论 */
if (typeof rid === 'string' && type !== 0) {
const send = () => BiliAPI.sendChat(rid, Base.getRandomOne(config.chat) || relay_chat, type);
if (rid && type) {
let status = 0;
const max_retry_times = 5;
for (let times = 0; times < max_retry_times && status; times++) {
status = await send();
if (status) {
log.info('自动评论', `将在 ${times + 1} 分钟后再次发送评论(${times + 1}/${max_retry_times})`)
await Base.delay(60 * 1000 * (times + 1))
for (let times = 0; times < max_retry_times; times++) {
status = await BiliAPI.sendChat(rid, Util.getRandomOne(config.chat), type)
if (!status) {
break
}
log.info('自动评论', `将在 ${times + 1} 分钟后再次发送评论(${times + 1}/${max_retry_times})`)
await Util.delay(60 * 1000 * (times + 1))
}
if (status) return 11;
}
/* 关注 */
if (uid.length) {
status = 0
for (let index = 0; index < uid.length && !status; index++) {
const one_uid = uid[index];
if (typeof one_uid === 'number') {
status = await BiliAPI.autoAttention(uid);
await Base.delay(5000);
if (!status) await BiliAPI.movePartition(uid, this.tagid);
}
}
const [u1, u2] = uid
if (u1) {
let status = await BiliAPI.autoAttention(u1)
if (status) return 20 + status;
status = await BiliAPI.movePartition(u1, this.tagid)
if (status) return 20 + status;
if (u2) {
Util.delay(5000)
status = await BiliAPI.autoAttention(u2)
if (status) return 20 + status;
status = await BiliAPI.movePartition(u2, this.tagid)
if (status) return 20 + status;
}
}
/* 点赞 */
@@ -343,9 +352,6 @@ class Monitor extends Public {
/* 转发 */
if (await BiliAPI.autoRelay(GlobalVar.get("myUID"), dyid, relay_chat, ctrl)) return 41;
/* 延时 */
await Base.delay(config.wait * (Math.random() + 0.5));
return 0
}
}
+4 -4
View File
@@ -1,5 +1,5 @@
const Base = require("./Base");
const { log } = Base;
const Util = require("./Util");
const { log } = Util;
const MyStorage = {
/**
@@ -10,7 +10,7 @@ const MyStorage = {
searchDyid: (dyid) => {
return new Promise((resolve) => {
const Rdyid = new RegExp(dyid);
const rs = Base.readDyidFile(Number(process.env.NUMBER));
const rs = Util.readDyidFile(Number(process.env.NUMBER));
let status = false;
rs.on('data', chunk => {
if (Rdyid.test(chunk)) {
@@ -33,7 +33,7 @@ const MyStorage = {
updateDyid: (dyid) => {
log.info('更新dyid', `写入${dyid}`);
return new Promise((resolve) => {
const ws = Base.writeDyidFile(Number(process.env.NUMBER));
const ws = Util.writeDyidFile(Number(process.env.NUMBER));
ws.write(dyid + ',', () => {
ws.destroy();
resolve()
+7 -7
View File
@@ -1,7 +1,7 @@
const Base = require('./Base');
const Util = require('./Util');
const BiliAPI = require('./BiliAPI');
const config = require("./config");
const { log } = Base
const { log } = Util
/**
* 基础功能
*/
@@ -40,7 +40,7 @@ class Public {
log.info('检查所有动态', `准备读取${pages}页动态`);
const mDR = this.modifyDynamicRes,
getOneDynamicInfoByUID = BiliAPI.getOneDynamicInfoByUID,
curriedGetOneDynamicInfoByUID = Base.curryify(getOneDynamicInfoByUID); /* 柯里化的请求函数 */
curriedGetOneDynamicInfoByUID = Util.curryify(getOneDynamicInfoByUID); /* 柯里化的请求函数 */
/**
* 储存了特定UID的请求函数
*/
@@ -72,10 +72,10 @@ class Public {
allModifyDynamicResArray.push.apply(allModifyDynamicResArray, mDRArry);
i + 1 < pages
? log.info('检查所有动态', `开始读取第${i + 2}页动态信息`)
: log.info('检查所有动态', `${pages}页信息全部成功读取完成`);
: log.info('检查所有动态', `${pages}页信息读取完成`);
offset = nextinfo.next_offset;
}
await Base.delay(time);
await Util.delay(time);
}
return ({ allModifyDynamicResArray, offset });
}
@@ -86,7 +86,7 @@ class Public {
* @returns {{modifyDynamicResArray: UsefulDynamicInfo[];nextinfo: {has_more: number;next_offset: string;};} | null}
*/
modifyDynamicRes(res) {
const strToJson = Base.strToJson,
const strToJson = Util.strToJson,
{ data, code } = strToJson(res);
if (code !== 0) {
log.error('处理动态数据', '获取动态数据出错,可能是访问太频繁 \n' + res);
@@ -202,7 +202,7 @@ class Public {
if (_modify === null) return null;
mDRdata.push.apply(mDRdata, _modify.modifyDynamicResArray);
next_offset = _modify.nextinfo.next_offset;
await Base.delay(config.search_wait);
await Util.delay(config.search_wait);
}
const fomatdata = mDRdata.map(o => {
return {
+11 -59
View File
@@ -6,7 +6,7 @@ const { HttpRequest } = require("./HttpRequest");
/**
* 基础工具
*/
const Base = {
const Util = {
/**环境变量设置文件 */
env_file: path.join(process.cwd(), "env.js"),
/**配置文件 */
@@ -68,7 +68,7 @@ const Base = {
* @returns {Promise<void>}
*/
delay(time) {
Base.log.info('时延', `${time}ms`);
Util.log.info('时延', `${time}ms`);
return new Promise(resolve => {
setTimeout(() => {
resolve();
@@ -94,12 +94,13 @@ const Base = {
},
/**
* 随机获取数组中的一个元素
* @param {any[]} arr
* @returns {any}
* @template T
* @param {T[]} arr
* @returns {T}
*/
getRandomOne(arr) {
let RandomOne = null;
if (arr instanceof Array && arr.length) {
if (Array.isArray(arr) && arr.length) {
RandomOne = arr[parseInt(Math.random() * arr.length)];
}
return RandomOne
@@ -127,71 +128,22 @@ const Base = {
debug(context, msg) {
if (this.level > 3) {
if (msg instanceof Object) msg = JSON.stringify(msg, null, 4);
this.proPrint([`[${Date()}]`, chalk.grey("[Debug]"), chalk.hex('#FFA500')(`[${context}]`), chalk.hex('#0070BB')(`[\n${msg}\n]`)])
this.proPrint([chalk.hex('#64B3FF')(`[${Date()}]`), chalk.grey("[Debug]"), chalk.hex('#FFA500')(`[${context}]`), chalk.hex('#0070BB')(`[\n${msg}\n]`)])
}
},
info(context, msg) {
if (this.level > 2)
this.proPrint([`[${Date()}]`, chalk.grey("[Info]"), chalk.hex('#FFA500')(`[${context}]`), chalk.hex('#48BB31')(`[${msg}]`)])
this.proPrint([chalk.hex('#64B3FF')(`[${Date()}]`), chalk.grey("[Info]"), chalk.hex('#FFA500')(`[${context}]`), chalk.hex('#48BB31')(`[${msg}]`)])
},
warn(context, msg) {
if (this.level > 1)
this.proPrint([`[${Date()}]`, chalk.grey("[Warn]"), chalk.hex('#FFA500')(`[${context}]`), chalk.hex('#BBBB23')(`[${msg}]`)])
this.proPrint([chalk.hex('#64B3FF')(`[${Date()}]`), chalk.grey("[Warn]"), chalk.hex('#FFA500')(`[${context}]`), chalk.hex('#BBBB23')(`[${msg}]`)])
},
error(context, msg) {
if (this.level > 0)
this.proPrint([`[${Date()}]`, chalk.grey("[Error]"), chalk.hex('#FFA500')(`[${context}]`), chalk.hex('#FF0006')(`[${msg}]`)])
this.proPrint([chalk.hex('#64B3FF')(`[${Date()}]`), chalk.grey("[Error]"), chalk.hex('#FFA500')(`[${context}]`), chalk.hex('#FF0006')(`[${msg}]`)])
}
},
/**
* 提取开奖信息
* @param {string} des 描述
* @returns {
{
ts: number|0;
text:string|'开奖时间: 未填写开奖时间';
item:string|'请自行查看';
isMe:string|'请自行查看';
}
* }
*/
getLotteryNotice(des) {
const r = /([\d零一二两三四五六七八九十]+)[.月]([\d零一二两三四五六七八九十]+)[日号]?/;
if (des === '') return {
ts: 0,
text: `开奖时间: 未填写开奖时间`,
item: '请自行查看',
isMe: '请自行查看'
}
const _date = r.exec(des) || [];
const timestamp10 = ((month, day) => {
if (month && day) {
let date = new Date(`${new Date(Date.now()).getFullYear()}-${month}-${day} 23:59:59`).getTime()
if (!isNaN(date)) return date / 1000;
}
return 0
})(_date[1], _date[2])
if (timestamp10 === 0) return {
ts: 0,
text: `开奖时间: 未填写开奖时间`,
item: '请自行查看',
isMe: '请自行查看'
}
const timestamp13 = timestamp10 * 1000,
time = new Date(timestamp13);
const remain = (() => {
const timestr = ((timestamp13 - Date.now()) / 86400000).toString()
, timearr = timestr.replace(/(\d+)\.(\d+)/, "$1,0.$2").split(',');
const text = timearr[0][0] === '-' ? `开奖时间已过${timearr[0].substring(1)}天余${parseInt(timearr[1] * 24)}小时` : `还有${timearr[0]}天余${parseInt(timearr[1] * 24)}小时`;
return text
})();
return {
ts: timestamp10,
text: `开奖时间: ${time.toLocaleString()} ${remain}`,
item: '请自行查看',
isMe: '请自行查看'
};
},
/**
* 获取远程设置
* @returns {Promise<JSON>}
@@ -297,4 +249,4 @@ const Base = {
};
module.exports = Base;
module.exports = Util;
+3 -3
View File
@@ -1,4 +1,4 @@
const { log, delay } = require("./Base");
const { log, delay } = require("./Util");
const BiliAPI = require("./BiliAPI");
const Public = require("./Public");
const GlobalVar = require('./GlobalVar');
@@ -52,9 +52,9 @@ async function clear() {
let before_separate = [];
const MY_UID = Number(GlobalVar.get('myUID'));
for (let index = 0; ; index++) {
log.info('清理动态', `开始读取第${index + 1}页(12条)`);
const { allModifyDynamicResArray, offset: _offset } = await Public.prototype.checkAllDynamic(GlobalVar.get("myUID"), 1, 5 * 1000, offset);
offset = _offset;
log.info('清理动态', `开始读取第${index + 1}页(12条)`);
for (let index = 0; index < allModifyDynamicResArray.length; index++) {
const res = allModifyDynamicResArray[index];
const { type, dynamic_id, createtime } = res;
@@ -86,7 +86,7 @@ async function clear() {
}
}
}
log.info('清理动态', `${index}页中的转发动态与关注全部处理成功`)
log.info('清理动态', `${index + 1}页中的转发动态与关注全部处理成功`)
if (offset === '0' || !success) break;
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
const { config_file } = require('./Base');
const { config_file } = require('./Util');
const my_config = require(config_file);
const config = {
+8 -8
View File
@@ -1,4 +1,4 @@
const Base = require('./Base');
const Util = require('./Util');
const BiliAPI = require('./BiliAPI');
const eventBus = require('./eventBus');
const GlobalVar = require('./GlobalVar');
@@ -6,7 +6,7 @@ const Public = require('./Public');
const Monitor = require('./Monitor');
const { sendNotify } = require('./sendNotify');
const config = require('./config');
const { log } = Base;
const { log } = Util;
async function createRandomDynamic(num) {
if (config.create_dy) {
@@ -14,8 +14,8 @@ async function createRandomDynamic(num) {
const Dynamic = await Public.prototype.checkAllDynamic(GlobalVar.get("myUID"), 1);
if ((Dynamic.allModifyDynamicResArray[0] || { type: 0 }).type === 1) {
for (let index = 0; index < num; index++) {
await BiliAPI.createDynamic(Base.getRandomOne(config.dy_contents));
await Base.delay(2000);
await BiliAPI.createDynamic(Util.getRandomOne(config.dy_contents));
await Util.delay(2000);
}
} else {
log.info('随机动态', '已有非抽奖动态故无需创建');
@@ -30,7 +30,7 @@ async function createRandomDynamic(num) {
*/
function start() {
return new Promise(resolve => {
let times = Base.counter();
let times = Util.counter();
/* 注册事件 */
eventBus.on('Turn_on_the_Monitor', async () => {
const lotterys = GlobalVar.get("Lottery");
@@ -93,8 +93,8 @@ async function isMe() {
session_t = session_ts;
if (talker_id) {
BiliAPI.updateSessionStatus(talker_id);
await Base.delay(1000);
if (/中奖|获得|填写|写上|提供|地址|支付宝账号|码|大会员/.test(content)) {
await Util.delay(1000);
if (/中奖|获得|填写|写上|提供|收货地址|支付宝账号|码|大会员/.test(content)) {
desp += `发生时间: ${new Date(timestamp * 1000).toLocaleString()} \n\n`
desp += `用户: ${sender_uid} \n\n`
desp += `私信你(${GlobalVar.get("myUID")})说: ${content} \n\n`
@@ -104,7 +104,7 @@ async function isMe() {
}
}
if (MySession.has_more) {
await Base.delay(3e3);
await Util.delay(3e3);
MySession = await BiliAPI.getSessionInfo(type, session_t)
}
max++
+2 -2
View File
@@ -1,4 +1,4 @@
const { log } = require("./Base");
const { log } = require("./Util");
const { HttpRequest } = require("./HttpRequest");
const { createTransport } = require("nodemailer");
@@ -430,7 +430,7 @@ function ddBotNotify(text, desp) {
const dateNow = Date.now();
const hmac = crypto.createHmac('sha256', DD_BOT_SECRET);
hmac.update(`${dateNow}\n${DD_BOT_SECRET}`);
const result = encodeURIComponent(hmac.digest('base64'));
const result = encodeURIComponent(hmac.digest('Util64'));
HttpRequest({
method: 'POST',
url: `https://oapi.dingtalk.com/robot/send`,
+4 -4
View File
@@ -1,4 +1,4 @@
const Base = require("./Base");
const Util = require("./Util");
const GlobalVar = require("./GlobalVar");
const config = require("./config");
@@ -21,10 +21,10 @@ async function setVariable(cookie, n) {
GlobalVar.set(key_map.get(_item[0]), _item[1]);
});
GlobalVar.set('Lottery', [...config.UIDs, ...config.TAGs]);
GlobalVar.set('remoteconfig', await Base.getRemoteConfig());
GlobalVar.set('remoteconfig', await Util.getRemoteConfig());
}
await Base.createDir('dyids');
await Base.createFile(n < 2 ? 'dyid.txt' : `dyid${n}.txt`, '', 'a')
await Util.createDir('dyids');
await Util.createFile(n < 2 ? 'dyid.txt' : `dyid${n}.txt`, '', 'a')
return
}
+10 -7
View File
@@ -1,4 +1,4 @@
const { env_file, config_file, log, delay, hasFileOrDir } = require("./lib/Base");
const { env_file, config_file, log, delay, hasFileOrDir } = require("./lib/Util");
const metainfo = [
` _ _ _ _____ _ _ `,
@@ -10,7 +10,7 @@ const metainfo = [
` __/ | | | `,
` |___/ |_| `,
` `,
` by shanmite `,
` v1.9.0 by shanmite`,
]
/**多账号存储 */
let multiple_account = [];
@@ -36,6 +36,9 @@ async function main() {
await main();
await delay(acco.WAIT);
}
/**多账号状态还原 */
process.env.ENABLE_MULTIPLE_ACCOUNT = ENABLE_MULTIPLE_ACCOUNT;
} else {
if (!COOKIE) {
return '请查看README文件, 在env.js指定位置填入cookie'
@@ -110,18 +113,18 @@ async function main() {
process.env.lottery_mode = process.argv[2]
const err_msg = await main();
if (err_msg) {
log.error('错误', '\n' + err_msg + '\n');
log.warn('结束运行', '5秒后自动退出');
await delay(5 * 1000);
} else {
if (loop_wait > 0) {
while (loop_wait) {
log.info('程序休眠', `${loop_wait / 1000}秒后再次启动`)
await delay(loop_wait);
} else {
log.info('结束运行', '未设置休眠时间')
await delay(loop_wait)
await main()
}
log.info('结束运行', '未设置休眠时间')
}
process.exit(0);
})()
+1 -1
View File
@@ -44,4 +44,4 @@
"nodemailer": "^6.5.0",
"unzipper": "^0.10.11"
}
}
}