Greasy Fork is available in English.
迅雷#的福音来啦~\(≧▽≦)/~,免VIP,免115浏览器,对了还能在线播放(使用前务必阅读“使用步骤”)
// ==UserScript== // @name 115批量文件迅雷下载(暂不支持文件夹类型下载) // @namespace sscozak // @include *://115.com/?ct=file* // @version 1.3.8.3 // @run-at document-end // @grant none // @description 迅雷#的福音来啦~\(≧▽≦)/~,免VIP,免115浏览器,对了还能在线播放(使用前务必阅读“使用步骤”) // @compatible firefox // @compatible chrome // ==/UserScript== // ======================================= Monkey插件兼容处置 ============================================= const RWD = window.parent; const RWDs = "window.parent"; const RDM = RWD.document; const RDMs = RWDs+".document"; // ======================================= XunLei下载 ============================================= RWD.Core.FileAPI.Thunder = { // 存放URL列表及相关维护操作 thunder_urls : [], thunder_table : null, thunder_counter : null, thunder_total : 0, thunderClear : function() { var len = this.thunder_urls.length; this.thunder_urls.splice(0,len); this.thunder_table = null; this.thunder_counter = null; this.thunder_total = 0; }, // 更新窗口URL列表 thunderUpdateTable : function(r) { if (this.thunder_table) { var row = this.thunder_table.insertRow(); row.style["white-space"]="nowrap"; // 内容水平展开,不自动换行 var cell = row.insertCell(); cell.align = "left"; cell.innerHTML = r.file_name; var cell = row.insertCell(); cell.align = "left"; cell.innerHTML = r.file_url; } if (this.thunder_counter) { this.thunder_counter.innerHTML = '['+this.thunder_urls.length+'/'+this.thunder_total+']'; } }, thunderPushURL : function(url) { this.thunder_urls.push(url); }, thunderHelperBeacon : "", thunderCheckHelper : function() { this.thunderHelperBeacon = ""; var helper = RDM.querySelectorAll("thunderapihelper"); if (0 === helper.length) { return false; } this.thunderHelperBeacon = helper[0].innerHTML; return true; }, thunderBuildTaskWithCookie : function() { var len = this.thunder_urls.length; if (0 >= len) { alert("URL列表为空。。"); return; } // 携带Cookie下载(请确保已安装addon:ThunderAPIHelper_WebExt) var urls = this.thunder_urls; var links = []; for (var i = 0; i < len; i++) { links.push(urls[i].file_url); } var link_container = RDM.getElementById("ID_link_container"); link_container = link_container ? link_container : RDM.createElement("ThunderLinksContainer"); link_container.setAttribute("id", "ID_link_container"); link_container.setAttribute("hrefs", JSON.stringify(links)); RDM.documentElement.appendChild(link_container); var evt = RDM.createEvent("Events"); evt.initEvent(this.thunderHelperBeacon, true, false); link_container.dispatchEvent(evt); }, thunderBuildTaskWithoutCookie : function() { var len = this.thunder_urls.length; if (0 >= len) { alert("URL列表为空。。"); return; } // 裸链接下载(无cookie) var urls = this.thunder_urls; var pid = 66666; // 迅雷合作ID(随意) BatchTasker.BeginBatch(4,pid); //开始批量添加 for (var i = 0; i < len; i++) { BatchTasker.AddTask(ThunderEncode(urls[i].file_url), urls[i].file_name); //添加下载任务 } BatchTasker.EndBatch(pid); }, // 启动下载 thunderLaunch : function() { // 判断迅雷NPAPI插件是否存在,若存在则调用原JS方法,否则调用ThunderAPIHelper扩展提供的JS接口 if (navigator.mimeTypes['application/np_xunlei_plugin'] || navigator.mimeTypes['application/np_xunlei_plugin.2']) { this.thunderBuildTaskWithoutCookie(); } else if (this.thunderCheckHelper()) { this.thunderBuildTaskWithCookie(); } else if (confirm("当前浏览器不支持迅雷NPAPI插件," +"请安装ThunderAPIHelper扩展," +"详情留意Greasyfork上的脚本说明")) { var greasyfork = "https://greasyfork.org/zh-CN/scripts/28050-115%E6%89%B9%E9%87%8F%E6%96%87%E4%BB%B6%E8%BF%85%E9%9B%B7%E4%B8%8B%E8%BD%BD-%E6%9A%82%E4%B8%8D%E6%94%AF%E6%8C%81%E6%96%87%E4%BB%B6%E5%A4%B9%E7%B1%BB%E5%9E%8B%E4%B8%8B%E8%BD%BD"; //document.location = greasyfork; RWD.open(greasyfork,"_blank"); } }, // 批量复制链接 thunderCopyToClipboard : function() { var len = this.thunder_urls.length; if (0 >= len) { alert("URL列表为空。。"); return; } var urls = this.thunder_urls; var urls_content = ''; for (var i = 0; i < urls.length; i++) { urls_content += urls[i].file_url+'\r\n'; } var url_clipboard = RDM.getElementById('ID_url_clip'); url_clipboard.innerHTML = urls_content; // 选取并复制URLs RWD.$(url_clipboard).focus(); RWD.$(url_clipboard).select(); if (RDM.execCommand('copy', false, "")) { alert("已复制 "+urls.length+" 条链接至剪切板"); } else { alert("复制失败,请留言至GreasyFork反馈,谢谢"); } }, // 预加载子窗口框架页面 thunderPreloadFramePage : function() { var stylePatcher = function(obj, attr_nm, attr_vl) { for (var i = 0; i < attr_nm.length; i++) { obj.style[attr_nm[i]] = attr_vl[i]; } }; // 子窗口 var url_wdw = RDM.createElement('div'); url_wdw.id = "ID_url_wdw"; url_wdw.className = 'dialog-box dialog-mini easy-download window-current'; stylePatcher(url_wdw, ['z-index', 'width', 'position', 'top', 'left', 'display'], ['1000000002', '50%', 'fixed', '15%', '25%', 'none']); RDM.body.appendChild(url_wdw); // 构建列表页面 var html = []; html.push('<div class="dialog-box dialog-mini easy-download window-current" style="z-index: 1000000002; ' +'width: 50%; height:60%; position: fixed; top: 15%; left: 25%;">'); html.push('<div class="dialog-header" rel="title_box" ws_property="1">' +'<div style="float:left"><h3 rel="base_title">115迅雷小工具</h3></div>' +'<div id="ID_thunder_counter"></div>' +'</div>'); html.push('<div class="dialog-handle"><a href="javascript:;" class="close" id="ID_thunder_close">关闭</a></div>'); html.push('<div id="ID_thunder_context" rel="base_content" style="height:85%"></div></div>'); // 神隐的复制板 html.push('<textarea id="ID_url_clip" style="width:1px;height:1px;border-style:none;"></textarea>'); // 插入HTML文本 url_wdw.innerHTML = (function(){ var res = ''; for (var i = 0; i < html.length; i++) { res += html[i]; } return res; })(); // 背景蒙版 var bk_mask = RDM.createElement('div'); bk_mask.id = "ID_bk_mask"; stylePatcher(bk_mask, ['z-index', 'background', 'height', 'left', 'position', 'top', 'width', 'opacity', 'display'], ['1000000001', 'rgb(0, 0, 0)', '100%', '0px', 'fixed', '0px', '100%', '0.4', 'none']); RDM.body.appendChild(bk_mask); var bk_mask_inner = RDM.createElement('div'); stylePatcher(bk_mask_inner, ['height', 'width'], ['100%', '100%']); bk_mask.appendChild(bk_mask_inner); // 设置关闭窗口按钮事件 var btn_close = RDM.getElementById('ID_thunder_close'); btn_close.onclick = Function('(function(){'+RDMs+'.getElementById("ID_bk_mask").style["display"]="none";' +''+RDMs+'.getElementById("ID_url_wdw").style["display"]="none";' +''+RDMs+'.getElementById("ID_thunder_context").innerHTML="";' +'})()'); return url_wdw; }, // 装填子窗口内容 thunderShowPageWithContext : function(context, callback) { var url_wdw = RDM.getElementById('ID_url_wdw'); url_wdw = url_wdw?url_wdw:this.thunderPreloadFramePage(); var bk_mask = RDM.getElementById('ID_bk_mask'); url_wdw.style["display"] = ""; bk_mask.style["display"] = ""; var ctx = RDM.getElementById('ID_thunder_context'); ctx.innerHTML = context, callback&&callback(); }, // 显示资源链接列表 thunderShowLinks : function() { // 文件链接显示列表 var html = []; html.push('<div id="ID_thunder_links" style="height:100%"><div class="dialog-frame" style="height:100%; overflow:scroll;">'); html.push('<table id="ID_thunder_table" style="height:auto" border="1" cellspacing="20"></table></div>'); // 按钮 html.push('<div style="height:20%">' // 开始下载 +'<a href="javascript:;" class="button btn-green" style="width:50%; padding:unset" onclick="Core.FileAPI.Thunder.thunderLaunch()">' +'<i class="icon ico-normal"></i><em>开始下载</em></a>' // 复制链接 +'<a href="javascript:;" class="button btn-blue" style="width:50%; padding:unset" onclick="Core.FileAPI.Thunder.thunderCopyToClipboard()">' +'<i class="icon ico-normal"></i><em>复制链接</em></a>' +'</div></div>'); var context; context = (function(){ var res = ''; for (var i = 0; i < html.length; i++) { res += html[i]; } return res; })(); this.thunderShowPageWithContext(context, ()=>{ // 获取列表Table RWD.Core.FileAPI.Thunder.thunder_table = RDM.getElementById('ID_thunder_table'); RWD.Core.FileAPI.Thunder.thunder_counter = RDM.getElementById('ID_thunder_counter'); }); }, // 在线播放视频(网页播放器,目前兼容性不好,暂搁置) thunderPlayVideoOnWeb : function(url) { var html = []; //html.push('<video id="ID_thunder_player" style="height:100%;width:100%" controls="controls" preload="auto" src=""></video>'); html.push('<embed id="ID_thunder_player" src="" type="audio/x-pn-realaudio-plugin" height="100%" width="100%"/>'); var context; context = (function(){ var res = ''; for (var i = 0; i < html.length; i++) { res += html[i]; } return res; })(); this.thunderShowPageWithContext(context, ()=>{ RDM.getElementById('ID_thunder_player').src = url; }); }, }; // ======================================= 在线点播 ============================================= RWD.Core.FileAPI.Player = { VideoList : [], VideoTypes : ['mp4','avi','rmvb','rm','3gp','wmv','mov','mp3','flv','mpeg','mkv','f4v','mpg','dat'], GetFileType : function(file_name) { return file_name.split('.').pop(); }, CheckVideoType : function(type_name) { var video_types = this.VideoTypes; for (var idx = 0; idx < video_types.length; ++idx) { if (type_name === video_types[idx]) { return true; } } return false; }, AddVideoButtonForItem : function() { const DM = RWD.frames["wangpan"].document; var items = DM.querySelectorAll("li[rel='item'][file_type='1']"); for (var idx = 0; idx < items.length; ++idx) { if (this.CheckVideoType(this.GetFileType(items[idx].attributes.title.value))) { var opdv = items[idx].querySelector("div.file-opr")||items[idx].querySelector("span.file-name"); var aplay = '<a href="javascript:;" menu="play_one" onclick="window.parent.Core.FileAPI.Player.PlayOne(this)">' +'<i class=""></i>' +'<span>播放</span>' +'</a>'; opdv.innerHTML += aplay; } } }, AddVideoButtonForBar : function() { const DM = RWD.frames["wangpan"].document; // 获取当前被选中的文件 var items = DM.querySelectorAll('li[rel=\'list\'], li[rel=\'item\'][file_type=\'1\'].' + "selected"); // 筛选其中可以播放的文件 this.VideoList.splice(0, this.VideoList.length); // 清空上次的信息 for (var idx = 0; idx < items.length; ++idx) { if (this.CheckVideoType(this.GetFileType(items[idx].attributes.title.value))) { this.VideoList.push(items[idx]); } } if (0 === this.VideoList.length) { return; } var bar = DM.querySelector("ul"); var aplay = '<li menu="play_all" onclick="window.parent.Core.FileAPI.Player.PlayAll()">' +'<span>播放全部</span>' +'</li>'; bar.innerHTML += aplay; }, // 播放单个文件 PlayOne : function(item_btn_elem) { var item_info_elem = item_btn_elem.parentElement.parentElement; var pick_code = item_info_elem.attributes.pick_code.value; RWD.Core.FileAPI.RequestFileURL(pick_code, ((r)=>{ RWD.Core.FileAPI.Player.PlayVideo([{title:r.file_name,url:r.file_url}]); })); }, // 批量播放 PlayAll : function() { if (0 === this.VideoList.length) { return; } const video_count = this.VideoList.length; var remain = video_count; var play_list = new Array(video_count); var unplayed = true; var timer_key = 0; var delay_time = 5000; // 设置超时行为 var time_to_play = function() { if (!unplayed) { return; } unplayed = false; var ready_list = []; for (var idx = 0; idx < video_count; ++idx) { if (play_list[idx]) { ready_list.push(play_list[idx]); } } RWD.Core.FileAPI.Player.PlayVideo(ready_list); }; // 异步请求播放文件URL for (var idx = 0; idx < video_count; ++idx) { const idc = idx; // 保存当前文件任务的ID,必须使用Const类型 RWD.Core.FileAPI.RequestFileURL(this.VideoList[idx].attributes.pick_code.value,( (r)=>{ play_list[idc] = {title:r.file_name,url:r.file_url}; // 检查是否已获取全部url RWD.clearTimeout(timer_key); // 取消当前延时 if (!unplayed) { return; } else if (--remain === 0) { unplayed = false; RWD.Core.FileAPI.Player.PlayVideo(play_list); } else { // 重设延时器 timer_key = RWD.setTimeout(time_to_play,delay_time); } })); } // 设置超时 timer_key = RWD.setTimeout(time_to_play,delay_time); }, // 生成ASX文件调用本地PotPlayer PlayVideo : function(video_infos) { if (0 === video_infos.length) { return; } console.log("Ready to play: "+video_infos.length); console.log(video_infos); var hrefs = '<ASX Version="3.0">'; for (var i = 0; i < video_infos.length; ++i) { hrefs += '<Entry>'; if (video_infos[i].title) { hrefs += '<Title>' + video_infos[i].title + '</Title>'; } hrefs += '<Ref href ="' + video_infos[i].url + '" />'; hrefs += '</Entry>'; } hrefs += '</ASX>'; var asx_content = [hrefs]; var asx_blob = new Blob(asx_content,{'type':'video/x-ms-asf-plugin'}); // 由关联ASX文件的程序调用 var url = URL.createObjectURL(asx_blob); // 提供blob对象的url地址 location.href = url; // 等效于将url直接输入于地址栏,播放视频 }, }; // ====================================== 工具函数 ============================================== // 异步请求文件URL RWD.Core.FileAPI.RequestFileURL = function(pick_code, callback) { var _ = function () { RWD.UA$.ajax({ url: 'files/download?pickcode=' + pick_code, type: 'GET', dataType: 'json', cache: false, success: function (r) { callback&&callback(r); } }) }; _(); return; } // ===================================== 注入 =============================================== // 替换原函数,直接根据pickcode请求资源URL RWD.Core.FileAPI.Download = function (pick_code, win) { this.RequestFileURL(pick_code, ((r)=>{ //alert("URL: "+r.file_url); RWD.Core.FileAPI.Thunder.thunderPushURL(r); RWD.Core.FileAPI.Thunder.thunderUpdateTable(r); })); }; // 替换原函数,对所有选中的文件(不含文件夹)进行URL获取 RWD.Core.FileAPI.DownloadSomeFile = function (list) { if (!list.length) { RWD.Core.MinMessage.Show({ text: '请选择文件', type: 'war', timeout: 2000 }); return; } var TypeFilter = function(list) { var file_list = []; for (var i = 0; i < list.length; i++) { if (list[i].attr('file_type') == '1') { file_list.push(list[i]); } } return file_list; } list = TypeFilter(list); if (0 === list.length) { alert("当前无法下载文件夹类型..."); return; } RWD.Core.FileAPI.Thunder.thunderClear(); RWD.Core.FileAPI.Thunder.thunderShowLinks(); RWD.Core.FileAPI.Thunder.thunder_total = list.length; for (var i = 0; i < list.length; i++) { RWD.Core.FileAPI.Download(list[i].attr('pick_code')); } }; // ======================================= 初始化 ============================================= // 加载迅雷JS库 (function(){ var getScriptSync = function(url) { RWD.$.ajax({ url: url, async: false, dataType: "script" }); }; getScriptSync('http://pstatic.xunlei.com/js/webThunderDetect.js'); getScriptSync('http://pstatic.xunlei.com/js/base64.js'); getScriptSync('http://pstatic.xunlei.com/js/thunderBatch.js'); })(); // 监听iframe载入 (function(){ var sub_wind = RDM.querySelector("iframe[rel='wangpan']"); sub_wind.onload = (function(){ // 设置观察器 var DM = RWD.frames["wangpan"].document; DM.item_bar_observer = new MutationObserver((function(e){RWD.Core.FileAPI.Player.AddVideoButtonForBar();})); DM.item_bar_observer.observe(DM.querySelector('#js_operate_box'),{'childList':true}); DM.item_list_observer = new MutationObserver((function(e){RWD.Core.FileAPI.Player.AddVideoButtonForItem();})); DM.item_list_observer.observe(DM.querySelector('#js_data_list'),{'childList':true}); }); })();