diff --git a/apps/thumbUp.js b/apps/thumbUp.js index c611b3c..8d9d0e6 100644 --- a/apps/thumbUp.js +++ b/apps/thumbUp.js @@ -1,7 +1,6 @@ import { funApi, common, memes } from "../model/index.js" import _ from "lodash" import { Config } from "../components/index.js" -import { successImgs, faildsImgs } from "../constants/fun.js" export class ThumbUp extends plugin { constructor(e) { @@ -24,67 +23,90 @@ export class ThumbUp extends plugin { * @param e */ async thumbUp(e) { - let _do = "赞" + const DO_ZAN = "赞" + const DO_CHAO = "超" + let doType = DO_ZAN let userId = e.user_id let isSelf = true - if (e.msg.includes("超", "操", "草", "抄", "吵", "炒")) { - _do = "超" + + // 使用数组和includes方法的正确用法 + const forbiddenWords = [ "超", "操", "草", "抄", "吵", "炒" ] + if (forbiddenWords.some(word => e.msg.includes(word))) { + doType = DO_CHAO } - if (e.at && e.msg.includes("他", "她", "它", "TA", "ta", "Ta")) { + + const atWords = [ "他", "她", "它", "TA", "ta", "Ta" ] + if (e.at && atWords.some(word => e.msg.includes(word))) { userId = e.at isSelf = false } /** 判断是否为好友 */ let isFriend = await (e.bot ?? Bot).fl.get(userId) let allowLikeByStrangers = Config.whole.Strangers_love - if (!isFriend && !allowLikeByStrangers) { return (e.message?.[0]?.text == "#全部赞我") ? false : e.reply(`不加好友不${_do}🙄`, true) } + if (!isFriend && !allowLikeByStrangers) { + return (e.message?.[0]?.text == "#全部赞我") ? false : e.reply(`不加好友不${doType}🙄`, true) + } + /** 执行点赞 */ let n = 0 - let failsMsg = `今天已经${_do}过了,还搁这讨${_do}呢!!!` + let failsMsg = `今天已经${doType}过了,还搁这讨${doType}呢!!!` + let thumbUpApi = new funApi.ThumbUpApi(e) // 复用ThumbUpApi实例 for (let i = 0; i < 10; i++) { let res = null try { - res = await new funApi.ThumbUpApi(e).thumbUp(userId, 10) + res = await thumbUpApi.thumbUp(userId, 10) } catch (error) { logger.error(error) return common.handleException(e, error) } + logger.debug(`${e.logFnc}给${userId}点赞`, res) + if (res.code) { if (res.code == 1) { - failsMsg = `${_do}失败,请检查是否开启陌生人点赞或添加好友` + failsMsg = `${doType}失败,请检查是否开启陌生人点赞或添加好友` } else { - if (_do == "超") { - failsMsg = res.msg.replace(/点赞/g, "超").replace("给", "超").replace("点", "").replace("个赞", "下") + if (doType == "超") { + failsMsg = generateFailMsg(doType, res.msg) } else { failsMsg = res.msg } } - break + continue } else { n += 10 } } - let successMsg = `给${isSelf ? "你" : userId}${_do}了${n}下哦,记得回我~ ${isFriend ? "" : `(如${_do}失败请添加好友)`}` + let successMsg = `给${isSelf ? "你" : userId}${doType}了${n}下哦,记得回我~ ${isFriend ? "" : `(如${doType}失败请添加好友)`}` const avatar = `https://q1.qlogo.cn/g?b=qq&s=100&nk=${userId}` const successFn = _.sample([ "ganyu", "zan" ]) /** 判断点赞是否成功 */ - let msg = n > 0 - ? [ - `\n${successMsg}`, - segment.image((await memes[successFn](avatar)) || - _.sample(successImgs) + userId) - ] - : (e.message?.[0]?.text == "#全部赞我") - ? [] - : [ - `\n${failsMsg}`, - segment.image((await memes.crawl(avatar)) || - _.sample(faildsImgs) + userId) - ] + let msg = (e.message?.[0]?.text == "#全部赞我") + ? [] + : await generateResponseMsg(n > 0, successMsg, failsMsg, avatar, successFn) /** 回复 */ if (msg.length) { return e.reply(msg, true, { at: userId }) } } } +// 工具函数:生成失败消息 +function generateFailMsg(doType, originalMsg) { + let failsMsg + if (doType === "超") { + failsMsg = originalMsg.replace(/点赞/g, "超").replace("给", "超").replace("点", "").replace("个赞", "下") + } else { + failsMsg = originalMsg + } + return failsMsg +} +// 工具函数:生成响应消息 +async function generateResponseMsg(isSuccess, successMsg, failsMsg, avatar, successFn) { + if (isSuccess) { + const imageSegment = segment.image((await memes[successFn](avatar))) + return [ `\n${successMsg}`, imageSegment ] + } else { + const imageSegment = segment.image((await memes.crawl(avatar))) + return [ `\n${failsMsg}`, imageSegment ] + } +} diff --git a/constants/fun.js b/constants/fun.js index c9bab0e..aab0ed1 100644 --- a/constants/fun.js +++ b/constants/fun.js @@ -1,21 +1,6 @@ -/** 点赞成功回复的图片 */ -export const successImgs = [ - "https://xiaobai.klizi.cn/API/ce/xin.php?qq=", - "https://xiaobai.klizi.cn/API/ce/zan.php?qq=" -] - /** 点赞失败回复的图片 */ export const faildsImgs = [ "https://xiaobai.klizi.cn/API/ce/paa.php?qq=" ] -export const heisiType = { - "白丝": { type: "baisi", page: 17 }, - "黑丝": { type: "heisi", page: 43 }, - "巨乳": { type: "juru", page: 8 }, - "jk": { type: "jk", page: 6 }, - "网红": { type: "mcn", page: 36 }, - "美足": { type: "meizu", page: 9 } -} - export const xiurenTypeId = { "秀人": { id: 117, diff --git a/lib/request/request.js b/lib/request/request.js index 3d3bf3d..fc212c0 100644 --- a/lib/request/request.js +++ b/lib/request/request.js @@ -36,6 +36,12 @@ export const qs = (obj) => { return res.slice(0, res.length - 1) } +const mergeOptions = (defaultOptions, userOptions) => { + // 优化headers的合并逻辑,确保安全性 + const headers = { ...defaultOptions.headers, ...userOptions.headers } + return { ...defaultOptions, ...userOptions, headers } +} + export default new class { /** * 发送HTTP GET请求并返回响应 @@ -49,38 +55,12 @@ export default new class { * @param {'buffer'|'json'|'text'|'arrayBuffer'|'formData'|'blob'}[options.statusCode] - 期望的返回数据,如果设置了该值,则返回响应数据的特定的方法(如json()、text()等) * @param {boolean} [options.origError] 出现错误是否返回原始错误 * @returns {Promise} - HTTP响应或响应数据 - * @throws {Error} - 如果请求失败,则抛出错误,将`options.origError`设置为true将返回原始错误 + * @throws {Error} - 如果请求失败,则抛出错误,将`options.origError`设置为true则抛出原始错误 */ async get(url, options = {}) { - // 处理参数 - if (options.params) { - url = url + "?" + qs(options.params) - } - logger.debug(`[Yenai-Plugin] GET请求:${decodeURI(url)}`) - options.headers = { - "User-Agent": CHROME_UA, - ...options.headers - } - if (!options.agent) options.agent = this.getAgent() - try { - let res = await fetch(url, options) - if (!options.closeCheckStatus) { - res = checkStatus(res) - } - if (options.statusCode) { - return res[options.statusCode]() - } - return res - } catch (err) { - if (options.origError) { - throw err - } else { - logger.error(err) - throw new RequestError( - `Get Error,${err.message.match(/reason:(.*)/)?.[1] || err.message}` - ) - } - } + options = mergeOptions({ method: "GET", url }, options) + options = this._prepareRequest(options) + return this._reques(options) } /** @@ -96,20 +76,16 @@ export default new class { * @param {'buffer'|'json'|'text'|'arrayBuffer'|'formData'|'blob'} [options.statusCode] - 期望的返回数据,如果设置了该值,则返回响应数据的特定的方法(如json()、text()等) * @param {boolean} [options.origError] 出现错误是否返回原始错误 * @returns {Promise} - HTTP响应或响应数据 - * @throws {Error} - 如果请求失败,则抛出错误,将`options.origError`设置为true将返回原始错误 + * @throws {Error} - 如果请求失败,则抛出错误,将`options.origError`设置为true则抛出原始错误 */ async post(url, options = {}) { - options.method = "POST" - options.headers = { - "User-Agent": CHROME_UA, - "Content-Type": "application/json", - ...options.headers - } - if (options.params) { - url = url + "?" + qs(options.params) - } - logger.debug(`[Yenai-Plugin] POST请求:${decodeURI(url)}`) + options = mergeOptions({ + method: "POST", headers: { "Content-Type": "application/json" }, url + }, options) + options = this._prepareRequest(options) + if (options.data) { + logger.debug("[Yenai-Plugin]POST request params data: ", options.data) if (/json/.test(options.headers["Content-Type"])) { options.body = JSON.stringify(options.data) } else if ( @@ -121,26 +97,7 @@ export default new class { } delete options.data } - if (!options.agent) options.agent = this.getAgent() - try { - let res = await fetch(url, options) - if (!options.closeCheckStatus) { - res = checkStatus(res) - } - if (options.statusCode) { - return res[options.statusCode]() - } - return res - } catch (err) { - if (options.origError) { - throw err - } else { - logger.error(err) - throw new RequestError( - `Get Error,${err.message.match(/reason:(.*)/)?.[1] || err.message}` - ) - } - } + return this._reques(options) } /** @@ -230,4 +187,40 @@ export default new class { }).catch(err => logger.error(err)) return segment.image(Request?.body ?? `${Plugin_Path}/resources/img/imgerror.png`, cache, timeout) } + + _prepareRequest(options) { + // 处理参数 + if (options.params) { + options.url = `${options.url}?${qs(options.params)}` + } + logger.debug(`[Yenai-Plugin] ${options.method.toUpperCase()}请求:${decodeURI(options.url)}`) + options.headers = { + "User-Agent": options.headers && options.headers["User-Agent"] ? options.headers["User-Agent"] : CHROME_UA, + ...options.headers + } + + if (options.agent == undefined) options.agent = this.getAgent(options.cf) + + return options + } + + async _reques(options) { + try { + let res = await fetch(options.url, options) + if (!options.closeCheckStatus) { + res = checkStatus(res) + } + if (options.statusCode) { + return res[options.statusCode]() + } + return res + } catch (err) { + logger.error(err) + if (options.origError) throw err + + throw new RequestError( + `${options.method.toUpperCase()} Error,${err.message.match(/reason:(.*)/)?.[1] || err.message}` + ) + } + } }()