JAV老司机

JAV老司机神器,支持各Jav老司机站点。拥有高效浏览Jav的页面排版,JAV高清预览大图,JAV列表无限滚动自动加载,合成“挊”的自动获取JAV磁链接,一键自动115离线下载。。。。没时间解释了,快上车!

  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 *://*r86m.com/*
  22. // @include *://*s87n.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 优化预览图加载顺序,优化预览图加载问题。(如遇预览图无法加载成功,优先考虑更新最新chrome版本再使用新版脚本)
  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 = 's87n.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 = `<div>
  297. <label class="tm-setting">jav各站开启瀑布流(自动加载下一页)<input type="checkbox" id="scroll_true" ${scroll_true} class="tm-checkbox"></label>
  298. <label class="tm-setting">javdb网址<input type="text" id="javdb_url" class="tm-text" value="${GM_getValue('javdb_url')}"></label>
  299. <label class="tm-setting">btsow网址<input type="text" id="btsow_url" class="tm-text" value="${GM_getValue('btsow_url')}"></label>
  300. <label class="tm-setting">btdig网址<input type="text" id="btdig_url" class="tm-text" value="${GM_getValue('btdig_url')}"></label>
  301. <label class="tm-setting">nyaa网址<input type="text" id="nyaa_url" class="tm-text" value="${GM_getValue('nyaa_url')}"></label>
  302. <label class="tm-setting">torrentkitty网址<input type="text" id="torrentkitty_url" class="tm-text" value="${GM_getValue('torrentkitty_url')}"></label>
  303. <label class="tm-setting">javlib网址<input type="text" id="javlib_url" class="tm-text" value="${GM_getValue('javlib_url')}"></label>
  304. <label class="tm-setting">javbus网址<input type="text" id="javbus_url" class="tm-text" value="${GM_getValue('javbus_url')}"></label>
  305. <label class="tm-setting">avsox网址<input type="text" id="avsox_url" class="tm-text" value="${GM_getValue('avsox_url')}"></label>
  306. </div>`;
  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 = $(`<img id="javRealImg" title="点击可放大缩小 (图片正常时)" class="${className}"></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(/<table class="videotextlist">/), doc.search(/<table style="width: 95%; margin: 10px auto;">/));
  1153. //<table class="videotextlist"> //<table style="width: 95%; margin: 10px auto;">
  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("<td style='text-align:center;'><div><a class='nong-copy' href='" + magnetUrl + "'>复制</a></div></td>");
  1246. $(trEle).append("<td><div class='nong-offline'><a class='nong-offline-download' target='_blank' "
  1247. + "href='http://115.com/?tab=offline&amp;mode=wangpan'>115离线</a></div></td>");
  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("<span style='color:red;'>(←点击复制)</span>");
  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('关闭瀑布流&nbsp;&nbsp;') : $(a3).append('开启瀑布流&nbsp;&nbsp;');
  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("<a href='/cn/vl_bestrated.php?deleteTwoMonthAway' class='hobby-a'>&nbsp;&nbsp;只看近两月份</a>");
  1451. $(".left select").after("<a href='/cn/vl_bestrated.php?deleteOneMonthAway' class='hobby-a'>&nbsp;&nbsp;只看当前月份</a>");
  1452. $(".left select").after("<a href='/cn/vl_bestrated.php?filterMyBrowse' class='hobby-a'>&nbsp;&nbsp;不看我阅览过(上个月)</a>");
  1453. $(".left select").after("<a href='/cn/vl_bestrated.php?filterMyBrowse&mode=2' class='hobby-a'>&nbsp;&nbsp;不看我阅览过(全部)</a>");
  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("<a href='" + document.location.origin + document.location.pathname
  1458. + "?delete9down" + document.location.search.replace('?', '&') + "' class='hobby-a'>只看9分以上&nbsp;&nbsp;</a>");
  1459. $(".displaymode .right").prepend("<a href='" + document.location.origin + document.location.pathname
  1460. + "?delete8down" + document.location.search.replace('?', '&') + "' class='hobby-a'>只看8分以上&nbsp;&nbsp;</a>");
  1461. $(".displaymode .right").prepend("<a href='" + document.location.origin + document.location.pathname
  1462. + "?delete7down" + document.location.search.replace('?', '&') + "' class='hobby-a'>只看7分以上&nbsp;&nbsp;</a>");
  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】+评分排序&nbsp;&nbsp;');
  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('按时间排序&nbsp;&nbsp;');
  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('<li><a href="https://onejav.com/popular/?amateur=1" target="_blank" style="color: red;">FC2发行</a></li>');
  1597. $('.menul1 ul li:contains("新发行")').after('<li><a href="vl_genre.php?g=aaua" style="color: red;">VR发行</a></li>');
  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(`<a target="_blank" href="${img.src.replace("-", "jp-")}">${img.outerHTML}</a>`);
  1615. });
  1616.  
  1617. //加入坐标div,辅助插入元素
  1618. $('#video_genres').before(`<div id="zuobiao" class="item"></div>`);
  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. '<div style="width: 100%;height: 100%;display: inline-block;margin: 0px 0px 0px 0px;">' +
  1629. '<div id="hobby_div_left" style="float: left;min-width: 60%;"></div>' +
  1630. '<div id="hobby_div_right" style="float: left;min-width: 66px;"></div>' +
  1631. '</div>'
  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. <div id="video_review_dmm" class="item">
  1655. <table><tbody><tr>
  1656. <td class="header"><a target="_blank" href="${dmmData.url}">DMM评价:</a></td>
  1657. <td><span class="text">${dmmData.score.replace("点", "分")}</span>, ${dmmData.user_num}人评, ${dmmData.collect_num}收藏</td>
  1658. </tr></tbody></table>
  1659. </div>
  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. <div id="video_review_javdb" class="item">
  1671. <table><tbody><tr>
  1672. <td class="header"><a target="_blank" href="${javdbData.url}">javdb评价:</a></td>
  1673. <td><span class="text">${score}</td>
  1674. </tr></tbody></table>
  1675. </div>
  1676. `);
  1677. }).catch(errMsg => { console.log(errMsg); });
  1678.  
  1679. let $div_video_cast = $('#video_cast');
  1680. //加入Jav跳转
  1681. $div_video_cast.after(`
  1682. <div id="javweb_jump" class="item">
  1683. <table><tbody><tr>
  1684. <td class="header">JAV跳转:</td>
  1685. <td id="linkJump">
  1686. <span class="genre"><a href="https://${GM_getValue('javbus_url')}/${AVID}" target="_blank">JavBus</a></span>
  1687. </td>
  1688. </tr></tbody></table>
  1689. </div>
  1690. `);
  1691. // javstoreLink
  1692. let $span = $(`<span class="genre"><a href="javascript:void(0);">JavStore</a></span>`);
  1693. $('#linkJump').prepend(Common.javstoreLinkMousedown($span, AVID));
  1694.  
  1695.  
  1696. //加入在线预览跳转
  1697. $div_video_cast.after(`
  1698. <div id="video_webplayer" class="item">
  1699. <table><tbody><tr>
  1700. <td class="header">在线预览:</td>
  1701. <td>
  1702. <span class="genre"><a href="https://missav.com/cn/${AVID}" target="_blank" title="需解封印" >missav</a></span>
  1703. <span class="genre"><a href="https://${MMTV_DOMAIN}/zh/censored_search/all/${AVID}/1.html" target="_blank" title="需解封印" >7mmtv</a></span>
  1704. <span class="genre"><a href="https://supjav.com/zh/?s=${Common.getAvCode(AVID)}+${AVID}" target="_blank" title="需解封印">supjav</a></span>
  1705. </td>
  1706. </tr></tbody></table>
  1707. </div>
  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. <div style="position: absolute;width: 100%;height: 12%;background: rgba(0,0,0,0.5);top: 88%;left: 0;">
  1723. <p style="color: white;font-size: 46px;margin: 0 0 0px;display: inline-block;text-align: left;">115网盘已拥有此片</p>
  1724. <a target="_blank" href="${playUrl}">
  1725. <p style="color: white;font-size: 46px;margin: 0 0 0px;display: inline-block;text-align: right;width: 50%;">115在线播放 ►</p></a>
  1726. </div>
  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. <div style="position: absolute;width: 100%;height: 12%;background: rgba(0,0,0,0.5);top: 88%;left: 0;">
  1741. <p style="color: white;font-size: 46px;margin: 0 0 0px;display: inline-block;text-align: left;">夸克网盘已有此片</p>
  1742. <a target="_blank" href="${result.playUrl}">
  1743. <p style="color: white;font-size: 46px;margin: 0 0 0px;display: inline-block;text-align: right;width: 50%;">夸克在线播放 ►</p></a>
  1744. </div>
  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(`<li><a href="https://onejav.com/popular/?amateur=1" target="_blank" style="color: red;">FC2</a></li>`);
  1772. // 新增VR菜单入口
  1773. $('#navbar ul.nav.navbar-nav li:eq(0)').after('<li><a href="/search/VR&type=1" style="color: red;">VR</a></li>');
  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('<p id="zuobiao"></p>');
  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. <p>
  1816. <span class="header">
  1817. <a target="_blank" href="${dmmData.url}" style="color: blue;">
  1818. DMM&nbsp;评:</a>
  1819. </span>
  1820. ${dmmData.score.replace("点", "分")}, ${dmmData.user_num}人评, ${dmmData.collect_num}收藏
  1821. </p>
  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. <p>
  1831. <span class="header"><a target="_blank" href="${javdbData.url}" style="color: blue;">javdb评:</a></span>
  1832. ${score}
  1833. </p>
  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. <div style="position: absolute;width: 100%;height: 12%;background: rgba(0,0,0,0.5);top: 88%;left: 0;">
  1843. <p style="color: white;font-size: 46px;margin: 0 0 0px;display: inline-block;text-align: left;">115网盘已拥有此片</p>
  1844. <a target="_blank" href="${playUrl}">
  1845. <p style="color: white;font-size: 46px;margin: 0 0 0px;display: inline-block;text-align: right;width: 50%;">115在线播放 ►</p></a>
  1846. </div>
  1847. `);
  1848. }
  1849.  
  1850. });
  1851.  
  1852. //查找夸克是否有此番号
  1853. Common.searchQuarkData(AVID).then(result => {
  1854. if (result.isHave) {
  1855. let $imgObj = $('.bigImage');
  1856. $imgObj.after(`
  1857. <div style="position: absolute;width: 100%;height: 12%;background: rgba(0,0,0,0.5);top: 88%;left: 0;">
  1858. <p style="color: white;font-size: 46px;margin: 0 0 0px;display: inline-block;text-align: left;">夸克网盘已有此片</p>
  1859. <a target="_blank" href="${result.playUrl}">
  1860. <p style="color: white;font-size: 46px;margin: 0 0 0px;display: inline-block;text-align: right;width: 50%;">夸克在线播放 ►</p></a>
  1861. </div>
  1862. `);
  1863. }
  1864. });
  1865.  
  1866. //加入在线预览跳转
  1867. $('.col-md-3.info').append(`
  1868. <p>
  1869. <span class="header">在线预览:</span>
  1870. <a href="https://missav.com/cn/${AVID}" target="_blank" style="color: rgb(204, 0, 0);" title="需解封印">missav&nbsp;</a>
  1871. <a href="https://${MMTV_DOMAIN}/zh/censored_search/all/${AVID}/1.html" target="_blank" style="color: rgb(204, 0, 0);" title="需解封印">7mmtv&nbsp;</a>
  1872. <a href="https://supjav.com/zh/?s=${AVID}" target="_blank" style="color: rgb(204, 0, 0);" title="需解封印">supjav&nbsp;</a>
  1873. </p>
  1874. `);
  1875. // 加入javlib的跳转链接
  1876. $('.col-md-3.info').append(`
  1877. <p id="linkJump">
  1878. <span class="header">JAV跳转:</span>
  1879. <a href="https://${GM_getValue('javlib_url')}/cn/vl_searchbyid.php?keyword=${AVID}" target="_blank" style="color: rgb(204, 0, 0);">JavLib&nbsp;</a>
  1880. </p>
  1881. `);
  1882. // javstoreLink
  1883. let $a = $(`<a title="综合 JAV资源站" href="javascript:void(0);" style="color: rgb(204, 0, 0);">JavStore&nbsp;</a>`);
  1884. $('#linkJump').append(Common.javstoreLinkMousedown($a, AVID));
  1885.  
  1886. // 修改javbus磁链列表头,增加两列
  1887. $('#magnet-table tbody tr').append('<td style="text-align:center;white-space:nowrap">操作</td><td style="text-align:center;white-space:nowrap">离线下载</td>');
  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("<div id='card' ></div>");
  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. <div style="position: absolute;width: 100%;height: 22%;background: rgba(0,0,0,0.5);top: 78%;left: 0;">
  1959. <a target="_blank" href="${playUrl}"><p class="hobby_p">115在线播放 ►</p></a>
  1960. </div>
  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('<th>操作</th><th>离线下载</th>');
  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. <td style='text-align:center;'><div><a class='nong-copy' href='${magnetUrl}'>复制</a></div></td>
  1989. <td><div class='nong-offline'>
  1990. <a class='nong-offline-download' target='_blank' href='http://115.com/?tab=offline&amp;mode=wangpan'>115离线</a>
  1991. </div></td>
  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('<a class="navbar-item" href="/advanced_search?type=0&score_min=4.2&score_max=&released_start=&released_end=&actors%5B%5D=&tags%5B%5D=&tags%5B%5D=212%7CVR&p=0&d=0&d=1&c=0&s=0&i=0&v=0&commit=檢索&lm=h" style="color: red;">VR</a>');
  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(`<div class="tabs is-boxed" style="justify-content: flex-end;"></div>`);
  2022. }
  2023. // 加入一个锚点
  2024. $(".tabs.is-boxed").before(`<a name="maodian" style="position: relative;top: -60px;"></a>`);
  2025. // 加入排序与过滤功能
  2026. $('.tabs.is-boxed').append(`
  2027. <div style="display: flex;">
  2028. <div class="is-active" style="border: 1px solid #3273dc;">
  2029. <a id="javtopusernum" href="#maodian" style="background-color: white;color: #3273dc;font-weight: bold;">
  2030. <span>评分人数排序</span>
  2031. </a>
  2032. </div>
  2033. <div class="is-active" style="border: 1px solid #3273dc;">
  2034. <a id="javtopscore" href="#maodian" style="background-color: white;color: #3273dc;font-weight: bold;">
  2035. <span>JAV评分排序</span>
  2036. </a>
  2037. </div>
  2038. <div style="border: 1px solid #3273dc;background-color: #f5f5f5;height: 2.8em;display: flex;">
  2039. <a href="#maodian" style="color: #3273dc; font-weight: bold;">
  2040. <span>屏蔽评分人数&nbsp&lt;&nbsp</span>
  2041. </a>
  2042. <input id="offusernum" name="offusernum" class="input" placeholder="0&nbsp人数" min="0" max="9999" type="number"
  2043. style="height: 1.5em;width: 5.5em;padding: 2px;margin: 0.6em 1em 0 0;">
  2044. </div>
  2045. </div>
  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. <div style="position: absolute;width: 100%;height: 12%;background: rgba(0,0,0,0.5);top: 88%;left: 0;">
  2110. <p style="color: white;font-size: 40px;margin: 0 0 0px;display: inline-block;text-align: left;">115网盘已拥有此片</p>
  2111. <a target="_blank" href="${playUrl}">
  2112. <p style="color: white;font-size: 40px;margin: 0 0 0px;display: inline-block;text-align: right;width: 50%;">115在线播放 ►</p></a>
  2113. </div>
  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(`<button class=\"button is-info is-small nong-offline-download\" href=\"${magnetUrl}\" type=\"button\">&nbsp;115离线&nbsp;</button>`);
  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 = $(`<img src="${imgUrl}" border="0">`);
  2168. $(e.parentElement).append($img);
  2169. e.parentElement.removeChild(e);
  2170. });
  2171.  
  2172. $(".boxoleft").append(`
  2173. <div class="box_left_news news_2n">
  2174. <h2><a href="javascript:void(0);">在线预览</a></h2>
  2175. <div class="onlinePlayLink">
  2176. </div>
  2177. <h2><a href="javascript:void(0);">下载</a></h2>
  2178. </div>
  2179. `);
  2180.  
  2181. // 挊
  2182. thirdparty.nong.searchMagnetRun();
  2183.  
  2184. $(".onlinePlayLink").append(`
  2185. <a href="https://njav.tv/zh/search?keyword=${$('.boxoleft .box_left_news.news_2n').attr("avid")}" target="_blank" style="color: rgb(204, 0, 0);" title="">njav&nbsp;&nbsp;</a>
  2186. <a href="https://missav.com/cn/${$('.boxoleft .box_left_news.news_2n').attr("avid")}" target="_blank" style="color: rgb(204, 0, 0);" title="此站需解封">missav&nbsp;&nbsp;</a>
  2187. <a href="https://${MMTV_DOMAIN}/zh/censored_search/all/${$('.boxoleft .box_left_news.news_2n').attr("avid")}/1.html" target="_blank" style="color: rgb(204, 0, 0);" title="此站需解封">7mmtv&nbsp;&nbsp;</a>
  2188. <a href="https://supjav.com/zh/?s=${$('.boxoleft .box_left_news.news_2n').attr("avid")}" target="_blank" style="color: rgb(204, 0, 0);" title="此站需解封">supjav&nbsp;&nbsp;</a>
  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(` &nbsp;${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(`<div class='hobby_add'style='color: red;font-size: 14px;'>
  2384. ${dateString}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${pingfengString}</div>`);
  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(/<table id="video_jacket_info">/),
  2453. doc.search(/<div id="video_favorite_edit" class="">/));
  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(`<a style='color:red;' href='https://${GM_getValue('javlib_url')}/cn/vl_searchbyid.php?keyword=` +
  2496. avcd + "&" + avid + "' target='_blank' title='点击到Javlib看看'>&nbsp;&nbsp;Javlib</a>");
  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("<br>") + 4);
  2516. let t2 = $(spanEle).html().substr(0, $(spanEle).html().indexOf("<br>"));
  2517. $(spanEle).html(t1 + "<br>" + 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(`<span class="tag is-success" style="background-color:#fff;">.</span>`);
  2547. }
  2548. if (!$("#waterfall").hasClass("v cols-4 vcols-8")) {
  2549. $div.append(`
  2550. <a title="可忽略" href="https://${GM_getValue('avsox_url')}/cn/search/${avid}" target="_blank">
  2551. <span class="tag hobby" style="margin-right: 5px;background-color:#bf9be6;display:none;">avsox</span>
  2552. </a>
  2553. <a title="无码 JAV资源站" href="https://${GM_getValue('javbus_url')}/${avid}" target="_blank">
  2554. <span class="tag hobby" style="margin-right: 5px;background-color:#febe00;">JavBus</span>
  2555. </a>
  2556. <a title="有码 JAV资源站" href="https://${GM_getValue('javlib_url')}/cn/vl_searchbyid.php?keyword=${avid}" target="_blank">
  2557. <span class="tag hobby" style="margin-right: 0px;background-color:#f908bb;">JavLib</span>
  2558. </a>
  2559. <a title="FC2 JAV资源站" href="${Common.getOneJavSearchUrl(avid)}" target="_blank">
  2560. <span class="tag hobby" style="margin-right: 3px;background-color:#00d1b2;">OneJav</span>
  2561. </a>
  2562. `);
  2563. let $a = $(`
  2564. <a title="素人 JAV资源站" href="javascript:void(0);">
  2565. <span class="tag hobby" style="margin-right: 0px;background-color:#418fa7;">Jav321</span>
  2566. </a>
  2567. `);
  2568. $div.append(Common.jav321LinkMousedown($a, avid));
  2569.  
  2570. let $b = $(`
  2571. <a title="综合 JAV资源站" href="javascript:void(0);">
  2572. <span class="tag hobby" style="margin-right: 0px;background-color:#ad1d18;">JavStore</span>
  2573. </a>
  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 = $(`<h1>The End</h1>`);
  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('<td id="hobby" style="vertical-align: top;"></td>');
  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('&nbsp;修改&nbsp;')
  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. `<a href="${url}" target="_blank" style="color: red;">&nbsp;Go</a>`); //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. })();