// ==UserScript== // @name 🔥拓展增强🔥妖火网插件 // @namespace https://yaohuo.me/ // @version 3.19.3 // @description 发帖ubb增强、回帖ubb增强、回帖表情增强、查看贴子显示用户等级增强、手动吃肉增强、自动加载更多帖子、自动加载更多回复、一键自动上传图床、支持个性化菜单配置 // @author 龙少c(id:20469)开发,参考其他大佬:外卖不用券(id:23825)、侯莫晨、Swilder-M // @match *://yaohuo.me/* // @match *://*.yaohuo.me/* // @icon https://yaohuo.me/css/favicon.ico // @run-at document-end // @license MIT // @downloadURL https://update.greasyfork.icu/scripts/464198/%F0%9F%94%A5%E6%8B%93%E5%B1%95%E5%A2%9E%E5%BC%BA%F0%9F%94%A5%E5%A6%96%E7%81%AB%E7%BD%91%E6%8F%92%E4%BB%B6.user.js // @updateURL https://update.greasyfork.icu/scripts/464198/%F0%9F%94%A5%E6%8B%93%E5%B1%95%E5%A2%9E%E5%BC%BA%F0%9F%94%A5%E5%A6%96%E7%81%AB%E7%BD%91%E6%8F%92%E4%BB%B6.meta.js // ==/UserScript== /* 功能描述: 1. 贴子列表、贴子页、回复页支持自动加载更多、最大加载数量内自动加载(默认 150 条可单独配置),达到最大加载数量则不会自动加载。 2. 自己手动进入肉帖吃肉(默认关闭) 3. 吃过的肉帖。自己手动提交会弹窗提示已吃过肉,是否确认提交 4. 自动记忆所有吃过的肉帖,在配置天数内(默认一天可单独配置),吃过的肉帖不会重复吃肉。 5. 贴子页显示楼主等级(默认打开) 6. 增加可配置菜单,默认移动端开启,悬浮在右上角,PC 端不打开。所有功能都能单独开启和关闭,兼容其他插件,可以和其他插件一起使用,关闭本插件的相同功能即可。 7. 回帖表情增强,可配置默认是否展开 8. 回帖ubb增强,可配置默认是否展开 9. 发帖ubb增强 10. 发帖、回帖页面增加自动上传图床功能,支持手动选择图片上传、复制图片上传、截图上传、拖拽图片上传 */ (function () { "use strict"; // 实现简易版替换用到的jquery,全部换成原生js太麻烦 let $, jQuery; $ = jQuery = myJquery(); let settingData = { // 是否显示站内图标 isShowSettingIcon: true, // 是否关闭站内勋章 isCloseMedal: false, // pc端帖子页面悬浮查看 isShowPcFloatPage: false, // 站内密码 websitePassword: "", // 是否开启自动吃肉,手动进去肉帖自动吃肉 isAutoEat: false, // 帖子里是否显示用户等级 isShowLevel: true, // 刷新时间间隔 timeInterval: 60, // 设置肉帖过期时间,过期前不会再自动吃肉 expiredDays: 1, // 是否自动加载下一页 isLoadNextPage: false, // 加载按钮方式: more / nextPage loadNextPageType: isMobile() ? "more" : "nextPage", // 一页最大的加载数量,超过数量就不会自动加载 maxLoadNum: 150, // 滑块range最小和最大值 minNumRange: 50, maxNumRange: 500, numStep: 50, // 设置悬浮按钮位置 settingBtnLeft: 0, settingBtnTop: 0, // 按钮的响应试大小,单位vw,默认18vw settingIconResponsiveSize: 18, // 按钮最大的大小,单位px,默认100px settingIconMaxSize: 100, // 自动加载页面时是否执行尾部 isExecTrail: true, // 是否增加发帖ubb isAddNewPostUBB: true, // 是否增加回帖ubb isAddReplyUBB: true, // 是否增加回帖表情 isAddReplyFace: true, // 是否默认展开表情 isUnfoldFace: false, // 回帖表情包图床:妖友七牛云:url1、极速图床:url2、imgBB:url3 replyFaceImageBed: "url1", // 是否默认展开表情 isUnfoldUbb: false, // 是否自动上传到图床 isUploadImage: false, // 上传图床token imageBedType: "极速图床", inkToken: "", meetToken: "", speedFreeToken: "", }; let yaohuo_userData = null; // 数据初始化 initSetting(); let { isAutoEat, isShowLevel, timeInterval, expiredDays, isLoadNextPage, isExecTrail, maxLoadNum, minNumRange, maxNumRange, numStep, isShowSettingIcon, settingBtnLeft, settingBtnTop, settingIconMaxSize, settingIconResponsiveSize, isAddNewPostUBB, isAddReplyUBB, isAddReplyFace, isUnfoldFace, replyFaceImageBed, isUnfoldUbb, loadNextPageType, isUploadImage, imageBedType, inkToken, meetToken, speedFreeToken, websitePassword, isCloseMedal, isShowPcFloatPage, } = yaohuo_userData; // 存储吃过肉的id,如果吃过肉则不会重复吃肉 let autoEatList = getItem("autoEatList"); // 回复页 const viewPage = ["/bbs/book_re.aspx", "/bbs/book_view.aspx"]; // 帖子列表页面 const bbsPage = ["/bbs/book_list.aspx", "/bbs/list.aspx"]; // 发帖 const postPage = [ "/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", ]; const loadNextPage = [ /\/bbs\/book_re.aspx/, /\/bbs\/book_list.aspx/, /\/bbs\/list.aspx/, /\/bbs-.*\.html/, /\/bbs\/book_list_hot\.aspx/, //热门页面 /\/bbs\/book_list_search\.aspx/, //查询用户界面 ]; // 404 const notFoundPage = ["/404.htm"]; const faceList = [ "踩.gif", "狂踩.gif", "淡定.gif", "囧.gif", "不要.gif", "重拳出击.gif", "砳砳.gif", "滑稽砳砳.gif", "沙发.gif", "汗.gif", "亲亲.gif", "太开心.gif", "酷.gif", "思考.gif", "发呆.gif", "得瑟.gif", "哈哈.gif", "泪流满面.gif", "放电.gif", "困.gif", "超人.gif", "害羞.gif", "呃.gif", "哇哦.gif", "要死了.gif", "谢谢.gif", "抓狂.gif", "无奈.gif", "不好笑.gif", "呦呵.gif", "感动.gif", "喜欢.gif", "疑问.gif", "委屈.gif", "你不行.gif", "流口水.gif", "潜水.gif", "咒骂.gif", "耶耶.gif", "被揍.gif", "抱走.gif", ]; /* 妖友七牛云:url1 极速图床:url2 imgBB:url3 */ const diyFaceList = [ { url1: "http://static2.51gonggui.com/FhBfMfl4sGC3QJVTMaLqEKkE90Ia#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/43dd22ed354af.gif", url3: "https://i.ibb.co/hXBXGq8/jy.gif", name: "摸鱼", }, { url1: "http://static2.51gonggui.com/FmNyrjU8Wq0m3PiwHQJwDhHdv-EJ#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/eef531d5b6d9a.gif", url3: "https://i.ibb.co/L0scf9m/jw.gif", name: "稽舞", }, { url1: "http://static2.51gonggui.com/FoKvdu89eiq0q-24IfOM2mFB0vIq#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/1171162cca357.gif", url3: "https://i.ibb.co/rmQY19V/sj.gif", name: "色稽", }, { url1: "http://static2.51gonggui.com/FrZ6GDJiOAz3pp4e5_8uSShSXXXk#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/57521f3d1f794.gif", url3: "https://i.ibb.co/h14QP4d/jj.gif", name: "撒娇", }, { url1: "http://static2.51gonggui.com/FiZiSSyXSa8eCzwOXmIfOOpfA_7a#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/004aa1eb1823a.gif", url3: "https://i.ibb.co/9yD4mFW/jg.gif", name: "稽狗", }, { url1: "http://static2.51gonggui.com/FqNDzswUNJ-AsSHXyxXB4Qm1X0y-#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/51300ab6aede6.gif", url3: "https://i.ibb.co/CnNY1SG/mq.gif", name: "没钱", }, { url1: "http://static2.51gonggui.com/Fsq-HyBc5lP6vZY_qeWofOM9mRVH#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/f046ae22fbae2.gif", url3: "https://i.ibb.co/0qTfStm/sw.gif", name: "骚舞", }, { url1: "http://static2.51gonggui.com/FhCk4emkrO9f8ICFxKlm8wBcTOgT#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/c09bfc7f5330f.gif", url3: "https://i.ibb.co/yh8bSx7/cs.gif", name: "吃屎", }, { url1: "http://static2.51gonggui.com/FkEHwSlEfQ7bWya6-wg366Xy91qW#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/4b55370c90e67.gif", url3: "https://i.ibb.co/3BxqbXX/bs.gif", name: "鄙视", }, { url1: "http://static2.51gonggui.com/Fi2hY7M9DPgD9s0aCWemwk2iYUDW#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/21ab651293d60.gif", url3: "https://i.ibb.co/3NrbQfQ/tg.gif", name: "听歌", }, { url1: "http://static2.51gonggui.com/Fhry6EpdUBqFCt3OOyQTkLZMZGFR#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/2e503027f610f.gif", url3: "https://i.ibb.co/whDBFQd/st.gif", name: "伸头", }, { url1: "http://static2.51gonggui.com/FhgYnWJ-apnyjSXOpInJhLbfUQFY#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/a082bfe5b0df3.gif", url3: "https://i.ibb.co/7KzRsmd/gz.gif", name: "鼓掌", }, { url1: "http://static2.51gonggui.com/FvSxOEIhyA7ID1J8emIME7tBT7Io#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/93c17a9cd77e9.gif", url3: "https://i.ibb.co/KNGfHFw/tt.gif", name: "踢腿", }, { url1: "http://static2.51gonggui.com/FunDHky9UKkB-4zj-bfSb82u81Xg#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/3592472aaa316.png", url3: "https://i.ibb.co/sKS4R3x/nt.png", name: "男同", }, { url1: "http://static2.51gonggui.com/FgXUeACmKWWMDT9hrpVAnQp4dCqF#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/998ff0f986f04.gif", url3: "https://i.ibb.co/VCWLFgz/sq.gif", name: "手枪", }, { url1: "http://static2.51gonggui.com/Fg_qtra3abNozPxaoEMVKO7VIsuX#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/c75d396a66b71.gif", url3: "https://i.ibb.co/pjw803c/pt.gif", name: "拍头", }, { url1: "http://static2.51gonggui.com/FnNg1vOiuOlSe7WFWRyNZfO_4H3U#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/b630057c9a2b8.gif", url3: "https://i.ibb.co/fNcvwj0/tp.gif", name: "躺平", }, { url1: "http://static2.51gonggui.com/Fj7WAkv87tpL1I26WQgSaXlsyYBL#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/78c30a6fe8c89.gif", url3: "https://i.ibb.co/5jJwwdQ/zj.gif", name: "追稽", }, { url1: "http://static2.51gonggui.com/FgwFBazeUavJcw-SL7FS6wUkcUTk#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/ed1aa444817d3.gif", url3: "https://i.ibb.co/mRLMkyv/lsj.gif", name: "司稽", }, { url1: "http://static2.51gonggui.com/FjXNVx-MUgAVq62aNqekSPOUjDAC#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/6c4e56b9f0c2c.gif", url3: "https://i.ibb.co/7KKybVg/qt.gif", name: "乞讨", }, { url1: "http://static2.51gonggui.com/FjudMlJdd8dLXuGjyASN7JldAxqe#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/7f9769ba90ff0.gif", url3: "https://i.ibb.co/3r8mtKh/gj.gif", name: "跪稽", }, { url1: "http://static2.51gonggui.com/Fm8DQQwyYthk8Q97ZLScgCDXsv4_#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/e1248fbb24b75.gif", url3: "https://i.ibb.co/PWMFdB8/dn.gif", name: "刀你", }, { url1: "http://static2.51gonggui.com/FqTaBgs1l8bqeDYBxcWzxF4Wgt6_#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/d5eedd30ad4bd.gif", url3: "https://i.ibb.co/BcHh8kn/dp.gif", name: "冲刺", }, { url1: "http://static2.51gonggui.com/Fmw152FIzN1gpFrbCKlp7cmqlCxc#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/9272af6cae5d3.gif", url3: "https://i.ibb.co/LDycW8K/zq.gif", name: "转圈", }, { url1: "http://static2.51gonggui.com/Fmf5aWS5yqycKebxTno7un53h9HW#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/58e57366425c9.gif", url3: "https://i.ibb.co/7gNd669/cj.gif", name: "吃稽", }, { url1: "http://static2.51gonggui.com/FhUkLD2khZ7hn1uzArWkT47Pd9jq#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/ef0f9e3f3e353.gif", url3: "https://i.ibb.co/7S2T2pF/fj.gif", name: "犯贱", }, { url1: "http://static2.51gonggui.com/FihrjZwpB1jMdOF9QvtQG3J32z4q#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/524b369abefa3.gif", url3: "https://i.ibb.co/yFtQtLM/nb.gif", name: "牛掰", }, { url1: "http://static2.51gonggui.com/FlX6e1Ip6Z8gvl7lkimmCifwBhFt#.gif", url2: "https://tucdn.wpon.cn/2023/10/05/659798ffccac4.gif", url3: "https://i.ibb.co/FVnL0PB/yb.gif", name: "拥抱", }, { url1: "http://static2.51gonggui.com/FoIs-hNK7fhW8jwxEgDLRxARFcve#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/dfe36d68642e8.gif", url3: "https://i.ibb.co/Nj0V2gM/722ee7ce0b4fdecd.gif", name: "拍头", }, { url1: "http://static2.51gonggui.com/Fgx4XlxG9461Y_TJsg0hGxPTylYi#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/989aa4d6e0aeb.gif", url3: "https://i.ibb.co/64Gmn3C/25e66a6595b1dc82.gif", name: "摇头", }, { url1: "http://static2.51gonggui.com/Fvrng91QU_PKY9Uwat77VTVouj5k#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/84a18f0849126.gif", url3: "https://i.ibb.co/2jWY20p/rt.gif", name: "挠头", }, { url1: "http://static2.51gonggui.com/FkyiMRaJI1BfuA6T3w4Z9mJh1qbg#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/216607e845f48.gif", url3: "https://i.ibb.co/SdD7Vct/sx.gif", name: "上学", }, { url1: "http://static2.51gonggui.com/FpZEifxiFGs1BWtHjFsk5tJJNKSE#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/4914eecbff777.gif", url3: "https://i.ibb.co/dmng48J/lh.gif", name: "流汗", }, { url1: "http://static2.51gonggui.com/FiBZZ6mBTB5R5bu5lGkybboOwLwm#.gif", url2: "https://tucdn.wpon.cn/2023/08/07/4181f12786715.gif", url3: "https://i.ibb.co/GH0Q94V/5614974ef677a274.gif", name: "摩擦", }, { url1: "http://static2.51gonggui.com/FmMtly844_wS6LfLLtLSwgzcXSqg#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/9a7bd5c247170.gif", url3: "https://i.ibb.co/zbPnx6p/hyl.gif", name: "喝饮料", }, { url1: "http://static2.51gonggui.com/FqyckEvAxFVyD1SmA9m2jInv_Crb#.gif", url2: "https://tucdn.wpon.cn/2023/06/16/4416bfa6a8ba7.gif", url3: "https://i.ibb.co/Lhp7Hv5/mg.gif", name: "猛狗", }, { url1: "http://static2.51gonggui.com/FmfsKjv4ymuWR80UGY-sea-I_Ey5#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/e0b400a7e3dc2.gif", url3: "https://i.ibb.co/pzh7P1x/hl.gif", name: "妲己", }, { url1: "http://static2.51gonggui.com/FkEmzRCL3eJGlgkHHnHTy94sXwE1#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/06fe11a5e5fb1.gif", url3: "https://i.ibb.co/jbpQSMW/jw.gif", name: "街舞", }, { url1: "http://static2.51gonggui.com/FgiAIOkFg8qG3UZKQx24ImVDrDRj#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/d7bda91d8179a.gif", url3: "https://i.ibb.co/WtR06gb/gd.gif", name: "功德", }, { url1: "http://static2.51gonggui.com/Fl2Zonx2Y8z-xZrSQnGBWzsnRKC9#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/c2b8c1714199f.gif", url3: "https://i.ibb.co/HCp8nfK/hyl2.gif", name: "晃饮料", }, { url1: "http://static2.51gonggui.com/FvMXbnIX8RavSBAhflxf1zomD1ov#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/ce54bf9b4abbe.gif", url3: "https://i.ibb.co/fnsVq6r/sz.gif", name: "扇子", }, { url1: "http://static2.51gonggui.com/FmD3h-QCVdJ-ehjLh8_G-nQzynuv#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/1441dd979ce22.gif", url3: "https://i.ibb.co/64MJMCL/mb.gif", name: "膜拜", }, { url1: "http://static2.51gonggui.com/FoGXe8yRSIomTZFM78TZVyP-kwlz#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/d33fcaada32c2.gif", url3: "https://i.ibb.co/yyyKLDr/xx.gif", name: "醒醒", }, { url1: "http://static2.51gonggui.com/Fim_ZRiJugrWJkDtq4SlqbOziuZ3#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/12e032ec1f22f.gif", url3: "https://i.ibb.co/nL32s9K/bz.gif", name: "巴掌", }, { url1: "http://static2.51gonggui.com/FpVLTimqXFvRJB9PxWDKMherZoRi#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/9ec67435a9478.gif", url3: "https://i.ibb.co/12bpF7R/gz.gif", name: "鼓掌", }, { url1: "http://static2.51gonggui.com/Fit100hjJ-T5RwQxeNdoVWplvNvU#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/edf6a0ead646d.gif", url3: "https://i.ibb.co/C7wyK9x/qz.gif", name: "该死", }, { url1: "http://static2.51gonggui.com/FkeVK5icB5-Pc7mbZitDTX1AqfNO#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/c0f568beacb26.gif", url3: "https://i.ibb.co/NKZGsFh/xz.gif", name: "红酒", }, { url1: "http://static2.51gonggui.com/FnjJRSH3_CLjYyyQzVjD8mtY-PdB#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/d2175ea23bebb.gif", url3: "https://i.ibb.co/QQRBQTT/kx.gif", name: "开心", }, { url1: "http://static2.51gonggui.com/Foqd_tGWrk-ARnNrt-XraMCDzhUS#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/3ae5c9f741f59.gif", url3: "https://i.ibb.co/Z6jmV32/jz.gif", name: "紧张", }, { url1: "http://static2.51gonggui.com/FsCE3iHM0REN077WKr0bssyKiR7Z#.gif", url2: "https://tucdn.wpon.cn/2023/10/08/5bd9dd04fe8b6.gif", url3: "https://i.ibb.co/Bw8xYQP/kq2.gif", name: "伤心2", }, { url1: "https://p6.itc.cn/q_70/images03/20210723/3b9017a6580644e4af8b43d73b92c0a9.gif", name: "看戏", }, { url1: "https://p0.itc.cn/q_70/images03/20210723/4874b66b12f04be1aab989d289e8635a.gif", name: "顶你", }, { url1: "https://pic2.ziyuan.wang/user/guest/2024/04/kwyjjlck_81f49e01db86c.gif", name: "哭死", }, { url1: "https://p2.itc.cn/q_70/images03/20210723/f9c4a2e9879f438c9f151366442f311e.gif", name: "看不见", }, { url1: "https://p8.itc.cn/q_70/images03/20210723/189ca0ed210142999a1661d2bd3cf852.gif", name: "蹲坑", }, { url1: "https://pic2.zhimg.com/v2-568bb2311e00c3ecbc4dd49ab0709f09_b.gif", name: "磨刀", }, { url1: "https://pic.ziyuan.wang/user/sub/2024/04/458ed8da862d4a71bc5ab4c2435711fd_088c2fc6f5680.png", name: "小丑", }, { url1: "https://i.piantu.cn/2024/04/14/839386c85e1803d082b11cfe2fe5c33f.gif", name: "有鬼", }, ]; // 批量添加事件数组 let addEventAry = [ { id: "ubb_id", ubb: "[userid]", offset: 0, }, { id: "ubb_ip", ubb: "[ip]", offset: 0, }, { id: "ubb_url", ubb: "[url=网址]文字说明[/url]", offset: 6, }, { id: "ubb_text", ubb: "[text]全角转半角:代码内容[/text]", offset: 0, }, { id: "ubb_br", ubb: "///", offset: 0, }, { id: "ubb_hr", ubb: "[hr]", offset: 0, }, { id: "ubb_left", ubb: "[left]", offset: 0, }, { id: "ubb_center", ubb: "[center]", offset: 0, }, { id: "ubb_right", ubb: "[right]", offset: 0, }, { id: "ubb_font", ubb: "[font=serif][/font]", offset: 7, }, { id: "ubb_b", ubb: "[b]加粗文字[/b]", offset: 4, }, { id: "ubb_i", ubb: "[i]斜体文字[/i]", offset: 4, }, { id: "ubb_u", ubb: "[u]下划线文字[/u]", offset: 0, }, { id: "ubb_color", ubb: "[forecolor=red]颜色文字,默认红[/forecolor]", offset: 12, }, { id: "ubb_img", ubb: "[img]图片链接[/img]", offset: 6, }, { id: "ubb_strike", ubb: "[strike]删除线文字[/strike]", offset: 9, }, { id: "ubb_call", ubb: "[call]拨号手机号码[/call]", offset: 0, }, { id: "ubb_sms", ubb: "[url=sms:手机号码?body=短信内容]点此发送[/url]", offset: 0, }, { id: "ubb_now", ubb: "当前系统日期和时间:[now]", offset: 0, }, { id: "ubb_codo", ubb: "倒计天:[codo]2030-01-01[/codo]", offset: 0, }, { id: "ubb_audio", ubb: "[audio=X]音频直链地址[/audio]", offset: 8, }, { id: "ubb_movie", ubb: "[movie=100%*100%]视频直链地址|封面图片地址[/movie]", offset: 8, }, { id: "ubb_nzgsa", ubb: "[audio=X]https://file.uhsea.com/2304/3deb45e90564252bf281f47c7b47a153KJ.mp3[/audio]", offset: 0, }, ]; let timer = null; // 是否点击加载更多 let isClickLoadMoreBtn = false; // 是否是新页面 let isNewPage = false; const spanstyle = "color: #fff; padding: 2px 4px; font-size: 14px; background-color: #ccc;border-radius: 10%;"; const a2style = "color: #fff; padding: 2px 4px; font-size: 14px; background-color: #d19275;border-radius: 10%;"; const a3style = "color: #fff; padding: 2px 4px; font-size: 14px; background-color: #66ccff;border-radius: 10%;"; // ==主代码执行== (function () { // 修复网站更新样式错乱问题 handleStyle(); // 处理浏览器滚动条事件 handleWindowScroll(); // 处理窗口改变事件 handleWindowResize(); // 添加站内设置按钮 addSettingBtn(); // 自动填充密码并确认 handlePassword(); // 关闭勋章显示 handleCloseMedal(); // 如果关闭了悬浮图标,在网站首页右上角添加插件设置入口 handleAddSettingText(); // 加载更多按钮点击事件监听 handleAddLoadMoreBtnClick(); // 手动吃肉:手动进入肉帖吃 handleAutoEat(); // 增加回帖ubb handleAddReplyUBB(); // 增加回帖表情 handleAddReplyFace(); // 优化回帖 handleReply(); // pc端帖子页面悬浮查看 handleBbsListFloatOpen(); // 自动上传图床功能 handleUploadImage(); // 增加发帖ubb handleAddNewPostUBB(); // 显示用户等级 // handleShowUserLevel(); // 处理404页面跳回新帖页面 handleNotFoundPage(); })(); // ==其他功能函数和方法== function handleStyle() { MY_addStyle(` .centered-container { display: block !important; } `); let flexDivs = document.querySelectorAll('div[style*="display: flex"]'); // 遍历选中的元素并添加额外的样式 for (let i = 0; i < flexDivs.length; i++) { flexDivs[i].style.flexWrap = "wrap"; } } function handleCloseMedal() { if ( /^\/bbs-\d+\.html|\/bbs\/book_view.aspx$/.test( window.location.pathname ) && isCloseMedal ) { let medalImg = [...document.querySelectorAll(".xunzhangtupian > img")]; medalImg.forEach((item, index) => { if (index === 0) { item.insertAdjacentHTML( "afterend", `已关闭勋章显示` ); } item.remove(); }); } } function handlePassword() { let password = document.querySelector("input[type=password]"); let submit = document.querySelector("input[type=submit]"); if (document.title === "请输入密码") { if (!password.value) { password.value = websitePassword; } if (password.value) { submit.click(); } } } function handleAddSettingText() { // 修改pc端滚动条样式 if (!isMobile()) { MY_addStyle(` /*滚动条整体样式*/ /*高宽分别对应横竖滚动条的尺寸*/ ::-webkit-scrollbar { width: 8px; height: 8px; background-color: #F5F5F5; } /*定义滚动条轨道 内阴影+圆角*/ ::-webkit-scrollbar-track { box-shadow: inset 0 0 6px rgba(0,0,0,0.1); border-radius: 3px; background-color: #F5F5F5; } /*滚动条里面小方块*/ ::-webkit-scrollbar-thumb { /* height: 50px; */ border-radius:3px; box-shadow: inset 0 0 6px rgba(0,0,0,.3); background-color: #b8b8b8; } ::-webkit-scrollbar-thumb:hover { /* height: 50px; */ background-color: #878987; border-radius: 6px } `); } if (!isShowSettingIcon && $(".top2").length) { $(".top2").append( `插件设置` ); $(".yaohuo-setting-text").click(() => { setMenu(); }); } } function isMobile() { return /Mobile/i.test(navigator.userAgent); } function initSetting() { // 在移动设备上执行的代码 if (isMobile()) { // 移动端默认显示站内设置图标 settingData.isShowSettingIcon = true; } else { // 在桌面设备上执行的代码 } // 获取用户历史数据 yaohuo_userData = MY_getValue("yaohuo_userData"); // 查看本地是否存在旧数据 if (!yaohuo_userData) { yaohuo_userData = settingData; // MY_setValue("yaohuo_userData", yaohuo_userData); } // 自动更新数据 for (let value in settingData) { if (!yaohuo_userData.hasOwnProperty(value)) { yaohuo_userData[value] = settingData[value]; MY_setValue("yaohuo_userData", yaohuo_userData); } } initSettingBtnPosition("init"); } // 更新按钮位置到最右边 /** * 当按钮靠最右边时,设置按钮的left偏移 * @param {'init' | 'update'} type type值为init / update */ function initSettingBtnPosition(type = "update") { let { settingBtnTop, settingIconResponsiveSize, settingIconMaxSize } = yaohuo_userData; let newLeft; // btn最大100px,根据屏幕视口取18vw newLeft = Math.floor( window.innerWidth - Math.min( (window.innerWidth / 100) * settingIconResponsiveSize, settingIconMaxSize ) ); if (type === "update") { const floatingDiv = $("#floating-setting-btn")[0]; floatingDiv.style.left = newLeft + "px"; } saveSettingBtnPosition({ left: newLeft, top: settingBtnTop }); } /** * 保存设置按钮的位置 * @param {Object} pos - 按钮位置信息 * @param {number} pos.left - 按钮左边距 * @param {number} pos.top - 按钮上边距 */ function saveSettingBtnPosition({ left, top }) { yaohuo_userData.settingBtnLeft = left; yaohuo_userData.settingBtnTop = top; setItem("yaohuo_userData", yaohuo_userData); } function addSettingBtn() { if ($("#floating-setting-btn").length) { return; } MY_addStyle(` #floating-setting-btn { display: ${isShowSettingIcon ? "block" : "none"}; max-width: ${settingIconMaxSize}px; max-height: ${settingIconMaxSize}px; width: ${settingIconResponsiveSize}vw; height: ${settingIconResponsiveSize}vw; user-select: none; box-sizing: border-box; position: fixed; z-index: 999; cursor: move; background-repeat: no-repeat; background-position: center; } #floating-setting-btn svg { width: 100%; height: 100%; opacity: 0.6; filter: drop-shadow(0px 0px 3px #666); } .overflow-hidden-scroll { overflow: hidden !important; } .touch-action-none { touch-action: none; } .add-position-static{ position: static !important; } `); let innerH = `
`; $("body").append(innerH); const floatingDiv = $("#floating-setting-btn")[0]; let mouseOffsetX = 0; let mouseOffsetY = 0; let isDragging = false; let dragThreshold = 5; // 拖动阈值,即鼠标移动的距离超过多少像素才开始拖动 let clickThreshold = 500; // 点击阈值,即鼠标按下的时间不超过多少毫秒才算是点击 let mouseDownTime; // 鼠标按下的时间 let mouseDownX; // 鼠标按下的位置 let mouseDownY; // 鼠标事件 floatingDiv.addEventListener("mousedown", onMouseDown); document.addEventListener("mousemove", throttle(onMouseMove, 15)); document.addEventListener("mouseup", onMouseUp); // 触摸事件 floatingDiv.addEventListener("touchstart", onTouchStart); document.addEventListener("touchmove", throttle(onTouchMove, 5)); document.addEventListener("touchend", onTouchEnd); // 鼠标事件监听器 function onMouseDown(e) { floatingDiv.style.transition = "unset"; // 记录鼠标按下的时间和位置 mouseDownTime = new Date().getTime(); mouseDownX = e.clientX; mouseDownY = e.clientY; // 鼠标相对于拖动图标的偏移x和y距离 mouseOffsetX = e.clientX - floatingDiv.offsetLeft; mouseOffsetY = e.clientY - floatingDiv.offsetTop; isDragging = true; e.preventDefault(); e.stopPropagation(); } function onMouseMove(e) { if (!isDragging) { return; } const left = e.clientX - mouseOffsetX; const top = e.clientY - mouseOffsetY; const maxLeft = window.innerWidth - floatingDiv.offsetWidth; const maxTop = window.innerHeight - floatingDiv.offsetHeight; floatingDiv.style.left = Math.min(Math.max(0, left), maxLeft) + "px"; floatingDiv.style.top = Math.min(Math.max(0, top), maxTop) + "px"; } function onMouseUp(e) { if (!isDragging) { return; } // 拖动结束重置数据 mouseOffsetX = 0; mouseOffsetY = 0; isDragging = false; // 如果按下的时间不够长,则认为是点击事件 // 如果移动的距离 let distanceX = Math.abs(e.clientX - mouseDownX); let distanceY = Math.abs(e.clientY - mouseDownY); // 计算鼠标点击的时间小于500ms,并且移动的距离少于5像素则认为时点击事件 if ( new Date().getTime() - mouseDownTime < clickThreshold && distanceX < dragThreshold && distanceY < dragThreshold ) { setMenu(); return; } // 拖动按钮自动靠边处理 let newLeft; let position = floatingDiv.getBoundingClientRect(); // 如果左边比右边多就靠左,否则靠右 if (window.innerWidth - position.right > position.left) { newLeft = 0; } else { newLeft = window.innerWidth - position.width; } floatingDiv.style.left = newLeft + "px"; floatingDiv.style.transition = "all 0.2s ease-in-out"; // 更新悬浮图标位置信息 saveSettingBtnPosition({ top: position.top, left: newLeft }); } // 触摸事件监听器 function onTouchStart(e) { floatingDiv.style.transition = "unset"; // 记录鼠标按下的时间和位置 mouseDownTime = new Date().getTime(); mouseDownX = e.touches[0].clientX; mouseDownY = e.touches[0].clientY; mouseOffsetX = e.touches[0].clientX - floatingDiv.offsetLeft; mouseOffsetY = e.touches[0].clientY - floatingDiv.offsetTop; isDragging = true; e.preventDefault(); e.stopPropagation(); $("body").addClass("touch-action-none"); $("body").addClass("overflow-hidden-scroll"); } function onTouchMove(e) { if (!isDragging) { return; } const left = e.touches[0].clientX - mouseOffsetX; const top = e.touches[0].clientY - mouseOffsetY; const maxLeft = window.innerWidth - floatingDiv.offsetWidth; const maxTop = window.innerHeight - floatingDiv.offsetHeight; floatingDiv.style.left = Math.min(Math.max(0, left), maxLeft) + "px"; floatingDiv.style.top = Math.min(Math.max(0, top), maxTop) + "px"; } function onTouchEnd(e) { if (!isDragging) { return; } $("body").removeClass("touch-action-none"); $("body").removeClass("overflow-hidden-scroll"); // 拖动结束重置数据 mouseOffsetX = 0; mouseOffsetY = 0; isDragging = false; // 如果按下的时间不够长,则认为是点击事件 // 如果移动的距离 let touch = e.changedTouches[0]; let clientX = touch.clientX; let clientY = touch.clientY; let distanceX = Math.abs(clientX - mouseDownX); let distanceY = Math.abs(clientY - mouseDownY); // 计算鼠标点击的时间小于500ms,并且移动的距离少于5像素则认为时点击事件 if ( new Date().getTime() - mouseDownTime < clickThreshold && distanceX < dragThreshold && distanceY < dragThreshold ) { setMenu(); return; } // 拖动按钮自动靠边处理 let newLeft; let position = floatingDiv.getBoundingClientRect(); // 如果左边比右边多就靠左,否则靠右 if (window.innerWidth - position.right > position.left) { newLeft = 0; } else { newLeft = window.innerWidth - position.width; } floatingDiv.style.left = newLeft + "px"; floatingDiv.style.transition = "all 0.2s ease-in-out"; // 更新悬浮图标位置信息 saveSettingBtnPosition({ top: position.top, left: newLeft }); } } // 处理窗口改变事件 function handleWindowResize() { // 窗口改变重新计算悬浮按钮的位置 window.addEventListener("resize", function (e) { let { settingBtnLeft } = yaohuo_userData; if (settingBtnLeft !== 0) { initSettingBtnPosition("update"); } }); } function getIcon(icon, tips) { let iconConfig = { tipIcon: ``, eyeIcon: ``, }; return iconConfig[icon]; } function setMenu() { // 避免重复添加 if ($(".yaohuo-modal-mask").length) { return; } MY_addStyle(` .yaohuo-modal-mask { display: none; position: fixed; top: 0; left: 0; bottom: 0; right: 0; z-index: 1000; height: 100%; width: 100%; background-color: rgba(0, 0, 0, 0.45); } .yaohuo-wrap { padding: 20px 0; box-sizing: border-box; position: relative; margin: 0 auto; background: #fff; border-radius: 12px; top: 10%; width: 400px; max-width: 95vw; user-select: none; } .yaohuo-wrap header { padding: 0 20px; color: rgba(0, 0, 0, 0.88); font-weight: 600; font-size: 16px; line-height: 1.5; margin-bottom: 8px; } .yaohuo-wrap footer { font-size: 0px; text-align: right; margin-top: 10px; padding: 0 20px; } .yaohuo-wrap footer button { font-size: 14px; height: 32px; padding: 4px 15px; border-radius: 6px; border: 1px solid transparent; cursor: pointer; } .yaohuo-wrap footer .cancel-btn { background-color: #fff; border-color: #d9d9d9; margin-right: 8px; box-shadow: 0 2px 0 rgba(0, 0, 0, 0.02); } .yaohuo-wrap footer .ok-btn { color: #fff; background-color: #1677ff; box-shadow: 0 2px 0 rgba(5, 145, 255, 0.1); } .yaohuo-wrap ul { margin: 0; padding: 0 10px 0 20px; margin-right: 7px; max-height: 65vh; overflow: auto; } /* 设置滚动条的宽度和高度 */ .yaohuo-wrap ::-webkit-scrollbar { width: 3px; } /* 设置滚动条滑块的背景色 */ .yaohuo-wrap ::-webkit-scrollbar-thumb { background-color: #999; border-radius:10px; } .yaohuo-wrap i { font-style: normal; } .yaohuo-wrap li { display: flex; justify-content: space-between; align-items: center; height: 44px; } .yaohuo-wrap li .tip-icon{ vertical-align: text-top; margin-left: 5px; cursor: pointer; } .yaohuo-wrap li input[type="range"] { width: 130px; height: 1px; appearance: auto; border: none; padding: 0; } .yaohuo-wrap li select { height: 28px; line-height: 28px; font-size: 14px; width: 130px; border: 1px solid #5c5c5c; border-radius: 5px; text-align: center; outline: 0; margin-right: 0; } .yaohuo-wrap .switch { position: relative; display: inline-block; width: 60px; height: 30px; } .yaohuo-wrap .switch input { opacity: 0; width: 0; height: 0; } .yaohuo-wrap .password-container{ width: 60%; position: relative; } .password-container .toggle-password { position: absolute; top: 52%; right: 6px; transform: translateY(-50%); cursor: pointer; } .yaohuo-wrap-title{ height: 38px !important; } .yaohuo-wrap-title .title-line { margin: 0px; border: none; border-top: 1px dashed #dcdcdc; width: 30%; /* 可根据需要调整宽度 */ } .yaohuo-wrap li .password-container input { width: 100%; box-sizing: border-box; height: 32px; padding-right: 28px; } .yaohuo-wrap li input[type="number"] { width: 130px; box-sizing: border-box; height: 30px; } .yaohuo-wrap .switch label { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; -webkit-transition: 0.4s; transition: 0.4s; border-radius: 34px; } .yaohuo-wrap .switch label::before { position: absolute; content: ""; height: 22px; width: 22px; left: 6px; bottom: 4px; background-color: white; transition: 0.4s; border-radius: 50%; } .yaohuo-wrap .switch input:checked + label { background-color: #2196f3; } .yaohuo-wrap .switch input:checked + label::before { transform: translateX(26px); } .yaohuo-wrap hr { margin:5px 0 } `); let innerH = `
🔥拓展增强🔥插件设置【检测更新】
`; $("body").append(innerH).addClass("overflow-hidden-scroll"); $(".yaohuo-modal-mask").show(); setSettingInputEvent("edit"); $(".cancel-btn").click(handleCancelBtn); $(".ok-btn").click(handleOkBtn); } /** * 设置设置菜单,点击设置打开菜单,并且回显数据,保存则保存数据 * @param {"edit" | 'save'} status edit和save两种模式 */ function setSettingInputEvent(status = "edit") { $(".yaohuo-wrap input, .yaohuo-wrap select").each((index, item) => { let type = item.type; let dataKey = item.getAttribute("data-key"); switch (type) { case "checkbox": if (status === "edit") { item.checked = getValue(dataKey) ? true : false; // 根据当前的按钮选中状态处理子项的联动显示或隐藏 autoShowElement({ fatherIdAry: ["isShowSettingIcon"], childIdAry: ["settingIconMaxSize"], dataKey, }); autoShowElement({ fatherIdAry: ["isLoadNextPage"], childIdAry: ["loadNextPageType", "maxLoadNum"], dataKey, }); autoShowElement({ fatherIdAry: ["isAutoEat"], childIdAry: ["expiredDays"], dataKey, }); autoShowElement({ fatherIdAry: ["isUploadImage"], childIdAry: [ "imageBedType", "inkToken", "meetToken", "speedFreeToken", ], dataKey, }); autoShowElement({ fatherIdAry: ["isAddReplyUBB"], childIdAry: ["isUnfoldUbb"], dataKey, }); autoShowElement({ fatherIdAry: ["isAddReplyFace"], childIdAry: ["isUnfoldFace", "replyFaceImageBed"], dataKey, }); } else { setValue(dataKey, item.checked); } break; case "range": if (status === "edit") { $(item).on("input propertychange", function (event) { $(item).prev().children(".range-num").text(item.value); }); } else { setValue(dataKey, parseInt(item.value)); } break; case "select-one": if (status === "edit") { item.value = getValue(dataKey); $(item).on("change", function (event) { autoShowImageToken(item, dataKey); }); autoShowImageToken(item, dataKey); } else { setValue(dataKey, item.value); } break; case "number": if (status === "edit") { item.value = getValue(dataKey); } else { setValue(dataKey, item.value); } break; case "password": if (status === "edit") { item.value = getValue(dataKey, ""); $(item) .next() .on("click", function (event) { item.type = item.type === "password" ? "text" : "password"; }); } else { setValue(dataKey, item.value); } break; default: if (status === "edit") { item.value = getValue(dataKey, ""); } else { setValue(dataKey, item.value); } break; } }); function autoShowImageToken(item, dataKey) { if (dataKey === "imageBedType") { let config = { 水墨图床: "#inkToken", 极速图床: "#speedFreeToken", }; Object.keys(config).forEach((name) => { if (item.value === name) { $(config[name]).closest("li").show(); } else { $(config[name]).closest("li").hide(); } }); } } /** * 根据当前的选中状态处理子项的显示或隐藏 * @param {Object} options - 选项对象 * @param {Array} options.fatherIdAry - 包含父元素ID的字符串数组 * @param {Array} options.childId - 子元素的ID * @param {string} options.dataKey - 存储在父元素上的数据键名 */ function autoShowElement({ fatherIdAry, childIdAry, dataKey }) { execFn(); fatherIdAry.forEach((item) => { $(`#${item}`).on("change", function (event) { execFn(); }); }); function execFn() { if (fatherIdAry.includes(dataKey)) { childIdAry.forEach((childId) => { let parent = $(`#${childId}`).closest("li"); let isShow = fatherIdAry.some((item) => $(`#${item}`).prop("checked") ); isShow ? parent.show() : parent.hide(); }); } } } } function checkSaveSetting() { let openUploadImageBed = $("#isUploadImage").prop("checked"); let imageBedType = $("#imageBedType").prop("value"); let meetToken = $("#meetToken").prop("value"); // if (openUploadImageBed && imageBedType === "遇见图床" && !meetToken) { // alert("遇见图床必须填写token"); // return false; // } return true; } function handleCancelBtn() { $("body").removeClass("overflow-hidden-scroll"); $(".yaohuo-modal-mask").remove(); } function handleOkBtn() { if (!checkSaveSetting()) { return; } setSettingInputEvent("save"); $("body").removeClass("overflow-hidden-scroll"); $(".yaohuo-modal-mask").hide(); MY_setValue("yaohuo_userData", yaohuo_userData); if (!yaohuo_userData.isShowSettingIcon) { $("#floating-setting-btn").hide(); } else { $("#floating-setting-btn").show(); } // 刷新页面 setTimeout(function () { window.location.reload(); }, 300); } function handleBbsListFloatOpen() { if ( bbsPage.includes(window.location.pathname) && !isMobile() && isShowPcFloatPage ) { MY_addStyle(` /* 背景遮罩 */ .overlay { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); justify-content: center; align-items: center; z-index: 9999; } /* iframe容器 */ .iframe-container { position: relative; width: 80%; max-width: 750px; height: 98%; background-color: #e8e8e8; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); border-radius: 10px; } `); document.addEventListener("click", (event) => { // 检查点击的元素是否具有 topic-link 类 if (event.target.classList.contains("topic-link")) { event.preventDefault(); // 防止默认链接行为 let url = event.target.getAttribute("href"); // 获取链接的 href 属性 // iframe打开当前链接 openLayer(url); } }); function openLayer(url) { // 创建遮罩(overlay) const overlay = document.createElement("div"); overlay.className = "overlay"; overlay.style.display = "flex"; // 创建iframe容器 const iframeContainer = document.createElement("div"); iframeContainer.className = "iframe-container"; // 创建iframe const iframe = document.createElement("iframe"); iframe.src = url; // 设置iframe的目标URL iframe.style.width = "100%"; iframe.style.height = "100%"; iframe.style.border = "none"; iframe.style.borderRadius = "10px"; // 将iframe添加到iframe容器中 iframeContainer.appendChild(iframe); // 将iframe容器添加到遮罩中 overlay.appendChild(iframeContainer); // 将遮罩添加到页面 document.body.appendChild(overlay); // 点击遮罩关闭iframe和遮罩 overlay.addEventListener("click", function (event) { if (event.target === overlay) { document.body.removeChild(overlay); // 移除遮罩 } }); } } } // 浏览器scroll事件 function handleWindowScroll() { window.addEventListener( "scroll", throttle(() => { let isPage = loadNextPage.some((item) => item.test(window.location.pathname) ); // 处理点击加载更多后的全自动吃肉 if (isPage) { let nextBtn = null; // 下一页按钮的父节点 let nextPageWrap = document.querySelector(".bt2"); if (loadNextPageType === "more" || !nextPageWrap) { // 加载更多加载下一页 nextBtn = document.querySelector("span[id$=show_tip]"); // 已经请求到数据 if (nextBtn?.innerText.includes("加载更多")) { // 加载完成了 isClickLoadMoreBtn = false; isNewPage = false; // 处理自动加载更多,需要放到最后 handleLoadNextPage(); } } else { // 下一页按钮加载下一页 nextBtn = nextPageWrap.firstChild; handleLoadNextPage(); } } }, 100) ); } // 返回当前列表数据的长度 function getListLength() { let length = 0; if ($(".listdata").length) { length = $(".listdata").length; } else { length = $(".reline").length + $(".list-reply").length; } return length; } // 自动吃肉:手动进入肉帖自动吃 function handleAutoEat() { if (/^\/bbs-.*\.html$/.test(window.location.pathname) && isAutoEat) { const form = document.getElementsByName("f")[0]; let isAutoEatBbs = window.location.search.includes("open=new"); if (!form) { // 如果是自动吃肉的则直接返回,并记录不可吃肉 if (isAutoEatBbs) { autoEatCallback(); } return; } const face = form.getElementsByTagName("select")[0]; const replyBtn = document.getElementsByName("g")[0]; const textarea = document.querySelector(".retextarea"); // 帖子标识id let id = window.location.pathname.match(/\d+/)[0]; // 吃肉 必须放在后面 const fileTag = document.querySelector( "a[href^='/bbs/book_re_addfile.aspx']" ); let eatMeat = document.createElement("input"); eatMeat.style.float = "right"; eatMeat.type = "submit"; eatMeat.value = "一键吃肉"; eatMeat.addEventListener("click", (e) => { e.preventDefault(); let eatWordsArr = [ "吃", "吃吃", "吃吃.", "吃吃。", "吃吃..", "吃吃。。", "吃了", "吃肉", "来吃肉", "吃.", "吃。", "吃了.", "吃了。", "吃肉.", "吃肉。", "来吃肉.", "来吃肉。", "吃..", "吃。。", "吃了..", "吃了。。", "吃肉..", "吃肉。。", "来吃肉..", "来吃肉。。", "口乞了", "口乞了.", "口乞了。", "口乞肉", "口乞肉.", "口乞肉。", "口乞..", "口乞。。", "chile..", "chile。。", "7肉..", "7肉。。", "7了..", "7了。。", "肉肉肉", "肉肉肉.", "肉肉肉。", "肉肉肉..", "肉肉肉。。", "先吃肉", "先吃肉.", "先吃肉。", "先吃肉..", "先吃肉。。", ]; let index = Math.floor(Math.random() * eatWordsArr.length); console.log("吃肉回复:", eatWordsArr[index]); insertText(textarea, eatWordsArr[index], 0); replyBtn.click(); autoEatCallback(); }); // 添加事件监听,如果吃过肉则会提示 document.getElementsByName("g")[0].addEventListener( "click", (e) => { if (autoEatList[id] && !confirm("当前已经吃过肉,是否继续回复")) { // 取消提交 // textarea.value = ""; e.preventDefault(); e.stopPropagation(); } }, true ); const meatTag = document.querySelector("span.yushuzi"); if (!isAutoEat) { console.log("未开启自动吃肉,可在编辑脚本进行开启"); } else { if (meatTag == undefined) { console.log("非肉勿7"); // autoEatCallback(); } else if (parseInt(meatTag.innerHTML) <= 0) { console.log("无肉怎7"); // 把无肉帖添加进去 autoEatCallback(); } else { let autoEatList = getItem("autoEatList"); if (!autoEatList[id]) { console.log("有肉快7"); eatMeat.click(); } else { console.log("已经吃过了"); autoEatCallback(); } } } // 将吃肉插入到文件回帖后面 fileTag.after(eatMeat); } } function insertText(obj, str, offset) { if (document.selection) { let sel = document.selection.createRange(); sel.text = str; } else if ( typeof obj.selectionStart === "number" && typeof obj.selectionEnd === "number" ) { let startPos = obj.selectionStart, endPos = obj.selectionEnd, cursorPos = startPos, tmpStr = obj.value; obj.value = tmpStr.substring(0, startPos) + str + tmpStr.substring(endPos, tmpStr.length); cursorPos += str.length; obj.selectionStart = obj.selectionEnd = cursorPos - offset; } else { obj.value += str; } obj.focus(); } // 吃完肉的回调 function autoEatCallback() { let id = window.location.pathname.match(/\d+/)[0]; let isAutoEatBbs = window.location.search.includes("open=new"); // let autoEatList = getItem("autoEatList"); autoEatList[id] = new Date().getTime(); setItem("autoEatList", autoEatList); } /** * 返回指定天数后的一天开始的时间,例如1天,则为明天00:00:00,2天则为后天00:00:00 * 肉帖1天有效期则代表明天00:00:00过期,2天有效期则是后天00:00:00 * @param {number} time 传入一个时间戳 * @param {number} days 传入过期的天数 * @returns {number} 返回到期时间的时间戳 */ function timeLeft(time, days = 1) { const target = new Date(time + (days - 1) * 24 * 60 * 60 * 1000); target.setHours(24, 0, 0, 0); return target.getTime(); } // 获取值 function getItem(key, defaultValue = {}) { if (key === "autoEatList") { let autoEatList = MY_getValue(key, {}); // 删除过期的肉帖 deleteExpiredID(autoEatList); // 更新肉帖数据 setItem(key, autoEatList); return autoEatList; } return MY_getValue(key, {}); } function MY_addStyle(innerHTML) { // 创建 style 元素 let style = document.createElement("style"); style.type = "text/css"; // 设置样式内容 let css = innerHTML; style.innerHTML = css; // 将 style 元素添加到 head 元素中 document.head.appendChild(style); } function MY_setValue(key, value) { if (typeof value === "object") { value = JSON.stringify(value); } localStorage.setItem(key, value); } function MY_getValue(key, defaultValue = {}) { const value = localStorage.getItem(key) || defaultValue; try { return JSON.parse(value); } catch (e) { return value; } } // 设置值 function setItem(key, value) { // if (key === "autoEatList") { // deleteExpiredID(value); //删除过期的肉帖 // } MY_setValue(key, value); } /** * 返回yaohuo_userData里的数据 * @param {string} key 要获取值的属性 * @param {any} value 获取的值 * @returns {any} */ function getValue(key, value) { let setting = yaohuo_userData; return setting[key] || value; } /** * 更新yaohuo_userData里的数据 * @param {string} key 要设置值的属性 * @param {any} value 设置的值 * @returns {any} */ function setValue(key, value) { yaohuo_userData[key] = value; // setItem("yaohuo_userData", yaohuo_userData); } // 增加发帖ubb function handleAddNewPostUBB() { if (postPage.includes(window.location.pathname) && isAddNewPostUBB) { let bookContent = document.getElementsByName("book_content")[0]; bookContent.insertAdjacentHTML( "beforebegin", ` ` ); addEventAry.forEach((item) => { handleEventListener(item.id, bookContent, item.ubb, item.offset); }); document.getElementById("ubb_more").addEventListener("click", () => { let ubb_tool = document.getElementsByClassName("more_ubb_tools")[0]; ubb_tool.style.display = ubb_tool.style.display === "none" ? "block" : "none"; }); } } // 增加回帖ubb function handleAddReplyUBB() { if ( (/^\/bbs-.*\.html$/.test(window.location.pathname) || viewPage.includes(window.location.pathname)) && isAddReplyUBB ) { const form = document.getElementsByName("f")[0]; if (!form) { return; } const fileTag = document.querySelector( "a[href^='/bbs/book_re_addfile.aspx']" ); // 添加ubb展开按钮 fileTag.insertAdjacentHTML( "afterend", `` ); // 妖火图床、超链接、图片 form.insertAdjacentHTML( "beforeend", `
链接 图片 音频 视频 你真该死啊
半角 换行 加粗 斜体 颜色字 下划 删除 分割
短信 拨号 时间 倒计天
妖火图床 皮皮 b站 抖音 快手 外链 短链接

` ); // 处理默认展开ubb if (isUnfoldUbb) { $(".ubb_wrap").height("auto"); } else { $(".ubb_wrap").height(32); } // 处理折叠ubb $("#ubb_unfold").click(function (event) { if (this.value == "折叠UBB") { $(".ubb_wrap").height(32); this.value = "展开UBB"; } else { $(".ubb_wrap").height("auto"); this.value = "折叠UBB"; } event.preventDefault(); }); // 超链接 const textarea = document.querySelector("textarea"); addEventAry.forEach((item) => { handleEventListener(item.id, textarea, item.ubb, item.offset); }); } } // 增加回帖表情 function handleAddReplyFace() { if ( (/^\/bbs-.*\.html$/.test(window.location.pathname) || viewPage.includes(window.location.pathname)) && isAddReplyFace ) { const form = document.getElementsByName("f")[0]; if (!form) { return; } const face = form.getElementsByTagName("select")[0]; const sendmsg = form.querySelector("#sendselect") || form.getElementsByTagName("select")[1] || form.querySelector(".tongzhi"); const textarea = form.getElementsByTagName("textarea")[0]; // 显示表情 textarea.insertAdjacentHTML("beforebegin", '
'); const facearea = document.getElementById("facearea"); let allFaceHtml = ""; faceList.forEach((faceStr, i) => { let name = faceStr.split(".")[0]; allFaceHtml += ` `; }); diyFaceList.forEach((item, i) => { allFaceHtml += ` `; }); facearea.innerHTML = allFaceHtml; // 添加表情展开按钮 sendmsg.insertAdjacentHTML( "afterend", `表情${isUnfoldFace ? "折叠" : "展开"}` ); // 处理点击添加表情包 facearea.onclick = function (event) { if (event.target.tagName.toLowerCase() === "img") { // 自定义图片 let diySrc = event.target.dataset.src; // 处理完折叠表情 $("#facearea").hide(); $("#unfold").text("表情展开"); if (diySrc) { //把光标移到文本框最前面 textarea.focus(); textarea.setSelectionRange(0, 0); insertText(textarea, `[img]${diySrc}[/img]`, 0); } else { // 处理图片的点击事件 face.value = event.target.getAttribute("value"); } } }; // 处理默认展开表情 if (isUnfoldFace) { $("#facearea").show(); } else { $("#facearea").hide(); } // 处理折叠表情 $("#unfold").click(function (event) { if (this.innerText == "表情展开") { $("#facearea").show(); this.innerText = "表情折叠"; } else { $("#facearea").hide(); this.innerText = "表情展开"; } }); } } function handleReply() { if ( (/^\/bbs-.*\.html$/.test(window.location.pathname) || viewPage.includes(window.location.pathname)) && (isAddReplyUBB || isAddReplyFace) ) { // 取消回复文本框粘性定位。 $(".sticky").addClass("add-position-static"); // 回复页不处理 if (!window.location.pathname.includes("/bbs/book_re.aspx")) { let wrap = document.querySelector("forum-container") || document.querySelector(".recontent"); wrap.addEventListener("click", (event) => { if ( event.target.innerText === "回" || event.target.className === "replyicon" || event.target.alt === "回复" ) { // 如果是回复指定楼层就定位到回复输入框 if ( /回复\d+楼/.test(document.querySelector(".sticky b")?.innerText) ) { window.scrollTo(0, document.querySelector(".sticky").offsetTop); } } }); } } } function handleUploadImage() { if (isUploadImage) { let textArea = document.getElementsByTagName("textarea")[0]; if (!textArea) return; // 排除游戏大厅页面 if (/^\/games\/\w+\/index\.aspx$/.test(window.location.pathname)) return; let isReplyPage = /^\/bbs-.*\.html$/.test(window.location.pathname) || viewPage.includes(window.location.pathname); let insertDom = textArea; let isMessagePage = ["/bbs/messagelist_view.aspx"].includes( window.location.pathname ); if (isMessagePage) { insertDom = textArea.parentNode; } MY_addStyle(` .upload-wrap { position: relative; display: inline-block; width: 100%; box-sizing: border-box; height: 50px; border: 2px dashed #ccc; border-radius: 5px; font-size: 16px; color: #555; text-align: center; cursor: pointer; transition: all 0.3s; margin-bottom: ${isMessagePage ? "5px" : 0}; } .upload-wrap-disabled{ background: #ddd; cursor: not-allowed; } .upload-wrap:hover { border-color: #aaa; } .upload-wrap:focus { outline: none; } .upload-input-label { width: 100%; height: 100%; font-weight: bold; display: flex; justify-content: center; align-items: center; } .upload-loading { box-sizing: border-box; border: 6px solid #f3f3f3; border-top: 6px solid #3498db; border-radius: 50%; width: 40px; height: 40px; animation: spin 2s linear infinite; margin: auto; position: absolute; z-index: 10; left: 50%; top: 50%; margin-top: -20px; margin-left: -20px; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } `); insertDom.insertAdjacentHTML( isMessagePage ? "beforebegin" : "afterend", `` ); // 获取上传图标的 input 元素 const uploadInput = document.querySelector("#upload-input"); const uploadWrap = document.querySelector(".upload-wrap"); const uploadLoading = document.querySelector(".upload-loading"); uploadInput.addEventListener("change", handleFileSelect); uploadWrap.addEventListener("dragover", handleDragOver); uploadWrap.addEventListener("drop", handleDrop); textArea.addEventListener("paste", handlePaste); // 剪贴板事件 async function handlePaste(event) { const clipboardData = event.clipboardData || event.originalEvent.clipboardData; const items = clipboardData.items; handleUploadStatus("start"); const files = []; for (const item of items) { if (item.type.indexOf("image") !== -1) { const blob = item.getAsFile(); // paste 事件的处理程序是异步的,所以不能在这里直接上传,否则有多个只会读取第一个 // await uploadFile(blob); files.push(blob); } } // 此处处理上传 for (const item of files) { await uploadFile(item); } handleUploadStatus("end"); } // 上传事件 async function uploadFile(file) { let uploadConfig = { 水墨图床: { url: "https://img.ink/api/upload", name: "image", token: inkToken || "", }, 极速图床: { url: "https://tucdn.wpon.cn/api/upload", name: "image", token: speedFreeToken || "", }, 美团图床: { url: "https://aapi.helioho.st/upload.php", name: "image", }, }; let { url: uploadUrl, name: uploadName, token: uploadToken, } = uploadConfig[imageBedType]; let formData = new FormData(); formData.append(uploadName, file); if (imageBedType === "美团图床") { formData.append("fileId", file.name); } try { let response; if (imageBedType === "美团图床") { response = await fetch(uploadUrl, { method: "POST", body: formData, }); } else { response = await fetch(uploadUrl, { method: "POST", headers: { token: uploadToken || "", }, body: formData, }); } const res = await response.json(); let { code, url, data, msg } = res; if (code === 200 || code === 0 || url) { // 处理葫芦侠图床直接取url,其他取data.url if (!url) { url = data.url; } if (url) { // 如果是回帖页面把光标移到文本框最前面 if (isReplyPage) { textArea.focus(); textArea.setSelectionRange(0, 0); } insertText(textArea, `[img]${url}[/img]`, 0); } } else { alert(msg); } } catch (error) { alert(error); console.error("上传失败:", error); } } // 选择文件change事件 async function handleFileSelect(event) { const files = event.target.files; handleUploadStatus("start"); for (const file of files) { await uploadFile(file); } handleUploadStatus("end"); } // 拖拽事件 function handleDragOver(event) { event.stopPropagation(); event.preventDefault(); event.dataTransfer.dropEffect = "copy"; } async function handleDrop(event) { event.stopPropagation(); event.preventDefault(); const files = event.dataTransfer.files; handleUploadStatus("start"); for (const file of files) { if (file.type.indexOf("image") !== -1) { await uploadFile(file); } } handleUploadStatus("end"); } /** * 处理上传状态 * @param {'start' | 'end'} type 处理的状态 */ function handleUploadStatus(type) { if (type === "start") { uploadWrap.classList.toggle("upload-wrap-disabled"); uploadInput.disabled = true; uploadLoading.style.display = "block"; } if (type === "end") { uploadWrap.classList.toggle("upload-wrap-disabled"); uploadInput.disabled = false; uploadLoading.style.display = "none"; uploadInput.value = ""; } } } } // 处理404页面跳回新帖页面 function handleNotFoundPage() { if (notFoundPage.includes(window.location.pathname)) { history.go(-2); // let year = new Date().getFullYear(); // location.href = `/bbs/book_list.aspx?gettotal=${year}&action=new`; } } /** * 删除过期的帖子 * @param {number|string} value 存储肉帖的对象 */ function deleteExpiredID(value) { let nowTime = new Date().getTime(); Object.keys(value).forEach((key) => { let lastTime = value[key]; if (nowTime > timeLeft(lastTime, expiredDays)) { delete value[key]; } }); } // 获取用户等级 function handleShowUserLevel() { if (!/^\/bbs-.*\.html$/.test(window.location.pathname) || !isShowLevel) { return; } let user_id = document.getElementsByClassName("subtitle")[0].firstElementChild.href; function success(rp) { let lv_zz = /<\/b>(\S*)级/; let lv_text = rp.match(lv_zz)?.[1] || "0"; // console.log(lv_text); addLvTip(lv_text); } function fail(code) { console.log("error"); } let request = new XMLHttpRequest(); request.onreadystatechange = function () { if (request.readyState === 4) { if (request.status === 200) { return success(request.responseText); } else { return fail(request.status); } } else { } }; request.open("GET", user_id); //request.responseType = 'document'; request.send(); function addLvTip(lv) { let info_d = document.getElementsByClassName("subtitle")[0]; let user_name_d = info_d.children[1]; console.log(user_name_d); let lv_d = document.createElement("div"); lv_d.innerText = "Lv " + lv; lv_d.style = "display:inline;margin-left:10px; text-align:center; margin-right:10px;color:#ff4234;font-size:17px;border-radius: 30px;"; info_d.insertBefore(lv_d, user_name_d); } } function handleAddLoadMoreBtnClick() { // 如果打开了全自动吃肉和自动加载更多,并且在帖子列表页才添加事件 let isPage = loadNextPage.some((item) => item.test(window.location.pathname) ); if (isPage) { let loadMoreBtn = null; let nextPageWrap = document.querySelector(".bt2"); if (loadNextPageType === "nextPage" && nextPageWrap) { loadMoreBtn = nextPageWrap.firstChild; } else { loadMoreBtn = document.querySelector("#KL_loadmore"); } loadMoreBtn?.addEventListener("click", (e) => { isClickLoadMoreBtn = true; isNewPage = false; }); } } // 自动加载下一页 function handleLoadNextPage() { // 处理自动加载更多 let isPage = loadNextPage.some((item) => item.test(window.location.pathname) ); if (isPage && isLoadNextPage) { let nextBtn = null; let nextPageWrap = document.querySelector(".bt2"); // 距离按钮最大多少就会触发 let bottomMaxDistance = 250; if (loadNextPageType === "more" || !nextPageWrap) { nextBtn = document.querySelector("span[id$=show_tip]"); } else { nextBtn = nextPageWrap.firstChild; bottomMaxDistance = 150; } let A = nextBtn.getBoundingClientRect().bottom; let B = document.documentElement.clientHeight; // 获取当前列表的长度 let newLength = getListLength(); // 加载更多按钮距离距底部小于300px才开始加载 // 没有加载完成前不会再次加载 // 小于页面最大加载数量才会加载 if ( A <= B + bottomMaxDistance && !isClickLoadMoreBtn && newLength < maxLoadNum ) { nextBtn.click(); // 放到加载更多按钮里面监听,此处不处理 // isClickLoadMoreBtn = true; // isNewPage = false; } } } /** * 节流函数 * @param {function} fn - 要节流的函数 * @param {number} interval - 节流时间间隔(毫秒) * @param {Object} options - 选项对象 * @param {boolean} [options.leading=true] - 是否在开始时立即执行一次函数 * @param {boolean} [options.trailing=isExecTrail] - 是否在结束时再执行一次函数 * @returns {function} 节流后的函数 */ function throttle( fn, interval, { leading = true, trailing = isExecTrail } = {} ) { let startTime = 0; let timer = null; const _throttle = function (...args) { return new Promise((resolve, reject) => { try { // 1.获取当前时间 const nowTime = new Date().getTime(); // 对立即执行进行控制 if (!leading && startTime === 0) { startTime = nowTime; } // 2.计算需要等待的时间执行函数 const waitTime = interval - (nowTime - startTime); if (waitTime <= 0) { // console.log("执行操作fn") if (timer) clearTimeout(timer); const res = fn.apply(this, args); resolve(res); startTime = nowTime; timer = null; return; } // 3.判断是否需要执行尾部 if (trailing && !timer) { timer = setTimeout(() => { // console.log("执行timer") const res = fn.apply(this, args); resolve(res); startTime = new Date().getTime(); timer = null; }, waitTime); } } catch (error) { reject(error); } }); }; _throttle.cancel = function () { if (timer) clearTimeout(timer); startTime = 0; timer = null; }; return _throttle; } /** * 添加事件监听 * @param {string} id dom元素id * @param {HTMLElement} textarea 插入的文本框 * @param {string} ubb 插入的内容 * @param {number} offset 插入的位置 */ function handleEventListener(id, textarea, ubb, offset) { document.getElementById(id)?.addEventListener("click", (e) => { if (id === "ubb_nzgsa") { // if (textarea.value !== "") { insertText( textarea, "[audio=X]https://file.uhsea.com/2304/3deb45e90564252bf281f47c7b47a153KJ.mp3[/audio]", 0 ); // } else { // alert("不要无意义灌水啦!"); // } } else { e.preventDefault(); insertText(textarea, ubb, offset); } }); } /** * 简易版jquery实现,用于替换之前写的部分语法,不引用cdn库 * @returns */ function myJquery() { let jQuery = function (selector) { return new jQuery.fn.init(selector); }; jQuery.fn = jQuery.prototype = { constructor: jQuery, init: function (selector) { if (!selector) { return this; } if (typeof selector === "string") { let elements = document.querySelectorAll(selector); this.length = elements.length; for (let i = 0; i < elements.length; i++) { this[i] = elements[i]; } } else if (selector.nodeType) { this[0] = selector; this.length = 1; } else if (selector instanceof jQuery) { return selector; } else if (Array.isArray(selector)) { for (let i = 0; i < selector.length; i++) { this[i] = selector[i]; } this.length = selector.length; return this; } return this; }, length: 0, each: function (callback) { for (let i = 0; i < this.length; i++) { callback.call(this[i], i, this[i]); } return this; }, css: function (prop, value) { if (typeof prop === "string") { if (value !== undefined) { this.each(function () { this.style[prop] = value; }); return this; } else { return this[0].style[prop]; } } else { for (let key in prop) { this.each(function () { this.style[key] = prop[key]; }); } return this; } }, text: function (text) { if (text !== undefined) { this.each(function () { this.textContent = text; }); return this; } else { let result = ""; this.each(function () { result += this.textContent; }); return result; } }, html: function (html) { if (html !== undefined) { this.each(function () { this.innerHTML = html; }); return this; } else { return this[0].innerHTML; } }, append: function (content) { if (typeof content === "string") { this.each(function () { this.insertAdjacentHTML("beforeend", content); }); } else if (content.nodeType) { this.each(function () { this.appendChild(content); }); } else if (content instanceof jQuery) { this.each(function () { let self = this; content.each(function () { self.appendChild(this); }); }); } return this; }, addClass: function (className) { let classNames = className.split(" "); this.each(function () { for (let i = 0; i < classNames.length; i++) { if (this.classList) { this.classList.add(classNames[i]); } else { let currentClasses = this.className.split(" "); if (currentClasses.indexOf(classNames[i]) === -1) { this.className += " " + classNames[i]; } } } }); return this; }, removeClass: function (className) { let classNames = className.split(" "); this.each(function () { for (let i = 0; i < classNames.length; i++) { if (this.classList) { this.classList.remove(classNames[i]); } else { let currentClasses = this.className.split(" "); let index = currentClasses.indexOf(classNames[i]); if (index !== -1) { currentClasses.splice(index, 1); this.className = currentClasses.join(" "); } } } }); return this; }, show: function () { this.each(function () { // 恢复元素之前的display属性 let classDisplay = getComputedStyle(this).getPropertyValue("display"); let display = this.getAttribute("data-display") || (classDisplay === "none" ? "block" : classDisplay); this.style.display = display ? display : ""; }); return this; }, hide: function () { this.each(function () { // 记住元素之前的display属性 let display = this.style.display || getComputedStyle(this).getPropertyValue("display"); if (display !== "none") { this.setAttribute("data-display", display); } this.style.display = "none"; }); return this; }, click: function (callback) { this.each(function () { this.addEventListener("click", callback); }); return this; }, on: function (event, childSelector, data, handler) { if (typeof childSelector === "function") { handler = childSelector; childSelector = null; data = null; } else if (typeof data === "function") { handler = data; data = null; } this.each(function () { let element = this; let listener = function (e) { let target = e.target; if ( !childSelector || element.querySelector(childSelector) === target ) { handler.call(target, e, data); } }; event.split(" ").forEach(function (type) { element.addEventListener(type, listener); }); }); return this; }, prev: function () { let prevElement = null; this.each(function () { prevElement = this.previousElementSibling; }); return jQuery(prevElement); }, next: function () { let nextElement = null; this.each(function () { nextElement = this.nextElementSibling; }); return new jQuery(nextElement); }, children: function (selector) { let childElements = []; this.each(function () { let children = this.children; for (let i = 0; i < children.length; i++) { if (!selector || children[i].matches(selector)) { childElements.push(children[i]); } } }); return jQuery(childElements); }, parent: function (selector) { let parentElements = []; this.each(function () { let parent = this.parentElement; if (!selector || parent.matches(selector)) { parentElements.push(parent); } }); return jQuery(parentElements); }, closest: function (selector) { var result = []; this.each(function () { var closestElement = this.closest(selector); if (closestElement) { result.push(closestElement); } }); return new jQuery(result); }, prop: function (name, value) { if (value === undefined) { let element = this[0] || {}; return element[name]; } else { this.each(function () { this[name] = value; }); return this; } }, remove: function () { this.each(function () { this.parentElement.removeChild(this); }); return this; }, height: function (value) { if (value === undefined) { if (this[0]) { return this[0].clientHeight; } else { return null; } } else { this.each(function () { this.style.height = isNaN(value) ? value : value + "px"; }); return this; } }, }; jQuery.fn.init.prototype = jQuery.fn; return jQuery; } })();