├── 115helper_icon_001.jpg ├── JavOldDriver.user.js ├── LICENSE └── README.md /115helper_icon_001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hobbyfang/javOldDriver/44de9055f9b294a1920620cbef7b37eb1866b833/115helper_icon_001.jpg -------------------------------------------------------------------------------- /JavOldDriver.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name JAV老司机 3 | // @namespace https://sleazyfork.org/zh-CN/users/25794 4 | // @version 3.8.9 5 | // @supportURL https://sleazyfork.org/zh-CN/scripts/25781/feedback 6 | // @source https://github.com/hobbyfang/javOldDriver 7 | // @description JAV老司机神器,支持各Jav老司机站点。拥有高效浏览Jav的页面排版,JAV高清预览大图,JAV列表无限滚动自动加载,合成“挊”的自动获取JAV磁链接,一键自动115离线下载。。。。没时间解释了,快上车! 8 | // @author Hobby 9 | 10 | // @require https://lib.baomitu.com/jquery/2.2.4/jquery.min.js 11 | // @require https://lib.baomitu.com/lovefield/2.1.12/lovefield.min.js 12 | // @require https://lib.baomitu.com/limonte-sweetalert2/9.17.2/sweetalert2.all.min.js 13 | // @require https://cdn.jsdelivr.net/npm/jquery@2.2.4/dist/jquery.min.js 14 | // @require https://cdn.jsdelivr.net/npm/lovefield@2.1.12/dist/lovefield.min.js 15 | // @require https://cdn.jsdelivr.net/npm/sweetalert2@9.17.2/dist/sweetalert2.all.min.js 16 | // @resource icon https://cdn.jsdelivr.net/gh/hobbyfang/javOldDriver@master/115helper_icon_001.jpg 17 | 18 | // javlib主要有码jav资源、排行榜、点评,最新地址在github.com/javlibcom 19 | // @include *://*javlibrary.com/* 20 | // @include *://*javlib.com/* 21 | // @include *://*o83h.com/* 22 | // @include *://*r86m.com/* 23 | 24 | // javbus有无码jav资源、论坛 25 | // @include *://*javbus.com/* 26 | // @include *://www.*bus*/* 27 | // @include *://www.*javsee*/* 28 | // @include *://www.*seejav*/* 29 | 30 | // onejav有FC2资源、排行榜 31 | // @include *://*onejav.com/* 32 | 33 | // avsox有无码jav资源,含FC2 tellme.pw/avsox 34 | // @include *://*avsox.*/* 35 | 36 | // jav321有素人资源、排行榜 37 | // @include *://*jav321.com/video/* 38 | 39 | // javdb有各资源排行榜,但部分需付费 javdb.com 40 | // @include *://*javdb*.com/* 41 | 42 | // @include *://*javstore.*/* 43 | // @include *://*avmoo.*/* 44 | // @include ://tellme.pw/avmoo 45 | // @include *://115.com/* 46 | // @include *://*.quark.cn/list* 47 | // @include *://www.*dmm*/* 48 | 49 | // @run-at document-idle 50 | // @grant GM_xmlhttpRequest 51 | // @grant GM_addStyle 52 | // @grant GM_getValue 53 | // @grant GM_setValue 54 | // @grant GM_deleteValue 55 | // @grant GM_notification 56 | // @grant GM_setClipboard 57 | // @grant GM_getResourceURL 58 | // @grant GM_registerMenuCommand 59 | // @grant GM_info 60 | // @grant GM_openInTab 61 | 62 | // @connect * 63 | // @copyright hobby 2016-12-18 64 | // @license GPL-3.0 65 | // @compatible chrome V52+ & Tampermonkey 66 | 67 | // 大陆用户推荐Chrome(V52+) + Tampermonkey(必须扩展) + Clash/V2ray(代理) + Proxy SwitchyOmega(扩展)的环境下配合使用。 68 | // 上车请使用chrome浏览器,其他浏览器的问题本人不支持发现和修复相关问题。 69 | 70 | // 注意:2.0在每个版本号更新后,javlibrary每个不同域名站点在登录javlibrary的情况下,都会分别首次运行此脚本。 71 | // 根据电脑性能及访问网速情况不同,正常能在1分钟以内(以5000个车牌量为例)缓存个人数据到本地浏览器中. 72 | // 此目的用于过滤个人已阅览过的内容提供快速判断,目前个人图书馆账号的想要、看过、拥有及最新浏览过的番号为已阅数据依据。 73 | // 目前在同步过程中如果浏览器当前页面不在javlibrary站点或者浏览器在后台,同步会被暂停或中止,需注意. 74 | // 如果不登录javlibrary或同版本号已经同步过,就不会运行同步,那么则无此影响. 75 | 76 | // 油猴脚本技术交流:https://t.me/+TgfN6vLVRew7aMWt 77 | 78 | // 已知问题:javlib加了Cloudflare防御,目前更新版本利用新网址列表功能已经复活8成以上,代价是2秒左右刷新一个列表的番号。目前只能这样了。 79 | // 如有更优方案,可留言反馈。另外blogjav站已经能访问了,但新番号基本无预览图了,就做一个备用预览大图源吧。 80 | 81 | // v3.8.9 优化预览图加载顺序,优化预览图加载问题。 82 | // v3.8.8 修复javlib加了Cloudflare防御导致列表功能失效问题。 83 | // v3.8.7 修复部分页面预览图失效的问题。javlib新增了FC2菜单跳转(onejav)。 84 | 85 | // v3.8.6 增加了115离线成功,3秒后刷新当前页面。修复了磁力列表下javdb查找问题。 86 | // v3.8.5 增加javdb影片详情页的115离线快捷键及115在线播放入口(by Stel000)。修复因新版chrome中DOMNodeInserted事件废弃导致无法离线下载问题。 87 | // v3.8.4 修复了javlib同步问题。修复了115网盘关联视频问题。 88 | // v3.8.3 修复javstore22年12月番号视频内容预览大图改版前后的图片获取及显示兼容问题。解决获取dmm评价数据受18岁询问限制。 89 | // v3.8.2 修复javstore番号页图片显示问题,修复javstore备用预览图失效的问题。 90 | // v3.8.1 javlib、javbus、javdb新增了VR菜单入口,javbus新增了FC2菜单跳转,javdb修改了FC2菜单内容(需登录)。修复了已知问题。 91 | // v3.8.0 增加各Jav站点番号浏览记录缓存。增加javbus、javdb列表阅览番号标色。增加夸克在线播放的关联入口,夸克在线播放页排版调整。 92 | // 优化dmm评分数据获取,多数番号突破dmm地区访问限制。代码调整优化。修复了已知问题。 93 | 94 | // v3.7.1 再优化blogjav预览图获取方式,优化预览图加载时间。修复了已知问题。 95 | // v3.7.0 增加javdb列表的JAV评分排序、屏蔽指定评分人数功能。优化blogjav预览图获取方式。 96 | 97 | // v3.6.0 原番号页面增加dmm、javdb评分展示及在线播放跳转、JAV跳转,增加javstore番号页改造,增加javdb瀑布流及列表增加JAV跳转和排版优化。 98 | // 原javlib番号页面自带预览图可点击查看,onejav列表简单优化,其他已知bug修复,部分代码优化。 99 | 100 | // v3.5.2 修复部分地区无法访问脚本依赖库问题,重新梳理匹配脚本域名作用地址。 101 | // v3.5.1 修复javdb站源的磁力搜索,增加jav磁链地址的修改入口。 102 | // v3.5.0 图书馆jav列表“按评分排序”升级为“按【VR】+评分排序”,VR标题增加背景颜色区分。 103 | // v3.4.0 针对JVR影片查找资源的需求,结合javlib站的进阶搜寻中多重搜寻来过滤VR资源,增加了javdb站做为jav磁链接下载来源。 104 | // 修复了预览图失效的问题。 105 | // v3.3.3 预览图备用站更换成javstore。 106 | // v3.3.0 新增图书馆浏览时根据115在线播放来同步图书馆的已拥有功能(建议登录,不然会弹窗提示)。 107 | // v3.2.0 新增javarchive站的预览图做备用,当blogjav预览图无法正常读取时使用。 108 | // 优化图书馆缓存个人数据的同步效率(60秒内可完成)。优化图书馆站点瀑布流列表排版。修复了部分115在线播放查找识别问题。 109 | // v3.1.7 增加脚本设置功能,支持磁链地址失效可自己更换。更新最新磁链地址。 110 | // v3.1.6 更换失效的磁链地址。另btdig,nayy,torrentkitty站点需科学上网,其中btdig还需手工验证非机器访问。 111 | // v3.1.5 增加过滤评分及排序时排除10分的番号,更换失效的磁链地址。 112 | // v3.1.0 优化javbus/avmoo/avsox瀑布流排版。 113 | // v3.0.0 增加115在线播放的关联入口。同时本代码重新梳理及优化。 114 | 115 | // v2.3.0 增加jav321网站内容排版的支持,增加查找已登录115网盘是否拥有当前番号显示。 116 | // v2.2.0 增加onejav网站内容排版的支持,热门Jav预览搜集更省时省力。更换两个磁链资源新地址。 117 | // v2.1.5 增加点击番号完成复制功能。 118 | // v2.1.3 增加btdigg磁链资源站点。修复了已知问题。 119 | // v2.1.1 增加jav站点瀑布流控制按钮功能。 120 | // v2.1.0 增加javbus站内磁链列表的复制、115离线的快捷键功能。 121 | 122 | // v2.0.7 增加一种情况Jav列表排序功能支持(仅javlib)。 123 | // v2.0.5 增加Jav列表“按评分排序”、“按时间排序”功能(仅javlib),及更新Jav站点域名。 124 | // v2.0.0 增加自动同步个人数据缓存到本地,jav列表能识别个人已阅览过的内容(需登录javlibray),针对javlibrary的高评价栏目,增加过滤"不看我阅览过"功能。 125 | 126 | // v1.2.0 针对javlibrary的高评价栏目,增加过滤“只看当前月份”、“只看近两月份”功能。另默认此栏目近两月份的内容增加背景颜色区分。 127 | // v1.2.0 更新了合成“挊”脚本的更多网站的支持,感谢作者thunderhit,同时修复原脚本部分网站功能失效问题。 128 | // v1.1.0 优化更新了JAV列表无限滚动自动加载的代码,增加JAV列表中显示"发行日期"和"评分"的排版,以及修复了已知问题。 129 | // v1.0.3 优化了高清预览大图的获取。 130 | // v1.0.2 优化了javlibrary排版,做了最低分辨率1280x800的排版适配调整,及修复了已知问题。 131 | // v1.0.0 支持javlibrary.com、javbus.com、avmo.pw、avso.pw等老司机站点,第一版发布。 132 | 133 | // ==/UserScript== 134 | /* jshint -W097 */ 135 | (function () { 136 | 'use strict'; 137 | const EMPTY_IMAGE_DATA = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALQAAAB4CAMAAABsOSjPAAAAn1BMVEUAAAD/lgD/x3f/zoj/nRH/3Kr/+e7/sD//68z/1Zj/qzP/skT/uVX/9eX/pCL/oh3/wGb/8d3/4LL/5Lv/2aL/tUv/kAD/0o//9uj/v2L/mQn//vv//Pf/rjf/+vL/1pn/2pT/mAX/kwD/+/X/9OH/4rb/qzD/qSX/mAH/6sn/6cL/26f/y4D/nxr/vV7/uU//wnH/7tb/1YX/wEL/nypWdfcGAAAAAXRSTlMAQObYZgAABOdJREFUeNrs2F1TgkAYhmGeRMRWLbDlS5BAUPysqf7/b6sYt600dQ8a3nW4T3Teo2uWHRYw2tquMOiU5mhDl64ADR36jdZhsVv0X7XoFn2iFt2iT9Si/wG93AxY73Q8fLAooW2GizI7MRm0j4tLCiJoBTPyN4sE2s6h0o4EmkMprySAXmaK6CcC6A0UG1nNowdQLFo2j2aQmTxMKpyrbB7dk5rd54VfLXAmlxI6NOqKrUZocygOG43QXEycSB90KCZTUx90Mvk6bvRBV+P95F6jPY1RUQ9SrW55uPOdqR3id3kUEUYDkZkdmu8da731KrLoI3mPxkfDV486Ovthrps800aPUrs7l2ZR6uV00XPrc2GZMMtWC7Lo26Aez7gwyyxGFJ0MxWHOhVlmlW7pugE1dL03hPpl/y/wA2KfxX6gk++62cSoixkShxba9fuywjgsfgKwHZNCHyuYfVtvjjqfOHqdSWHMsG8XU0Z3I6Av98ZXi5vOR5uNQxDtVoBQzzhk+f63Sw+9juQenjKiz9Pj/oNsnQ4qYeNpZ0H1JYBBsWzVPPoZim2L5tElFOsRuOXFc6iVEkAbXSiVTCigjRAKmTaNE/G9nfNtbRsGwnjudBKW5Gk2ZtCtsJcb7N2+/5ebHv1JXROEkkFxih6IkSr57ufrnaQ2Ia93UP/4c5pt3Ar16dvfE509XpT/Hb62FX593852YHp9+dLWz3MfTfc686cQbmpAD+iGBvSAbmhAD+iGBvSAbmhAD+iGBvSAbuhjoDdKErYPmDSBttISWRvzhJI899m1tDShFRW5B6AnomBqSzXn3fWWANPchDbMMxF74segq3khf/h3X3g3b+Ek02V3aUFX+2QuD2l9e6vFH35VimjaQaPTr7mVHtW+XB6TAXRO5uVgRP8fNPdCM81WyCsp0dOeiBaDGY4o28GgqB00C7l8s5RhHx8iUFK4BW0dkdMpoyY493E4TJ5ydFUgCoFUL/RMQkViriXKGKgIS26pN2ht4a1Az7WkpZg5FuIGs8XBlrocp2uC59LNsv3QlO/2uH9DgwEINws7kmSdWWqZAE7jQRSMlGGPJULzgnv0EVqn1W9B6WP2CqcuuaJkZioOSN8BHVZHHoZtZIELXEL8cQ7JQrIiVXgPfXGYBCOeJKWGOmYEoANHpUBbuPKANrUFCy6aVWkJNdIPzYBzIArx4hBPQJucDj72HYVdduThtMXQpsjF4SVX0RFaJ9LqJLl0FTqatQgDPNdlowNaXyPtk5EKyPl2kzyuggdBytj96pGjKiTLFdqRugFt3kFzju+a/Sm0MnTOvP5IAzVlAeotxF6YLlYigaDAHfh8gpw8rhU6Q0U5pIdGKekMvd2ABqCCWcYMC9S5ACAxVS38diEaR1kqBwoGcImvrAAbUC7J2ny/eVtAgw1yZUjfgjZCZXE3lOUL9BxdrVIdNKEnKuIYX1egLZy4sphMBq0ggAB13bprOCu1zwsWCqORHmiXM8hSn9HCZ/aspdC000Nx1npZGVXFKl0AwmwvVuU5a4lcXgOqlLqy8ARUZnUcgnjXMdcjiI4ty7q4W9kWHjXx2oDul+rdiU/yR4C28SV9B5SzQJtr0nfoLNDlIOFNz9zTQKfi031TzwN9hwb0gG5oQA/oDxR9iq80ehI9PfQT6amhh4Y+k/4BYXA+w/0JM4sAAAAASUVORK5CYII='; 138 | const JAVDB_ITEM_SELECTOR = '.movie-list.v.cols-4.vcols-8 .item, .movie-list.v.cols-4.vcols-5 .item, .movie-list.h.cols-4.vcols-8 .item, .movie-list.h.cols-4.vcols-5 .item'; 139 | const BTSOW_DOMAIN = 'btsow.motorcycles'; 140 | const JAVDB_DOMAIN = 'javdb368.com'; 141 | const TORRENTKITTY_DOMAIN = 'www.torrentkitty.one'; 142 | const MMTV_DOMAIN = '7mmtv.sx'; 143 | const JAVLIB_DOMAIN = 'r86m.com'; 144 | 145 | // 115用户ID 146 | let jav_userID = GM_getValue('jav_user_id', 0); 147 | // icon图标 148 | let icon = GM_getResourceURL('icon'); 149 | // 瀑布流状态:1:开启、0:关闭 150 | let waterfallScrollStatus = GM_getValue('scroll_status', 1); 151 | // 当前网页域名 152 | let domain = location.host; 153 | // 数据库 154 | let javDb; 155 | // 表 156 | let myMovie; 157 | 158 | /** 159 | * 对Date的扩展,将 Date 转化为指定格式的String 160 | * 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,/'; 161 | * 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字) 162 | * 例子:(new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423f 163 | * (new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18 164 | * @param {string} fmt 日期格式 165 | * @returns {void | string} 格式化后的日期字符串 166 | */ 167 | Date.prototype.Format = function (fmt) { //author: meizz 168 | var o = { 169 | "M+": this.getMonth() + 1, //月份 170 | "d+": this.getDate(), //日 171 | "h+": this.getHours(), //小时 172 | "m+": this.getMinutes(), //分 173 | "s+": this.getSeconds(), //秒 174 | "q+": Math.floor((this.getMonth() + 3) / 3), //季度 175 | "S": this.getMilliseconds() //毫秒 176 | }; 177 | if (/(y+)/.test(fmt)) 178 | fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); 179 | for (var k in o) 180 | if (new RegExp("(" + k + ")").test(fmt)) 181 | fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); 182 | return fmt; 183 | }; 184 | 185 | /** 186 | * 多线程异步队列 依赖 jQuery 1.8+ 187 | * @param {Number} n 正整数, 线程数量 188 | */ 189 | function Queue(n) { 190 | n = parseInt(n, 10); 191 | return new Queue.prototype.init((n && n > 0) ? n : 1) 192 | } 193 | 194 | Queue.prototype = { 195 | init: function (n) { 196 | this.threads = []; 197 | this.taskList = []; 198 | while (n--) { 199 | this.threads.push(new this.Thread) 200 | } 201 | }, 202 | /** 203 | * @param {Function} callback promise对象done时的回调函数,它的返回值必须是一个promise对象 204 | */ 205 | push: function (callback) { 206 | if (typeof callback !== 'function') return; 207 | var index = this.indexOfIdle(); 208 | if (index != -1) { 209 | this.threads[index].idle(callback); 210 | //try { console.log('Thread-' + (index+1) + ' accept the task!') } catch (e) {} 211 | } else { 212 | this.taskList.push(callback); 213 | for (var i = 0, l = this.threads.length; i < l; i++) { 214 | ((thread, self, id) => { 215 | thread.idle(() => { 216 | if (self.taskList.length > 0) { 217 | //try { console.log('Thread-' + (id+1) + ' accept the task!') } catch (e) {} 218 | let promise = self.taskList.shift()(); // 正确的返回值应该是一个promise对象 219 | return promise.promise ? promise : $.Deferred().resolve().promise(); 220 | } else { 221 | return $.Deferred().resolve().promise(); 222 | } 223 | }) 224 | })(this.threads[i], this, i); 225 | 226 | } 227 | } 228 | }, 229 | indexOfIdle: function () { 230 | var threads = this.threads, 231 | thread = null, 232 | index = -1; 233 | for (var i = 0, l = threads.length; i < l; i++) { 234 | thread = threads[i]; 235 | if (thread.promise.state() === 'resolved') { 236 | index = i; 237 | break; 238 | } 239 | } 240 | return index; 241 | }, 242 | Thread: function () { 243 | this.promise = $.Deferred().resolve().promise(); 244 | this.idle = (callback) => { 245 | this.promise = this.promise.then(callback) 246 | } 247 | } 248 | }; 249 | Queue.prototype.init.prototype = Queue.prototype; 250 | 251 | /** 252 | * 公用类 253 | */ 254 | class Common { 255 | static init() { 256 | // 是否新版本 257 | let isNewVersion = Common.compareVersions(GM_info.script.version, GM_getValue("javOldDriver_version", "0.0.1")); 258 | 259 | // 磁链访问地址初始化 260 | if (isNewVersion || GM_getValue('btsow_url', undefined) === undefined) { 261 | GM_setValue('btsow_url', BTSOW_DOMAIN); 262 | } 263 | if (isNewVersion || GM_getValue('btdig_url', undefined) === undefined) { 264 | GM_setValue('btdig_url', 'www.btdig.com'); 265 | } 266 | if (isNewVersion || GM_getValue('nyaa_url', undefined) === undefined) { 267 | GM_setValue('nyaa_url', 'sukebei.nyaa.si'); 268 | } 269 | if (isNewVersion || GM_getValue('torrentkitty_url', undefined) === undefined) { 270 | GM_setValue('torrentkitty_url', TORRENTKITTY_DOMAIN); 271 | } 272 | if (isNewVersion || GM_getValue('javdb_url', undefined) === undefined) { 273 | GM_setValue('javdb_url', JAVDB_DOMAIN); 274 | } 275 | if (isNewVersion || GM_getValue('javlib_url', undefined) === undefined) { 276 | GM_setValue('javlib_url', 'www.javlibrary.com'); 277 | } 278 | if (isNewVersion || GM_getValue('javbus_url', undefined) === undefined) { 279 | GM_setValue('javbus_url', 'www.javbus.com'); 280 | } 281 | if (isNewVersion || GM_getValue('avsox_url', undefined) === undefined) { 282 | GM_setValue('avsox_url', 'avsox.click'); 283 | } 284 | GM_setValue("javOldDriver_version", GM_info.script.version); 285 | 286 | GM_registerMenuCommand('设置', () => { Common.openSystemConfig() }); 287 | } 288 | 289 | static openSystemConfig() { 290 | let scroll_true = ''; 291 | if (GM_getValue('scroll_status', 1) !== 0) { 292 | GM_setValue('scroll_status', 1); 293 | scroll_true = "checked"; 294 | } 295 | 296 | let dom = `
297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 |
`; 307 | let $dom = $(dom); 308 | Swal.fire({ 309 | title: '脚本设置', 310 | html: $dom[0], 311 | confirmButtonText: '保存' 312 | }).then((result) => { 313 | if (result.value) { 314 | if ($('#scroll_true')[0].checked) { 315 | GM_setValue('scroll_status', 1); 316 | } else { 317 | GM_setValue('scroll_status', 0); 318 | } 319 | GM_setValue('btsow_url', $('#btsow_url').val()); 320 | GM_setValue('btdig_url', $('#btdig_url').val()); 321 | GM_setValue('nyaa_url', $('#nyaa_url').val()); 322 | GM_setValue('torrentkitty_url', $('#torrentkitty_url').val()); 323 | GM_setValue('javdb_url', $('#javdb_url').val()); 324 | GM_setValue('javlib_url', $('#javlib_url').val()); 325 | GM_setValue('javbus_url', $('#javbus_url').val()); 326 | GM_setValue('avsox_url', $('#avsox_url').val()); 327 | history.go(0); 328 | } 329 | }) 330 | } 331 | /** 332 | * 版本号比较方法 333 | * 传入两个字符串,当前版本号:curV;比较版本号:reqV 334 | * @param {string} curV 当前版本号 335 | * @param {string} reqV 比较版本号 336 | * @returns {boolean} 调用方法举例:compare("3.1.10","3.1.9"),将返回true 337 | */ 338 | static compareVersions(curV, reqV) { 339 | if (curV && reqV) { 340 | //将两个版本号拆成数字 341 | var arr1 = curV.split('.'), 342 | arr2 = reqV.split('.'); 343 | var minLength = Math.min(arr1.length, arr2.length), 344 | position = 0, 345 | diff = 0; 346 | //依次比较版本号每一位大小,当对比得出结果后跳出循环(后文有简单介绍) 347 | while (position < minLength && ((diff = parseInt(arr1[position]) - parseInt(arr2[position])) == 0)) { 348 | position++; 349 | } 350 | diff = (diff != 0) ? diff : (arr1.length - arr2.length); 351 | //若curV大于reqV,则返回true 352 | return diff > 0; 353 | } else { 354 | //输入为空 355 | console.log("版本号不能为空"); 356 | return false; 357 | } 358 | } 359 | /** 360 | * 设置cookie 361 | * @param {string} cname 名字 362 | * @param {string} cvalue 值 363 | */ 364 | static setCookie(cname, cvalue) { 365 | let d = new Date(); 366 | d.setTime(d.getTime() + (30 * 24 * 60 * 60 * 1000)); 367 | let expires = "expires=" + d.toUTCString(); 368 | document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/"; 369 | } 370 | /** 371 | * html文本转换为Document对象 https://jsperf.com/domparser-vs-createelement-innerhtml/3 372 | * @param {string} text 373 | * @returns {Document} 374 | */ 375 | static parsetext(text) { 376 | try { 377 | let doc = document.implementation.createHTMLDocument(''); 378 | doc.documentElement.innerHTML = text; 379 | return doc; 380 | } catch (e) { 381 | alert('parse error'); 382 | } 383 | } 384 | 385 | /** 386 | * 判断日期是否最近X个月份的日期 387 | * @param {String} DateStr 日期 388 | * @param {Number} MonthNum 月数(X) 389 | * @returns {boolean} 390 | */ 391 | static isLastXMonth(DateStr, MonthNum) { 392 | let now = new Date(); //当前日期 393 | let compDate = new Date(DateStr); 394 | let m2 = now.getFullYear() * 12 + now.getMonth(); 395 | let m1 = compDate.getFullYear() * 12 + compDate.getMonth(); 396 | if ((m2 - m1) < MonthNum) { 397 | return true; 398 | } 399 | return false; 400 | } 401 | 402 | /** 403 | * 方法: 通用chrome通知 404 | * @param {string} title 405 | * @param {string} body 406 | * @param {string} icon 407 | * @param {string} click_url 408 | */ 409 | static notifiy(title, body, icon, click_url) { 410 | var notificationDetails = { 411 | text: body, 412 | title: title, 413 | timeout: 3000, 414 | image: icon, 415 | onclick: () => { 416 | window.open(click_url); 417 | } 418 | }; 419 | GM_notification(notificationDetails); 420 | } 421 | 422 | /** 423 | * 发起网络请求 424 | * @param {string} url 对象参数 425 | * @param {string} referrer 426 | * @param {number} timeoutInt 超时毫秒数 427 | * @returns {Promise} 428 | */ 429 | static request(url, referrerStr, timeoutInt) { 430 | return new Promise((resolve, reject) => { 431 | console.log(`发起网址请求:${url}`); 432 | GM_xmlhttpRequest({ 433 | url, 434 | method: 'GET', 435 | headers: { 436 | "Cache-Control": "no-cache", 437 | referrer: referrerStr 438 | }, 439 | timeout: timeoutInt > 0 ? timeoutInt : 20000, 440 | onload: response => { //console.log(url + " reqTime:" + (new Date() - time1)); 441 | response.loadstuts = true; 442 | resolve(response); 443 | }, 444 | onabort: response => { 445 | console.log(url + " abort"); 446 | response.loadstuts = false; 447 | resolve(response); 448 | }, 449 | onerror: response => { 450 | console.log(url + " error"); 451 | console.log(response); 452 | response.loadstuts = false; 453 | resolve(response); 454 | }, 455 | ontimeout: response => { 456 | console.log(`${url} ${timeoutInt > 0 ? timeoutInt : 20000}ms timeout`); 457 | response.loadstuts = false; 458 | response.finalUrl = url; 459 | resolve(response); 460 | }, 461 | }); 462 | }); 463 | } 464 | 465 | /** 466 | * 发起网络请求 467 | * @param {*} details 对象参数 468 | * @returns {Promise} 469 | */ 470 | static requestGM_XHR(details) { 471 | return new Promise((resolve, reject) => { 472 | console.log(`发起网址请求:${details.url}`); 473 | let req = GM_xmlhttpRequest({ 474 | method: details.method ? details.method : "GET", 475 | url: details.url, 476 | headers: details.headers, 477 | timeout: details.timeout > 0 ? details.timeout : 20000, 478 | onprogress: rsp => { 479 | if (details.onprogress && details.onprogress(rsp)) { 480 | resolve(rsp); 481 | req.abort(); 482 | } 483 | }, 484 | onload: rsp => resolve(rsp), 485 | onerror: rsp => { 486 | console.log(`${details.url} : error`); 487 | reject(`error`); 488 | }, 489 | ontimeout: rsp => { 490 | console.log(`${details.url} ${details.timeout > 0 ? details.timeout : 20000}ms timeout`); 491 | reject(`timeout`); 492 | } 493 | }); 494 | }); 495 | } 496 | 497 | /** 498 | * 获取带-的番号 499 | * @param {String} avid 番号如:ABP888 500 | * @returns {String} 带-的番号 501 | */ 502 | static getAvCode(avid) { 503 | //debugger; 504 | // 带-的番号不处理,除了-0 如:DSVR-01167 505 | if (avid.match(/-[^0]/g)) return avid; 506 | // 999999_001,999999-001 不处理 507 | if (avid.match(/^[0-9-_]+$/g)) return avid; 508 | // crazyasia99999,sm999,video_999,BrazzersExxtra.99.99.99 不处理 509 | if (avid.match(/^(crazyasia|sm|video_|BrazzersExxtra)+/gi)) return avid; 510 | //去除开头的FC2 511 | avid = avid.replace(/\b(FC2+)/gi, ""); 512 | let letter = avid.match(/[a-z|A-Z]+/gi); 513 | let num = avid.match(/\d+$/gi)[0]; 514 | if (num.length > 3) { 515 | num = num.replace(/\b(0+)/gi, ""); //去除开头的0 516 | if (num.length < 3) { 517 | num = (Array(3).join(0) + num).slice(-3); 518 | } 519 | } 520 | return letter.toString().replace(/,/g, "-") + "-" + num; 521 | } 522 | /** 523 | * 通过图片或视频url解析出DmmId 524 | * @param {String} url 带DmmId的图片或视频url 525 | * @returns {String} DmmId的番号 526 | */ 527 | static getDmmId(url) { 528 | //let url = "https://pics.dmm.co.jp/digital/video/1mtall028/1mtall028-2.jpg"; 529 | let array = url.split("/"); 530 | let dmmId = array[array.length - 2]; 531 | //结尾数字串 532 | let num = dmmId.match(/\d+$/gi); 533 | //前缀 534 | let prefix = dmmId.replace(num, ""); 535 | 536 | if (num) { 537 | //非00开头的数字同时字符数小于5的,添加00开头 538 | if (!num[0].match(/^00/) && num[0].length < 5) { 539 | num = '00' + num; 540 | } 541 | return prefix + num; 542 | } else { 543 | return null; 544 | } 545 | } 546 | /** 547 | * 根据avid转成dmmId即cid 548 | * @param {string} avid 番号 549 | * @returns {string} dmmId dmm的cid番号 550 | */ 551 | static avIdToDmmId(avid) { 552 | // todo:待优化 553 | return avid; 554 | } 555 | /** 556 | * 获取查询onejav的url 557 | * @param {string} avid 番号 558 | * @returns {string} 返回符合onejav查询番号参数的url 559 | */ 560 | static getOneJavSearchUrl(avid) { 561 | //FC2-PPV-9999999 => 9999999 , ABP-999 => ABP999 562 | avid = avid.replace(/-|FC2|PPV/g, ""); 563 | return "https://onejav.com/search/" + avid; 564 | } 565 | /** 566 | * 获取查询blogjav的番号处理过后的查询字符 567 | * @param {string} avid 番号 568 | * @returns {string} 返回番号处理过后的查询字符 569 | */ 570 | static getBlogJavSearchVal(avid) { 571 | //FC2-PPV-9999999 => FC2+PPV+9999999 , HEYZO-9999 => HEYZO+9999 572 | let cd = avid.replace(/-/g, "+"); 573 | // 不含空格的情况,同时只含有字母与数字 574 | if (!(/\s+/g).test(cd) && (/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]+$/g).test(cd)) { 575 | // ABP999 => ABP+999 576 | // 取结尾数字 577 | let num = cd.match(/\d+$/gi); 578 | //前缀 579 | let prefix = cd.replace(num, ""); 580 | cd = prefix + "+" + num; 581 | } 582 | return cd; 583 | } 584 | /** 585 | * 获取查询jav321的url 586 | * @param {string} avid 番号 587 | * @returns {Promise} 返回符合Jav321查询番号参数的url 588 | */ 589 | static getJav321SearchUrl(avid) { 590 | // 测试 todo 591 | return new Promise((resolve, reject) => { 592 | GM_xmlhttpRequest({ 593 | method: "POST", 594 | url: 'https://www.jav321.com/search', 595 | headers: { 596 | 'Content-Type': 'application/x-www-form-urlencoded' 597 | }, 598 | data: "sn=" + avid, 599 | timeout: 20000, 600 | onload: (r) => resolve(r.finalUrl), 601 | onerror: (r) => reject(`查找jav321的 ${avid} 出错了`), 602 | ontimeout: (r) => reject(`查找jav321的 ${avid} 超时了`) 603 | }); 604 | }); 605 | } 606 | /** 607 | * 获取查询javstore的url 608 | * @param {string} avid 番号 609 | * @returns {Promise} 返回符合JavStore查询番号参数的url 610 | */ 611 | static getJavStoreSearchUrl(avid) { 612 | let promise1 = Common.request(`https://javstore.net/search/${avid}.html`); 613 | return promise1.then((result) => { 614 | if (!result.loadstuts) return; 615 | let doc = Common.parsetext(result.responseText); 616 | // 查找包含avid番号的a标签数组 617 | let a_array = $(doc).find(`.news_1n li h3 span a`); 618 | let a = a_array[0]; 619 | //如果找到全高清大图优先获取全高清的 620 | for (let i = 0; i < a_array.length; i++) { 621 | // 筛选匹配的番号数据 FC2-PPV-9999999 => 正则/FC2.*PPV.*9999999/gi 622 | let reg = RegExp(avid.replace(/-/g, ".*"), "gi"); 623 | if (a_array[i].title.search(reg) > 0) { 624 | if (!a) a = a_array[i]; 625 | let search_idx = a_array[i].title.search(/Uncensored|FHD|4K|Mosaic/i); 626 | // 是否更新的链接 627 | if ( parseInt(a_array[i].href.match(/\d+/)[0]) > parseInt(a.href.match(/\d+/)[0]) && search_idx >= 0) { 628 | a = a_array[i]; 629 | } 630 | } 631 | } 632 | 633 | return a ? `https://javstore.net${a.pathname}` : null; 634 | }); 635 | } 636 | /** 637 | * jav321链接加入鼠标点击打开页面事件 638 | * @param {jQuery} $ele 链接元素 639 | * @param {String} avid 番号 640 | * @returns {jQuery} 链接元素 641 | */ 642 | static jav321LinkMousedown($ele, avid) { 643 | $ele.mousedown((e) => { 644 | //鼠标左键 0 鼠标中键滚轮 1 645 | if (e.button < 2) { 646 | Common.getJav321SearchUrl(avid).then((url) => { 647 | if (url && !(/https:\/\/www.jav321.com\/search/).test(url)) { 648 | GM_openInTab(url, { active: !e.button, insert: true, setParent: true }); 649 | } else { 650 | Common.notifiy(`Jav321查无此番号: ${avid}`, '换个JAV站点查找试试吧!', icon, ""); 651 | } 652 | }).catch((errMsg) => Common.notifiy(errMsg)); 653 | } 654 | }); 655 | return $ele; 656 | } 657 | /** 658 | * javstore链接加入鼠标点击打开页面事件 659 | * @param {jQuery} $ele 链接元素 660 | * @param {String} avid 番号 661 | * @returns {jQuery} 链接元素 662 | */ 663 | static javstoreLinkMousedown($ele, avid) { 664 | $ele.mousedown((e) => { 665 | //鼠标左键 0 鼠标中键滚轮 1 666 | if (e.button < 2) { 667 | //FC2-PPV-9999999 => FC2+PPV+9999999 , HEYZO-9999 => HEYZO+9999 668 | avid = avid.replace(/-/g, "+"); 669 | Common.getJavStoreSearchUrl(avid).then((url) => { 670 | if (url) { 671 | GM_setValue(url, avid); 672 | GM_openInTab(url, { active: !e.button, insert: true, setParent: true }); 673 | } else { 674 | Common.notifiy(`JavStore查无此番号: ${avid}`, '换个JAV站点查找试试吧!', icon, ""); 675 | } 676 | }); 677 | } 678 | }); 679 | return $ele; 680 | } 681 | /** 682 | * 加入AV预览内容图使用的CSS 683 | */ 684 | static addAvImgCSS() { 685 | GM_addStyle(` 686 | .min {max-height: 535px;height:auto;cursor: pointer;} /*Common.addAvImg使用*/ 687 | .max {min-width: 1520px;} /*Common.addAvImg使用*/ 688 | `); 689 | } 690 | /** 691 | * 加入AV预览内容图 692 | * @param {string} avid av唯一码 693 | * @param {function} func 函数 694 | * @param {boolean} isZoom 是否放大,默认true 695 | */ 696 | static addAvImg(avid, func, isZoom) { 697 | let p = Common.getBigPreviewImgUrlFromBlogjav(avid); 698 | let p2 = Common.getBigPreviewImgUrlFromJavStore(avid); 699 | p.then(imgUrl => { 700 | 701 | if (!imgUrl || imgUrl === null) { 702 | addJavArchiveImg.call(this); 703 | return; 704 | } 705 | 706 | Common.requestGM_XHR({ 707 | method: 'HEAD', 708 | url: imgUrl, 709 | headers: { 'referrer': imgUrl.replace(/^(https?:\/\/[^\/#&]+).*$/, '$1') }, 710 | timeout: 5000 711 | }).then(result => { 712 | if (result.status == 200 && (imgUrl.replace(/^https?:\/\//, '') == result.finalUrl.replace(/^https?:\/\//, '') || result.finalUrl.search(/removed.png/i) < 0)) { 713 | GM_deleteValue(`temp_img_url_${avid}`); 714 | addImg(imgUrl, func, isZoom); 715 | Promise.resolve(); 716 | } else { 717 | return Promise.reject("error"); 718 | } 719 | }).catch(msg => { 720 | console.log("blogjav获取的图片地址已经被移除或加载失败" + msg); 721 | addJavArchiveImg.call(this); 722 | }); 723 | 724 | function addJavArchiveImg() { 725 | p2.then(url => { 726 | imgUrl = GM_getValue(`temp_img_url_${avid}`, ""); 727 | if (imgUrl === "") { 728 | console.log(`${avid} 没有找到预览图`); 729 | addImg(EMPTY_IMAGE_DATA, func, false); 730 | } else { 731 | GM_deleteValue(`temp_img_url_${avid}`); 732 | addImg(imgUrl, func, isZoom); 733 | } 734 | }); 735 | } 736 | 737 | function addImg(targetImgUrl, func, isZoom) { 738 | console.log("显示的图片地址:" + targetImgUrl); 739 | //创建img元素,加载目标图片地址 740 | //创建新img元素 741 | let className = "max"; 742 | if (isZoom != undefined && !isZoom) { 743 | className = "min"; 744 | } 745 | let $img = $(``); 746 | $img.attr("src", targetImgUrl); 747 | $img.attr("style", "float: left;cursor: pointer;"); 748 | $img.click(function () { 749 | if ($(this).hasClass('max')) { 750 | $(this).attr("class", 'min'); 751 | this.parentElement.parentElement.scrollIntoView(); 752 | } 753 | else { 754 | $(this).attr("class", 'max'); 755 | } 756 | }); 757 | //将新img元素插入指定位置 758 | func($img); 759 | } 760 | }); 761 | } 762 | /** 763 | * 根据番号从blogjav获取大预览图Url 764 | * @param {string} avid av唯一码 765 | * @returns {Promise} 大预览图Url地址 766 | */ 767 | static getBigPreviewImgUrlFromBlogjav(avid) { 768 | // oneJav 取消获取blogjav预览图 769 | if ((/(OneJAV)/g).test(document.title)) { 770 | return Promise.resolve(null); 771 | } 772 | //请求搜索blogjav.net的番号 773 | return Common.searchBing(Common.getBlogJavSearchVal(avid),"blogjav.net","&mkt=zh-TW") 774 | // .then(a => { 775 | // if (a) { 776 | // return Promise.resolve(a); 777 | // } else { 778 | // return Common.request(`https://blogjav.net/?s=${Common.getBlogJavSearchVal(avid)}`, "", 15000).then((result) => { 779 | // if (!result.loadstuts) { 780 | // console.log("从blogjav查找番号出错"); 781 | // return null; 782 | // } 783 | // var doc = Common.parsetext(result.responseText); 784 | // let a_array = $(doc).find(".entry-title a"); 785 | // let a = null; 786 | // console.log("avid:" + avid); 787 | // //如果找到全高清大图优先获取全高清的 788 | // for (let i = 0; i < a_array.length; i++) { 789 | // if (i == 5) break; 790 | // // 筛选匹配的番号数据 mium-999 => 正则/mium.*999/gi 791 | // let reg = RegExp(avid.replace(/-/g, ".*"), "gi"); 792 | // if (a_array[i].innerHTML.search(reg) > 0) { 793 | // if (!a) a = a_array[i]; 794 | // var fhd_idx = a_array[i].innerHTML.search(/FHD/i); 795 | // if (fhd_idx > 0) { 796 | // a = a_array[i]; 797 | // break; 798 | // } 799 | // } 800 | // }; 801 | // return Promise.resolve(a); 802 | // }); 803 | // } 804 | //}) 805 | .then(url => { 806 | let targetImgUrl = ""; 807 | if (url.length > 0) { 808 | //请求调用内页详情的访问地址 809 | return Common.request(url, "https://pixhost.to/", 15000).then((result) => { 810 | if (!result.loadstuts) return null; 811 | let doc = Common.parsetext(result.responseText); 812 | let img_array = $(doc).find('.entry-content a img[data-lazy-src*="imagetwist."],.entry-content a img[data-lazy-src*="pixhost."],.entry-content a img[data-src*="pixhost."]'); 813 | 814 | //如果找到内容大图 815 | if (img_array.length > 0) { 816 | //debugger; 817 | var new_img_src = $(img_array[img_array.length - 1]).data('src')//.data('lazySrc'); 818 | targetImgUrl = new_img_src.replace('thumbs', 'images').replace('//t', '//img').replace(/[\?*\"*]/, '').replace('/th/', '/i/'); 819 | if (/imagetwist/gi.test(targetImgUrl)) targetImgUrl = targetImgUrl.replace('.jpg', '.jpeg'); 820 | console.log("blogjav获取的图片地址:" + targetImgUrl); 821 | if (targetImgUrl.length === 0) { 822 | return null; 823 | } else { 824 | return targetImgUrl; 825 | } 826 | } else { 827 | return null; 828 | } 829 | }); 830 | } else { 831 | return Promise.resolve(null); 832 | } 833 | }); 834 | } 835 | /** 836 | * 根据番号从JavStore获取大预览图Url,并且缓存到GM中 837 | * @param {string} avid av唯一码 838 | */ 839 | static getBigPreviewImgUrlFromJavStore(avid) { 840 | //异步请求搜索JavStore的番号 841 | GM_setValue(`temp_img_url_${avid}`, ""); 842 | return Common.searchBing(avid,"javstore.net","&mkt=ja-JP").then(javUrl => { 843 | if (javUrl.length > 0) { 844 | //异步请求调用内页详情的访问地址 845 | return Common.request(javUrl, "http://pixhost.to/").then((result) => { 846 | if (!result.loadstuts) return; 847 | let doc = Common.parsetext(result.responseText); 848 | let img_array = $(doc).find('.news a font[size*="+1"],.news a img[alt*=".th"]'); 849 | if (img_array.length > 0) { 850 | let imgUrl = img_array[img_array.length - 1].parentElement.href; 851 | if(img_array[0].tagName === 'IMG'){ 852 | imgUrl = img_array[img_array.length - 1].src; 853 | imgUrl = imgUrl ? imgUrl : img_array[0].dataset.src; 854 | imgUrl = imgUrl.replace('pixhost.org', 'pixhost.to').replace('.th', '') 855 | .replace('thumbs', 'images').replace('//t', '//img').replace(/[\?*\"*]/, ''); 856 | } 857 | 858 | return Common.requestGM_XHR({ 859 | method: 'HEAD', 860 | url: imgUrl, 861 | headers: { 'referrer': imgUrl.replace(/^(https?:\/\/[^\/#&]+).*$/, '$1') }, 862 | timeout: 5000 863 | }).then(result => { 864 | if (result.status == 200 && (imgUrl.replace(/^https?:\/\//, '') == result.finalUrl.replace(/^https?:\/\//, '') || result.finalUrl.search(/removed.png/i) < 0)) { 865 | console.log("javstore获取的图片地址:" + imgUrl); 866 | GM_setValue(`temp_img_url_${avid}`, imgUrl); 867 | return Promise.resolve(imgUrl); 868 | } else { 869 | console.log("javstore获取的图片地址已经被移除或加载失败"); 870 | return Promise.resolve(); 871 | } 872 | }); 873 | } 874 | }); 875 | } else { 876 | return Promise.resolve(); 877 | } 878 | }); 879 | } 880 | /** 881 | * 882 | * @param {string} key 883 | * @param {string} site 884 | * @returns {Promise} Promise内实现异步返回参数url 885 | */ 886 | static searchBing(key,site,other) { 887 | return Common.request(`https://www.bing.com/search?q=site:${site}+${key}${other}`, "", 3000).then((result) => { 888 | if (!result.loadstuts) { 889 | console.log(`从bing查找${site}番号出错`); 890 | return Promise.resolve(""); 891 | } 892 | var doc = Common.parsetext(result.responseText); 893 | let a_array = $(doc).find("#b_results .b_algo h2 a"); //$(doc).find("#rso span a");google 894 | let url = "",b = true; 895 | //如果找到全高清大图优先获取全高清的 896 | for (let i = 0; i < a_array.length; i++) { 897 | if (i == 5) 898 | break; 899 | // 筛选匹配的番号数据 mium-999 => 正则/mium.*999/gi 900 | let reg = RegExp(key.replace(/\+/g, ".*").replace(/-/g, ".*"), "gi"); 901 | if (a_array[i].innerHTML.search(reg) >= 0) { 902 | if (url.length == 0) url = a_array[i].href; 903 | var search_idx = a_array[i].innerHTML.search(/Uncensored|FHD|4K|Mosaic/i); 904 | // 是否更新的链接,针对javstore 905 | if((/(javstore)/g).test(site) && parseInt(a_array[i].href.match(/\d+/)[0]) < parseInt(url.match(/\d+/)[0])) b = false ; 906 | if ( b && search_idx >= 0) { 907 | url = a_array[i].href; 908 | } 909 | } 910 | }; 911 | return new Promise(resolve => { resolve(url)}); 912 | }); 913 | } 914 | 915 | /** 916 | * 获取Dmm对应番号的数据 917 | * @param {string} dmmIdUrl DmmId网址 918 | * @returns {Promise} Promise内实现异步返回参数dmmData 919 | */ 920 | static getDmmData(dmmIdUrl) { 921 | if (!dmmIdUrl) return Promise.resolve(null); 922 | //异步请求dmm的番号页面 923 | return Common.requestGM_XHR({ 924 | url: dmmIdUrl, 925 | timeout: 15000, 926 | headers: { 927 | "Accept-Language": "ja-JP", //突破dmm地区访问限制,部分作品限制日本ip访问,例如STARS-706 928 | "cookie": "age_check_done=1;" //跳过18岁以上限制 929 | }, 930 | }).then((result) => { 931 | var doc = Common.parsetext(result.responseText); 932 | let dmmData = {}; 933 | dmmData.collect_num = $(doc).find(".tx-count span").text(); 934 | dmmData.score = $(doc).find(".d-review__average strong").text(); 935 | dmmData.user_num = $(doc).find(".d-review__evaluates strong").text(); 936 | dmmData.url = dmmIdUrl; 937 | dmmData.finalUrl = result.finalUrl; 938 | return dmmData; 939 | }).catch(msg => { 940 | return {}; 941 | }); 942 | } 943 | /** 944 | * 获取JavDb对应番号的数据 945 | * @param {string} avid av编号 946 | * @returns {Promise} Promise内实现异步返回参数javdbData 947 | */ 948 | static getJavDbData(avid) { 949 | return new Promise((resolve, reject) => { 950 | let promise = Common.request("https://" + GM_getValue('javdb_url') + "/search?f=all&q=" + avid); 951 | promise.then((result) => { 952 | if (!result.loadstuts) { 953 | console.log("javdb获取番号数据出错"); 954 | } 955 | let doc = Common.parsetext(result.responseText); 956 | let a = $(doc).find(`.box .video-title:contains('${avid.toUpperCase()}')`); 957 | if (a.length) { 958 | let javdbData = {}; 959 | javdbData.score = $(a[0].parentElement).find('.score>span').text(); 960 | if(a[0].parentElement.href.indexOf("http") >= 0) { 961 | javdbData.url = a[0].parentElement.href.replace(location.origin, 'https://' + [GM_getValue('javdb_url')]); 962 | } else { 963 | javdbData.url = 'https://' + [GM_getValue('javdb_url')] + a[0].parentElement.href; 964 | } 965 | resolve(javdbData); 966 | } else { 967 | reject("javdb没查找到此番号"); 968 | } 969 | }); 970 | }); 971 | } 972 | /** 973 | * 查询115网盘是否拥有番号 974 | * @param {string} javId 番号 975 | * @param {Function} callback 回调函数 976 | */ 977 | static search115Data(javId, callback) { 978 | //异步请求搜索115番号 //115查询 979 | let javId2 = javId.replace(/(-)/g, ""); //把番号-去除,例如ABC-123 =》 ABC123 980 | let javId3 = javId.replace(/(-)/g, "00"); //把番号-替换为00,例如CCVR-065 =》 CCVR00065 981 | let javId4 = javId.replace(/(-)/g, "-0"); //把番号-替换为-0,例如DSVR-584 =》 DSVR-0584 982 | let javId5 = javId.replace(/(-0)/g, "-"); //把番号-替换为-0,例如VRKM-01057 =》 VRKM-1057 983 | let javId6 = javId.replace(/(-)/g, "0"); //把番号-替换为0,例如VRKM-1192 =》 VRKM01192 984 | let javId_Key = javId.replace(/(-)/g, "+"); //把番号-替换为+,例如VRKM-1192 =》 VRKM+1192 985 | 986 | //保存查询关键词参数 987 | GM_setValue("115_search_var", `${javId}|${javId2}|${javId3}|${javId4}|${javId5}|${javId6}`); 988 | let promise1 = Common.request(`https://webapi.115.com/files/search?search_value=${javId_Key}&format=json&limit=100`,"",3000); 989 | promise1.then((result) => { 990 | if(result.loadstuts){ 991 | let resultJson = JSON.parse(result.responseText); 992 | if (resultJson.count > 0) { 993 | let pickcode = ''; 994 | let reg = new RegExp(GM_getValue("115_search_var"), "gi"); 995 | for (let i = 0; i < resultJson.data.length; i++) { 996 | let row = resultJson.data[i]; 997 | if (row.play_long && (row.n.search(reg) >= 0)) { //iv vdi ico play_long 998 | pickcode = row.pc; 999 | callback(true, `https://v.anxia.com/?pickcode=${pickcode}`, pickcode); 1000 | return; 1001 | } 1002 | } 1003 | } 1004 | } 1005 | callback(false, null, null); 1006 | }); 1007 | } 1008 | /** 1009 | * 查询夸克网盘是否拥有番号 1010 | * @param {string} javId 番号 1011 | * @returns {Promise} Promise内返回参数resultData 1012 | */ 1013 | static searchQuarkData(javId) { 1014 | //异步请求搜索夸克番号 1015 | let javId2 = javId.replace(/(-)/g, " "); //把番号-去除,例如ABC-123 =》 ABC 123 1016 | let javId3 = javId.replace(/(-)/g, "00"); //把番号-替换为00,例如CCVR-065 =》 CCVR00065 1017 | let javId4 = javId.replace(/(-)/g, "-0"); //把番号-替换为-0,例如DSVR-584 =》 DSVR-0584 1018 | //保存查询关键词参数 1019 | GM_setValue("quark_search_var", `${javId}|${javId2}|${javId3}|${javId4}`); 1020 | let p1 = Common.request(`https://drive.quark.cn/1/clouddrive/file/search?pr=ucpro&fr=pc&q=${javId2}&_page=1&_size=50&_fetch_total=1&_sort=file_type:desc,updated_at:desc&_is_hl=1`,"",3000); 1021 | return p1.then((result) => { 1022 | if(result.loadstuts){ 1023 | let resultJson = JSON.parse(result.responseText); 1024 | if (resultJson.status == 200 && resultJson.metadata._count > 0) { 1025 | let reg = new RegExp(GM_getValue("quark_search_var"), "gi"); 1026 | for (let i = 0; i < resultJson.data.list.length; i++) { 1027 | let row = resultJson.data.list[i]; 1028 | if (row.duration && (row.file_name.search(reg) >= 0)) { //时长、文件名判断 1029 | return Promise.resolve({ 1030 | isHave: true, 1031 | playUrl: `https://pan.quark.cn/list#/video/${row.fid}`, 1032 | pickcode: row.fid 1033 | }); 1034 | } 1035 | } 1036 | } 1037 | } 1038 | return Promise.resolve({ isHave: false }); 1039 | }); 1040 | } 1041 | /** 1042 | * 查找番号是否存在于缓存 1043 | * @param {string} javId 番号 1044 | * @returns {boolean} 1045 | */ 1046 | static browseJavidHasCache(javId) { 1047 | return GM_getValue("myBrowseJavidArray", '[]').indexOf(javId) > 0 ? true : false; 1048 | } 1049 | /** 1050 | * 保存番号到GM缓存 1051 | * @param {string} javId 番号 1052 | */ 1053 | static addBrowseJavidCache(javId) { 1054 | if (!this.browseJavidHasCache(javId)) { 1055 | let myBrowseJavidArray = JSON.parse(GM_getValue("myBrowseJavidArray", '[]')); 1056 | myBrowseJavidArray.push(javId); 1057 | GM_setValue("myBrowseJavidArray", JSON.stringify(myBrowseJavidArray)); 1058 | } 1059 | } 1060 | static getSchemaBuilder() { 1061 | // 构造jav库 1062 | let ds = lf.schema.create('jav_v3', 5); 1063 | // 创建MyMovie表 1064 | ds.createTable('MyMovie'). 1065 | //addColumn('id', lf.Type.INTEGER). 1066 | //索引编码 如javlikqu54 1067 | addColumn('index_cd', lf.Type.STRING). 1068 | //识别编码 如CHN-141 番号 1069 | addColumn('code', lf.Type.STRING). 1070 | //缩略图路径 1071 | addColumn('thumbnail_url', lf.Type.STRING). 1072 | //片名 1073 | addColumn('movie_name', lf.Type.STRING). 1074 | //演员 1075 | addColumn('actor', lf.Type.STRING). 1076 | //封面图路径 1077 | addColumn('cover_img_url', lf.Type.STRING). 1078 | //预览图路径 1079 | addColumn('prev_img_url', lf.Type.STRING). 1080 | //发布日期 1081 | addColumn('release_date', lf.Type.STRING). 1082 | //评分 1083 | addColumn('score', lf.Type.STRING). 1084 | //片长(分钟) 1085 | addColumn('duration', lf.Type.INTEGER). 1086 | //导演 1087 | addColumn('director', lf.Type.STRING). 1088 | //制作商 1089 | addColumn('maker', lf.Type.STRING). 1090 | //发行商 1091 | addColumn('publisher', lf.Type.STRING). 1092 | //加入时间 1093 | addColumn('add_time', lf.Type.STRING). 1094 | //115的pickcode 1095 | addColumn('pick_code', lf.Type.STRING). 1096 | //是否已阅 1097 | addColumn('is_browse', lf.Type.BOOLEAN). 1098 | //是否想要 0:否 1:是 2:未知 1099 | addColumn('is_want', lf.Type.INTEGER). 1100 | //是否看过 0:否 1:是 2:未知 1101 | addColumn('is_seen', lf.Type.INTEGER). 1102 | //是否拥有 0:否 1:是 2:未知 1103 | addColumn('is_have', lf.Type.INTEGER). 1104 | //是否同步 1105 | addColumn('is_sync', lf.Type.BOOLEAN). 1106 | //定义主键 1107 | addPrimaryKey(['index_cd']). 1108 | //定义索引 1109 | addIndex('idxaddtime', ['add_time'], false, lf.Order.DESC); 1110 | return ds; 1111 | } 1112 | }; 1113 | 1114 | class Jav { 1115 | /** 1116 | * 加载数据 todo 改进 1117 | * @param {String} pageName 访问网页名 1118 | */ 1119 | static loadData(pageName, queue) { 1120 | Common.toString();// 无此步骤Common作用域失效,暂时未知原因 1121 | let todo = async () => { // todo 190628 1122 | await this.loadPageNumData(pageName, 1); 1123 | for (let i = 2; i < GM_getValue(pageName + "_pageNum") + 1; i++) { 1124 | queue.push(() => { 1125 | let defer = $.Deferred(); 1126 | this.loadPageNumData(pageName, i).then(() => { 1127 | defer.resolve(); 1128 | }); 1129 | return defer.promise(); 1130 | }); 1131 | } 1132 | }; 1133 | return todo(); 1134 | } 1135 | 1136 | static loadPageNumData(pageName, PageNum) { 1137 | let url = location.origin + "/cn/" + pageName + ".php?&sort=added&page=" + PageNum;// console.log("打开链接url:" + url); 1138 | let commonClass = Common;// 无此步骤Common作用域失效,暂时未知原因 1139 | let promise1 = Common.request(url); 1140 | promise1.then((result) => { 1141 | return new Promise(resolve => { 1142 | if ($.type(result) !== "function" && result.status !== 200) { 1143 | return resolve(); 1144 | } 1145 | let doc = result.responseText; 1146 | //设置初始化总页数 1147 | if (PageNum == 1) { 1148 | let docArr = doc.split("的影片: "); 1149 | let totalNum = parseInt(docArr[1].substring(0, docArr[1].search(/<\/div/))); 1150 | GM_setValue(pageName + "_pageNum", parseInt((totalNum + 19) / 20)); 1151 | } 1152 | let tableText = doc.substring(doc.search(//), doc.search(/
/)); 1153 | //
//
1154 | let $movList = $(commonClass.parsetext(tableText)).find("tr"); 1155 | let indexArrStr = "0"; 1156 | let timeArrStr = "0"; 1157 | let myBrowseJson = ""; 1158 | for (let i = 1; i < $movList.length; i++) { 1159 | let movie = $movList.get(i); 1160 | let $aEle = $($(movie).children("td.title").find("a").get(0)); 1161 | // 索引编码 1162 | let index_cd = $aEle.attr("href").split("=")[1]; 1163 | // 番号 1164 | let code = $aEle.attr("title").match(/^[A-Za-z0-9-]+/g); 1165 | // 创建时间 1166 | let add_time = $($(movie).children("td").get(2)).text(); 1167 | indexArrStr = indexArrStr + index_cd + ','; 1168 | timeArrStr = timeArrStr + add_time + "|"; 1169 | myBrowseJson = myBrowseJson + `{"index_cd":"${index_cd}","code":"${code}","add_time":"${add_time}"},`; 1170 | } 1171 | 1172 | // 保存当前页的json格式数据 1173 | GM_setValue(pageName + "_myBrowseJson" + result.finalUrl.split("page=")[1], myBrowseJson); 1174 | console.log("处理完url:" + location.origin + "/ja/" + pageName + ".php?&sort=added&page=" + PageNum); 1175 | resolve(); 1176 | }); 1177 | }); 1178 | return promise1; 1179 | } 1180 | 1181 | /** 1182 | * 合并json数据 1183 | * @param {string} pageName 访问网页名 1184 | */ 1185 | static mergeJson(pageName) { 1186 | // 读取访问指定网页的页数量 1187 | var p = GM_getValue(pageName + "_pageNum"); 1188 | if (p > 0) { 1189 | GM_setValue(pageName + "_myBrowseJsonAll", ""); 1190 | // 循环合并Json,以同步方式保存. 1191 | let loopMerge = async () => { 1192 | for (let i = 1; i < p; i++) { 1193 | let tempJson = GM_getValue(pageName + "_myBrowseJson" + i); 1194 | if (tempJson && tempJson !== "") { 1195 | await new Promise(resolve => { 1196 | GM_setValue(pageName + "_myBrowseJsonAll", GM_getValue(pageName + "_myBrowseJsonAll") + tempJson); 1197 | resolve(); 1198 | }) 1199 | } 1200 | } 1201 | }; 1202 | return loopMerge().then(() => { 1203 | console.log("doNum:" + (GM_getValue("doNum") + 1) + " --" + pageName); 1204 | GM_setValue("doNum", GM_getValue("doNum") + 1); 1205 | }); 1206 | } 1207 | } 1208 | 1209 | /** 1210 | * JSON数组去重 1211 | * @param {Array} array Array 1212 | * @param {string} key 唯一的key名,根据此键名进行去重 1213 | * @param {function} func 1214 | */ 1215 | static uniqueArray(array, key, func) { 1216 | var result = [array[0]]; 1217 | for (var i = 1; i < array.length; i++) { 1218 | var item = array[i]; 1219 | var repeat = false; 1220 | for (var j = 0; j < result.length; j++) { 1221 | if (item[key] == result[j][key]) { 1222 | func(item, result[j]); 1223 | repeat = true; 1224 | break; 1225 | } 1226 | } 1227 | if (!repeat) { 1228 | result.push(item); 1229 | } 1230 | } 1231 | return result; 1232 | } 1233 | 1234 | 1235 | 1236 | /** 1237 | * javbus详情页磁链列表增加复制、115离线快捷键功能函数 1238 | */ 1239 | static javbusUs() { 1240 | $('#magnet-table tbody tr td[colspan="4"]').attr("colspan", "5"); 1241 | let tr_array = $('#magnet-table tr[height="35px"]'); 1242 | for (var i = 0; i < tr_array.length; i++) { 1243 | let trEle = tr_array[i]; 1244 | let magnetUrl = $(trEle).find("td a")[0].href; 1245 | $(trEle).append(""); 1246 | $(trEle).append(""); 1248 | $(trEle).attr("maglink", magnetUrl); 1249 | $(trEle).find(".nong-copy")[0].addEventListener('click', thirdparty.nong.magnet_table.handle_event, false); 1250 | $(trEle).find(".nong-offline-download")[0].addEventListener('click', thirdparty.nong.magnet_table.handle_event, false); 1251 | } 1252 | } 1253 | 1254 | /** 1255 | * 初始化同步保存数据方法 1256 | */ 1257 | static syncSaveData() { 1258 | GM_setValue("doNum", 0);//console.log("saveData"); 1259 | let pm1 = this.mergeJson("mv_wanted"); 1260 | let pm2 = this.mergeJson("mv_watched"); 1261 | let pm3 = this.mergeJson("mv_owned"); 1262 | 1263 | Promise.all([pm1, pm2, pm3]).then(() => { 1264 | console.log("mergeJson处理完毕"); 1265 | if (GM_getValue("doNum") === 3) { 1266 | let j1 = GM_getValue("mv_wanted_myBrowseJsonAll"); 1267 | let j2 = GM_getValue("mv_watched_myBrowseJsonAll"); 1268 | let j3 = GM_getValue("mv_owned_myBrowseJsonAll"); 1269 | //let myBrowseAll = j3.substring(0, j3.length - 1); 1270 | let myBrowseAll = j1 + j2 + j3.substring(0, j3.length - 1); 1271 | let myBrowseArray = JSON.parse("[" + myBrowseAll + "]"); 1272 | 1273 | //json数组去重 1274 | myBrowseArray = this.uniqueArray(myBrowseArray, "index_cd", (item, resultObj) => { 1275 | if (item["add_time"] < resultObj["add_time"]) { 1276 | resultObj["add_time"] = item["add_time"]; 1277 | } 1278 | }); 1279 | GM_setValue("myBrowseAllData", JSON.stringify(myBrowseArray)); 1280 | //应同步的总数 1281 | GM_setValue("myBrowseAllNum", myBrowseArray.length);//console.log(JSON.stringify(myBrowseArray)); 1282 | 1283 | let startTime = new Date();//console.log("startTime: " + startTime); 1284 | let b = GM_getValue(domain + "_stepTwo_V3", false); 1285 | if (!b) { 1286 | let jsonObj; 1287 | let row; 1288 | for (let i = 0; i < myBrowseArray.length; i++) { 1289 | jsonObj = myBrowseArray[i]; 1290 | row = myMovie.createRow({ 1291 | 'index_cd': jsonObj.index_cd, 1292 | 'code': jsonObj.code, 1293 | 'release_date': '', 1294 | 'duration': '', 1295 | 'director': '', 1296 | 'maker': '', 1297 | 'score': '', 1298 | 'actor': '', 1299 | 'cover_img_url': '', 1300 | 'thumbnail_url': '', 1301 | 'prev_img_url': '', 1302 | 'movie_name': '', 1303 | 'publisher': '', 1304 | 'add_time': jsonObj.add_time, 1305 | 'pick_code': '', 1306 | 'is_browse': true, 1307 | 'is_want': 2, 1308 | 'is_seen': 2, 1309 | 'is_have': 2, 1310 | 'is_sync': false 1311 | }); 1312 | javDb.insertOrReplace().into(myMovie).values([row]).exec(); 1313 | Common.addBrowseJavidCache(jsonObj.code); 1314 | } 1315 | // 如果保存影片数量大于等于需同步总数,则同步完成 1316 | if (GM_getValue(domain + "_saveMovieNum", 0) >= myBrowseArray.length) { 1317 | GM_setValue(domain + "_stepTwo_V3", true); 1318 | GM_setValue(domain + "_doDataSyncStepAll_V3", true); 1319 | } 1320 | console.log(domain + "_stepTwoTime:" + (new Date() - startTime)); 1321 | return Promise.resolve(); 1322 | } 1323 | } 1324 | }); 1325 | } 1326 | 1327 | static getMovie($doc) { 1328 | return { 1329 | index_cd: $('#video_title a', $doc).attr('href').split("v=")[1], 1330 | code: $('.header', $doc)[0].nextElementSibling.textContent, 1331 | release_date: $('#video_date .text', $doc).text(), 1332 | duration: $('#video_length .text', $doc).text(), 1333 | director: $('#video_director .text', $doc).text(), 1334 | maker: $('#video_maker .text', $doc).text(), 1335 | score: $('#video_review .text .score', $doc).text(), 1336 | actor: $('#video_cast .text', $doc).text(), 1337 | cover_img_url: $('#video_jacket_img', $doc).attr("src").replace("http://", "").replace("https://", ""), 1338 | thumbnail_url: $('#video_jacket_img', $doc).attr("src").replace("http://", "").replace("https://", "").replace("pl", "ps"), 1339 | prev_img_url: "", 1340 | movie_name: $('#video_title a', $doc).text(), 1341 | publisher: $('#video_label .text a', $doc).text(), 1342 | add_time: (new Date()).Format("yyyy-MM-dd hh:mm:ss"), 1343 | pick_code: '', 1344 | is_browse: true, 1345 | is_want: ($('#subscribed .smallbutton.hidden', $doc).length > 0) ? 1 : 0, 1346 | is_seen: ($('#watched .smallbutton.hidden', $doc).length > 0) ? 1 : 0, 1347 | is_have: ($('#owned .smallbutton.hidden', $doc).length > 0) ? 1 : 0, 1348 | is_sync: true 1349 | } 1350 | } 1351 | /** 1352 | * 同步movie信息到myMovie表中 1353 | * @param result 页面响应结果 1354 | */ 1355 | static syncMovie(result) { 1356 | let commonClass = Common;// 无此步骤Common作用域失效,暂时未知原因 1357 | let $doc = $(commonClass.parsetext(result.responseText)); 1358 | let movie = Jav.getMovie($doc); 1359 | let myBrowseJsonArray = JSON.parse(GM_getValue("myBrowseAllData", "[]")); 1360 | if (myBrowseJsonArray.length > 0) { 1361 | let jsonObj = myBrowseJsonArray.filter((p) => { 1362 | return p.index_cd == result.finalUrl.split("v=")[1]; 1363 | }); 1364 | if (jsonObj.length > 0) movie.add_time = jsonObj[0].add_time; 1365 | } 1366 | let row = myMovie.createRow(movie); 1367 | javDb.insertOrReplace().into(myMovie).values([row]).exec(); 1368 | } 1369 | 1370 | /** 1371 | * javlib记录已阅影片 1372 | */ 1373 | static javlibSaveData(AVID, pickcode, pm_mater) { 1374 | //console.log($(document)); 1375 | let movie = Jav.getMovie($(document)); 1376 | movie.pick_code = pickcode; 1377 | let newId = Common.getAvCode(AVID); 1378 | Common.addBrowseJavidCache(AVID); 1379 | if(AVID !== newId) Common.addBrowseJavidCache(newId); 1380 | pm_mater.then(() => { 1381 | //查找是否存在此番号数据 1382 | return javDb.select().from(myMovie).where(myMovie.index_cd.eq(movie.index_cd)).exec() 1383 | .then((results) => { 1384 | if (results.length > 0) movie.add_time = results[0].add_time; 1385 | let row = myMovie.createRow(movie); 1386 | javDb.insertOrReplace().into(myMovie).values([row]).exec(); 1387 | console.log(`${movie.code} 已经存入已阅影片`); 1388 | }); 1389 | }); 1390 | } 1391 | 1392 | /** 1393 | * 针对页面的番号信息增加功能及样式修改. javlib和javbus共同使用 1394 | * @returns {string} 番号 1395 | */ 1396 | static getAvidAndChgPage() { 1397 | let AVID = $('.header')[0].nextElementSibling.textContent; 1398 | // 实现点击番号复制到系统剪贴板 todo 181221v1 1399 | $('.header')[0].nextElementSibling.id = "avid"; 1400 | $('#avid').empty().attr("title", "点击复制番号").attr("avid", AVID); 1401 | let a_avid = document.createElement('a'); 1402 | $(a_avid).attr("href", "#").append(AVID); 1403 | $(a_avid).click(() => { 1404 | GM_setClipboard($('#avid').attr("avid")); 1405 | }); 1406 | $('#avid').append(a_avid); 1407 | $('#avid').after("(←点击复制)"); 1408 | $($('.header')[0]).attr("class", "header_hobby"); 1409 | return AVID; 1410 | } 1411 | 1412 | static waterfallButton() { 1413 | // 瀑布流ui按钮 1414 | let a3 = document.createElement('a'); 1415 | (waterfallScrollStatus > 0) ? $(a3).append('关闭瀑布流  ') : $(a3).append('开启瀑布流  '); 1416 | $(a3).css({ 1417 | "color": "blue", 1418 | "font": "bold 12px monospace" 1419 | }); 1420 | $(a3).attr("href", "#"); 1421 | $(a3).click(function () { 1422 | if ((/关闭/g).test($(this).html())) { 1423 | GM_setValue('scroll_status', 0); 1424 | } else { 1425 | GM_setValue('scroll_status', 1); 1426 | } 1427 | window.location.reload(); 1428 | }); 1429 | return a3; 1430 | } 1431 | 1432 | static javlibaryScript() { 1433 | let a3 = this.waterfallButton(); 1434 | if ((/(JAVLibrary)/g).test(document.title)) { 1435 | //数据库初始化 start01 1436 | var pm_mater = Common.getSchemaBuilder().connect({ 1437 | storeType: lf.schema.DataStoreType.INDEXED_DB 1438 | }).then((database) => { 1439 | javDb = database; 1440 | myMovie = javDb.getSchema().table('MyMovie'); 1441 | //javDb.delete().from(myMovie).exec();// 清空MyMovie表数据. 1442 | return javDb.select().from(myMovie).where(myMovie.is_browse.eq(true)).exec(); 1443 | }).then((results) => { 1444 | console.log("已经保存已阅影片数量:" + results.length); 1445 | GM_setValue(domain + "_saveMovieNum", results.length); 1446 | // results.forEach(function(row) { 1447 | // console.log(row['index_cd'],'|',row['code'],'|', row['add_time'],'|',row['movie_name']); 1448 | // }); 1449 | if (document.URL.indexOf("bestrated") > 0) { 1450 | $(".left select").after("  只看近两月份"); 1451 | $(".left select").after("  只看当前月份"); 1452 | $(".left select").after("  不看我阅览过(上个月)"); 1453 | $(".left select").after("  不看我阅览过(全部)"); 1454 | //todo 1455 | } else if (document.URL.indexOf("vl_newrelease") > 0 || document.URL.indexOf("vl_update") > 0 1456 | || document.URL.indexOf("vl_genre") > 0 || document.URL.indexOf("vl_mostwanted") > 0) { 1457 | $(".displaymode .right").prepend("只看9分以上  "); 1459 | $(".displaymode .right").prepend("只看8分以上  "); 1461 | $(".displaymode .right").prepend("只看7分以上  "); 1463 | } 1464 | 1465 | if ((/(bestrated|newrelease|newentries|vl_update|mostwanted|vl_star)/g).test(document.URL) || 1466 | (/(vl_genre|vl_searchbycombo|mv_owned|mv_watched|mv_wanted|mv_visited)/g).test(document.URL) || 1467 | (/(vl_label|vl_maker|vl_director|vl_searchbyid|userwanted|userowned)/g).test(document.URL)) { 1468 | 1469 | // 指定站点页面加入瀑布流控制按钮 1470 | $(".displaymode .right").prepend($(a3)); 1471 | 1472 | // 瀑布流脚本 1473 | thirdparty.waterfallScrollInit(); 1474 | 1475 | let a1 = document.createElement('a'); 1476 | 1477 | $(a1).append('按【VR】+评分排序  '); 1478 | $(a1).css({ 1479 | "color": "blue", 1480 | "font": "bold 12px monospace" 1481 | }); 1482 | $(a1).attr("href", "#"); 1483 | $(a1).click(() => { 1484 | let div_array = $("div.videos div.video"); 1485 | div_array.sort((a, b) => { 1486 | let a_score = parseFloat($(a).children("a").attr("score")); 1487 | let b_score = parseFloat($(b).children("a").attr("score")); 1488 | if (a_score > b_score) { 1489 | return -1; 1490 | } else if (a_score === b_score) { 1491 | return 0; 1492 | } else { 1493 | return 1; 1494 | } 1495 | }); 1496 | div_array.sort((a, b) => { 1497 | let a_val = $(a).children("a").attr("title").indexOf("【VR】") >= 0 ? 1 : 0; 1498 | let b_val = $(b).children("a").attr("title").indexOf("【VR】") >= 0 ? 1 : 0; 1499 | if (a_val > b_val) { 1500 | return -1; 1501 | } else if (a_val === b_val) { 1502 | return 0; 1503 | } else { 1504 | return 1; 1505 | } 1506 | }); 1507 | // 删除Dom列表数据关系,重新添加排序数据 1508 | div_array.detach().appendTo("#waterfall"); 1509 | }); 1510 | 1511 | let a2 = $(a1).clone(); 1512 | $(a2).html('按时间排序  '); 1513 | $(a2).click(() => { 1514 | let div_array = $("div.videos div.video"); 1515 | div_array.sort((a, b) => { 1516 | let a_time = new Date($(a).children("a").attr("release_date").replace(/-/g, "\/")).getTime(); 1517 | let b_time = new Date($(b).children("a").attr("release_date").replace(/-/g, "\/")).getTime(); 1518 | let a_score = parseFloat($(a).children("a").attr("score")); 1519 | let b_score = parseFloat($(b).children("a").attr("score")); 1520 | if (a_time > b_time) { 1521 | return -1; 1522 | } else if (a_time === b_time) { 1523 | return (a_score > b_score) ? -1 : 1; 1524 | } else { 1525 | return 1; 1526 | } 1527 | }); 1528 | 1529 | // 删除Dom列表数据关系,重新添加排序数据 1530 | div_array.detach().appendTo("#waterfall"); 1531 | }); 1532 | $(".displaymode .right").prepend($(a2)); 1533 | $(".displaymode .right").prepend($(a1)); 1534 | } 1535 | }); 1536 | //JavWebSql.DBinit(); 1537 | if ($('a[href="myaccount.php"]').length) { 1538 | // 已经登录 1539 | // 从未同步过,同步云数据到本地数据库 1540 | let isSync = GM_getValue(domain + "_doDataSyncStepAll_V3", false); 1541 | console.log(domain + " 是否同步过:" + isSync); 1542 | if (!isSync) { 1543 | pm_mater.then(() => { 1544 | return new Promise(resolve => { 1545 | var hasStepOne = GM_getValue(domain + "_stepOne_V3", false); 1546 | let stepOneStartTime = new Date(); 1547 | console.log(domain + " 同步是否完成第一步:" + hasStepOne); 1548 | if (!hasStepOne) { 1549 | // 立即下载数据 1550 | GM_setValue("mv_wanted_pageNum", 0); 1551 | GM_setValue("mv_watched_pageNum", 0); 1552 | GM_setValue("mv_owned_pageNum", 0); 1553 | 1554 | //start02 todo lovefieldDB 1555 | // 创建请求队列 //浏览器对同一域名进行请求的最大并发连接数:chrome为6 1556 | let queue = new Queue(7); 1557 | // 读取想要的影片 1558 | this.loadData("mv_wanted", queue); 1559 | // 读取看过的影片 1560 | this.loadData("mv_watched", queue); 1561 | // 读取拥有的影片 1562 | this.loadData("mv_owned", queue); 1563 | // 延迟1秒运行定时循环函数 1564 | setTimeout(() => { 1565 | // 定时循环函数,当队列执行完成时结束 1566 | var s4 = setInterval(() => { 1567 | //console.log("queue.taskList.length : " + queue.taskList.length); 1568 | if (queue.taskList.length == 0) { 1569 | let end_num = 0; 1570 | for (let i = 0, l = queue.threads.length; i < l; i++) { 1571 | if (queue.threads[i].promise.state() === 'resolved') { 1572 | end_num++; 1573 | } 1574 | } 1575 | if (end_num == queue.threads.length) { 1576 | GM_setValue(domain + "_stepOne_V3", true); // todo 需打开 1577 | console.log(domain + "_stepOneTime:" + (new Date() - stepOneStartTime)); 1578 | clearInterval(s4); 1579 | return resolve(); 1580 | } 1581 | } 1582 | }, 300); 1583 | }, 1000); 1584 | } else { 1585 | return resolve(); 1586 | } 1587 | }); 1588 | }).then(() => { 1589 | this.syncSaveData(); 1590 | }); 1591 | } 1592 | // 增加同步数据到本地的触发按钮 1593 | } 1594 | 1595 | // 新增VR发行、FC2发行菜单入口 1596 | $('.menul1 ul li:contains("新发行")').after('
  • FC2发行
  • '); 1597 | $('.menul1 ul li:contains("新发行")').after('
  • VR发行
  • '); 1598 | 1599 | 1600 | // 处理javlib番号详情页面的脚本 1601 | if ($('.header').length && $('meta[name="keywords"]').length) { 1602 | //获取番号影片详情页的番号 例如:http://www.javlibrary.com/cn/?v=javli7j724 1603 | let AVID = this.getAvidAndChgPage(); 1604 | 1605 | window.onload = () => { 1606 | $('iframe').remove(); 1607 | }; 1608 | let pickcode = ''; 1609 | 1610 | //增加预览图片大图链接 1611 | let imgs = $('.previewthumbs>img').clone(); 1612 | $('.previewthumbs>img').remove(); 1613 | imgs.each((i, img) => { 1614 | $('.previewthumbs').eq(0).append(`${img.outerHTML}`); 1615 | }); 1616 | 1617 | //加入坐标div,辅助插入元素 1618 | $('#video_genres').before(`
    `); 1619 | let $div_zuobiao = $('#zuobiao'); 1620 | 1621 | console.log("番号输出:" + AVID); 1622 | //加入预览JAV全片截图 1623 | Common.addAvImg(Common.getAvCode(AVID), ($img) => { 1624 | // http://www.javlibrary.com/cn/?v=javlilzo4e 1625 | let divEle = $("div[id='video_title']")[0]; // todo 190604 1626 | if (divEle) { 1627 | $(divEle).after( 1628 | '
    ' + 1629 | '
    ' + 1630 | '
    ' + 1631 | '
    ' 1632 | ); 1633 | $('#hobby_div_left').append($('#video_jacket_info')); 1634 | $('#hobby_div_left').append($('#video_favorite_edit')); 1635 | $('#hobby_div_right').append($img); 1636 | } 1637 | }, true); 1638 | 1639 | // 挊 1640 | thirdparty.nong.searchMagnetRun(); 1641 | 1642 | //加入dmm评分数据 1643 | if (imgs.length) { 1644 | let dmmId = Common.getDmmId(imgs[0].src); 1645 | if (!dmmId) { 1646 | dmmId = Common.avIdToDmmId(AVID); 1647 | } 1648 | 1649 | Common.getDmmData(`https://www.dmm.co.jp/digital/videoa/-/detail/=/cid=${dmmId}/`).then((dmmData) => { 1650 | $div_zuobiao.before(addLinkHtml(dmmData)); 1651 | 1652 | function addLinkHtml(dmmData) { 1653 | return ` 1654 |
    1655 |
    复制
    1656 | 1657 | 1658 |
    DMM评价:${dmmData.score.replace("点", "分")}, ${dmmData.user_num}人评, ${dmmData.collect_num}收藏
    1659 | 1660 | `; 1661 | } 1662 | }); 1663 | } 1664 | 1665 | //加入javdb评分数据 1666 | let p3 = Common.getJavDbData(Common.getAvCode(AVID)); 1667 | p3.then((javdbData) => { 1668 | let score = javdbData.score.trim().replace("由", "").replace("人評價", "人评"); 1669 | $div_zuobiao.after(` 1670 |
    1671 | 1672 | 1673 | 1674 |
    javdb评价:${score}
    1675 |
    1676 | `); 1677 | }).catch(errMsg => { console.log(errMsg); }); 1678 | 1679 | let $div_video_cast = $('#video_cast'); 1680 | //加入Jav跳转 1681 | $div_video_cast.after(` 1682 |
    1683 | 1684 | 1685 | 1688 |
    JAV跳转: 1686 | JavBus 1687 |
    1689 |
    1690 | `); 1691 | // javstoreLink 1692 | let $span = $(`JavStore`); 1693 | $('#linkJump').prepend(Common.javstoreLinkMousedown($span, AVID)); 1694 | 1695 | 1696 | //加入在线预览跳转 1697 | $div_video_cast.after(` 1698 |
    1699 | 1700 | 1701 | 1706 |
    在线预览: 1702 | missav 1703 | 7mmtv 1704 | supjav 1705 |
    1707 |
    1708 | `); 1709 | 1710 | $('#watched .smallbutton').html("放弃了"); 1711 | $('#watched .smalldarkbutton.hidden').html("我放弃这片了"); 1712 | 1713 | 1714 | 1715 | 1716 | //查找115是否有此番号 1717 | Common.search115Data(AVID, (BOOLEAN_TYPE, playUrl, pc) => { 1718 | if (BOOLEAN_TYPE) { 1719 | let $imgObj = $('#video_jacket_img'); 1720 | pickcode = pc; 1721 | $imgObj.after(` 1722 |
    1723 |

    115网盘已拥有此片

    1724 | 1725 |

    115在线播放 ►

    1726 |
    1727 | `); 1728 | $('#owned button[class="smallbutton"]').click(); 1729 | } 1730 | 1731 | // 只支持javlibray处理已阅影片 1732 | this.javlibSaveData(AVID, pickcode, pm_mater); 1733 | }); 1734 | 1735 | //查找夸克是否有此番号 1736 | Common.searchQuarkData(AVID).then(result => { 1737 | if (result.isHave) { 1738 | let $imgObj = $('#video_jacket_img'); 1739 | $imgObj.after(` 1740 |
    1741 |

    夸克网盘已有此片

    1742 | 1743 |

    夸克在线播放 ►

    1744 |
    1745 | `); 1746 | $('#owned button[class="smallbutton"]').click(); 1747 | } 1748 | 1749 | // 只支持javlibray处理已阅影片 1750 | this.javlibSaveData(AVID, pickcode, pm_mater); 1751 | }); 1752 | 1753 | //标题去除超链接 1754 | $('#video_title h3').after($('#video_title a')); 1755 | $('#video_title h3').text($('#video_title a').text()); 1756 | $('#video_title a').empty(); 1757 | 1758 | 1759 | }//番号影片详情页处理end 1760 | } 1761 | } 1762 | 1763 | static javBusScript() { 1764 | let a3 = this.waterfallButton(); 1765 | if ((/(JavBus|AVMOO|AVSOX)/g).test(document.title) || $("footer:contains('JavBus')").length) { 1766 | GM_addStyle(` 1767 | .info p {line-height: 18px!important;} 1768 | .screencap img{ width:100%; max-width: 1000px;} 1769 | `); 1770 | // 新增FC2菜单入口 1771 | $('#navbar ul.nav.navbar-nav li:eq(0)').after(`
  • FC2
  • `); 1772 | // 新增VR菜单入口 1773 | $('#navbar ul.nav.navbar-nav li:eq(0)').after('
  • VR
  • '); 1774 | // 指定站点页面加入瀑布流控制按钮 1775 | let li_elem = document.createElement('li'); 1776 | $(li_elem).append($(a3)); 1777 | // JavBus 1778 | $(".visible-md-block").closest(".dropdown").after($(li_elem)); 1779 | // AVMOO|AVSOX 1780 | $(".active").closest(".navbar-nav").append($(li_elem)); 1781 | $(".ad-box").remove(); 1782 | 1783 | // 瀑布流脚本 1784 | thirdparty.waterfallScrollInit(); 1785 | 1786 | //获取番号影片详情页的番号 例如:https://www.javbus.com/AVVR-323 1787 | if ($('.header').length && $('meta[name="keywords"]').length) { 1788 | let AVID = this.getAvidAndChgPage(); 1789 | Common.addBrowseJavidCache(AVID); 1790 | 1791 | //加入坐标div,辅助插入元素 1792 | $('p.header').before('

    '); 1793 | let $p_zuobiao = $('#zuobiao'); 1794 | 1795 | console.log("番号输出:" + AVID); 1796 | Common.addAvImg(AVID, ($img) => { 1797 | //https://www.javbus.com/CHN-141 1798 | let divEle = $("div[class='col-md-3 info']")[0]; 1799 | $(divEle).attr("id", "video_info"); 1800 | if (divEle) { 1801 | $(divEle.parentElement).append($img); 1802 | } 1803 | }, false);//javbus 默认不放大 1804 | 1805 | // 挊 1806 | thirdparty.nong.searchMagnetRun(); 1807 | 1808 | //加入dmm评分数据 1809 | let a_imgs = $('#sample-waterfall>a'); 1810 | if (a_imgs.length && !$('a.avatar-box[href*="uncensored"]').length && !location.hostname.includes('javbus.org') 1811 | && $('#sample-waterfall>a[href*="pics.dmm"]').length) { 1812 | let p1 = Common.getDmmData(`https://www.dmm.co.jp/digital/videoa/-/detail/=/cid=${Common.getDmmId(a_imgs[0].href)}/`); 1813 | p1.then((dmmData) => { 1814 | $p_zuobiao.before(` 1815 |

    1816 | 1817 | 1818 | DMM 评: 1819 | 1820 | ${dmmData.score.replace("点", "分")}, ${dmmData.user_num}人评, ${dmmData.collect_num}收藏 1821 |

    1822 | `); 1823 | }); 1824 | } 1825 | 1826 | //加入javdb评分数据 1827 | Common.getJavDbData(AVID).then((javdbData) => { 1828 | let score = javdbData.score.trim().replace("由", "").replace("人評價", "人评"); 1829 | $p_zuobiao.after(` 1830 |

    1831 | javdb评: 1832 | ${score} 1833 |

    1834 | `); 1835 | }); 1836 | 1837 | //查找115是否有此番号 1838 | Common.search115Data(AVID, (BOOLEAN_TYPE, playUrl, pc) => { 1839 | if (BOOLEAN_TYPE) { 1840 | let $imgObj = $('.bigImage'); 1841 | $imgObj.after(` 1842 |
    1843 |

    115网盘已拥有此片

    1844 | 1845 |

    115在线播放 ►

    1846 |
    1847 | `); 1848 | } 1849 | 1850 | }); 1851 | 1852 | //查找夸克是否有此番号 1853 | Common.searchQuarkData(AVID).then(result => { 1854 | if (result.isHave) { 1855 | let $imgObj = $('.bigImage'); 1856 | $imgObj.after(` 1857 |
    1858 |

    夸克网盘已有此片

    1859 | 1860 |

    夸克在线播放 ►

    1861 |
    1862 | `); 1863 | } 1864 | }); 1865 | 1866 | //加入在线预览跳转 1867 | $('.col-md-3.info').append(` 1868 |

    1869 | 在线预览: 1870 | missav  1871 | 7mmtv  1872 | supjav  1873 |

    1874 | `); 1875 | // 加入javlib的跳转链接 1876 | $('.col-md-3.info').append(` 1877 |

    1878 | JAV跳转: 1879 | JavLib  1880 |

    1881 | `); 1882 | // javstoreLink 1883 | let $a = $(`JavStore `); 1884 | $('#linkJump').append(Common.javstoreLinkMousedown($a, AVID)); 1885 | 1886 | // 修改javbus磁链列表头,增加两列 1887 | $('#magnet-table tbody tr').append('操作离线下载'); 1888 | // 先执行一次,针对已经提前加载出磁链列表结果时有效 1889 | this.javbusUs(); 1890 | // 针对为提前加载出磁链列表结果,通过dom元素是否改变事件来判断是否执行功能。 1891 | // $('#magnet-table').on("DOMNodeInserted", () => { 1892 | // // 触发后关闭监听事件 1893 | // $('#magnet-table').off(); 1894 | // this.javbusUs(); 1895 | // }); 1896 | 1897 | // 使用MutationObserver API替换DOMNodeInserted 1898 | const observer = new MutationObserver((mutationsList, observer) => { 1899 | // 触发后关闭监听事件 1900 | observer.disconnect(); // 停止监听 1901 | this.javbusUs(); 1902 | }); 1903 | // 指定要观察的目标节点 1904 | const targetNode = document.getElementById('magnet-table'); 1905 | // 配置观察选项 1906 | const config = { childList: true }; 1907 | // 开始观察目标节点 1908 | observer.observe(targetNode, config); 1909 | } 1910 | } 1911 | } 1912 | 1913 | static oneJavScript() { 1914 | if ((/(OneJAV)/g).test(document.title)) { //todo 190404 1915 | GM_addStyle(` 1916 | .column.is-5 {max-width: 82%;width: auto;} 1917 | .column {flex-basis: inherit;flex-grow: inherit;width: 800px;} 1918 | .container {max-width: 100%;width: 100%;} 1919 | .has-text-grey-dark {max-width: 1000px;} 1920 | .image {width: auto; max-width: 800px;} 1921 | `); 1922 | // 插入自己创建的div 1923 | $('div.container nav.pagination.is-centered').before("
    "); 1924 | // 将所有番号内容移到新建的div里 1925 | $('div#card').append($('div.container div.card.mb-3')); 1926 | // 瀑布流脚本 1927 | thirdparty.waterfallScrollInit(); 1928 | } 1929 | } 1930 | 1931 | static jav321Script() { 1932 | if ((/(^JAV321)/g).test(document.body.innerText)) { //todo 190531 1933 | Common.addAvImgCSS(); 1934 | GM_addStyle(` 1935 | .col-md-3 {width: 20%;padding-left: 18px; padding-right: 2px;} 1936 | .col-xs-12,.col-md-12 {padding-left: 2px; padding-right: 0px;} 1937 | .col-md-7 {width: 79%;padding-left: 2px;padding-right: 0px;} 1938 | .col-md-9 {width: max-content;} 1939 | .col-md-offset-1 {margin-left: auto;} 1940 | .hobby {display: inline-block;float: left;} 1941 | .hobby_mov {width: 75%;} 1942 | .hobby_p {color: white;font-size: 40px;margin: 0 0 0px;display: inline-block;text-align: right;width: 100%;} 1943 | `); 1944 | $(".col-md-7.col-md-offset-1.col-xs-12 .row .col-md-3 .img-responsive:eq(0)").offsetParent().attr("class", "hobby"); 1945 | $("#video_overlay_sample").offsetParent().attr("class", "hobby_mov"); 1946 | // 调整div位置 1947 | $('div.col-md-7.col-md-offset-1.col-xs-12').before($('div.col-xs-12.col-md-12')[0].parentElement); 1948 | 1949 | let meta = $('small')[0]; 1950 | let arr = meta.textContent.split(" "); 1951 | let javID = arr[0]; 1952 | 1953 | //查找115是否有此番号 1954 | Common.search115Data(javID, (BOOLEAN_TYPE, playUrl, pc) => { 1955 | if (BOOLEAN_TYPE) { 1956 | let $imgObj = $('div.col-xs-12.col-md-12 img.img-responsive'); 1957 | $imgObj.after(` 1958 |
    1959 |

    115在线播放 ►

    1960 |
    1961 | `); 1962 | } 1963 | 1964 | //插入预览图 1965 | Common.addAvImg(javID, ($img) => { 1966 | //https://www.jav321.com/video/300mium-391 1967 | var divEle = $("div.col-md-9")[0]; 1968 | //$(divEle).attr("id", "video_info"); 1969 | if (divEle) { 1970 | $(divEle).after($img); 1971 | } 1972 | }, !BOOLEAN_TYPE); 1973 | 1974 | Common.addBrowseJavidCache(javID); 1975 | }); 1976 | 1977 | $('.panel.panel-info:eq(0)').after($('.panel.panel-info:has(.table.table-striped)')); 1978 | 1979 | // 修改jav321磁链列表头,增加两列 1980 | $('table.table.table-striped tbody tr:eq(0)').append('操作离线下载'); 1981 | 1982 | //详情页磁链列表增加复制、115离线快捷键功能函数 1983 | let tr_array = $('table.table.table-striped tbody tr:gt(0)'); 1984 | for (var i = 0; i < tr_array.length; i++) { 1985 | let trEle = tr_array[i]; 1986 | let magnetUrl = $(trEle).find("td a")[0].href; 1987 | $(trEle).append(` 1988 |
    复制
    1989 |
    1990 | 115离线 1991 |
    1992 | `); 1993 | $(trEle).attr("maglink", magnetUrl); 1994 | $(trEle).find(".nong-copy")[0].addEventListener('click', thirdparty.nong.magnet_table.handle_event, false); 1995 | $(trEle).find(".nong-offline-download")[0].addEventListener('click', thirdparty.nong.magnet_table.handle_event, false); 1996 | //.addEventListener('click', this.handle_event, false); 1997 | } 1998 | } 1999 | } 2000 | 2001 | static javDBScript() { 2002 | if ((/(JavDB)/g).test(document.title)) { 2003 | if ($('.app-desktop-banner').length) $('.app-desktop-banner').remove(); 2004 | if ($('.modal.is-active.over18-modal').length) $('.modal.is-active.over18-modal').remove(); 2005 | 2006 | // 修改FC2菜单入口 2007 | $('.navbar-dropdown.is-boxed .navbar-item:contains("FC2")') 2008 | .attr("href","/advanced_search?type=3&score_min=4.2&score_max=&released_start=&released_end=&actors%5B%5D=&tags%5B%5D=&p=0&d=0&d=1&c=0&s=0&i=0&v=0&commit=檢索&lm=h").attr("style","color: red;"); 2009 | // 新增VR菜单入口 2010 | $('.navbar-dropdown.is-boxed .navbar-item:eq(0)') 2011 | .after('VR'); 2012 | 2013 | 2014 | // 瀑布流脚本 2015 | thirdparty.waterfallScrollInit(); 2016 | 2017 | // 非小封面列表 2018 | if (!$("#waterfall").hasClass("v cols-4 vcols-8")) { 2019 | // 如果没有,加入tabs元素 2020 | if (!$(".tabs.is-boxed").length) { 2021 | $("#waterfall").before(`
    `); 2022 | } 2023 | // 加入一个锚点 2024 | $(".tabs.is-boxed").before(``); 2025 | // 加入排序与过滤功能 2026 | $('.tabs.is-boxed').append(` 2027 |
    2028 |
    2029 | 2030 | 评分人数排序 2031 | 2032 |
    2033 |
    2034 | 2035 | JAV评分排序 2036 | 2037 |
    2038 |
    2039 | 2040 | 屏蔽评分人数 <  2041 | 2042 | 2044 |
    2045 |
    2046 | `); 2047 | 2048 | $('#javtopscore').click(() => { 2049 | let div_array = $(JAVDB_ITEM_SELECTOR); 2050 | div_array.sort((a, b) => { 2051 | let a_score = parseFloat($(a).attr("score")); 2052 | let b_score = parseFloat($(b).attr("score")); 2053 | if (a_score > b_score) { 2054 | return -1; 2055 | } else if (a_score === b_score) { 2056 | return 0; 2057 | } else { 2058 | return 1; 2059 | } 2060 | }); 2061 | // 删除Dom列表数据关系,重新添加排序数据 2062 | div_array.detach().appendTo("#waterfall"); 2063 | $('#javtopscore').css("background-color", "#3273dc").css("color", "white"); 2064 | $('#javtopusernum').css("background-color", "white").css("color", "#3273dc"); 2065 | }); 2066 | 2067 | $('#javtopusernum').click(() => { 2068 | let div_array = $(JAVDB_ITEM_SELECTOR); 2069 | div_array.sort((a, b) => { 2070 | let a_score = parseFloat($(a).attr("usernum")); 2071 | let b_score = parseFloat($(b).attr("usernum")); 2072 | if (a_score > b_score) { 2073 | return -1; 2074 | } else if (a_score === b_score) { 2075 | return 0; 2076 | } else { 2077 | return 1; 2078 | } 2079 | }); 2080 | // 删除Dom列表数据关系,重新添加排序数据 2081 | div_array.detach().appendTo("#waterfall"); 2082 | $('#javtopusernum').css("background-color", "#3273dc").css("color", "white"); 2083 | $('#javtopscore').css("background-color", "white").css("color", "#3273dc"); 2084 | }); 2085 | 2086 | $('#offusernum').change(() => { 2087 | let offusernum = $('#offusernum').val(); 2088 | if (offusernum) { 2089 | $(JAVDB_ITEM_SELECTOR).toArray().forEach(e => { 2090 | parseInt($(e).attr("usernum")) < parseInt(offusernum) ? $(e).hide() : $(e).show(); 2091 | }); 2092 | } 2093 | }); 2094 | 2095 | 2096 | if ($("div.video-detail")) { 2097 | var AVID = $("a.button.is-white.copy-to-clipboard")[0].dataset.clipboardText; 2098 | Common.addBrowseJavidCache(AVID); 2099 | //去除广告 2100 | $("div.top-meta").remove(); 2101 | 2102 | //查找115是否有此番号 2103 | Common.search115Data(AVID, (BOOLEAN_TYPE, playUrl, pc) => { 2104 | if (BOOLEAN_TYPE) { 2105 | let $imgObj = $("img.video-cover"); 2106 | $("div.column.column-video-cover a").before($imgObj); 2107 | $("div.column.column-video-cover a").remove(); 2108 | $imgObj.after(` 2109 |
    2110 |

    115网盘已拥有此片

    2111 | 2112 |

    115在线播放 ►

    2113 |
    2114 | `); 2115 | } 2116 | console.log("番号输出:" + AVID); 2117 | }); 2118 | 2119 | let mag_array = $("div.magnet-links .item"); 2120 | for (var i = 0; i < mag_array.length; i++) { 2121 | let magEle = mag_array[i]; 2122 | let magnetUrl = $(magEle).find("a")[0].href; 2123 | // console.log("磁链输出:" + magnetUrl); 2124 | $(magEle).find(".buttons.column").append(``); 2125 | $(magEle).find(".nong-offline-download")[0].addEventListener( 2126 | "click", 2127 | thirdparty.nong.magnet_table.handle_event, 2128 | false 2129 | ); 2130 | } 2131 | } 2132 | 2133 | } 2134 | } 2135 | } 2136 | 2137 | static javStoreScript() { 2138 | if ($('.all_page_javstore1 .danhgia_thich').length) { 2139 | GM_addStyle(` 2140 | .category_news_main_right {width: 100%;} 2141 | .boxoright {width: calc((100%) - 460px)} 2142 | .boxoleft { background: #ffffff!important; width: 460px; padding: 0 5px;} 2143 | .boxoleft > div { margin: 0 0 0 0; } 2144 | .news_2n > h2 { margin: 10px 0 10px 0;} 2145 | .onlinePlayLink {font-size: large; margin: 0 0 0 38px;} 2146 | `); 2147 | // 移除左侧右侧 2148 | if ($('.category_news_left_side,.slide_exlogo,.box_left_news.news_2n')) { 2149 | $('.category_news_left_side,.slide_exlogo,.box_left_news.news_2n').remove(); 2150 | } 2151 | // 显示大预览图 2152 | let img_array = $('.news a font[size*="+1"],.news a img[alt*=".th"]'); 2153 | //if (img_array.length == 0) $(doc).find('.news a img[alt*=".th"]'); 2154 | img_array.toArray().forEach(e => { 2155 | let imgUrl = e.parentElement.href; 2156 | if(e.tagName === 'IMG'){ 2157 | imgUrl = img_array[img_array.length - 1].src; 2158 | imgUrl = imgUrl ? imgUrl : img_array[0].dataset.src; 2159 | imgUrl = imgUrl.replace('pixhost.org', 'pixhost.to').replace('.th', '') 2160 | .replace('thumbs', 'images').replace('//t', '//img') 2161 | .replace(/[\?*\"*]/, ''); 2162 | } 2163 | e.parentElement.href = "#"; 2164 | e.parentElement.target = ""; 2165 | e.parentElement.title = "返回顶部"; 2166 | $(e.parentElement).attr("style", "display: inherit;text-align: center;"); 2167 | let $img = $(``); 2168 | $(e.parentElement).append($img); 2169 | e.parentElement.removeChild(e); 2170 | }); 2171 | 2172 | $(".boxoleft").append(` 2173 |
    2174 |

    在线预览

    2175 | 2177 |

    下载

    2178 |
    2179 | `); 2180 | 2181 | // 挊 2182 | thirdparty.nong.searchMagnetRun(); 2183 | 2184 | $(".onlinePlayLink").append(` 2185 | njav   2186 | missav   2187 | 7mmtv   2188 | supjav   2189 | `); 2190 | 2191 | Common.addBrowseJavidCache($('.name').text().match(/[a-z|A-Z|0-9| _-]+/)[0].trim()); 2192 | } 2193 | } 2194 | 2195 | static quarkScript() { 2196 | if ($('.VideoDetail--content-body--1KZ6K00').length) { 2197 | GM_addStyle(` 2198 | .DetailLayout--content--14Z28Ay {width: 100%;margin-top: auto;} 2199 | .VideoDetail--content--1LYsa87 {width: 100%;} 2200 | .VideoDetail--content-body--1KZ6K00 {height: 920px;} 2201 | .AnthologyList--anthology-list--Vlx6xtN {height: auto;} 2202 | .VideoDetail--content-header--2Cto_s7 {height: auto;padding-top: 0px;} 2203 | `); 2204 | $('.DetailLayout--header-wrap--3cP6QaP').remove(); 2205 | $('.VideoDetail--content--1LYsa87').append($('.VideoDetail--content-header--2Cto_s7')); 2206 | $('.VideoDetail--content--1LYsa87').append($('.VideoDetail--content-footer--3sQbRiy')); 2207 | 2208 | let loop = setInterval(() => { 2209 | if ($('.AnthologyList--anthology-title--1uEdKDT').length) { 2210 | $('.AnthologyList--anthology-title--1uEdKDT').remove(); 2211 | clearInterval(loop); 2212 | } 2213 | }, 500); 2214 | } 2215 | } 2216 | } 2217 | 2218 | // 第三方脚本调用 2219 | var thirdparty = { 2220 | // 登录115执行脚本,自动离线下载准备步骤 2221 | login115Run: () => { 2222 | if (domain.indexOf('115.com') >= 0) { 2223 | jav_userID = GM_getValue('jav_user_id', 0); //115用户ID缓存 2224 | //获取115ID 2225 | if (jav_userID === 0) { 2226 | if (domain.indexOf('115.com') >= 0) { 2227 | if (typeof (window.wrappedJSObject.user_id) != 'undefined') { 2228 | jav_userID = window.wrappedJSObject.user_id; 2229 | GM_setValue('jav_user_id', jav_userID); 2230 | alert('115登陆成功!'); 2231 | return; 2232 | } 2233 | } else { 2234 | //alert('请先登录115账户!'); 2235 | Common.notifiy("115还没有登录", 2236 | '请先登录115账户后,再离线下载!', 2237 | icon, 2238 | 'http://115.com/?mode=login' 2239 | ); 2240 | GM_setValue('jav_user_id', 0); 2241 | } 2242 | } 2243 | 2244 | if (domain.indexOf('115.com') >= 0) { 2245 | console.log('jav老司机:115.com,尝试获取userid.'); 2246 | jav_userID = GM_getValue('jav_user_id', 0); 2247 | if (jav_userID !== 0) { 2248 | console.log("jav老司机: 115账号:" + jav_userID + ",无需初始化."); 2249 | return false; 2250 | } 2251 | jav_userID = $.cookie("OOFL"); 2252 | console.log("jav老司机: 115账号:" + jav_userID); 2253 | if (!jav_userID) { 2254 | console.log("jav老司机: 尚未登录115账号"); 2255 | return false; 2256 | } else { 2257 | console.log("jav老司机: 初始化成功"); 2258 | Common.notifiy('老司机自动开车', '登陆初始化成功,赶紧上车把!', icon, ""); 2259 | GM_setValue('jav_user_id', jav_userID); 2260 | } 2261 | return false; 2262 | } 2263 | } 2264 | }, 2265 | // 瀑布流脚本 2266 | waterfallScrollInit: () => { 2267 | var w = new thirdparty.waterfall({}); 2268 | // javbus.com、avmo.pw、avso.pw 2269 | var $pages = $('div#waterfall div.item'); 2270 | if ($pages.length) { 2271 | $pages[0].parentElement.parentElement.id = "waterfall_h"; 2272 | // javbus.com 2273 | if ($("footer:contains('JavBus')").length) { 2274 | w = new thirdparty.waterfall({ 2275 | next: 'a#next', 2276 | item: 'div#waterfall div.item', 2277 | cont: '.masonry', 2278 | pagi: '.pagination-lg', 2279 | }); 2280 | } 2281 | //avmo.pw、avso.pw 2282 | if ((/(AVMOO|AVSOX)/g).test(document.title)) { 2283 | w = new thirdparty.waterfall({ 2284 | next: 'a[name="nextpage"]', //nextpage 2285 | item: 'div#waterfall div.item', 2286 | cont: '#waterfall', 2287 | pagi: '.pagination', 2288 | }); 2289 | } 2290 | } 2291 | // javlibrary 2292 | var $pages2 = $('div.videos div.video'); 2293 | if ($pages2.length) { 2294 | GM_addStyle(` 2295 | .videothumblist .videos .video {height: 270px;padding: 0px;margin: 4px;} 2296 | .videothumblist .videos .video .title {height: 2.8em;} 2297 | .id {height: 1.3em;overflow: hidden;} 2298 | `); 2299 | $pages2[0].parentElement.id = "waterfall"; 2300 | w = new thirdparty.waterfall({ 2301 | next: 'a[class="page next"]', 2302 | item: 'div.videos div.video', 2303 | cont: '#waterfall', 2304 | pagi: '.page_selector', 2305 | }); 2306 | } 2307 | // onejav 2308 | var $pages3 = $('div.container div.card.mb-3'); 2309 | if ($pages3.length) { 2310 | $pages3[0].parentElement.id = "waterfall"; 2311 | w = new thirdparty.waterfall({ 2312 | next: 'a.pagination-next.button.is-primary', 2313 | item: 'div.container div.card.mb-3', 2314 | cont: '#waterfall', 2315 | pagi: '.pagination.is-centered', 2316 | }); 2317 | } 2318 | 2319 | // javdb 2320 | var $pages4 = $(JAVDB_ITEM_SELECTOR); 2321 | if ($pages4.length) { 2322 | GM_addStyle(` 2323 | .container {max-width: inherit !important;} 2324 | .tags{display: block !important;} 2325 | .tag.hobby{display: block;float: right;color: #fff;line-height: 2em;} 2326 | `); 2327 | $pages4[0].parentElement.id = "waterfall"; 2328 | w = new thirdparty.waterfall({ 2329 | next: '.pagination .pagination-next', 2330 | item: JAVDB_ITEM_SELECTOR, 2331 | cont: '#waterfall', 2332 | pagi: '.pagination', 2333 | }); 2334 | } 2335 | 2336 | w.setSecondCallback((cont, elems) => { 2337 | if (location.pathname.includes('/star/') && elems) { 2338 | cont.append(elems.slice(1)); 2339 | } else { 2340 | cont.append(elems); 2341 | } 2342 | }); 2343 | 2344 | // javlib脚本 2345 | w.setJavlibCallback((elems) => { 2346 | // hobby mod script 2347 | let filerMonth = (indexCd_id, dateString) => { 2348 | //过滤最新X月份的影片 2349 | if ($(indexCd_id).context.URL.indexOf("bestrated.php?delete") > 0) { 2350 | if ($(indexCd_id).context.URL.indexOf("bestrated.php?deleteOneMonthAway") > 0 && !Common.isLastXMonth(dateString, 1)) { 2351 | $(indexCd_id).remove(); 2352 | } else if ($(indexCd_id).context.URL.indexOf("bestrated.php?deleteTwoMonthAway") > 0 && !Common.isLastXMonth(dateString, 2)) { 2353 | $(indexCd_id).remove(); 2354 | } 2355 | } 2356 | } 2357 | 2358 | let filerScore = (indexCd_id, score) => { 2359 | //过滤X评分以下的影片 //if(vid == 'javlikq7qu')debugger; 2360 | if ($(indexCd_id).context.URL.indexOf("?delete") > 0) { 2361 | if ($(indexCd_id).context.URL.indexOf("delete7down") > 0 && score <= 7.01) { 2362 | $(indexCd_id).remove(); 2363 | } else if ($(indexCd_id).context.URL.indexOf("delete8down") > 0 && score <= 8.01) { 2364 | $(indexCd_id).remove(); 2365 | } else if ($(indexCd_id).context.URL.indexOf("delete9down") > 0 && score <= 9.01) { 2366 | $(indexCd_id).remove(); 2367 | } 2368 | } 2369 | } 2370 | 2371 | let setbgcolor = (indexCd_id, dateString) => { 2372 | // 如果是最近两个月份的影片标上背景色 2373 | if ($(indexCd_id).context.URL.indexOf("bestrated") > 0 && Common.isLastXMonth(dateString, 2)) { 2374 | //$(indexCd_id).css("background-color", "blanchedalmond"); 2375 | $('div[class="hobby_add"]', $(indexCd_id)).css("background-color", "#ffffc9"); 2376 | } 2377 | } 2378 | 2379 | let extCode = (indexCd_id, actor, dateString, pingfengString) => { 2380 | $(indexCd_id).find(".id").append(`  ${actor}`); 2381 | let t = $(indexCd_id).find(".title").get(0); //todo v3.5.0 2382 | $(t).text().indexOf("【VR】") >= 0 ? $(t).css("background-color", "black").css("color", "white") : null; 2383 | $(indexCd_id).children("a").append(`
    2384 | ${dateString}      ${pingfengString}
    `); 2385 | $(indexCd_id).children("a").attr("release_date", dateString); 2386 | let s = 0; 2387 | let r = Math.random() / 100; 2388 | if (pingfengString.replace(/[\\(\\)]/g, "") != '') { 2389 | s = r + parseFloat(pingfengString.replace(/[\\(\\)]/g, "")); 2390 | } else { 2391 | s = 0 + r; 2392 | } 2393 | if (s >= 10) { 2394 | s = 0.01; 2395 | } 2396 | $(indexCd_id).children("a").attr("score", s); 2397 | setbgcolor(indexCd_id, dateString); 2398 | filerMonth(indexCd_id, dateString); 2399 | filerScore(indexCd_id, s); 2400 | } 2401 | 2402 | if (document.title.search(/JAVLibrary/) > 0 && elems) {//javlib列表 2403 | for (let i = 0; i < elems.length; i++) { 2404 | let _vid = $(elems[i]).attr("id").replace('vid_', ''); //vid_javlikd42y 2405 | // 给列表中的影片添加鼠标点击事件 2406 | $("a", $("#vid_" + _vid)).first().mousedown((event) => { 2407 | // 判断鼠标左键或中间才执行 2408 | if (event.button < 2) { 2409 | // 设置点击后填充新的背景色peachpuff 2410 | $("#vid_" + _vid).css("background-color", "#ffe7d3"); 2411 | } 2412 | }); 2413 | let indexCd_id, actor, dateString, pingfengString; 2414 | let code = $(elems[i]).find('.id').text(); 2415 | // 查找影片是否存在我浏览过的MyMovie表中 2416 | let prom = javDb.select().from(myMovie). 2417 | where(lf.op.and(myMovie.is_browse.eq(true), myMovie.index_cd.eq(_vid))).exec(); 2418 | prom.then(results => { 2419 | //let promise1 = Promise.resolve(); 2420 | //return new Promise(resolve => { 2421 | if (results.length != 0) { //存在MyMovie表中 2422 | indexCd_id = "#vid_" + results[0].index_cd; 2423 | if ($(indexCd_id).context.URL.indexOf("bestrated.php?filterMyBrowse") > 0) { 2424 | $(indexCd_id).remove(); 2425 | } else { 2426 | $(indexCd_id).css("background-color", "#ffe7d3"); //hotpink,khaki,indianred,peachpuff 2427 | if (results.length != 0 && results[0].is_sync) { //已经同步过 2428 | extCode(indexCd_id, results[0].actor, results[0].release_date, results[0].score); 2429 | } else { //未同步过 2430 | getMovieInfo(true); 2431 | } 2432 | Common.addBrowseJavidCache(code); 2433 | } 2434 | } 2435 | else if (Common.browseJavidHasCache(code)) { //存在GM缓存中 2436 | getMovieInfo(true); 2437 | } 2438 | else { //都不存在 2439 | getMovieInfo(false); 2440 | } 2441 | 2442 | function getMovieInfo(isSave) { 2443 | //console.log(`push:${_vid}`); 2444 | //console.log(w.queue); 2445 | w.queue.push(() => { 2446 | let defer = $.Deferred(); 2447 | let promise1 = Common.request(`https://${JAVLIB_DOMAIN}/ja/?v=${_vid}`); 2448 | promise1.then((result) => { 2449 | if(result.loadstuts && result.status < 300){ 2450 | indexCd_id = "#vid_" + result.finalUrl.split("=")[1]; //例如:http://www.j12lib.com/cn/?v=javlikd42a 2451 | let doc = result.responseText; 2452 | let movie_info = doc.substring(doc.search(//), 2453 | doc.search(/
    /)); 2454 | // 阻止构造Document对象时加载src内容 2455 | movie_info = movie_info.replace("src", "hobbysrc"); 2456 | let $doc = $(Common.parsetext(movie_info)); 2457 | actor = $('#video_cast .text .star a', $doc).text(); 2458 | dateString = $('#video_date .text', $doc).text(); 2459 | pingfengString = $('#video_review .text .score', $doc).text(); 2460 | extCode(indexCd_id, actor, dateString, pingfengString); 2461 | // todo 1118 2462 | if (isSave) Jav.syncMovie(result); 2463 | } else { 2464 | if(result.status > 300) console.log(`${result.finalUrl} 加载出错:${result.responseXML.title}`); 2465 | } 2466 | return Promise.resolve(); 2467 | }).then(() => { // 等待0.8秒执行下一个任务,受Cloudflare限制访问 2468 | setTimeout(() => { 2469 | defer.resolve(); 2470 | },800); 2471 | }); 2472 | return defer.promise(); 2473 | }); 2474 | } 2475 | }); 2476 | } 2477 | } 2478 | }); 2479 | 2480 | w.setFourthCallback((elems) => { // todo 20190404 2481 | if (document.title.search(/OneJAV/) > 0 && elems) { 2482 | // 增加对应所有番号的Javlib的跳转链接, 2483 | for (let index = 0; index < elems.length; index++) { 2484 | let aEle = $(elems[index]).find("h5.title.is-4.is-spaced a")[0]; 2485 | let avid = $(aEle).text().replace(/[ ]/g, "").replace(/[\r\n]/g, "") //去掉空格//去掉回车换行 2486 | let avcd = avid; 2487 | if (!(/(-)/g).test(avid)) { 2488 | avcd = Common.getAvCode(avid); 2489 | } 2490 | //debugger; 2491 | //修改样式 2492 | $(aEle.parentElement.parentElement).attr("style", "flex-direction: column;"); 2493 | if (!(/^FC2(-)/g).test(avid)) { 2494 | // Javlib的跳转链接 2495 | $(aEle.parentElement).append(`  Javlib"); 2497 | } 2498 | // 番号预览大图 2499 | Common.addAvImg(avcd, ($img) => { 2500 | let divEle = $(elems[index]).find("div.column.is-5")[0]; 2501 | if (divEle) { 2502 | $(divEle).append($img); 2503 | } 2504 | }, false); 2505 | } 2506 | } 2507 | 2508 | if (((/(JavBus|AVMOO|AVSOX)/g).test(document.title) || $("footer:contains('JavBus')").length) && elems) { 2509 | if (location.pathname.search('/searchstar|/actresses|/&mdl=favor&sort=4') < 0) { //排除actresses页面 2510 | // 处理列表文字内容排版 2511 | for (let i = 0; i < elems.length; i++) { 2512 | //$(elems[i]).css("height","385px"); 2513 | if ($(elems[i]).find("div.avatar-box").length > 0) continue; 2514 | let spanEle = $(elems[i]).find("div.photo-info span")[0]; 2515 | let t1 = $(spanEle).html().substr($(spanEle).html().indexOf("
    ") + 4); 2516 | let t2 = $(spanEle).html().substr(0, $(spanEle).html().indexOf("
    ")); 2517 | $(spanEle).html(t1 + "
    " + t2); 2518 | // 已阅番号标色 2519 | if (Common.browseJavidHasCache($(elems[i]).find(".photo-info>span>date:eq(0)").text())) { 2520 | $(elems[i]).find(".movie-box").css("background-color", "#ffe7d3"); 2521 | } 2522 | // 给列表中的影片添加鼠标点击事件 2523 | $("a", $(elems[i])).first().mousedown((event) => { 2524 | // 判断鼠标左键或中间才执行 2525 | if (event.button < 2) { 2526 | // 设置点击后填充新的背景色peachpuff 2527 | $(elems[i]).find(".movie-box").css("background-color", "#ffe7d3"); 2528 | } 2529 | }); 2530 | } 2531 | } 2532 | } 2533 | 2534 | // javdb列表内容排版处理 2535 | if ((/(JavDB)/g).test(document.title) && elems) { 2536 | elems.toArray().forEach(e => { 2537 | //移除新种标签 2538 | $(e).find(".tags.has-addons span:not(.tag.is-success,.tag.is-warning)").remove(); 2539 | if ($(e).find(".tag.is-warning").length) { 2540 | $(e).find(".tag.is-warning").text("含中字"); 2541 | } 2542 | let $div = $(e).find(".tags.has-addons").eq(0); 2543 | let avid = $(e).find(".video-title strong").text(); 2544 | 2545 | if (!$div.children().length) { 2546 | $div.append(`.`); 2547 | } 2548 | if (!$("#waterfall").hasClass("v cols-4 vcols-8")) { 2549 | $div.append(` 2550 | 2551 | 2552 | 2553 | 2554 | JavBus 2555 | 2556 | 2557 | JavLib 2558 | 2559 | 2560 | OneJav 2561 | 2562 | `); 2563 | let $a = $(` 2564 | 2565 | Jav321 2566 | 2567 | `); 2568 | $div.append(Common.jav321LinkMousedown($a, avid)); 2569 | 2570 | let $b = $(` 2571 | 2572 | JavStore 2573 | 2574 | `); 2575 | $div.append(Common.javstoreLinkMousedown($b, avid)); 2576 | 2577 | // 提取评分数、评分人数 2578 | $(e).attr("score", $(e).find('.score>span').text().match(/-?(?:\d+(?:\.\d*)?|\.\d+)/g)[0]); 2579 | $(e).attr("usernum", $(e).find('.score>span').text().match(/-?(?:\d+(?:\.\d*)?|\.\d+)/g)[1]); 2580 | // 已阅番号标色 2581 | if (Common.browseJavidHasCache(avid)) $(e).find(".video-title,.score").css("background-color", "#ffe7d3"); 2582 | } 2583 | }); 2584 | } 2585 | 2586 | }); 2587 | 2588 | if ((/(JavBus|AVMOO|AVSOX)/g).test(document.title) || $("footer:contains('JavBus')").length) { 2589 | // javbus.com、avmo.pw、avso.pw 样式 2590 | GM_addStyle(` 2591 | #waterfall_h {height: initial !important;width: initial !important;flex-direction: row;flex-wrap: wrap;margin: 5px 15px !important;} 2592 | #waterfall_h .item {position: relative !important;top: initial !important;left: initial !important;float: left;} 2593 | #waterfall_h .movie-box img {position: absolute; top: -200px; bottom: -200px; left: -200px; right: -200px; margin: auto;} 2594 | #waterfall_h .movie-box .photo-frame {position: relative;} #waterfall_h .avatar-box .photo-info p {margin: 0 0 2px;} 2595 | #waterfall_h .avatar-box .photo-info {line-height: 15px; padding: 6px;height: 220px;} 2596 | #waterfall_h .avatar-box .photo-frame {margin: 10px;text-align: center;} 2597 | #waterfall_h .avatar-box.text-center {height: 195px;}//actresses页面 2598 | `); 2599 | 2600 | if ($('#waterfall').length == 0 && location.pathname.search(/search/) > 0 && 2601 | location.pathname.search(/uncensored/) < 1) { 2602 | window.location.href = $('li[role="presentation"]:eq(1) a').attr("href"); 2603 | } 2604 | 2605 | if (location.pathname.includes('/uncensored') || location.hostname.includes('javbus.org') || (/(AVSOX)/g).test(document.title)) { 2606 | GM_addStyle(`#waterfall_h .movie-box {width: 354px;} #waterfall_h .movie-box .photo-info {height: 105px;}`); 2607 | } else { 2608 | GM_addStyle(`#waterfall_h .movie-box {width: 167px;} #waterfall_h .movie-box .photo-info {height: 145px;}`); 2609 | } 2610 | } 2611 | }, 2612 | // 瀑布流脚本 2613 | waterfall: (() => { 2614 | function waterfall(selectorcfg = {}) { 2615 | // 瀑布流脚本使用类 2616 | class Lock { 2617 | constructor(d = false) { 2618 | this.locked = d; 2619 | } 2620 | lock() { 2621 | this.locked = true; 2622 | } 2623 | unlock() { 2624 | this.locked = false; 2625 | } 2626 | } 2627 | // 创建请求队列 //浏览器对同一域名进行请求的最大并发连接数:chrome为6 2628 | this.queue = new Queue(1); 2629 | this.page_queue = new Queue(1); 2630 | this.lock = new Lock(); 2631 | this.baseURI = this.getBaseURI(); 2632 | this.selector = { 2633 | next: 'a.next', 2634 | item: '', 2635 | cont: '#waterfall', //container 2636 | pagi: '.pagination', 2637 | }; 2638 | Object.assign(this.selector, selectorcfg); 2639 | this.pagegen = this.fetchSync(location.href); 2640 | this.anchor = $(this.selector.pagi)[0]; 2641 | this._count = 0; 2642 | this._1func = (cont, elems) => { 2643 | cont.empty().append(elems); 2644 | }; 2645 | this._2func = (cont, elems) => { 2646 | cont.append(elems); 2647 | }; 2648 | this._3func = (elems) => { }; 2649 | if ($(this.selector.item).length) { 2650 | // 开启关闭瀑布流判断 2651 | if (waterfallScrollStatus > 0) { 2652 | document.addEventListener('scroll', this.scroll.bind(this)); 2653 | document.addEventListener('wheel', this.wheel.bind(this)); 2654 | } 2655 | this.appendElems(this._1func); 2656 | } 2657 | } 2658 | 2659 | waterfall.prototype.getBaseURI = () => { 2660 | let _ = location; 2661 | return `${_.protocol}//${_.hostname}${(_.port && `:${_.port}`)}`; 2662 | }; 2663 | waterfall.prototype.getNextURL = function (href) { 2664 | let a = document.createElement('a'); 2665 | a.href = href; 2666 | return `${this.baseURI}${a.pathname}${a.search}`; 2667 | }; 2668 | // 瀑布流脚本 2669 | waterfall.prototype.fetchURL = function (url) { 2670 | console.log(`fetchUrl = ${url}`); 2671 | let status = 404; 2672 | const fetchwithcookie = fetch(url, { credentials: 'same-origin' }); 2673 | return fetchwithcookie.then(response => { 2674 | status = response.status; 2675 | return response.text(); 2676 | }).then(html => new DOMParser().parseFromString(html, 'text/html')) 2677 | .then(doc => { 2678 | let $doc = $(doc); 2679 | let elems = []; 2680 | let nextURL; 2681 | if(status < 300){ 2682 | let href = $doc.find(this.selector.next).attr('href'); 2683 | nextURL = href ? this.getNextURL(href) : undefined; 2684 | elems = $doc.find(this.selector.item); 2685 | for (const elem of elems) { 2686 | const links = elem.getElementsByTagName('a'); 2687 | for (const link of links) { 2688 | link.target = "_blank"; 2689 | } 2690 | } 2691 | // javdb列表 bug:一直有最后一页 console.log(`1 ${url}`);console.log(`2 ${nextURL}`); 2692 | if ($(JAVDB_ITEM_SELECTOR).length && (this._count !== 0) && url === nextURL) { 2693 | if ($(`#waterfall>div>a[href="${$(elems[0]).find('a.box')[0].attr('href')}"]`).length > 0) { 2694 | nextURL = undefined; 2695 | elems = []; 2696 | } 2697 | } 2698 | } else { 2699 | nextURL = $doc.url; 2700 | } 2701 | return { 2702 | nextURL, 2703 | elems 2704 | }; 2705 | }); 2706 | }; 2707 | // 瀑布流脚本 2708 | waterfall.prototype.fetchSync = function* (urli) { 2709 | let url = urli; 2710 | do { 2711 | yield new Promise((resolve, reject) => { 2712 | if (this.lock.locked) { 2713 | reject(); 2714 | } 2715 | else { 2716 | this.lock.lock(); 2717 | resolve(); 2718 | } 2719 | }).then(() => { 2720 | return this.fetchURL(url).then(info => { 2721 | url = info.nextURL; 2722 | return info.elems; 2723 | }); 2724 | }).then(elems => { 2725 | this.lock.unlock(); 2726 | return elems; 2727 | }).catch((err) => { 2728 | // Locked! 2729 | }); 2730 | } while (url); 2731 | }; 2732 | // 瀑布流脚本 2733 | waterfall.prototype.appendElems = function () { 2734 | let nextpage = this.pagegen.next(); 2735 | if (!nextpage.done) { 2736 | nextpage.value.then(elems => { 2737 | const cb = (this._count === 0) ? this._1func : this._2func; 2738 | cb($(this.selector.cont), elems); 2739 | this._count += 1; 2740 | // hobby mod script 2741 | this._3func(elems); 2742 | this._4func(elems); 2743 | }); 2744 | } 2745 | return nextpage.done; 2746 | }; 2747 | // 瀑布流脚本 2748 | waterfall.prototype.end = function () { 2749 | document.removeEventListener('scroll', this.scroll.bind(this)); 2750 | document.removeEventListener('wheel', this.wheel.bind(this)); 2751 | let $end = $(`

    The End

    `); 2752 | $(this.anchor).replaceWith($end); 2753 | }; 2754 | waterfall.prototype.reachBottom = function (elem, limit) { 2755 | return (elem.getBoundingClientRect().top - $(window).height()) < limit; 2756 | }; 2757 | //滚动条事件触发 2758 | waterfall.prototype.scroll = function () { 2759 | this.pageQueuePush(); 2760 | }; 2761 | //滚轮事件触发 2762 | waterfall.prototype.wheel = function () { 2763 | this.pageQueuePush(); 2764 | }; 2765 | waterfall.prototype.pageQueuePush = function () { 2766 | this.page_queue.push(() => { 2767 | let defer = $.Deferred(); 2768 | new Promise(resolve => { 2769 | if (this.reachBottom(this.anchor, 1200) && this.appendElems(this._2func)) { 2770 | this.end(); 2771 | } 2772 | resolve(); 2773 | }).then(() => { 2774 | // 延迟1秒运行定时循环函数 2775 | setTimeout(() => { 2776 | // 判断域名是否当前页 2777 | if (new RegExp(JAVLIB_DOMAIN).test(domain)) { 2778 | // 定时循环函数,当队列执行完成时结束 2779 | var s4 = setInterval(() => { 2780 | if (this.queue.taskList.length == 0) { 2781 | defer.resolve(); 2782 | } 2783 | }, 200); 2784 | } else { 2785 | defer.resolve(); 2786 | } 2787 | }, 500); 2788 | }); 2789 | return defer.promise(); 2790 | }); 2791 | }; 2792 | waterfall.prototype.setFirstCallback = function (f) { 2793 | this._1func = f; 2794 | }; 2795 | waterfall.prototype.setSecondCallback = function (f) { 2796 | this._2func = f; 2797 | }; 2798 | waterfall.prototype.setJavlibCallback = function (f) { 2799 | this._3func = f; 2800 | }; 2801 | waterfall.prototype.setFourthCallback = function (f) { 2802 | this._4func = f; 2803 | }; 2804 | return waterfall; 2805 | })(), 2806 | // 挊 2807 | nong: { 2808 | main: { 2809 | //av信息查询类 2810 | //avsox|avmoo 2811 | jav: { 2812 | type: 0, 2813 | re: /.*movie.*/, 2814 | vid: () => { 2815 | return $('.header_hobby')[0].nextElementSibling.getAttribute("avid"); 2816 | }, 2817 | proc: (main) => { 2818 | var divE = $("div[class='col-md-3 info']")[0]; 2819 | $(divE).after(main.cur_tab); 2820 | } 2821 | }, 2822 | javbus: { 2823 | type: 0, 2824 | re: /(jav|bus|dmm|see|cdn|fan){2}\./g, 2825 | vid: () => { 2826 | var a = $('.header_hobby')[0].nextElementSibling; 2827 | return a ? a.getAttribute("avid") : ''; 2828 | }, 2829 | proc: (main) => { 2830 | var divE = $("div[class='col-md-3 info']")[0]; 2831 | $(divE).after(main.cur_tab); 2832 | } 2833 | }, 2834 | javlibrary: { 2835 | type: 0, 2836 | re: /.*\?v=jav.*/, 2837 | vid: () => { 2838 | let avid = $('#video_id')[0].getElementsByClassName('text')[0].getAttribute("avid"); 2839 | return Common.getAvCode(avid); 2840 | }, 2841 | proc: (main) => { 2842 | //去十八岁警告 2843 | Common.setCookie("over18", 18); 2844 | $('.socialmedia').remove(); 2845 | GM_addStyle(` 2846 | #video_info {text-align: left;font: 14px Arial;min-width: 230px;max-width: 260px;padding: 0px 0px 0px 0px;} 2847 | #video_jacket_info {overflow: hidden;} //table-layout: fixed; 2848 | #coverimg {vertical-align: top;overflow: hidden;max-width: 50%;} 2849 | #javtext {vertical-align: top;width: 260px;} 2850 | #video_info td.header {width: 75px;} 2851 | #video_info td.icon {width: 0px;} 2852 | #content {padding-top: 0px;} 2853 | #video_info table {margin-top: 6px;border-bottom: 1px solid #ffffff;} 2854 | `); 2855 | 2856 | var tdE = $("td[style='vertical-align: top;']")[0]; 2857 | tdE.id = "coverimg"; 2858 | $("td[style='vertical-align: top;']")[1].id = 'javtext'; 2859 | $('#leftmenu').remove(); 2860 | $('#rightcolumn').attr("style", "margin: 0px 0px 0px 0px;width: 100%;padding: initial;"); 2861 | $(tdE.parentElement).append('
    '); 2862 | $('#hobby').append(main.cur_tab); 2863 | } 2864 | }, 2865 | javstore: { 2866 | type: 0, 2867 | re: /.*javstore.*/, 2868 | vid: () => { 2869 | if (GM_getValue(document.URL, false)) { 2870 | let avid = GM_getValue(document.URL); 2871 | GM_deleteValue(document.URL); 2872 | $('.boxoleft .box_left_news.news_2n').attr("avid", avid); 2873 | return avid; 2874 | } else { 2875 | let $ele = $('.boxoleft .box_left_news.news_2n').attr("avid", $('.name').text().match(/[a-z|A-Z|0-9| _-]+/)[0].trim()); 2876 | return $ele.attr('avid'); 2877 | } 2878 | }, 2879 | proc: (main) => { 2880 | $('.boxoleft .box_left_news.news_2n').append(main.cur_tab); 2881 | } 2882 | }, 2883 | }, 2884 | resource_sites: { 2885 | [GM_getValue('javdb_url')]: (kw, callback) => { 2886 | let promise = Common.request("https://" + GM_getValue('search_index') + "/search?f=download&q=" + kw, "https://" + GM_getValue('search_index') + "/"); 2887 | promise.then((result) => { 2888 | let data = []; 2889 | return new Promise((resolve, reject) => { 2890 | thirdparty.nong.search_engines.full_url = result.finalUrl; 2891 | let doc = Common.parsetext(result.responseText); 2892 | let a = $(doc).find(`.box .video-title:contains('${kw.toUpperCase().replace("+", "-")}')`); 2893 | if (a) { 2894 | let url = a[0].parentElement.href.replace(location.origin, 'https://' + [GM_getValue('javdb_url')]); 2895 | if(url.indexOf("http") < 0) { 2896 | url = 'https://' + [GM_getValue('javdb_url')] + url; 2897 | } 2898 | resolve(url); 2899 | } 2900 | else { 2901 | reject(); 2902 | } 2903 | }).then(url => { 2904 | Common.request(url).then(result => { 2905 | thirdparty.nong.search_engines.full_url = result.finalUrl; 2906 | let doc = Common.parsetext(result.responseText); 2907 | let t = $(doc).find('#magnets-content .item'); 2908 | if (t) { 2909 | for (let elem of t) { 2910 | data.push({ 2911 | "title": elem.querySelector(".magnet-name span:nth-child(1)").textContent, 2912 | "maglink": elem.querySelector(".magnet-name a:nth-child(1)").href, 2913 | "size": elem.querySelector(".magnet-name .meta") ? elem.querySelector(".magnet-name .meta").textContent : "", 2914 | "src": result.finalUrl, 2915 | }); 2916 | } 2917 | } 2918 | else { 2919 | data.push({ 2920 | "title": "没有找到磁链接", 2921 | "maglink": "", 2922 | "size": "0", 2923 | "src": result.finalUrl, 2924 | }); 2925 | } 2926 | callback(result.finalUrl, data); 2927 | }) 2928 | }).catch(() => { 2929 | data.push({ 2930 | "title": "没有找到磁链接", 2931 | "maglink": "", 2932 | "size": "0", 2933 | "src": result.finalUrl, 2934 | }); 2935 | callback(result.finalUrl, data); 2936 | }); 2937 | }); 2938 | }, 2939 | [GM_getValue('btsow_url')]: (kw, callback) => { 2940 | let promise = Common.request("https://" + GM_getValue('search_index') + "/search/" + kw); 2941 | promise.then((result) => { 2942 | thirdparty.nong.search_engines.full_url = result.finalUrl; 2943 | var doc = Common.parsetext(result.responseText); 2944 | if (!doc) { 2945 | thirdparty.nong.search_engines.parse_error(GM_getValue('search_index')); 2946 | } 2947 | var data = []; 2948 | var t = doc.getElementsByClassName('data-list')[0]; 2949 | if (t) { 2950 | var a = t.getElementsByTagName('a'); 2951 | for (var i = 0; i < a.length; i++) { 2952 | if (!a[i].className.match('btn')) { 2953 | data.push({ 2954 | 'title': a[i].title, 2955 | 'maglink': 'magnet:?xt=urn:btih:' + a[i].outerHTML.replace(/.*hash\//, '').replace(/" .*\n.*\n.*\n.*/, ''), 2956 | 'size': a[i].nextElementSibling.textContent, 2957 | 'src': a[i].href, 2958 | }); 2959 | } 2960 | } 2961 | } 2962 | callback(result.finalUrl, data); 2963 | }); 2964 | }, 2965 | [GM_getValue('btdig_url')]: (kw, callback) => { 2966 | let promise = Common.request("https://" + GM_getValue('search_index') + "/search?q=" + kw); 2967 | promise.then((result) => { 2968 | thirdparty.nong.search_engines.full_url = result.finalUrl; 2969 | let doc = Common.parsetext(result.responseText); 2970 | let data = []; 2971 | let t = doc.querySelectorAll("div.one_result"); 2972 | if (t) { 2973 | for (let elem of t) { 2974 | data.push({ 2975 | "title": elem.querySelector(".torrent_name a").textContent, 2976 | "maglink": elem.querySelector(".fa.fa-magnet a").href, 2977 | "size": elem.querySelector(".torrent_size").textContent, 2978 | "src": elem.querySelector(".torrent_name a").href, 2979 | }); 2980 | } 2981 | } 2982 | else { 2983 | data.push({ 2984 | "title": "没有找到磁链接", 2985 | "maglink": "", 2986 | "size": "0", 2987 | "src": result.finalUrl, 2988 | }); 2989 | } 2990 | callback(result.finalUrl, data); 2991 | }); 2992 | }, 2993 | [GM_getValue('nyaa_url')]: (kw, callback) => { 2994 | let promise = Common.request("https://" + GM_getValue('search_index') + "/?f=0&c=0_0&q=" + kw); 2995 | promise.then((result) => { 2996 | thirdparty.nong.search_engines.full_url = result.finalUrl; 2997 | let doc = Common.parsetext(result.responseText); 2998 | if (!doc) { 2999 | thirdparty.nong.search_engines.parse_error(GM_getValue('search_index')); 3000 | } 3001 | let data = []; 3002 | let t = doc.querySelectorAll("tr.default,tr.success"); 3003 | if (t.length !== 0) { 3004 | for (let elem of t) { 3005 | data.push({ 3006 | "title": elem.querySelector("td:nth-child(2)>a:nth-child(1)").title, 3007 | "maglink": elem.querySelector("td:nth-child(3)>a:nth-last-child(1)").href, 3008 | //"torrent_url": "https://nyaa.si" + elem.querySelector("td:nth-child(3)>a:nth-child(1)").href, 3009 | "size": elem.querySelector("td:nth-child(4)").textContent, 3010 | "src": "https://" + [GM_getValue('nyaa_url')] 3011 | + elem.querySelector("td:nth-child(2)>a:nth-child(1)").getAttribute('href'), 3012 | }); 3013 | } 3014 | } 3015 | callback(result.finalUrl, data); 3016 | }); 3017 | }, 3018 | [GM_getValue('torrentkitty_url')]: (kw, callback) => { 3019 | let promise = Common.request("https://" + GM_getValue('search_index') + "/search/" + kw); 3020 | promise.then((result) => { 3021 | thirdparty.nong.search_engines.full_url = result.finalUrl; 3022 | let doc = Common.parsetext(result.responseText); 3023 | let data = []; 3024 | let t = $(doc).find("#archiveResult tr:gt(0)"); 3025 | if (t) { 3026 | for (let elem of t) { 3027 | if ((/(No result)/g).test(elem.querySelector(".name").textContent)) 3028 | break; 3029 | data.push({ 3030 | "title": elem.querySelector(".name").textContent, 3031 | "maglink": elem.querySelector(".action>a:nth-child(2)").href, 3032 | "size": elem.querySelector(".size").textContent, 3033 | "src": "https://" + [GM_getValue('torrentkitty_url')] + elem.querySelector(".action>a:nth-child(1)").getAttribute('href'), 3034 | }); 3035 | } 3036 | } 3037 | else { 3038 | data.push({ 3039 | "title": "没有找到磁链接", 3040 | "maglink": "", 3041 | "size": "0", 3042 | "src": result.finalUrl, 3043 | }); 3044 | } 3045 | callback(result.finalUrl, data); 3046 | }); 3047 | }, 3048 | }, 3049 | offline_sites: { 3050 | 115: { 3051 | name: '115离线', 3052 | url: 'http://115.com/?tab=offline&mode=wangpan', 3053 | enable: true, 3054 | }, 3055 | }, 3056 | // 挊 3057 | search_engines: { 3058 | switch_engine: (i) => { 3059 | // var index = GM_getValue("search_index",0); 3060 | GM_setValue('search_index', i); 3061 | return i; 3062 | }, 3063 | cur_engine: (kw, callback) => { 3064 | let ops = Object.keys(thirdparty.nong.resource_sites); 3065 | let z = thirdparty.nong.resource_sites[GM_getValue('search_index', ops[0])]; 3066 | if (!z) { 3067 | //alert("search engine not found"); 3068 | GM_setValue('search_index', Object.keys(thirdparty.nong.resource_sites)[0]); 3069 | z = thirdparty.nong.resource_sites[GM_getValue('search_index')]; 3070 | } 3071 | return z(kw, callback); 3072 | }, 3073 | parse_error: (a) => { 3074 | alert("调用搜索引擎错误,可能需要更新,请向作者反馈。i=" + a); 3075 | }, 3076 | full_url: '', 3077 | 3078 | }, 3079 | // 挊 3080 | magnet_table: { 3081 | template: { 3082 | create_head: () => { 3083 | var a = document.createElement('tr'); 3084 | a.className = 'jav-nong-row'; 3085 | a.id = 'jav-nong-head'; 3086 | var list = ['标题', '大小', '操作', '离线下载']; 3087 | for (var i = 0; i < list.length; i++) { 3088 | var b = thirdparty.nong.magnet_table.template.head.cloneNode(true); 3089 | if (i === 0) { 3090 | var select = document.createElement("select"); 3091 | var ops = Object.keys(thirdparty.nong.resource_sites); // todo 181225 3092 | var cur_index = GM_getValue("search_index", ops[0]); 3093 | for (var j = 0; j < ops.length; j++) { 3094 | var op = document.createElement("option"); 3095 | op.value = ops[j]; 3096 | op.textContent = ops[j]; 3097 | if (cur_index == ops[j]) { 3098 | op.setAttribute("selected", "selected"); 3099 | } 3100 | select.appendChild(op); 3101 | } 3102 | b.removeChild(b.firstChild); 3103 | b.appendChild(select); 3104 | let a3 = document.createElement('a'); 3105 | $(a3).append(' 修改 ') 3106 | $(a3).css({ 3107 | "color": "blue", 3108 | "font": "bold 12px monospace" 3109 | }); 3110 | $(a3).attr("href", "#"); 3111 | $(a3).click(() => { 3112 | Common.openSystemConfig(); 3113 | }); 3114 | b.append(a3); 3115 | a.appendChild(b); 3116 | continue; 3117 | } 3118 | b.firstChild.textContent = list[i]; 3119 | a.appendChild(b); 3120 | } 3121 | // var select_box = this.create_select_box(); 3122 | // a.firstChild.appendChild(select_box); 3123 | 3124 | return a; 3125 | }, 3126 | create_row: (data) => { 3127 | var a = document.createElement('tr'); 3128 | a.className = 'jav-nong-row'; 3129 | a.setAttribute('maglink', data.maglink); 3130 | // 暂时针对cnbtkitty.pw站点生效。 3131 | if (data.maglink.indexOf("#magnetlink") > -1) { 3132 | a.setAttribute('id', data.id); 3133 | let promise1 = Common.request(data.maglink + "?hobbyId=" + data.id);// 传递修改hobbyId,用于修改时定位。 3134 | promise1.then((result) => { 3135 | //定位磁链编码开始下标位置 3136 | let indexNum = result.responseText.indexOf('#website#infohash#'); 3137 | if (indexNum >= 0) { 3138 | let magnetlink = result.responseText.substring(indexNum + 18, indexNum + 58); 3139 | let hobbyId = result.finalUrl.substring(result.finalUrl.indexOf('?hobbyId=') + 9, result.finalUrl.length); 3140 | $("#" + hobbyId).attr("maglink", "magnet:?xt=urn:btih:" + magnetlink); 3141 | } 3142 | }); 3143 | } 3144 | 3145 | var b = document.createElement('td'); 3146 | var list = [ 3147 | thirdparty.nong.magnet_table.template.create_info(data.title, data.maglink), 3148 | thirdparty.nong.magnet_table.template.create_size(data.size, data.src), 3149 | thirdparty.nong.magnet_table.template.create_operation(data.maglink), 3150 | thirdparty.nong.magnet_table.template.create_offline() 3151 | ]; 3152 | for (var i = 0; i < list.length; i++) { 3153 | var c = b.cloneNode(true); 3154 | c.appendChild(list[i]); 3155 | a.appendChild(c); 3156 | } 3157 | return a; 3158 | }, 3159 | create_loading: () => { 3160 | var a = document.createElement('tr'); 3161 | a.className = 'jav-nong-row'; 3162 | var p = document.createElement('p'); 3163 | p.textContent = 'Loading'; 3164 | p.id = 'notice'; 3165 | a.appendChild(p); 3166 | return a; 3167 | }, 3168 | create_info: (title, maglink) => { 3169 | var a = thirdparty.nong.magnet_table.template.info.cloneNode(true); 3170 | a.firstChild.textContent = title.length < 20 ? title : title.substr(0, 20) + '...'; 3171 | a.firstChild.href = maglink; 3172 | a.title = title; 3173 | return a; 3174 | }, 3175 | create_size: (size, src) => { 3176 | var a = thirdparty.nong.magnet_table.template.size.cloneNode(true); 3177 | a.textContent = size; 3178 | a.href = src; 3179 | return a; 3180 | }, 3181 | create_operation: (maglink) => { 3182 | var a = thirdparty.nong.magnet_table.template.operation.cloneNode(true); 3183 | a.firstChild.href = maglink; 3184 | return a; 3185 | }, 3186 | create_offline: () => { //有用 hobby 3187 | var a = thirdparty.nong.magnet_table.template.offline(); 3188 | a.className = 'nong-offline'; 3189 | return a; 3190 | }, 3191 | create_select_box: () => { 3192 | var select_box = document.createElement('select'); 3193 | select_box.id = 'nong-search-select'; 3194 | select_box.setAttribute('title', '切换搜索结果'); 3195 | var search_name = GM_getValue('search', default_search_name); 3196 | for (var k in thirdparty.nong.search_engines) { 3197 | var o = document.createElement('option'); 3198 | if (k == search_name) { 3199 | o.setAttribute('selected', 'selected'); 3200 | } 3201 | o.setAttribute('value', k); 3202 | o.textContent = k; 3203 | select_box.appendChild(o); 3204 | } 3205 | return select_box; 3206 | }, 3207 | head: (() => { 3208 | var a = document.createElement('th'); 3209 | var b = document.createElement('a'); 3210 | a.appendChild(b); 3211 | return a; 3212 | })(), 3213 | info: (() => { 3214 | var a = document.createElement('div'); 3215 | var b = document.createElement('a'); 3216 | b.textContent = 'name'; 3217 | b.href = 'src'; 3218 | a.appendChild(b); 3219 | return a; 3220 | })(), 3221 | size: (() => { 3222 | var a = document.createElement('a'); 3223 | a.textContent = 'size'; 3224 | return a; 3225 | })(), 3226 | operation: (() => { 3227 | var a = document.createElement('div'); 3228 | var copy = document.createElement('a'); 3229 | copy.className = 'nong-copy'; 3230 | copy.textContent = '复制'; 3231 | a.appendChild(copy); 3232 | return a; 3233 | })(), 3234 | offline: () => { 3235 | var a = document.createElement('div'); 3236 | var b = document.createElement('a'); 3237 | b.className = 'nong-offline-download'; 3238 | b.target = '_blank'; 3239 | for (var k in thirdparty.nong.offline_sites) { 3240 | if (thirdparty.nong.offline_sites[k].enable) { 3241 | var c = b.cloneNode(true); 3242 | c.href = thirdparty.nong.offline_sites[k].url; 3243 | c.textContent = thirdparty.nong.offline_sites[k].name; 3244 | a.appendChild(c); 3245 | } 3246 | } 3247 | return a; 3248 | }, 3249 | }, 3250 | create_empty_table: () => { //有用 hobby 3251 | var a = document.createElement('table'); 3252 | a.id = 'nong-table-new'; 3253 | return a; 3254 | }, 3255 | updata_table: (src, data, type) => { 3256 | if (type == 'full') { 3257 | var tab = $('#nong-table-new')[0]; 3258 | tab.removeChild(tab.querySelector("#notice").parentElement); 3259 | for (var i = 0; i < data.length; i++) { 3260 | tab.appendChild(thirdparty.nong.magnet_table.template.create_row(data[i])); 3261 | } 3262 | } 3263 | thirdparty.nong.magnet_table.reg_event(); 3264 | }, 3265 | full: (src, data) => { 3266 | var tab = thirdparty.nong.magnet_table.create_empty_table(); 3267 | tab.appendChild(thirdparty.nong.magnet_table.template.create_head()); 3268 | var loading = thirdparty.nong.magnet_table.template.create_loading(); 3269 | tab.appendChild(loading); 3270 | return tab; 3271 | }, 3272 | handle_event: (event) => { 3273 | var maglink = event.target.parentElement.parentElement.getAttribute('maglink') 3274 | || event.target.parentElement.parentElement.parentElement.getAttribute('maglink')|| event.target.getAttribute("href"); 3275 | if ($(event.target).hasClass("nong-copy")) { 3276 | event.target.innerHTML = '成功'; 3277 | maglink = maglink.substr(0, 60); 3278 | GM_setClipboard(maglink); 3279 | setTimeout(() => { 3280 | event.target.innerHTML = '复制'; 3281 | }, 1000); 3282 | event.preventDefault(); //阻止跳转 3283 | } 3284 | else if ($(event.target).hasClass("nong-offline-download")) { 3285 | maglink = maglink.substr(0, 60); 3286 | GM_setValue('magnet', maglink); 3287 | //获取115 token接口 3288 | let promise = Common.request('http://115.com/?ct=offline&ac=space&_=' + new Date().getTime()); 3289 | promise.then((responseDetails) => { 3290 | if (responseDetails.responseText.indexOf('html') >= 0) { 3291 | //未登录处理 3292 | Common.notifiy("115还没有登录", 3293 | '请先登录115账户后,再离线下载!', 3294 | icon, 3295 | 'http://115.com/?mode=login' 3296 | ); 3297 | return false; 3298 | } 3299 | var sign115 = JSON.parse(responseDetails.response).sign; 3300 | var time115 = JSON.parse(responseDetails.response).time; 3301 | console.log("uid=" + jav_userID + " sign:" + sign115 + " time:" + time115); 3302 | console.log("rsp:" + responseDetails.response); 3303 | GM_xmlhttpRequest({ 3304 | method: 'POST', 3305 | url: 'http://115.com/web/lixian/?ct=lixian&ac=add_task_url', //添加115离线任务接口 3306 | headers: { 3307 | "Content-Type": "application/x-www-form-urlencoded" 3308 | }, 3309 | data: "url=" + encodeURIComponent(maglink) + "&uid=" + jav_userID + "&sign=" + sign115 3310 | + "&time=" + time115, 3311 | onload: (responseDetails) => { 3312 | var lxRs = JSON.parse(responseDetails.responseText); //离线结果 3313 | if (lxRs.state) { 3314 | //离线任务添加成功 3315 | Common.notifiy("115老司机自动开车", 3316 | '离线任务添加成功 , 3秒后刷新本页面', 3317 | icon, 3318 | 'http://115.com/?tab=offline&mode=wangpan' 3319 | ); 3320 | setTimeout(() => { 3321 | location.reload(); 3322 | }, 3000); 3323 | } 3324 | else { 3325 | //离线任务添加失败 3326 | if (lxRs.errcode == '911') { 3327 | lxRs.error_msg = '你的帐号使用异常,需要在线手工重新验证即可正常使用。'; 3328 | } 3329 | Common.notifiy("失败了", 3330 | '请重新打开115,' + lxRs.error_msg, 3331 | icon, 3332 | 'http://115.com/?tab=offline&mode=wangpan' 3333 | ); 3334 | } 3335 | console.log("sign:" + sign115 + " time:" + time115); 3336 | console.log("磁链:" + maglink + " 下载结果:" + lxRs.state + " 原因:" + lxRs.error_msg); 3337 | console.log("rsp:" + responseDetails.response); 3338 | } 3339 | }); 3340 | 3341 | }); 3342 | event.preventDefault(); //阻止跳转 3343 | } 3344 | }, 3345 | reg_event: () => { // target 处理 更精准 3346 | var list = [ 3347 | '.nong-copy', 3348 | '.nong-offline-download' 3349 | ]; 3350 | for (var i = 0; i < list.length; i++) { 3351 | var a = document.querySelectorAll(list[i]); 3352 | for (var u = 0; u < a.length; u++) { 3353 | a[u].addEventListener('click', thirdparty.nong.magnet_table.handle_event, false); 3354 | } 3355 | } 3356 | }, 3357 | }, 3358 | // 挊 3359 | searchMagnetRun: () => { 3360 | let main = thirdparty.nong.main; 3361 | let main_keys = Object.keys(main); 3362 | main.cur_tab = null; 3363 | main.cur_vid = ''; 3364 | for (var i = 0; i < main_keys.length; i++) { 3365 | var v = main[main_keys[i]]; 3366 | if (new RegExp(v.re).test(location.href)) { 3367 | if (v.type === 0) { 3368 | try { 3369 | main.cur_vid = v.vid(); 3370 | console.log('挊的番号:', main.cur_vid); 3371 | } 3372 | catch (e) { 3373 | main.cur_vid = ''; 3374 | } 3375 | if (main.cur_vid) { 3376 | GM_addStyle(` 3377 | #nong-table-new{margin:10px auto;color:#666 !important;font-size:13px;text-align:center;background-color: #F2F2F2;} 3378 | #nong-table-new th,#nong-table-new td{text-align: center;height:30px;background-color: #FFF;padding:0 5px 0;border: 1px solid #EFEFEF;} 3379 | .jav-nong-row{text-align: center;height:30px;background-color: #FFF;padding:0 5px 0;border: 1px solid #EFEFEF;} 3380 | .nong-copy{color:#08c !important;} 3381 | .nong-offline{text-align: center;} 3382 | #jav-nong-head a {margin-right: 5px;color: black;} 3383 | .nong-offline-download{color: rgb(0, 180, 30) !important; margin-right: 4px !important;} 3384 | .nong-offline-download:hover{color:red !important;} 3385 | `); 3386 | main.cur_tab = thirdparty.nong.magnet_table.full(); 3387 | v.proc(main); 3388 | 3389 | let t = $('#jav-nong-head')[0].firstChild; 3390 | t.firstChild.addEventListener('change', (e) => { 3391 | console.log("url: http://" + e.target.value); 3392 | GM_setValue('search_index', e.target.value); 3393 | let s = $('#nong-table-new')[0]; 3394 | s.parentElement.removeChild(s); 3395 | thirdparty.nong.searchMagnetRun(); 3396 | }); 3397 | 3398 | if (GM_getValue('search_index', null) === null) { 3399 | GM_setValue('search_index', Object.keys(thirdparty.nong.resource_sites)[0]); 3400 | } 3401 | thirdparty.nong.search_engines.cur_engine(main.cur_vid, (src, data) => { //callback 3402 | if (data.length === 0) { 3403 | let url = thirdparty.nong.search_engines.full_url; 3404 | $('#nong-table-new #notice').text('No search result! '); //todo 181224 3405 | $('#nong-table-new #notice').append( 3406 | ` Go`); //todo 190630 3407 | } 3408 | else { 3409 | thirdparty.nong.magnet_table.updata_table(src, data, 'full'); 3410 | /*display search url*/ 3411 | var y = $('#jav-nong-head th')[1].firstChild; 3412 | y.href = thirdparty.nong.search_engines.full_url; 3413 | } 3414 | }); 3415 | } 3416 | } 3417 | break; 3418 | } 3419 | } 3420 | }, 3421 | }, 3422 | }; 3423 | 3424 | function mainRun() { 3425 | Common.init(); 3426 | GM_addStyle(` 3427 | .tm-setting {display: flex;align-items: center;justify-content: space-between;padding-top: 20px;} 3428 | .tm-checkbox {width: 16px;height: 16px;} 3429 | .tm-text {width: 150px;height: 16px;} 3430 | `); 3431 | 3432 | Jav.javStoreScript(); 3433 | // 判断是否指定页面 3434 | if ((/(JAVLibrary|JavBus|AVMOO|AVSOX)/g).test(document.title) || $("footer:contains('JavBus')").length) { 3435 | Common.addAvImgCSS(); 3436 | GM_addStyle(` 3437 | .container {width: 100%;float: left;} 3438 | .col-md-3 {float: left;max-width: 260px;} 3439 | .col-md-9 {width: inherit;} 3440 | .hobby-a {color: red; font: bold 12px monospace;} /*javlib*/ 3441 | .footer {padding: 20px 0;background: #1d1a18;float: left;} /*javbus*/ 3442 | #nong-table-new {margin: initial !important;important;color: #666 !important;font-size: 13px;text-align: center;background-color: #F2F2F2;float: left;} 3443 | .header_hobby {font-weight: bold;text-align: right;width: 75px;} /*javbus*/ 3444 | `); 3445 | Jav.javlibaryScript(); 3446 | Jav.javBusScript(); 3447 | } 3448 | 3449 | Jav.oneJavScript(); 3450 | Jav.jav321Script(); 3451 | Jav.javDBScript(); 3452 | Jav.quarkScript(); 3453 | thirdparty.login115Run(); 3454 | } 3455 | mainRun(); 3456 | })(); -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jav老司机 2 | 3 | 请搭配Tampermonkey扩展插件来安装使用脚本,已经安装插件,可以点击直接安装 4 | 5 | https://sleazyfork.org/zh-CN/scripts/25781 6 | 7 | 油猴脚本技术交流:https://t.me/+TgfN6vLVRew7aMWt 8 | --------------------------------------------------------------------------------