feat: 修改转发验重逻辑

直接根据是否点赞判断
This commit is contained in:
shanmiteko 2021-10-05 17:04:47 +08:00
parent 88ad8ecfcc
commit 88d3e97595
10 changed files with 96 additions and 180 deletions

View File

@ -87,8 +87,6 @@ Chrome浏览器:
~/nlts-linux-x64
=> tree
.
├── dyids (自动生成的dyid存储)
│   └── dyid.txt
├── env.js (便捷设置环境变量和多账号参数)
├── lottery (可执行文件)
├── my_config.js (自定义设置文件) (!使用前必读)
@ -215,7 +213,12 @@ rm -rf lottery/
----------------------------------------
## 防重复转发
脚本将转发过的动态和被过滤的动态都写入`dyids/dyid*.txt`文件中
~~存储在专栏草稿~~
~~脚本将转发过的动态和被过滤的动态都写入`dyids/dyid*.txt`文件中~~
是否点赞
----------------------------------------

View File

@ -30,7 +30,7 @@ module.exports = Object.freeze({
/**
* 为防止环境变量过长, 请将多账号填在此处
* 以大括号内容为模板依次复制,逗号分割
* 以大括号内容为模板依次复制(包含大括号),逗号分割
*/
multiple_account_parm: [
{

View File

@ -5,7 +5,6 @@ const event_bus = require('../helper/event_bus');
const { Searcher } = require('./searcher');
const global_var = require("../data/global_var");
const config = require("../data/config");
const d_storage = require('../helper/d_storage');
const { log, hasEnv } = utils;
/**
@ -98,12 +97,10 @@ class Monitor extends Searcher {
}
if (ts < ts_10) {
log.info('过滤', '已过开奖时间')
d_storage.updateDyid(Lottery.dyid)
continue
}
if (ts > ts_10 + config.maxday * 86400) {
log.info('过滤', '超过指定开奖时间')
d_storage.updateDyid(Lottery.dyid)
continue
}
} else if (Lottery.uid[0]) {
@ -113,7 +110,6 @@ class Monitor extends Searcher {
}
if (followerNum < config.minfollower) {
log.info('过滤', `粉丝数(${followerNum})小于指定数量`)
d_storage.updateDyid(Lottery.dyid)
continue
}
}
@ -127,7 +123,7 @@ class Monitor extends Searcher {
default:
return status
}
d_storage.updateDyid(Lottery.dyid)
await utils.delay(config.wait * (Math.random() + 0.5));
}
log.info('抽奖', '开始转发下一组动态');
@ -170,6 +166,7 @@ class Monitor extends Searcher {
/** 所有抽奖信息 */
let alllotteryinfo = [];
const { key_words, model, chatmodel, is_imitator, only_followed, at_users, blockword, blacklist } = config;
/**Map<String, Boolean> */
let dyids_map = new Map();
@ -182,24 +179,15 @@ class Monitor extends Searcher {
return true
});
/**并发查询dyid */
await Promise.all(
[...dyids_map.keys()]
.map(it => d_storage
.searchDyid(it)
.then(hasIt => dyids_map.set(it, hasIt))
)
)
/* 检查动态是否满足要求 */
await utils.try_for_each(protoLotteryInfo, async function ({
lottery_info_type, uids,
uname, dyid,
lottery_info_type, is_liked,
uids, uname, dyid,
ctrl, rid, des, type,
hasOfficialLottery
}) {
/* 遇到转发过就退出 */
if (dyids_map.get(dyid)) return false;
if (is_liked) return false;
const
/**判断是转发源动态还是现动态 */

View File

@ -1,7 +1,6 @@
const utils = require('../utils');
const bili = require('../net/bili');
const config = require("../data/config");
const d_storage = require('../helper/d_storage');
const { log } = utils
@ -11,6 +10,7 @@ const { log } = utils
* @typedef {object} UsefulDynamicInfo
* @property {number} uid
* @property {string} uname
* @property {boolean} is_liked
* @property {number} createtime 10
* @property {string} rid_str
* @property {string} dynamic_id
@ -35,13 +35,16 @@ function parseDynamicCard(dynamic_detail_card) {
/**临时储存单个动态中的信息 */
let obj = {};
const { desc, card, extension, extend_json } = dynamic_detail_card
, { info } = desc.user_profile
, { is_liked, user_profile } = desc
, { info } = user_profile
, cardToJson = strToJson(card)
, { item } = cardToJson;
/* 转发者的UID */
obj.uid = info.uid;
obj.uid = info.uid
/* 转发者的name */
obj.uname = info.uname;
obj.uname = info.uname
/* 动态是否点过赞 */
obj.is_liked = is_liked > 0
/* 动态的ts10 */
obj.createtime = desc.timestamp
/* 动态类型 */
@ -132,6 +135,7 @@ class Searcher {
* 整理后的抽奖信息
* @typedef {object} LotteryInfo
* @property {string} lottery_info_type
* @property {boolean} is_liked
* @property {number[]} uids `[uid,ouid]`
* @property {string} uname
* @property {Array<{}>} ctrl
@ -213,21 +217,52 @@ class Searcher {
log.info('获取动态', `开始获取用户${UID}的动态信息`);
const { allModifyDynamicResArray } = await Searcher.checkAllDynamic(UID, config.uid_scan_page, config.search_wait);
if (!allModifyDynamicResArray.length) return null;
let { length } = allModifyDynamicResArray
if (!length) return null;
const fomatdata = await allModifyDynamicResArray
.filter(d => {
if (d.type === 1) {
return true
} else {
length--
return false
}
})
.reduce(async (pre, cur) => {
const results = await pre
, { origin_dynamic_id } = cur;
log.info('获取动态', `查看源动态(${origin_dynamic_id})的细节 (${length--})`)
const res = await bili.getOneDynamicByDyid(origin_dynamic_id)
, { code, data } = utils.strToJson(res)
, { card } = data || {};
if (code !== 0) {
log.error('获取动态', '获取动态数据出错,可能是访问太频繁 \n' + res)
return results
}
await utils.delay(2000)
const { is_liked } = parseDynamicCard(card)
return [...results, {
lottery_info_type: 'uid',
is_liked,
uids: [cur.uid, cur.origin_uid],
uname: cur.origin_uname,
ctrl: [],
dyid: cur.origin_dynamic_id,
rid: cur.origin_rid_str,
des: cur.origin_description,
type: cur.orig_type,
hasOfficialLottery: cur.origin_hasOfficialLottery
}]
}, Promise.resolve([]))
const fomatdata = allModifyDynamicResArray.map(o => {
return {
lottery_info_type: 'uid',
uids: [o.uid, o.origin_uid],
uname: o.origin_uname,
ctrl: [],
dyid: o.origin_dynamic_id,
rid: o.origin_rid_str,
des: o.origin_description,
type: o.orig_type,
hasOfficialLottery: o.origin_hasOfficialLottery
}
}).filter(a => a.type != 0)
log.info('获取动态', `成功获取用户${UID}的动态信息`);
return fomatdata;
@ -271,6 +306,7 @@ class Searcher {
const fomatdata = mDRdata.map(o => {
return {
lottery_info_type: 'tag',
is_liked: o.is_liked,
uids: [o.uid, o.origin_uid],
uname: o.uname,
ctrl: o.ctrl,
@ -311,36 +347,38 @@ class Searcher {
/**单个专栏中的dyid */
_dyinfos = [];
log.info('获取动态', `提取专栏(${cv})中提及的dyid(${length})`)
/**遍历某专栏中的dyids */
for (const dyid of dyids_set) {
const isRelayed = await d_storage.searchDyid(dyid);
if (isRelayed) {
_weight += 1;
}
if (_weight >= weight && !config.not_check_article) {
log.warn('获取动态', `1/2动态曾经转过,该专栏或已查看,故中止`)
_dyinfos = []
break
}
if (dyid.length === utils.dyid_length) {
if (!isRelayed) {
log.info('获取动态', `查看动态(${dyid})的细节 (${length--})`)
const res = await bili.getOneDynamicByDyid(dyid)
, { code, data } = utils.strToJson(res)
, { card } = data || {};
log.info('获取动态', `查看专栏中所提及动态(${dyid})的细节 (${length--})`)
const res = await bili.getOneDynamicByDyid(dyid)
, { code, data } = utils.strToJson(res)
, { card } = data || {};
if (code !== 0) {
log.error('获取动态', '获取动态数据出错,可能是访问太频繁 \n' + res)
if (code !== 0) {
log.error('获取动态', '获取动态数据出错,可能是访问太频繁 \n' + res)
break
}
await utils.delay(2000)
if (card) {
const parsed_card = parseDynamicCard(card)
, { is_liked } = parsed_card;
if (is_liked) {
log.info('获取动态', `动态(${dyid})已转发过`)
_weight += 1;
}
if (_weight >= weight && !config.not_check_article) {
log.warn('获取动态', `1/2动态曾经转过,该专栏或已查看,故中止`)
_dyinfos = []
break
}
await utils.delay(2000)
if (card) {
_dyinfos.push(parseDynamicCard(card));
}
} else {
log.info('获取动态', `动态(${dyid})已转发过 (${length--})`)
_dyinfos.push(parsed_card);
}
} else {
log.warn('获取动态', `动态(${dyid})无效 (${length--})`)
@ -351,6 +389,7 @@ class Searcher {
const fomatdata = dyinfos.map(o => {
return {
lottery_info_type: 'article',
is_liked: o.is_liked,
uids: [o.uid, o.origin_uid],
uname: o.uname,
ctrl: o.ctrl,

View File

@ -37,8 +37,6 @@ let global_var = {
]);
this.set('remoteconfig', await getRemoteConfig());
}
await createDir('dyids');
await createFile(n < 2 ? 'dyid.txt' : `dyid${n}.txt`, '', 'a')
}
};

View File

@ -1,52 +0,0 @@
const { log, readDyidFile, writeDyidFile, dyid_length } = require("../utils");
const d_storage = {
/**
* 搜索dyid
* @param {string} dyid
* @returns {Promise<boolean>}
*/
searchDyid: (dyid) => {
return new Promise((resolve) => {
const Rdyid = new RegExp(dyid);
const rs = readDyidFile(Number(process.env.NUMBER));
let status = false;
rs.on('data', chunk => {
if (Rdyid.test(chunk)) {
status = true
}
})
rs.on('end', () => {
resolve(status)
})
rs.on('error', err => {
log.error('搜索dyid', err)
resolve(status)
})
})
},
/**
* 更新dyid
* @param {string} dyid
*/
updateDyid: (dyid) => {
log.info('更新dyid', `写入${dyid}`);
if (dyid.length !== dyid_length) {
log.error('更新dyid', `dyid(${dyid})长度不为18 若出现此问题请即时通知开发者`)
}
return new Promise((resolve) => {
const ws = writeDyidFile(Number(process.env.NUMBER));
ws.write(dyid + ',', () => {
ws.destroy();
resolve()
})
ws.on('error', err => {
log.error('更新dyid', err)
resolve()
})
});
}
}
module.exports = d_storage;

View File

@ -13,8 +13,6 @@ const utils = {
env_file: path.join(process.cwd(), "env.js"),
/**配置文件 */
config_file: path.join(process.cwd(), "my_config.js"),
/**dyid存储文件 */
dyids_dir: path.join(process.cwd(), "dyids"),
/**dyid长度 */
dyid_length: 18,
/**
@ -294,50 +292,6 @@ const utils = {
resolve()
})
});
},
/**
* CreateFile
* @param {string} filepath 相对于dyids的文件路径
* @param {string} [defaultValue] 写入默认值
* @param {string} flag
* @returns {Promise<void>}
*/
createFile(filepath, defaultValue, flag) {
const fpath = path.join(utils.dyids_dir, filepath);
const buffer = Buffer.from(defaultValue);
return new Promise((resolve, rejects) => {
fs.open(fpath, flag, (err, fd) => {
if (err) {
rejects(err)
} else {
fs.write(fd, buffer, 0, buffer.length, 0, err => {
if (err) {
rejects(err)
} else {
resolve();
}
})
}
})
});
},
/**
* 读取dyid文件
* @param {number} num
* @returns {fs.ReadStream}
*/
readDyidFile(num) {
const fpath = num < 2 ? path.join(utils.dyids_dir, 'dyid.txt') : path.join(utils.dyids_dir, `dyid${num}.txt`);
return fs.createReadStream(fpath, { encoding: 'utf8', highWaterMark: (utils.dyid_length + 1) * 1000 })
},
/**
* 追加dyid
* @param {number} num
* @returns {fs.WriteStream}
*/
writeDyidFile(num) {
const fpath = num < 2 ? path.join(utils.dyids_dir, 'dyid.txt') : path.join(utils.dyids_dir, `dyid${num}.txt`);
return fs.createWriteStream(fpath, { flags: 'a' })
}
};

View File

@ -1,4 +1,4 @@
module.exports = {
module.exports = Object.freeze({
/**
* 默认设置(公用)
*/
@ -7,7 +7,6 @@ module.exports = {
* 监视更转的用户uid
*/
UIDs: [
31252386,
689277291,
241675899
],
@ -73,7 +72,7 @@ module.exports = {
* - 获取专栏数量
*/
article_scan_page: 3,
/**
* - 不检查专栏是否看过若选择检查可以提高检测效率
* - 默认false(检查)
@ -255,4 +254,4 @@ module.exports = {
config_1: {},
config_2: {},
config_3: {}
}
})

View File

@ -1,6 +1,6 @@
{
"name": "lottery-auto-script",
"version": "2.1.8",
"version": "2.2.0",
"description": "自动参与B站动态抽奖",
"main": "main.js",
"scripts": {

View File

@ -3,8 +3,6 @@ set -e
# 脚本根目录
SCRIPT_FOLDER=lottery
# dyid存放目录
DYID_FOLDER=dyids
# 设置环境变量文件
ENV_FILE=env.js
# 自定义设置文件
@ -26,14 +24,6 @@ fi
cd $SCRIPT_FOLDER/
# 新建dyid储存目录
if [ ! -d "$DYID_FOLDER" ]; then
echo "create $DYID_FOLDER/"
mkdir $DYID_FOLDER
else
echo "$DYID_FOLDER/ exists"
fi
# 新建环境变量设置文件
if [ ! -f "$ENV_FILE" ]; then
echo "create $ENV_FILE"
@ -58,7 +48,6 @@ echo -e "#!/bin/bash\n\
docker run \
-v $PWD/$ENV_FILE:/lottery/$ENV_FILE \
-v $PWD/$CONFIG_FILE:/lottery/$CONFIG_FILE \
-v $PWD/$DYID_FOLDER/:/lottery/$DYID_FOLDER/ \
$DOCKER_REPO \
start" \
> start.sh
@ -69,7 +58,6 @@ echo -e "#!/bin/bash\n\
docker run \
-v $PWD/$ENV_FILE:/lottery/$ENV_FILE \
-v $PWD/$CONFIG_FILE:/lottery/$CONFIG_FILE \
-v $PWD/$DYID_FOLDER/:/lottery/$DYID_FOLDER/ \
$DOCKER_REPO \
check" \
> check.sh
@ -80,7 +68,6 @@ echo -e "#!/bin/bash\n\
docker run \
-v $PWD/$ENV_FILE:/lottery/$ENV_FILE \
-v $PWD/$CONFIG_FILE:/lottery/$CONFIG_FILE \
-v $PWD/$DYID_FOLDER/:/lottery/$DYID_FOLDER/ \
$DOCKER_REPO \
clear" \
> clear.sh