// ==UserScript== // @name 妖火网增强脚本Plus // @namespace https://www.yaohuo.me/ // @version 0.0.5 // @description 让妖火再次变得伟大(手动狗头.jpg) // @author 柠檬没有汁@27894 // @match *://yaohuo.me/* // @match *://*.yaohuo.me/* // @icon https://yaohuo.me/css/favicon.ico // @run-at document-body // @license MIT // @grant none // @noframes // @homepage https://www.yaohuo.me/bbs/userinfo.aspx?touserid=27894 // @supportURL https://www.yaohuo.me/bbs/userinfo.aspx?touserid=27894 // @require https://code.jquery.com/jquery-3.7.1.min.js // @downloadURL none // ==/UserScript== (async function () { "use strict"; if (!checkLocation()) return; if (!checkJQueryLoad()) return; await initSetting(); const customSetting = JSON.parse(localStorage.getItem("yaohuoBetterPlusSetting")); console.log("yaohuoBetterPlus 用户设置:", customSetting); // 确保在页面加载完成后再执行代码,否则jquery可能会获取不到 document 内容 $(document).ready(() => { createScriptSetting(); customSetting["showTopAndDownBtn"] && addTopAndDown(); customSetting["showChuiniuHistory"] && executeFunctionForURL("/games/chuiniu/doit.aspx", chuiniuHistory); customSetting["oneClickCollectMoney"] && executeFunctionForURL(/^\/bbs-.*\.html$/, speedEatMoney, true); // bookViewAddUbb(); }); })(); // 发帖UBB增强 function bookViewAddUbb() { const bookViewPageList = [ "/bbs/book_view_add.aspx", "/bbs/book_view_sendmoney.aspx", "/bbs/book_view_addvote.aspx", "/bbs/book_view_addfile.aspx", "/bbs/book_view_mod.aspx", "/bbs/book_view_addURL.aspx", ]; console.log(window.location.pathname); // if (bookViewPageList.includes(window.location.pathname)) // let targetEle = $('.book_view_add_height'); // console.log(targetEle); // let newEle = $('
历史记录获取中...
` ).insertBefore($(".subtitle")); const userinfoEle = $('a[href*="userinfo.aspx"]'); const chuiniuQueUserId = getUrlParam("touserid", userinfoEle.attr("href")); // 发布者ID const chuiniuQueUserNickname = userinfoEle.text(); // 发布者昵称 const queHistoryArr = Array.from(await getQueUserHistoryArr(chuiniuQueUserId)); // 发布者历史大话ID if (queHistoryArr.length > 0) { // 获取成功 const queHistoryAnswers = await Promise.all(queHistoryArr.map(getChuiniuAnswer)); const countAnswer1 = queHistoryAnswers.filter((v) => v === "1").length; const countAnswer2 = queHistoryAnswers.filter((v) => v === "2").length; $("#chuiniuWinningEle") .css({ "text-align": "left", }) .html( `“${chuiniuQueUserNickname}”最近${queHistoryAnswers.length}次已完成大话选项:答案1次数:${countAnswer1},答案2次数: ${countAnswer2}` ); } else { // 获取失败 $("#chuiniuWinningEle").html(`未知错误,获取历史数据失败,请私信反馈`); } // 获取指定大话答案 async function getChuiniuAnswer(chuiniuId) { const chuiniuRes = await getPageContent(`/games/chuiniu/book_view.aspx?id=${chuiniuId}`); const ansRule1 = chuiniuRes.match(/挑战方出的是\[答案1\]/); const ansRule2 = chuiniuRes.match(/挑战方出的是\[答案2\]/); if (ansRule1) return "1"; if (ansRule2) return "2"; } // 获取对方大话指定条数历史记录ID async function getQueUserHistoryArr(toUserId, computeTotal = 15) { return new Promise(async (resolve, reject) => { const idArr = new Set(); // 存放大话ID,利用Set特性去重(翻页时会有重复项出现,非本脚本bug) let historyPage = 1; // 翻页,达到预设值时停止 const historyText = await getPageContent(`/games/chuiniu/book_list.aspx?type=0&touserid=${toUserId}`); const userHistoryTotal = historyText.slice(historyText.indexOf("页,共 ") + 4, historyText.indexOf(" 条")); // 吹牛历史总条数 const getQueUserHistoryid = async () => { const tempElements = $(historyText).filter(".line1, .line2"); for (const line of tempElements) { const idLink = line.querySelector('a[href*="book_view.aspx"]'); if (idLink && !line.textContent.includes("进行中")) { const dahuaId = getUrlParam("id", idLink.href); if (dahuaId) idArr.add(dahuaId); if (idArr.length >= computeTotal) break; } } if (idArr.length < 15 && userHistoryTotal > 15) { historyPage++; getQueUserHistoryid(); } else { resolve(idArr); } }; getQueUserHistoryid(); }); } } // 一键回到顶部/底部,在原作者基础上做了删减、改动,原作者发布地址:https://greasyfork.org/zh-CN/scripts/38899-回到顶部-底部 function addTopAndDown() { if (window.self != window.top) return; function ce(n) { return document.createElement(n); } function addStyle(css) { let head = document.head || document.getElementsByTagName("head")[0]; if (head) { let style = ce("style"); style.type = "text/css"; style.appendChild(document.createTextNode(css)); head.appendChild(style); } } let el = navigator.userAgent.indexOf("Firefox") != -1 || navigator.userAgent.indexOf("MSIE") != -1 ? document.documentElement : document.body, t1, t2, speed_by_click = 200, zIindex = 1001; function getDocumentHeight() { return document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight; } function get_scroll(a) { let d = document, b = d.body, e = d.documentElement, c = "client" + a, f = "scroll" + a; return /CSS/.test(d.compatMode) ? e[c] < e[f] : b[c] < b[f]; } function scrollTo(element, to, duration) { (start = document.documentElement.scrollTop || document.body.scrollTop), (change = to - start), (currentTime = 0), (increment = 20), (newDuration = typeof duration === "undefined" ? 500 : duration); let animateScroll = function () { currentTime += increment; let val = Math.easeInOutQuad(currentTime, start, change, newDuration); window.scrollTo(0, val); if (currentTime < newDuration) { setTimeout(animateScroll, increment); } }; animateScroll(); } Math.easeInOutQuad = function (t, b, c, d) { t /= d / 2; if (t < 1) return (c / 2) * t * t + b; t--; return (-c / 2) * (t * (t - 2) - 1) + b; }; function shareCSS() { let s = "", img_up, img_dn; img_up = "data:img/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAUCAYAAACAl21KAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB+SURBVDhPY1i1atV/amAGahgCMoNhaIGlS5cKAp19BoRBbLJcj2QILDJINwzoAmMgfoclIkBixkS5DI8hMJcRNgxoSBoOl6CnNZBhaVhdBjWE1MSJahjQkA4KEmYH2GUrV66cSYEhYB+AzKBtFiHkQqKiH6Ro1CDCQTWgYQQAs81DU0G/83sAAAAASUVORK5CYII="; img_dn = "data:img/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAUCAYAAACAl21KAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACPSURBVDhPY2DAAlatWvUfH8amB6vYqEGEg2pgw4iQ7cTKM6xcuXImsYpxqQOZAQ4woIIOCgzrQAl1oEFpZBiWhitFgwx7R4SBIDXYDYGZDFRgTMAwkCHGhBMRJMxwGUa8ITCbli5dKgg08AySN8+AxIhyCboiJMPIN4Qsm6miiYioxltawvSDYogohYTUAQC80UNTOht/YwAAAABJRU5ErkJggg=="; s += "#play_btn_up { position:fixed; right:0; top:55%;z-index:" + zIindex + "; height:40px; width:36px; cursor:pointer; background:url(" + img_up + ") no-repeat scroll 50% 50% rgba(0, 0, 0, 0.7); border-radius:5px 0 0 5px; margin-top:-24px; }"; s += "#play_btn_dn { position:fixed; right:0; top:60%; z-index:" + zIindex + "; height:40px; width:36px; cursor:pointer; background:url(" + img_dn + ") no-repeat scroll 50% 50% rgba(0, 0, 0, 0.7); border-radius:5px 0 0 5px; margin-top:-24px; }"; s += ".play_btn { -webkit-transition-duration:0.5s linear; -o-transition-duration:0.5s linear; -moz-transition-duration:0.5s linear; transition-duration:0.5s linear; opacity:0.65; }"; s += ".play_btn:hover { opacity:1; }"; addStyle("" + s); } function create_btn_element() { let up, dn, scrolled, h = get_scroll("Height"); if (!h) { return; } shareCSS(); if (el) { up = ce("span"); dn = ce("span"); up.setAttribute("id", "play_btn_up"); dn.setAttribute("id", "play_btn_dn"); up.className = "play_btn"; dn.className = "play_btn"; document.body.appendChild(up); document.body.appendChild(dn); scrolled = window.pageYOffset || document.documentElement.scrollTop; up.style.display = scrolled > 0 ? "" : "none"; up.addEventListener( "mouseout", function () { clearTimeout(t1); }, false ); dn.addEventListener( "mouseout", function () { clearTimeout(t2); }, false ); up.addEventListener( "click", function () { scrollTo(el, 0, speed_by_click); }, false ); dn.addEventListener( "click", function () { scrollTo(el, getDocumentHeight(), speed_by_click); }, false ); window.onscroll = function () { let scrolled = document.documentElement.scrollTop, diffHeight = document.body.scrollHeight - window.innerHeight; up.style.display = scrolled > 0 ? "" : "none"; dn.style.display = diffHeight > scrolled ? "" : "none"; }; } } create_btn_element(); } // 生成设置图标 function createScriptSetting() { createIcon(); function createPopupContainer() { // 蒙版 const overlay = $("").text("这是一个弹出内容的示例。".repeat(500)));
// 禁止蒙版下的body内容滚动
$("body").css("overflow", "hidden");
}
function closePopupContainer() {
// 恢复body内容滚动
$("body").css("overflow", "auto");
// 移除蒙版和弹出内容容器
$(".popup-overlay").remove();
}
function createIcon() {
const windowWidth = $(window).width();
const bodyContentWidth = $("body").width();
const iconSize = windowWidth > 720 ? "60px" : "40px";
$("")
.attr("id", "settingICon")
.attr("src", "https://pic.imgdb.cn/item/66c4cb46d9c307b7e92a418b.png")
.css({
"position": "fixed",
"top": "10px",
"right": "10px",
"width": iconSize,
"height": iconSize,
"z-index": 9998,
})
.appendTo("body")
.click(() => {
createPopupContainer();
});
// PC端设置右偏移量
if (windowWidth > bodyContentWidth) {
const rightOffset = (windowWidth - bodyContentWidth) / 2 + 10;
$("#settingICon").css("right", rightOffset + "px");
}
}
}
// 初始化本地设置文件(存放于localStorage,清除浏览器缓存会让设置失效)
function initSetting() {
return new Promise((resolve, reject) => {
const defaultSetting = {
// 第一次加载脚本
firstLoadScript: true,
// 显示设置 logo
showSettingIcon: true,
// 设置 logo 大小
settingIconSize: 50,
// 显示吹牛胜率
showChuiniuHistory: true,
// 显示一键回到顶部/底部
showTopAndDownBtn: true,
// 发帖 ubb 展开
showMoreUbb: true,
// 显示勋章
showMedal: true,
// 回帖 ubb 展开
// 回帖表情展开
// 回帖 +1
// 站内图片增强
// 一键吃肉
oneClickCollectMoney: true,
};
const localSetting = JSON.parse(localStorage.getItem("yaohuoBetterPlusSetting")) || {};
const saveSetting = { ...defaultSetting, ...localSetting }; // 合并设置,自定义项覆盖默认选项,避免添加新功能时已缓存设置没有新功能相关从而产生bug
try {
localStorage.setItem("yaohuoBetterPlusSetting", JSON.stringify(saveSetting));
console.log("======> [ 已成功初始化设置 ]");
resolve();
} catch (error) {
reject(error);
}
});
}
/**
* 递归检测jQuery是否成功加载
* @param {Number} maxAttempts 最大检测次数
* @param {Number} interval 检测间隔时间/ms
* @param {Number} attempt 已检测次数
* @returns
*/
function checkJQueryLoad(maxAttempts = 50, interval = 200, attempt = 0) {
if (typeof jQuery !== "undefined") {
console.log("已成功加载 jQuery");
return true;
} else if (attempt < maxAttempts) {
console.log("已检测次数:", attempt + 1);
setTimeout(() => {
checkJQueryLoad(maxAttempts, interval, attempt + 1);
}, interval);
} else {
console.log("无法加载 jQuery");
notifyBox("jQuery 加载失败,增强脚本运行已终止", false);
return false;
}
}
// 判断是否是在网站中(有些手机端浏览器无法识别油猴 @match 标识,导致在所有网站都会执行脚本)
function checkLocation() {
const currentUrl = window.location.href;
const regex1 = new RegExp(/^https?:\/\/yaohuo\.me\/.*/i);
const regex2 = new RegExp(/^https?:\/\/[^/]+\.yaohuo\.me\/.*/i);
if (regex1.test(currentUrl) || regex2.test(currentUrl)) {
return true;
} else {
return false;
}
}
/* ================================================== 自定义方法开始 ================================================== */
/**
* 在指定textarea/input当前光标处插入内容
* @param {*} content 插入内容
* @param {String} targetEle 插入目标 element(jquery可使用的选择器)
*/
function insetCustomContent(content, targetEle) {
const textarea = $(targetEle); // 获取目标元素
const cursorPosition = textarea[0].selectionStart; // 获取当前光标位置
const currentValue = textarea.val(); // 当前内容
const newValue = currentValue.slice(0, cursorPosition) + content + currentValue.slice(cursorPosition); // 将内容插入当前光标处。如果未选择输入框则插入最后
textarea.val(newValue); // 写入完整内容
// 将光标移到插入内容的最后
textarea[0].selectionStart = cursorPosition + content.length;
textarea[0].selectionEnd = cursorPosition + content.length;
textarea.focus();
}
/**
* 当前页面为指定 url 时执行函数
* @param {*} targetPath 指定 url,可为正则表达式
* @param {Function} executeFunction 执行函数
* @param {Boolean} isRegex 是否使用正则判断 url
*/
function executeFunctionForURL(targetPath, executeFunction, isRegex = false) {
if (isRegex) {
targetPath.test(window.location.pathname) && executeFunction();
} else {
if (typeof targetPath !== "string" || typeof executeFunction !== "function") {
throw new Error("参数无效!");
}
window.location.pathname === targetPath && executeFunction();
}
}
// 从指定url获取get参数`
function getUrlParam(paramName, targetUrl = window.location.href) {
try {
let urlObj = new URL(targetUrl, window.location.origin);
return urlObj.searchParams.get(paramName);
} catch (error) {
console.error("无效的URL:", targetUrl, error);
return null;
}
}
// 获取指定页面内容
function getPageContent(path, method = "GET") {
const url = `${window.location.origin}${path}`;
return new Promise((resolve, reject) => {
$.ajax({
url,
method,
dataType: "html",
success: (response) => {
resolve(response);
},
error: (error) => {
reject(error);
},
});
});
}
// 设置保存
function settingChange(setName, setValue) {
let cacheSetting = JSON.parse(localStorage.getItem("yaohuoBetterPlusSetting"));
cacheSetting[setName] = setValue;
try {
localStorage.setItem("yaohuoBetterPlusSetting", JSON.stringify(cacheSetting));
notifyBox("保存成功");
} catch (error) {
notifyBox("保存失败", false);
}
}
// 设置获取
function settingGet(name) {
// let cacheSetting = JSON.parse(localStorage.getItem("yaohuoBetterPlusSetting"));
// return cacheSetting[name];
try {
return JSON.parse(localStorage.getItem("yaohuoBetterPlusSetting"))[name];
} catch (error) {
throw new Error("未知错误,获取设置失败");
}
}
/**
* 弹出提示
* @param {String} message 提示内容
* @param {Boolean} status 提示状态,true成功,false失败,默认true
* @param {Number} delayTime 提示时间/ms,默认1500ms
*/
let offsetY = 0; // 消息框初始垂直偏移量
function notifyBox(message, status = true, delayTime = 1500) {
// 消息父容器
const containerDiv = $("