Greasy Fork is available in English.

115批量文件迅雷下载(暂不支持文件夹类型下载)

迅雷党的福音来啦~\(≧▽≦)/~,免VIP,免115浏览器,对了还能在线播放(使用前务必阅读“使用步骤”)

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==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});
    });
})();