// ==UserScript==
// @name 发送到115
// @author zxf10608
// @version 7.5.1
// @icon https://115.com/favicon.ico
// @namespace https://greasyfork.org/zh-CN/scripts/408466
// @description 115离线下载功能
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js
// @require https://greasyfork.org/scripts/398240-gm-config-zh-cn/code/GM_config_zh-CN.js
// @require https://greasyfork.org/scripts/412267-base64-v1-0/code/base64_v10.js
// @require https://cdn.jsdelivr.net/npm/[email protected]/toastr.min.js
// @resource toastrCss https://cdn.jsdelivr.net/npm/[email protected]/build/toastr.min.css
// @match http*://*/*
// @match http*://*.115.com/*
// @exclude http*://*.115.com/bridge*
// @exclude http*://*.115.com/*/static*
// @exclude http*://*.baidu.com/*
// @exclude http*://*.iqiyi.com/*
// @exclude http*://*.qq.com/*
// @exclude http*://*.youku.com/*
// @exclude http*://*.bilibili.com/
// @exclude http*://*.pptv.com/*
// @exclude http*://*.fun.tv/*
// @exclude http*://*.sohu.com/*
// @exclude http*://*.le.com/*
// @exclude http*://*.tudou.com/*
// @exclude http*://*.bilibili.com/*
// @exclude http*://music.163.com/*
// @exclude http*://github.com/*
// @exclude http*://gitee.com/*
// @exclude http*://btcache.me/*
// @exclude http*://*.jd.com/*
// @exclude http*://*.taobao.com/*
// @exclude http*://*.tmall.com/*
// @exclude http*://*.vip.com/*
// @exclude http*://*.pinduoduo.com/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addStyle
// @grant GM_download
// @grant GM_openInTab
// @grant GM_setClipboard
// @grant GM_getResourceText
// @grant GM_xmlhttpRequest
// @grant GM_registerMenuCommand
// @connect 115.com
// @connect *
// @grant unsafeWindow
// @grant window.open
// @grant window.close
// @run-at document-start
// @compatible chrome
// @license GPL License
// ==/UserScript==
(function() {
'use strict';
var newVersion = 'v7.5.1';
if (typeof GM_config == 'undefined') {
alert('115优化大师:\n网络异常,相关库文件加载失败,脚本无法使用,请刷新网页重新加载!');
return;
} else {
console.log('115优化大师:相关库文件加载成功!');
}
// 配置界面
function config() {
var windowCss = '#Cfg .nav-tabs {margin: 20 2} #Cfg .config_var textarea{width: 310px; height: 50px;} #Cfg .inline {padding-bottom:0px;} #Cfg .config_header a:hover {color:#1e90ff;} #Cfg .config_var {margin-left: 10%;margin-right: 10%;} #Cfg input[type="checkbox"] {margin: 3px 3px 3px 0px;} #Cfg input[type="text"] {width: 53px;} #Cfg {background-color: lightblue;} #Cfg .reset_holder {float: left; position: relative; bottom: -1em;} #Cfg .saveclose_buttons {margin: .7em;} #Cfg .section_desc {font-size: 10pt;}';
GM_registerMenuCommand('设置', opencfg);
function opencfg() {
GM_config.open();
}
GM_config.init({
id: 'Cfg',
title: GM_config.create('a', {
href: 'https://greasyfork.org/zh-CN/scripts/408466',
target: '_blank',
className: 'setTitle',
textContent: '115优化大师',
title: '作者:zxf10608 版本:' + newVersion + ' 点击访问主页'
}),
isTabs: true,
skin: 'tab',
css: windowCss,
frameStyle: {
height: '550px',
width: '445px',
zIndex: '2147483648',
},
fields: {
// 离线升级
offline_Down: {
section: ['离线升级', '升级离线下载功能'],
label: '启用一键离线下载',
labelPos: 'right',
type: 'checkbox',
default: true,
},
offline_result: {
label: '任务添加后显示离线结果',
labelPos: 'right',
type: 'checkbox',
default: true,
},
open_List: {
label: '离线后自动打开任务列表',
labelPos: 'right',
type: 'checkbox',
default: false,
},
open_search: {
label: '离线成功后开启视频搜索',
labelPos: 'right',
type: 'checkbox',
default: true,
line: 'start',
},
search_result: {
label: '显示视频搜索结果',
labelPos: 'right',
type: 'checkbox',
default: true,
},
open_Popup: {
label: '搜到视频自动播放',
labelPos: 'right',
type: 'checkbox',
default: false,
line: 'end',
},
fuzzy_find: {
label: '启用下载地址模糊匹配',
labelPos: 'right',
type: 'checkbox',
default: false,
},
diy_folder: {
label: '自定义离线下载文件夹',
labelPos: 'right',
type: 'checkbox',
default: false,
line: 'start',
},
save_folder: {
label: '设置文件夹',
labelPos: 'right',
type: 'button',
line: 'end',
click: function() {
setFolder();
}
},
reminder2: {
label: '温馨提示',
labelPos: 'right',
type: 'button',
click: function() {
alert('1、显示离线下载结果有10s延时,用于服务器响应时间。\n2、为避免通知弹窗过多,最多只显示3个视频搜索结果,更多请自行到115查看。\n3、“启用下载地址模糊匹配”后,能根据哈希值或纯文本模糊匹配磁力链接和迅雷专用链,如在磁力搜索引擎、资源网等有奇效,但在某些网页有一定几率误识别,请谨慎开启。');
}
},
},
events: {
save: function() {
GM_config.close();
location.reload();
}
},
});
}
config();
var G = GM_config;
var localHref = window.location.href;
var show_result = G.get('offline_result');
var down_reg = /^(magnet|thunder|ftp|ed2k):/i;
var UA = navigator.userAgent; // 使用浏览器默认UA
var sign_url = 'http://115.com/?ct=offline&ac=space';
var task_del = 'https://115.com/web/lixian/?ct=lixian&ac=task_del';
var add_url = 'http://115.com/web/lixian/?ct=lixian&ac=add_task_url';
var add_urls = 'http://115.com/web/lixian/?ct=lixian&ac=add_task_urls';
var lists_url = 'http://115.com/web/lixian/?ct=lixian&ac=task_lists';
var a_list = `<br><a target="_blank" class="openList" href="javascript:void(0);" style="color:blue;" title="点击打开离线链接任务列表">打开任务列表</a>`;
console.log('115脚本UA:' + UA);
// 通知样式
function notice() {
GM_addStyle(GM_getResourceText('toastrCss'));
GM_addStyle('.toast{font-size:15px!important;width:360px!important;} .toast-title{font-size:16px!important;text-align:center}');
toastr.options = {
"closeButton": true,
"debug": false,
"progressBar": true,
"timeOut": 8000,
"extendedTimeOut": 8000,
"positionClass": 'toast-top-right', // 固定右上角
"allowHtml": true,
"newestOnTop": false,
};
}
notice();
// AJAX请求
function AjaxCall(href, callback) {
GM_xmlhttpRequest({
method: "GET",
url: href,
headers: {
"User-Agent": UA,
Origin: "https://115.com",
},
onload: function(data) {
if (data.readyState == 4 && data.status == 200) {
var htmlTxt = data.responseText;
callback(null, htmlTxt);
}
},
onerror: function(error) {
callback(error);
},
ontimeout: function(error) {
callback(error);
},
});
}
// 设置离线下载文件夹
function setFolder() {
var old_cid = GM_getValue('offlineFolder') || '';
var new_cid = prompt('请输入离线下载保存文件夹的cid值:\n ※ 获取cid值方法:打开需要保存到的网盘文件夹,复制地址栏中"cid="后面的一串数字,以"&"截止,如https://115.com/?cid=012345678912345678&...,cid值则为 012345678912345678。该项不填或填无效值则保存至默认文件夹(云下载)。※', old_cid);
if (/^(\d{17,19}|0)$/.test(new_cid)) {
GM_setValue('offlineFolder', new_cid);
alert('设置成功,现cid值为:\n' + new_cid);
} else if (new_cid == '') {
GM_setValue('offlineFolder', '');
alert('未输入cid值,保存至默认文件夹(云下载)。');
} else if (new_cid == null) {
console.log('已点击取消');
} else {
alert('设置失败,cid值无效,请重新输入!\n(该值除根目录为 0 外,其他文件夹均为17至19位纯数字)');
setFolder();
}
}
// 处理下载链接
function getRightUrl(url) {
var newUrl = url;
if (/^thunder/i.test(url)) {
var key = url.replace(/thunder:\/\//i, '');
var temp = decode64(key);
newUrl = decodeURIComponent(temp.slice(2, -2));
}
if (/^magnet/i.test(newUrl)) {
var hash = newUrl.split('&')[0].substring(20) || newUrl.substring(20);
if (hash.length == 32) {
hash = base32To16(hash);
}
newUrl = 'magnet:?xt=urn:btih:' + hash;
} else if (/^\/\//.test(url)) {
newUrl = location.protocol + url;
} else if (/^\/(?!\/)/.test(url)) {
newUrl = location.protocol + '//' + location.host + url;
}
return newUrl;
}
// Base32转Base16
function base32To16(str) {
if (str.length % 8 !== 0 || /[0189]/.test(str)) {
return str;
}
str = str.toUpperCase();
var bin = "", newStr = "", i;
for (i = 0; i < str.length; i++) {
var charCode = str.charCodeAt(i);
if (charCode < 65) charCode -= 24;
else charCode -= 65;
charCode = '0000' + charCode.toString(2);
charCode = charCode.substr(charCode.length - 5);
bin += charCode;
}
for (i = 0; i < bin.length; i += 4) {
newStr += parseInt(bin.substring(i, i + 4), 2).toString(16);
}
return newStr;
}
// 检查重复链接
function repeat(link) {
var result = false;
var A = link.slice(0, 60);
if ($('.115offline').length == 0) return result;
$('.115offline').each(function() {
var B = $(this).data('href').slice(0, 60);
if (A.toLowerCase() == B.toLowerCase()) {
result = true;
return false;
}
});
return result;
}
// 搜索离线任务
function searchTask(json, link) {
var dataEl = false;
for (var i = 0; i < json.tasks.length; i++) {
if (json.tasks[i].url == link || json.tasks[i].url == decodeURIComponent(link)) {
dataEl = json.tasks[i];
break;
}
}
return dataEl;
}
// 账号验证弹窗
function verify() {
var time = new Date().getTime();
var w = 335;
var h = 500;
var t = (window.screen.availHeight - h) / 2;
var l = (window.screen.availWidth - w) / 2;
var link = 'https://captchaapi.115.com/?ac=security_code&type=web&cb=Close911_' + time;
var a = confirm('立即打开验证账号弹窗?');
if (a) {
var blocked = false;
try {
var wroxWin = window.open(link, '请验证账号', 'height=' + h + ',width=' + w + ',top=' + t + ',left=' + l + ',toolbar=no,menubar=no,scrollbars=no,resizable=no,location=no,status=no');
if (wroxWin == null) {
blocked = true;
}
} catch (e) {
blocked = true;
}
if (blocked) {
alert('验证弹窗已被拦截,请允许本页面弹出式窗口!');
}
}
}
// 离线下载核心逻辑
var offline = function() {
return {
getSign: function(key, save_name) {
return new Promise(function(resolve, reject) {
if (/^\w+=/.test(key)) {
resolve(key);
return;
}
var UserID = GM_getValue('115ID') || '';
var cid = G.get('diy_folder') ? GM_getValue('offlineFolder') : '';
var title = save_name ? save_name : '';
GM_xmlhttpRequest({
method: 'GET',
url: sign_url,
responseType: 'json',
headers: {
"User-Agent": UA,
Origin: "https://115.com",
},
onload: function(result) {
if (result.responseText.indexOf('html') != -1) {
toastr.error('请先登录115网盘账号!', '离线任务添加失败。');
setTimeout(function() {
var a = confirm('立即打开115网盘登录页面?');
if (a) {
GM_openInTab('https://115.com/?mode=login', false);
}
}, 3000);
return;
}
var data = {
uid: UserID,
sign: result.response.sign,
time: result.response.time,
wp_path_id: cid,
savepath: title
};
if ($.isPlainObject(key)) {
var value = $.param($.extend(data, key));
} else {
var value = $.param(data) + `&url=${key}`;
}
resolve(value);
},
onerror: function(error) {
reject(error);
},
});
});
},
getData: function(herf, key, save_name) {
return offline.getSign(key, save_name).then(function(value) {
return new Promise(function(resolve, reject) {
GM_xmlhttpRequest({
method: 'POST',
data: value,
url: herf,
responseType: 'json',
headers: {
"User-Agent": UA,
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Accept": "application/json, text/javascript, */*; q=0.01",
Origin: "https://115.com",
"X-Requested-With": "XMLHttpRequest"
},
onload: function(result) {
resolve(result.response);
},
onerror: function(error) {
reject(error);
},
});
});
});
},
check: function(link, link2, one) {
if (document.hidden) {
GM_setValue('noTimeOut', true);
toastr.options.timeOut = 0;
} else {
GM_setValue('noTimeOut', false);
toastr.options.timeOut = 12000;
}
var c = 1;
var retry = false;
var txt2 = '5秒后自动重试,请稍等。';
function add(retry, txt2) {
if (c == 6) {
console.log('离线结果查询异常。离线任务数量过多,请清空后再试。');
toastr.warning('离线任务数量过多,请清空后再试。', '离线结果查询异常!');
return;
}
var key = '';
var lists_url2 = lists_url + '&page=' + c;
console.log('离线任务数据地址:' + lists_url2);
offline.getData(lists_url2, key).then(function(json) {
console.log('离线任务列表第' + c + '页:');
console.log(json);
if (json.state) {
var dataEl = searchTask(json, link);
if (dataEl) {
var name = dataEl.del_path == '' ? dataEl.name : dataEl.del_path.slice(0, -1);
var a_del = ` <a target="_blank" class="delTask" data=${dataEl.info_hash} href="javascript:void(0);" style="color:blue;" title="删除该离线任务">删除任务</a>`;
if (dataEl.status != -1) {
if (dataEl.move == -1) {
toastr.warning('空间不足,请到115扩容', '离线下载异常!');
return;
}
var down_result = dataEl.percentDone.toFixed(0);
var cid = dataEl.file_id || 0;
if (down_result >= 99 && cid != 0) {
var txt = `文件(夹)名:${name},大小:${change(dataEl.size)}。`;
resultMark(link2, 3);
if (one) {
console.log(txt + '离线下载已完成。');
return;
}
if (show_result && !retry) {
toastr.success(txt + a_list + a_del, '离线下载已完成', { timeOut: 5000 });
}
if (G.get('open_search')) {
offline.search(dataEl.name, cid, function(search_result, video, j, num) {
if (search_result) {
if (G.get('search_result')) {
var videoTxt = JSON.stringify(video);
var txt = `文件名:${video.name},大小:${video.size},时长:${tranTime(video.time)}。`;
var h1 = `<br><a target="_blank" class="115play" data=${videoTxt} href="javascript:void(0);" style="color:blue;" title="播放该视频">播放</a>`;
var h2 = ` <a target="_blank" class="115down" data=${videoTxt} one="1" href="javascript:void(0);" style="color:blue;" title="下载该视频">下载</a>`;
var h3 = ` <a target="_blank" class="115del" data=${videoTxt} href="javascript:void(0);" style="color:blue;" title="删除该视频文件夹">删除</a>`;
var h4 = ` <a target="_blank" class="115newName" data=${videoTxt} href="javascript:void(0);" style="color:blue;" title="重命名该视频">重命名</a>`;
var h5 = ` <a target="_blank" class="openFolder" data=${cid} href="javascript:void(0);" style="color:blue;" title="查看所属文件列表">查看</a>`;
toastr.success(txt + h1 + h2 + h3 + h4 + h5, `发现第 ${j} 个视频(共 ${num} 个)`);
}
if (G.get('open_Popup') && j == 1) {
setTimeout(function() {
var type = '115play';
palyData(video, type);
}, 500);
}
} else {
if (dataEl.move == 2 || dataEl.move == 0 || dataEl.status == 0) {
var txt = '离线数据取回网盘中。';
} else {
var txt = '未发现任何视频文件。';
}
var h1 = `<br><a target="_blank" class="openFolder" data=${cid} href="javascript:void(0);" style="color:blue;" title="点击打开所属文件列表">打开文件列表</a>`;
toastr.warning(txt + txt2 + h1, '视频搜索无结果!');
if (!retry) {
setTimeout(function() {
retry = true;
txt2 = '';
toastr.clear();
console.log('重试搜索结果:');
add(retry, txt2);
}, 5000);
}
}
});
}
} else if (show_result) {
resultMark(link2, 4);
if (one) {
console.log(`文件(夹)名:${name},已离线下载 ${down_result}%。`);
return;
}
var txt = `文件(夹)名:${name},下载进度为:<span style="color:purple;">${down_result}%</span>。`;
toastr.warning(txt + a_list + a_del, '离线下载中...');
}
} else if (show_result) {
resultMark(link2, 4);
if (one) {
console.log(`文件(夹)名:${name},离线下载失败。`);
return;
} else if (dataEl.err == 10016) {
var txt = '文件含违规内容,已自动拦截。';
} else {
var txt = '未知原因,请到115网盘查看。';
var a_del = '';
}
toastr.error(txt + a_list + a_del, '离线下载失败!', { timeOut: 8000 });
return;
}
} else {
console.log('第' + c + '页查询失败,无匹配数据');
if (c == json.page_count) {
console.log('离线链接对比异常,已搜索所有离线列表页面,无返回结果。');
toastr.warning('搜索参数错误。', '离线结果查询异常!', { timeOut: 5000 });
return;
}
c++;
add();
}
} else {
toastr.error('查询离线结果失败。', '服务器错误!');
return;
}
});
}
add(retry, txt2);
},
addButton: function() {
$('[href]').each(function() {
var url = $(this).attr('href');
var reg1 = /\.(torrent|rar|zip|7z|mp4|rmvb|mkv|avi)$/i;
var $El = $(this).parent().filter('li,td,th,:header').find('[Searched]');
if ((!down_reg.test(url) && !reg1.test(url)) || $(this).is('[Searched]') || $El.length > 1 || ($El.length = 1 && url.indexOf($El.attr('Searched')) != -1)) {
return;
}
if (down_reg.test(url)) {
$(this).attr('Searched', url.split(':')[0]);
} else if (/torrent$/i.test(url)) {
$(this).attr('Searched', 'torrent');
} else {
$(this).attr('Searched', 'other');
}
var link = getRightUrl(url);
if (repeat(link)) {
return;
}
$(this).css('display', 'inline-block');
$(this).after('<img src="https://cdn.jsdelivr.net/gh/zxf10608/JavaScript/icon/115logo.ico" class="115offline" data-href=' + link + ' style="z-index:9123456789;display:inline-block;cursor:pointer;margin:0px 5px 2px;border-radius:50%;border:0px;vertical-align:middle;outline:none!important;padding:0px!important;height:20px!important;width:20px!important;left:0px!important;top:0px!important;" title="使用115网盘离线下载,右键复制地址\n' + link + '">');
});
},
addLink: function() {
$('a,button,span,li').each(function() {
var reg1 = /(^|\/|&|-|\.|\?|=|:|#|_|@)([a-f0-9]{40}|[a-z2-7]{32})(?!\w)/i;
var reg2 = /[a-z]{40}|[a-z]{32}/i;
if ($(this).next().addBack().is('[Searched],[href*="google"],[href*="motelppp.com"],[href*="bvmqkla.de"]') || $(this).find('img').length > 0) {
return;
}
var url = getAttribute(this);
if (url.length > 0) {
for (var i = 0; i < url.length; i++) {
if (down_reg.test(url[i]) || (reg1.test(url[i]) && !reg2.test(url[i].match(reg1)[2]))) {
if (down_reg.test(url[i])) {
var value = url[i].split(':')[0];
var templink = url[i];
} else {
var value = 'magnet';
var templink = 'magnet:?xt=urn:btih:' + url[i].match(reg1)[2];
}
var link = getRightUrl(templink);
if (repeat(link)) {
return;
}
$(this).attr('Searched', value);
$(this).after('<img src="https://cdn.jsdelivr.net/gh/zxf10608/JavaScript/icon/115logo.ico" class="115offline" data-href=' + link + ' style="z-index:9123456789;display:inline-block;cursor:pointer;margin:0px 5px 2px;border-radius:50%;border:0px;vertical-align:middle;outline:none!important;padding:0px!important;height:20px!important;width:20px!important;left:0px!important;top:0px!important;" title="使用115网盘离线下载2,右键复制地址\n' + link + '">');
return;
}
}
}
});
},
addSelect: function() {
if ($('.115offline').length < 3) return;
$('.115offline:not([Sed])').each(function() {
$(this).attr('Sed', 1);
var url = $(this).data('href');
$(this).after('<input type="checkbox" class="115select" value=' + url + ' title="长按shift键,连续选择" style="z-index:9123456789;display:inline-block;cursor:pointer;height:16px!important;width:16px!important;margin:0px 2px 1px;border-radius:50%;border:0px;vertical-align:middle;outline:none!important;padding:0px!important;left:0px!important;top:0px!important;" />');
});
var sel = $('.115offline').length > 10 ? $('.115select:eq(-1),.115select:eq(0)') : $('.115select:eq(-1)');
sel.each(function() {
if ($(this).is('[batched]')) return;
$(this).attr('batched', 1);
$(this).after('<img src="https://cdn.jsdelivr.net/gh/zxf10608/JavaScript/icon/batch_down00.png" class="115offline_batch" style="z-index:9123456789;display:inline-block;cursor:pointer;margin:0px 1px 2px;border:0px;vertical-align:middle;outline:none!important;padding:0px!important;height:23px!important;width:23px!important;left:0px!important;top:0px!important;" title="使用115网盘批量离线下载所选地址,右键可全选等">');
$(this).parent().css('overflow', 'visible');
});
},
search: function(name, cid, callback) {
var title = new Array();
title[0] = name.replace(/(\.|-|_)?(f?hd|sd|720p|1080p|full|mp4|avi|mkv|wmv|rmvb|rm|flv|f4v)/gi, ' ');
title[1] = title[0].replace(/\/|&|-|\.|\?|=|:|#|_|@/g, ' ');
title[2] = '.';
var a = 0;
function add2() {
if (a == 3) {
console.log('该文件夹无视频文件。');
callback(false);
return;
}
var searchLink = 'https://webapi.115.com/files/search?cid=' + cid + '&search_value=' + encodeURIComponent(title[a]) + '&type=4';
AjaxCall(searchLink, function(error, htmlTxt) {
if (typeof htmlTxt == 'undefined') {
a++;
add2();
} else {
var json = JSON.parse(htmlTxt);
if (a == 2 && json.folder.name == '云下载') {
callback(false);
return;
}
if (json.count > 0) {
var num = json.count;
for (var i = 0; i < num; i++) {
var $dataEh = json.data[i];
var video = {};
video['name'] = name2($dataEh.n);
video['pid'] = $dataEh.pc;
video['cid'] = $dataEh.cid;
video['fid'] = $dataEh.fid;
video['size'] = change($dataEh.s);
video['sha'] = $dataEh.sha;
video['time'] = $dataEh.play_long;
callback(true, video, i + 1, num);
console.log('第' + a + '次搜索结果' + i + ':' + $dataEh.n + ' ' + video.size);
if (i == 2) {
return;
}
}
} else {
a++;
add2();
}
}
});
}
add2();
}
};
}();
// 文件大小转换
function change(number) {
var size = "";
if (number < 1024 * 1024 * 1024) {
size = (number / (1024 * 1024)).toFixed(2) + "MB";
} else {
size = (number / (1024 * 1024 * 1024)).toFixed(2) + "GB";
}
var sizeStr = size + "";
var index = sizeStr.indexOf(".");
var dou = sizeStr.substr(index + 1, 2);
if (dou == "00") {
return sizeStr.substring(0, index) + sizeStr.substr(index + 3, 2);
}
return size;
}
// 文件名处理
function name2(txt) {
var newName = txt.replace(/\.(?!\w{2,4}$)/g, '_').replace(/\s/g, ' ');
return newName;
}
// 时间转换
function tranTime(num) {
var showTime = '';
if (num > 3600) { showTime += ' ' + parseInt(num / 3600) + ' 小时'; num = num % 3600; }
if (num > 60) { showTime += ' ' + parseInt(num / 60) + ' 分'; num = num % 60; }
return showTime += ' ' + parseInt(num) + ' 秒';
}
// 点击限制
function clickOne(el, t) {
var time = t ? t : 5000;
if (el.attr('clicked') == 1) {
console.log('5s内不可点击该按钮');
return false;
} else {
el.attr('clicked', 1);
el.css('opacity', '0.2');
setTimeout(function() {
el.attr('clicked', 0);
el.css('opacity', '0.7');
}, time);
return true;
}
}
// 标记结果
function resultMark(el, type) {
if (el.length == 0 || !show_result) return;
var urls = [];
var color = { 1: '#00CCFF', 2: '#DA70D6', 3: '#AEDD81', 4: '#EB7347' }[type];
for (var i = 0; i < el.length; i++) {
urls.push(el[i].url);
$('.115offline').each(function() {
var link = $(this).data('href');
var $al = $(this).prev();
var m = $al.attr('marked');
if ((el[i].url == link || el[i].url == decodeURIComponent(link)) && m != 3) {
$al.attr('marked', type).css('background-color', color);
$al.find('[style]').removeAttr('style');
return false;
}
});
}
return urls;
}
// 获取属性
function getAttribute(e) {
var data = [];
$.each(e.attributes, function() {
if (this.specified && this.value.length > 30) {
data.push(this.value);
}
});
if ($(e).text().length > 25) data.push($(e).text());
return data;
}
// 右键菜单
function right_menu() {
$('body').append(`
<div class="115menu" style="width:97px;height:85px;z-index:9123456789;overflow:hidden;position:absolute;display:none;background-color:#D0D0D0">
<ul style="padding:5px 7px;margin:0px;list-style:none;">
<li><a href="javascript:;" class="right_menu00">全选</a></li>
<li><a href="javascript:;" class="right_menu01">反选</a></li>
<li><a href="javascript:;" class="right_menu02">复制所选</a></li>
<li><a href="javascript:;" class="right_menu11">复制地址</a></li>
<li><a href="javascript:;" class="right_menu12">种子下载1</a></li>
<li><a href="javascript:;" class="right_menu13">种子下载2</a></li>
</ul>
</div>`);
$('.115menu a').css({ 'line-height': '25px', 'text-decoration': 'none', 'color': '#2C3E50', 'padding': '1px 5px', 'font-size': '16px', 'font-family': 'arial' });
$('.115menu a').hover(function() {
$(this).css({ 'background-color': '#2777F8', 'color': '#FFF' });
}, function() {
$(this).css({ 'background-color': '', 'color': '#2C3E50' });
});
}
// 播放视频
function palyData(video, type) {
var link = 'https://115.com/?ct=play&ac=location&pickcode=' + video.pid + '&hls=1';
GM_openInTab(link, false);
}
// 文档加载事件
$(document).ready(function() {
if (localHref.indexOf('https://115.com/') != -1) {
if (typeof (unsafeWindow.USER_ID) != 'undefined') {
GM_setValue('115ID', unsafeWindow.USER_ID);
console.log('115账号已登录,账号ID获取成功!');
} else {
console.log('115账号未登录,账号ID获取失败!');
}
}
if (localHref.indexOf('https://captchaapi.115.com') != -1) {
var t_close;
$('body').on('click', '.vcode-hint', function() {
t_close = setTimeout(function() {
console.log('验证正确');
window.open('', '_self');
window.close();
}, 200);
return false;
});
$('.vcode-hint').on('DOMNodeInserted', function(e) {
console.log('验证错误!');
clearTimeout(t_close);
});
}
});
// 主逻辑
$(document).ready(function() {
$(document).on('click', function(e) {
$('.115menu').hide();
});
$('body').on('click', '.115offline', function(e) {
if (!clickOne($(this))) return;
var link = $(this).data('href');
var save_name = '';
offline.getData(add_url, link, save_name).then(function(json) {
console.log('离线任务添加结果:');
console.log(json);
var errNum = json.errcode || json.error_code || '';
var link2 = [{'url': link}];
if (json.state) {
if (show_result) {
var txt = '10秒后显示离线结果。';
} else {
var txt = link;
if (G.get('open_List')) {
setTimeout(function() {
GM_openInTab('https://115.com/?tab=offline&mode=wangpan', false);
}, 2000);
}
}
resultMark(link2, 1);
toastr.info(txt, '离线任务添加成功。', { timeOut: 10000 });
setTimeout(function() {
offline.check(link, link2);
}, 10000);
} else if (errNum == 10008) {
toastr.warning('任务已存在,无需重复添加。', '离线任务添加无效!', { timeOut: 5000 });
if (G.get('open_List')) {
setTimeout(function() {
GM_openInTab('https://115.com/?tab=offline&mode=wangpan', false);
}, 2000);
}
resultMark(link2, 1);
offline.check(link, link2);
} else if (errNum == 911) {
toastr.warning('账号异常,请验证账号。', '离线下载失败!', { timeOut: 5000 });
setTimeout(function() {
verify();
}, 1000);
} else {
resultMark(link2, 2);
toastr.warning(json.error_msg, '离线任务添加失败!', { timeOut: 12000 });
}
console.log('离线链接:' + link + ' 添加结果:' + json.state + ' 原因:' + json.error_msg);
}, function(error) {
toastr.error('服务器繁忙,请稍后再试。', '离线任务添加异常!');
console.log(error);
});
return false;
});
$('body').on('click', '.115offline_batch', function() {
var l = $('.115select:checked').length;
if (l < 10 && !clickOne($('.115offline_batch'))) {
return;
} else if (l < 2 || l > 100) {
toastr.warning('单次选中数量限 <span style="color:red;">2-99</span> 个。', '批量离线操作无效!', { timeOut: 6000 });
return;
} else if (l > 10) {
toastr.info('所选中地址较多,服务器需要较长时间响应,请稍等10s以上,未弹出结果前勿重复点击。', '温馨提示。', { timeOut: 10000 });
if (!clickOne($('.115offline_batch'), 10000)) return;
}
var links = {};
$('.115select:checked').each(function(e) {
links['url[' + e + ']'] = $(this).attr('value');
});
offline.getData(add_urls, links).then(function(json) {
console.log('批量离线任务添加结果:');
console.log(json);
var errNum = json.errcode || json.error_code || '';
if (json.state) {
var s = 0, e = 0, f = 0;
var success_result = [], exist_result = [], all_result = [], fail_result = [];
for (var n = 0; n < json.result.length; n++) {
var dataEl = json.result[n];
if (dataEl.state) {
s++;
success_result.push(dataEl);
all_result.push(dataEl);
} else if (dataEl.errcode == 10008) {
e++;
exist_result.push(dataEl);
all_result.push(dataEl);
} else {
f++;
fail_result.push(dataEl);
}
}
var txt2 = '10秒后显示离线结果。';
var error = fail_result.length > 0 ? fail_result[0].error_msg : '任务已存在';
if (f + e == json.result.length) {
var txt1 = `有 <span style="color:red;">${f + e}</span> 个任务创建失败,原因:${error}。`;
toastr.warning(txt1 + a_list, '批量离线任务添加失败。', { timeOut: 10000 });
} else if (f + e > 0) {
if (e > 0) txt2 = '新建任务' + txt2;
var txt1 = `有 <span style="color:purple;">${s}</span> 个任务创建成功。有 <span style="color:red;">${f + e}</span> 个任务创建失败,原因:${error}。`;
toastr.info(txt1 + txt2 + a_list, '批量离线任务添加成功。', { timeOut: 10000 });
} else {
var txt1 = `有 <span style="color:purple;">${s}</span> 个任务创建成功。`;
toastr.info(txt1 + txt2 + a_list, '批量离线任务添加成功。', { timeOut: 10000 });
}
var success_links = resultMark(success_result, 1);
var exist_links = resultMark(exist_result, 1);
resultMark(fail_result, 2);
if (s + e > 20) {
toastr.warning('离线数量大于20,请自行到115查看。' + a_list, '未查询离线结果!', { timeOut: 6000 });
return;
}
if (s > 0) {
setTimeout(function() {
for (let h = 0; h < s; h++) {
var one = (all_result[0].url == success_links[h]) ? false : true;
var url2 = [{'url': success_links[h]}];
offline.check(success_links[h], url2, one);
}
}, 10000);
}
if (e > 0) {
for (let i = 0; i < e; i++) {
var one = (all_result[0].url == exist_links[i]) ? false : true;
var url2 = [{'url': exist_links[i]}];
offline.check(exist_links[i], url2, one);
}
}
if (f != json.result.length && G.get('open_List')) {
setTimeout(function() {
GM_openInTab('https://115.com/?tab=offline&mode=wangpan', false);
}, 2000);
}
} else if (errNum == 911) {
toastr.warning('账号异常,请验证账号。', '批量离线下载失败!', { timeOut: 5000 });
setTimeout(function() {
verify();
}, 1000);
} else {
toastr.warning(json.error_msg + a_list, '批量离线任务添加失败!', { timeOut: 12000 });
}
}, function(error) {
toastr.error('服务器繁忙,请稍后再试。', '批量离线任务添加异常!');
console.log(error);
});
return false;
});
$('body').on('click', '.115select', function(e) {
if (e.shiftKey) {
var first = $('.115select').index($('.115select:checked').first());
var me = $('.115select').index($(this));
var last = $('.115select').index($('.115select:checked').last());
var Min = Math.min(first, me, last);
var Max = Math.max(first, me, last);
for (var i = Min; i <= Max; i++) {
$('.115select').eq(i).prop('checked', true);
}
}
});
$('body').on('click', '.openList:not([click="1"]), .openFolder:not([click="1"])', function() {
$(this).attr('click', '1');
if ($(this).is('.openList')) {
var txt = 'tab=offline';
} else {
var fID = $(this).attr('data');
var txt = 'cid=' + fID + '&offset=0';
}
GM_openInTab('https://115.com/?' + txt + '&mode=wangpan', false);
return false;
});
$('body').on('contextmenu', '.115offline, .115offline_batch', function(e) {
$('.115menu').css({ left: e.pageX + 'px', top: e.pageY + 'px' });
$('.115menu').show();
var link = $(this).data('href') || '';
if ($(this).is('.115offline_batch')) {
$('.115menu [class^="right_menu0"]').show();
$('.115menu [class^="right_menu1"]').hide();
} else if (/^magnet/i.test(link)) {
$('.115menu').attr('data-href', link);
$('.115menu [class^="right_menu1"]').show();
$('.115menu [class^="right_menu0"]').hide();
} else {
$('.115menu').hide();
GM_setClipboard(link);
toastr.success('下载地址复制成功!');
}
return false;
});
$('body').on('click', '[class^="right_menu0"]', function() {
if ($(this).is('.right_menu00')) {
$('.115select').prop('checked', true);
} else if ($(this).is('.right_menu01')) {
$('.115select').each(function() {
if ($(this).prop('checked')) {
$(this).prop('checked', false);
} else {
$(this).prop('checked', true);
}
});
} else {
if ($('.115select:checked').length == 0) {
toastr.warning('复制失败,未选中任何链接!');
return;
}
var urls = [];
$('.115select:checked').each(function() {
urls.push($(this).attr('value'));
});
GM_setClipboard(urls.join('\r\n'));
toastr.success(urls.length + ' 个下载地址复制成功!');
}
return false;
});
$('body').on('click', '[class^="right_menu1"]', function() {
var link = $(this).parents('.115menu').data('href');
var hash = link.match(/[a-f0-9]{40}/i)[0].toUpperCase();
if ($(this).is('.right_menu11')) {
GM_setClipboard(link);
toastr.success('下载地址复制成功!');
} else if ($(this).is('.right_menu12')) {
GM_openInTab(`https://itorrents.org/torrent/${hash}.torrent`, false);
} else if ($(this).is('.right_menu13')) {
GM_openInTab(`https://btcache.me/torrent/${hash}`, false);
}
return false;
});
if (G.get('offline_Down') && localHref.indexOf('115.com') == -1) {
if (localHref.match(/[0-9]mag\.net|yuhuage/) != null) {
right_menu();
var time1 = setInterval(function() {
offline.addButton();
if ($('.115offline').length >= 20) {
clearInterval(time1);
}
}, 500);
setTimeout(function() {
offline.addSelect();
$('.mag1').remove();
clearInterval(time1);
}, 5000);
} else if (localHref.match(/www\.gying\./) != null) {
right_menu();
if (localHref.match(/\/bt\//) != null) {
setTimeout(function() {
offline.addLink();
offline.addSelect();
}, 500);
} else {
var time2 = setInterval(function() {
if ($('.torrent').length > 0) {
offline.addButton();
offline.addSelect();
clearInterval(time2);
}
if ($('.torrent').length == 0) {
clearInterval(time2);
}
}, 1500);
}
} else {
var time3 = 300;
if (localHref.match(/av/) != null) {
time3 = 3000;
}
setTimeout(function() {
offline.addButton();
if (localHref.match(/av/) != null) {
$('.movie td').removeAttr('onclick');
}
}, time3);
if (G.get('fuzzy_find')) {
setTimeout(function() {
offline.addLink();
}, time3 + 10);
}
setTimeout(function() {
right_menu();
offline.addSelect();
$('.mag1').remove();
}, time3 + 20);
}
}
});
})();