将dmhy的超长磁链换成btih为40个字符长度的磁链,用于不支持btih为32个字符的磁链的下载渠道,对另外四个站的列表页新增同类的磁力链接,对dmhy和类似miobt的站点提供批量磁链复制,支持跨页复制 PS:沿用这个脚本并不是因为我认为这四个站跟极影有任何关系,只是受众有重叠
// ==UserScript== // @name KTXP&dmhyTorrentLinkToMagnet // @namespace http://KTXP&dmhyTorrentLinkToMagnet/ // @version 3.13 // @description 将dmhy的超长磁链换成btih为40个字符长度的磁链,用于不支持btih为32个字符的磁链的下载渠道,对另外四个站的列表页新增同类的磁力链接,对dmhy和类似miobt的站点提供批量磁链复制,支持跨页复制 PS:沿用这个脚本并不是因为我认为这四个站跟极影有任何关系,只是受众有重叠 // @match http://www.miobt.com/* // @match http://miobt.com/* // @match http://share.dmhy.org/* // @match https://mikanani.me/Home/Classic* // @match https://mikanani.me/Home/Search* // @include /http(s)?:\/\/share.dmhy.org\/.*/ // @include /http:\/\/(www.)?comicat.org\/.*/ // @include /http:\/\/(www.)?kisssub.org\/.*/ // @require https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-y/??jquery/1.9.0/jquery.min.js,mousetrap/1.4.6/mousetrap.min.js // @grant GM_setClipboard // @grant GM_xmlhttpRequest // @connect jmnsy.github.io // @license GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html // @copyright 2014.01.17, JMNSY // ==/UserScript== (function() { 'use strict'; let observer,targetNodeBody; let confirmText = ["即将进行磁链多行复制操作,确认进行?", "即将追加选中的磁链到剪贴板,确认进行?", "即将清除缓存和剪贴板中的内容,确认进行?"]; let copyimg = "https://jmnsy.github.io/black-tie-bold-2f74f123f4edd720c202dbfac55ab2a8454e5785fddb6975b2d8d1d0ebc6f45f.png"; //页面变量,作用范围为两次load之间 var localMap = {}; //如果页面变量中不存在任何变量,即声明后不曾设值,则初始化 if(Object.getOwnPropertyNames(localMap).length === 0 && localStorage.getItem("multiMagnet")!=null){ //把localStorage中的多行磁链切开并为其设置 var localArr = localStorage.getItem("multiMagnet").split("\r\n"); for(var j in localArr){ localMap[localArr[j]] = true; } } jQuery().ready(function(){ doChange(); observer.observe(targetNodeBody, { attributes: true, childList: true, subtree: true }); }); function doChange(){ let debounceFunction; jQuery.noConflict(); var isShowTorrent = JSON.parse(getItemByDefault("isShowTorrentLink","true")); var isShowPikpak = JSON.parse(getItemByDefault("isShowPikpak","true")); var link; var switchy; var thisurl = window.location.href; //适配天国的极影列表页 if(jQuery(".quick-down").length > 0){ link = jQuery(".quick-down"); switchy = 1; } //适配花园列表页 else if(jQuery(".jmd").length > 0 && jQuery(".jmd_base").length > 0){ //对平时显示的节目单进行隐藏 jQuery(".jmd").hide(); //显示平时隐藏的全周节目单,并加上平时节目单的class,用于配合原本样式和可能存在的事件绑定 jQuery(".jmd_base").show().addClass("jmd"); //今天周几,用于节目单中的标黄强调 var nowDay = new Date().getDay(); var TRs = jQuery(".jmd_base >tbody> tr"); //全周节目单从周日开始,遍历整个节目单表格行,分别加上奇偶行类和当天类,用于配合原本样式和可能存在的事件绑定 for(var i in TRs){ if(i == nowDay){ TRs.eq(i).addClass("today"); } if(i % 2 === 0){ TRs.eq(i).addClass("even"); } else{ TRs.eq(i).addClass("odd"); } } //修改表头,加宽磁链的列宽并改变列名 if(isShowTorrent){ jQuery("span.title").eq(3).parent().attr("width","8%"); jQuery("span.title").eq(3).text("磁鏈 種子"); } //获得原本的磁链,这里有整页所有的磁链 link = jQuery(".download-arrow[title='磁力下載']"); //新建全选复选框对象 var checkall = jQuery("<input/>",{type:"checkbox",id:"checkAll",title:"全選"}); //在表头添加全选复选框 if(jQuery("#checkAll").length === 0){ jQuery("span.title").eq(3).before(checkall).parent(); } else{ jQuery("#checkAll").get(0).checked=false; } //对全选复选框和其他复选框监听变更事件 jQuery("#checkAll").on("change",checkAll); confirmText = ["即將進行磁鏈多行複製操作,確認進行?", "即將追加選中的磁鏈到剪貼簿,確認進行?", "即將清除快取和剪貼簿中的内容,確認進行?"]; //link以dmhy的处理方式处理 switchy = 0; //当且仅当勾上显示控件图标选项时,请求图片并加载控件 if(JSON.parse(getItemByDefault("controlVisible","true"))){ //以图片链接,链接类型,回调函数作为参数调用方法发起去掉reffer的请求 //对图片链接进行请求后,把相应内容交由回调函数处理 requestNoReferer(copyimg,'image/png',dmhyAddOperation); } //鼠标按键绑定相应的函数,按键通过函数从localStorage中获取 Mousetrap.stopCallback = function () { return false; }; Mousetrap.bind(getItemByDefault("append","shift+f1"), addLocalStorage); Mousetrap.bind(getItemByDefault("delete","shift+f2"), clearLocalStorageAndClipboard); Mousetrap.bind(getItemByDefault("copy","shift+f4"), copyMagnet); Mousetrap.bind(getItemByDefault("settingsSC","esc"), showDmhySettingDiv); //用可用的上一页下一页链接的href用来拼接跳转目标页的地址 var pageControl = jQuery("a:contains('下一頁')"); //若下一页文本不被链接元素包围 if(pageControl.length === 0){ //尝试上一页文本 pageControl = jQuery("a:contains('上一頁')"); } //如果上面获得了有效的结果,调用函数添加跳转组件 for(i in pageControl){ if(i >= 0){ addGoToPair(i,pageControl.eq(i)); } } if(!isShowPikpak){ jQuery("a.download-pikpak").remove(); } // 创建一个MutationObserver对象,翻页工具翻页后再次渲染页面 observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { // 判断新添加的节点是否是动态创建的div元素 if (mutation.addedNodes[0] && mutation.addedNodes[0].tagName && mutation.addedNodes[0].tagName.toLowerCase() === "tbody") { debounceFunction = debounceFunction === undefined?debounce(doChange,100,false):debounceFunction; debounceFunction() } }); }); targetNodeBody = document.querySelector("#topic_list"); } //适配bt.acg.gg和miobt.com列表页 else if(jQuery(".clear > table#listTable > tbody.tbody > tr[class^='alt'] > td > a[href^='show']").length > 0){ link = jQuery(".clear > table#listTable > tbody.tbody > tr[class^='alt'] > td > a[href^='show']"); if(/http[s]?:\/\/bt.acg.gg\/.*/.test(thisurl)){ //link以bt.acg.gg的处理方式处理 switchy = 2; var headTh = jQuery(".l3"); for(i in headTh){ var newColumn = headTh.eq(i).clone(); newColumn.removeClass("l3").addClass("l31").css("width","65px"); headTh.eq(i).after(newColumn.text("磁链")); } //鼠标按键绑定相应的函数,按键通过函数从localStorage中获取 Mousetrap.stopCallback = function () { return false; }; Mousetrap.bind(getItemByDefault("append","shift+f1"), addLocalStorage); Mousetrap.bind(getItemByDefault("delete","shift+f2"), clearLocalStorageAndClipboard); Mousetrap.bind(getItemByDefault("copy","shift+f4"), copyMagnet); Mousetrap.bind(getItemByDefault("settingsSC","esc"), showGGSettingDiv); } else if(/http[s]?:\/\/(www.)?miobt.com\/.*/.test(thisurl)||/http[s]?:\/\/(www.)?comicat.org\/.*/.test(thisurl)||/http[s]?:\/\/(www.)?kisssub.org\/.*/.test(thisurl)){ //link以miobt系的处理方式处理 switchy = 3; headTh = jQuery(".l3.tableHeaderOver"); newColumn = headTh.clone(); newColumn.removeClass("l3").addClass("l31").css("width","65px"); checkall = jQuery("<input/>",{type:"checkbox",id:"checkAll",title:"全选"}); if(jQuery("#checkAll").length === 0){ headTh.after(newColumn.text("").append(checkall).append("磁链")); } else{ jQuery("#checkAll").get(0).checked=false; } //对全选复选框和其他复选框监听变更事件 jQuery("#checkAll").on("change",checkAll); //鼠标按键绑定相应的函数,按键通过函数从localStorage中获取 Mousetrap.stopCallback = function () { return false; }; Mousetrap.bind(getItemByDefault("append","shift+f1"), addLocalStorage); Mousetrap.bind(getItemByDefault("delete","shift+f2"), clearLocalStorageAndClipboard); Mousetrap.bind(getItemByDefault("copy","shift+f4"), copyMagnet); Mousetrap.bind(getItemByDefault("settingsSC","esc"), showMioSettingDiv); //我自己画的,有意见你就帮我画一个 //对miobt.com中,由该脚本新增的链接添加样式,使链接有足够面积被点击,并以有明显意义的图标作为背景 requestNoReferer("https://jmnsy.github.io/magnet.gif",'image/gif',mioAddMagnetIcon); // 创建一个MutationObserver对象 observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { // 判断新添加的节点是否是动态创建的div元素 if (mutation.addedNodes[0] && mutation.addedNodes[0].tagName && mutation.addedNodes[0].tagName.toLowerCase() === "tr") { debounceFunction = debounceFunction === undefined?debounce(doChange,100,false):debounceFunction; debounceFunction() } }); }); targetNodeBody = document.querySelector("#data_list"); } } //适配蜜柑计划列表页和搜索页 else if(/http[s]?:\/\/mikanani.me\/.*/.test(thisurl)){ link = jQuery("table.table > tbody >tr >td >a >img").parent(); //link以蜜柑计划的处理方式处理 switchy = 4; //当且仅当勾上显示控件图标选项时,请求图片并加载控件 if(JSON.parse(getItemByDefault("controlVisible","true"))){ //以图片链接,链接类型,回调函数作为参数调用方法发起去掉reffer的请求 //对图片链接进行请求后,把相应内容交由回调函数处理 requestNoReferer(copyimg,'image/png',mikanAddOperation); } let bangumiColumn = jQuery("table.table.table-striped > thead >tr >th:contains('番组名')"); bangumiColumn.attr("width",parseInt(bangumiColumn.attr("width").match(/\d+/)[0])-2+"%") headTh = jQuery("table.table.table-striped > thead >tr >th:last"); headTh.attr("width","7%"); checkall = jQuery("<input/>",{type:"checkbox",id:"checkAll",title:"全选"}).css({"width":"15px","height":"15px"}); if(jQuery("#checkAll").length === 0){ headTh.prepend(checkall); } else{ jQuery("#checkAll").get(0).checked=false; } //对全选复选框和其他复选框监听变更事件 jQuery("#checkAll").on("change",checkAll); //鼠标按键绑定相应的函数,按键通过函数从localStorage中获取 Mousetrap.stopCallback = function () { return false; }; Mousetrap.bind(getItemByDefault("append","shift+f1"), addLocalStorage); Mousetrap.bind(getItemByDefault("delete","shift+f2"), clearLocalStorageAndClipboard); Mousetrap.bind(getItemByDefault("copy","shift+f4"), copyMagnet); Mousetrap.bind(getItemByDefault("settingsSC","esc"), showMikanSettingDiv); // 创建一个MutationObserver对象 observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { // 判断新添加的节点是否是动态创建的div元素 if (mutation.addedNodes[0] && mutation.addedNodes[0].tagName && mutation.addedNodes[0].tagName.toLowerCase() === "tr") { debounceFunction = debounceFunction === undefined?debounce(doChange,100,false):debounceFunction; debounceFunction() } }); }); targetNodeBody = document.querySelector("table.table.table-striped.tbl-border.fadeIn"); var observerTR = new MutationObserver(function(mutations) { mutations.forEach(function(mutationRecord) { jQuery("#checkAll").get(0).checked=false; jQuery(".checkMagnet:checked").each(function(){ jQuery(this).get(0).checked=false; }); }); }); var target = document.querySelector('.js-search-r###lts-row'); if(target != undefined){ observerTR.observe(target, { attributes: true, attributeFilter: ['style'] }); } } //对列表页表格中的每一行 if(link != null){ // 不可使用!==进行两者的比较,因为undefined !== null的值为true link.each(function(){ var temp,str,magnet; if(switchy == 1){ temp = jQuery(this).clone();//原本用于复制一个种子下载图标,链接改为磁链,现在用不上,说到底这个分支目前都不会走 str = jQuery(this).attr("href"); jQuery(this).attr("href",str.substring(0,60)); } else if (switchy === 0){ //复制一个磁链图标并改造为种子下载图标 temp = jQuery(this).clone().removeClass("arrow-magnet").addClass("arrow-torrent").attr("title","種子下載"); if( jQuery(this).data("srcMagnet") == null){ jQuery(this).data("srcMagnet",jQuery(this).attr("href")) } //获得当前资源磁链 str = jQuery(this).data("srcMagnet"); //获得当前资源发布日期时间 var datetime = jQuery(this).parent().parent().children().eq(0).children().eq(0).text(); //获得当前资源发布日期 var date = datetime.substring(0,datetime.lastIndexOf(" ")); var tracker = str.substring(str.indexOf("&")); //获得当前磁链的base32编码hash var b32 = str.split("&")[0].substring(20,52); if(b32 == null){ debounceFunction(); return false; } //解码后编码为HEX var b16 = base32ToHex(b32); //构成磁链 magnet = "magnet:?xt=urn:btih:" + b16;//b32;// //构成种子链 var torrentLink = thisurl.substring(0,thisurl.indexOf("/"))+"//dl.dmhy.org/" + date + "/" + b16.toLowerCase() + ".torrent"; if(JSON.parse(getItemByDefault("hasTracker","false"))){ magnet = magnet + tracker; } var checkboxValue = magnet; if(JSON.parse(getItemByDefault("copyTorrent","false"))){ checkboxValue = torrentLink; } //把种子下载链接的href置为种子链 temp.attr("href",torrentLink); var check = jQuery("<input/>",{type:"checkbox",class:"checkMagnet",value:checkboxValue}).css("margin-bottom","4px"); //把磁链的href置为16位磁链,在磁链图标后加入种子下载图标 var magnetArrow = jQuery(this).attr("href",magnet).attr("data-tracker",tracker); if(magnetArrow.parent().find(".checkMagnet").length === 0){ magnetArrow.before(check); } if(isShowTorrent && magnetArrow.parent().find(".arrow-torrent").length === 0){ magnetArrow.after(temp); } } else if (switchy == 2){ //从资源页url中切出hex编码hash str = jQuery(this).attr("href").substring(5,45); //构成磁链 magnet = "magnet:?xt=urn:btih:" + str; var td = jQuery("<td/>"); check = jQuery("<input/>",{type:"checkbox",class:"checkMagnet",value:magnet}); //新增一个图标,以链接元素包围 var a = jQuery("<a/>",{href:magnet,class:"magnet"}); var icon = jQuery("<img/>",{src:"http://bt.acg.gg/images/icon_magnet.gif"}); var addEle = a.append(icon); if(jQuery(this).parent().parent().find(".checkMagnet").length === 0){ jQuery(this).parent().after(td.append(check).append(a)); } } else if(switchy == 3){ //从资源页url中切出hex编码hash str = jQuery(this).attr("href").substring(5,45); //构成磁链 magnet = "magnet:?xt=urn:btih:" + str; td = jQuery("<td/>"); check = jQuery("<input/>",{type:"checkbox",class:"checkMagnet",value:magnet}); //把整个元素放到后面的td中 a = jQuery("<a/>",{href:magnet,class:"magnet"}); if(jQuery(this).parent().parent().find(".checkMagnet").length === 0){ jQuery(this).parent().after(td.append(check).append(a)); } } else if(switchy == 4){ //从资源页url中切出hex编码hash torrentLink = jQuery(this).prop("href"); //获取磁链 magnet = jQuery(this).parent().parent().find(".magnet-link").data("clipboard-text"); var checkboxValue = magnet; if(JSON.parse(getItemByDefault("copyTorrent","false"))){ checkboxValue = torrentLink; } check = jQuery("<input/>",{type:"checkbox",class:"checkMagnet",value:checkboxValue}).css({"width":"15px","height":"15px"}); if(jQuery(this).parent().find(".checkMagnet").length === 0){ jQuery(this).children().eq(0).css({"margin-left":"2px","height":"15px","width":"20px","margin-bottom":"7px"}); jQuery(this).prepend(check); } } }); } if(jQuery(".checkMagnet")){ //对checkMagnet类的变更事件绑定全选复选框的选中变更函数 jQuery(".checkMagnet").on("change",checkThis); } } //在页面中第index个下一页或者上一页<a/>(ele)后追加用于跳转页面的组件,包括数字输入框和按钮 function addGoToPair(index,ele){ //获取传入元素的href属性 var href = ele.get(0).href; //切出页码前的字符 var prefix = href.substring(0,href.lastIndexOf("/page/")+6); //切出页面参数(搜索参数一类),当href不存在?时,suffix会被赋以href值 var suffix = href.substring(href.lastIndexOf("?")); var showIndex = window.location.href.replace(prefix,"").replace(suffix,""); //当suffix被赋以href值,赋值为空字串 suffix = (suffix == href?"":suffix); //组件的部分id字串 var id = "index" + index; //声明一个输入框,id为index,并绑定enter键按下事件 var input = jQuery("<input/>",{type:'number',min:'1',placeholder:'前往頁碼',id:id,width:'70px',height:'12px',value:showIndex}).on("keydown",function(event){ if(event.keyCode == 13){ //按下enter键则模拟点击旁边的前往按钮 jQuery("#goto"+id).click(); } }); //声明前往按钮,点击更改窗口url var goto = jQuery("<a/>",{id:"goto"+id,href:'#'}).text("前 往").on("click",function(){go(prefix,id,suffix);}); //把两个组件加入到dom树中 if(jQuery("#"+id).length === 0){ ele.eq(0).parent().append(jQuery("<span/>").text(" ")).append(input).append(jQuery("<span/>").text(" ")).append(goto); } } function go(prefix,id,suffix){ //获取旁边的输入框的输入值 var index = jQuery("#"+id).val(); //更改窗口url window.location.href = prefix + index + suffix; } //dmhy站的操作图标返回后调用的回调函数 function dmhyAddOperation(responseDetails,titles,showSettingdivFun) { if(titles == undefined){ titles = ["多行複製","追加磁鏈","清空剪貼簿","设定"]; } if(showSettingdivFun == undefined){ showSettingdivFun = showDmhySettingDiv; } //将返回的图片编码成base64字串 var base64 = customBase64Encode(responseDetails.responseText); var iconsImage = "data:image/png;base64," + base64; //声明图片组件按钮并插入到dom树上 var copyIt = jQuery("<div/>",{id:"copySelectedMagnet",title:titles[0],class:"controlIcon"}).on("click",copyMagnet).css({ "background":"url(" + iconsImage + ") -485px -285px", // "background-size":"contain", "background-repeat":"no-repeat", "padding":"15px 15px", "position":"fixed", "right":"5px", "bottom":"90px", "cursor":"pointer" }); var addIt = copyIt.clone().css({"bottom":"195px","background":"url(" + iconsImage + ") -85px -45px"}).attr({"id":"addSelectedMagnet","title":titles[1]}).on("click",addLocalStorage); var clearIt = copyIt.clone().css({"bottom":"160px","background":"url(" + iconsImage + ") -565px -45px"}).attr({"id":"clearMagnet","title":titles[2]}).on("click",clearLocalStorageAndClipboard); var settings = copyIt.clone().css({"bottom":"55px","background":"url(" + iconsImage + ") -525px -45px"}).attr({"id":"settingIcon","title":titles[3]}).on("click",showSettingdivFun); jQuery("body").append(copyIt).append(addIt).append(clearIt).append(settings); } function mikanAddOperation(responseDetails) { dmhyAddOperation(responseDetails,["多行复制","追加磁链","清空剪贴板","设定"],showMikanSettingDiv); } //对设置界面表单元素进行设值的函数 function setSettingValue(str){ if(jQuery("#settingDiv").length === 1){ jQuery("#appendInput").val(getItemByDefault("append","shift+f1")); jQuery("#deleteInput").val(getItemByDefault("delete","shift+f2")); jQuery("#copyInput").val(getItemByDefault("copy","shift+f4")); jQuery("#settingsInput").val(getItemByDefault("settingsSC","esc")); jQuery("#CFCheck").attr("checked",JSON.parse(getItemByDefault("copyNoConfirm","false"))); if(str == 'mikan' || str == 'dmhy'){ jQuery("#TRCheck").attr("checked",JSON.parse(getItemByDefault("copyTorrent","false"))); jQuery("#CVCheck").attr("checked",JSON.parse(getItemByDefault("controlVisible","true"))); if(str == 'dmhy'){ jQuery("#HTCheck").attr("checked",JSON.parse(getItemByDefault("hasTracker","false"))); jQuery("#STCheck").attr("checked",JSON.parse(getItemByDefault("isShowTorrentLink","true"))); } } } } //显示dmhy的设置界面 function showDmhySettingDiv(){ showSettingDiv(getDmhySettingDiv,dmhySaveAndClose); jQuery("#TRCheck").on("change",function(){ if("true" == (jQuery("#TRCheck:checked").length == 1?"true":"false")){ jQuery("#STCheck").prop("checked",true); } }); jQuery("#STCheck").on("change",function(){ if("false" == (jQuery("#STCheck:checked").length == 1?"true":"false")){ jQuery("#TRCheck").prop("checked",false); } }); setSettingValue("dmhy"); } //显示Mikan的设置界面 function showMikanSettingDiv(){ showSettingDiv(getMikanSettingDiv,mikanSaveAndClose); setSettingValue("mikan"); } //显示acg.gg的设置界面 function showGGSettingDiv(){ showSettingDiv(getGGSettingDiv,ggSaveAndClose); setSettingValue("GG"); } //显示mio的设置界面 function showMioSettingDiv(){ showSettingDiv(getMioSettingDiv,mioSaveAndClose); setSettingValue("mio"); } //显示设置,以获取设置界面html的函数以及界面关闭函数作为参数调用 function showSettingDiv(func1,func2){ //设置界面关闭状态时显示,显示状态时关闭 if(jQuery("#settingDiv").length === 0){ var html = func1(); jQuery(html).appendTo("body"); jQuery("#closeSpan").on("click",func2); } else{ func2(); } } //之前用js写html的我真是太天真了,全改成了好修改的长字符串 //返回mio设置界面html的函数 function getGGSettingDiv(){ var html = getMioSettingDiv().replace("00A1CB","1283AF"); return html; } //返回mio设置界面html的函数 function getMioSettingDiv(){ var html = '<div id="settingDiv" style="background: #ffffff; width: 200px; height: 190px; position: fixed; bottom: 320px; right: 20px;z-index:20;">'+ ' <div id="settingDivTitle" style="background: #00A1CB; color: #ffffff; width: 190px; height: 20px; position: fixed; bottom: 485px; right: 25px;">'+ ' 设定'+ ' <span id="closeSpan" style="float: right; margin: 2px; color: #ffffff; cursor: pointer;">(X)</span>'+ ' </div>'+ ' <div id="settingMain" style="background: #f0f0f0; color: #000000; width: 190px; height: 158px; position: fixed; bottom: 325px; right: 25px;">'+ ' <div id="appendSC" style="margin: 2px;">'+ ' <span id="appendLabel" style="width: 65px; display: inline-block;">追加磁链</span>'+ ' <input id="appendInput" type="text" style="width: 80px;"></div>'+ ' <div id="deleteSC" style="margin: 2px;">'+ ' <span id="deleteLabel" style="width: 65px; display: inline-block;">清空剪贴板</span>'+ ' <input id="deleteInput" type="text" style="width: 80px;"></div>'+ ' <div id="copySC" style="margin: 2px;">'+ ' <span id="copyLabel" style="width: 65px; display: inline-block;">多行复制</span>'+ ' <input id="copyInput" type="text" style="width: 80px;"></div>'+ ' <div id="settingsSC" style="margin: 2px;">'+ ' <span id="settingsLabel" style="width: 65px; display: inline-block;">设定</span>'+ ' <input id="settingsInput" type="text" style="width: 80px;" readOnly unselectable></div>'+ ' <div id="confirmTD" style="margin: 2px;">'+ ' <span id="CFLabel" style="width: 80px; display: inline-block;">复制无需确认</span>'+ ' <input id="CFCheck" type="checkbox" style="width: 80px;" /></div>'+ ' </div>'+ '</div>' ; return html; } //返回dmhy设置界面html的函数,我需要一个美工给我一点建议 function getDmhySettingDiv(){ var html = '<div id="settingDiv" style="background: #ffffff; width: 300px; height: 220px; position: fixed; bottom: 20px; right: 50px;">'+ ' <div id="settingDivTitle" style="background: #224477; color: #ffffff; width: 290px; height: 20px; position: fixed; bottom: 215px; right: 55px;">'+ ' 设定'+ ' <span id="closeSpan" style="float: right; margin: 2px; color: #ffffff; cursor: pointer;">(X)</span>'+ ' </div>'+ ' <div id="settingMain" style="background: #ccddff; color: #000; width: 290px; height: 188px; position: fixed; bottom: 25px; right: 55px;">'+ ' <div id="appendSC" style="margin: 2px;">'+ ' <span id="appendLabel" style="width: 65px; display: inline-block;">追加磁鏈:</span>'+ ' <input id="appendInput" type="text" style="width: 80px;"></div>'+ ' <div id="deleteSC" style="margin: 2px;">'+ ' <span id="deleteLabel" style="width: 65px; display: inline-block;">清空剪貼簿:</span>'+ ' <input id="deleteInput" type="text" style="width: 80px;"></div>'+ ' <div id="copySC" style="margin: 2px;">'+ ' <span id="copyLabel" style="width: 65px; display: inline-block;">多行複製</span>'+ ' <input id="copyInput" type="text" style="width: 80px;"></div>'+ ' <div id="settingsSC" style="margin: 2px;">'+ ' <span id="settingsLabel" style="width: 65px; display: inline-block;">设定</span>'+ ' <input id="settingsInput" type="text" style="width: 80px;" readOnly unselectable></div>'+ ' <div id="showTD" style="margin: 2px;">'+ ' <span id="STLabel" style="width: 80px; display: inline-block;">顯示種子鏈</span>'+ ' <input id="STCheck" type="checkbox" style="width: 80px;" value="shift+f2"></div>'+ ' <div id="copyTD" style="margin: 2px;">'+ ' <span id="TRLabel" style="width: 80px; display: inline-block;">只複製種子鏈</span>'+ ' <input id="TRCheck" type="checkbox" style="width: 80px;" value="shift+f2"></div>'+ ' <div id="confirmTD" style="margin: 2px;">'+ ' <span id="CFLabel" style="width: 80px; display: inline-block;">複製無需確認</span>'+ ' <input id="CFCheck" type="checkbox" style="width: 80px;" value="shift+f2"></div>'+ ' <div id="hasTracker" style="margin: 2px;">'+ ' <span id="HTLabel" style="width: 80px; display: inline-block;">磁鏈帶Tracker</span>'+ ' <input id="HTCheck" type="checkbox" style="width: 80px;" value="shift+f2"></div>'+ ' <div id="controlVisible" style="margin: 2px;">'+ ' <span id="CVLabel" style="width: 80px; display: inline-block;">显示控件图标</span>'+ ' <input id="CVCheck" type="checkbox" style="width: 80px;" value="shift+f2"></div>'+ ' </div>'+ '</div>'; return html; } //返回mikan设置界面html的函数,我需要一个美工给我一点建议 function getMikanSettingDiv(){ var html = '<div id="settingDiv" style="background: #ffffff; width: 300px; height: 220px; position: fixed; bottom: 20px; right: 50px;">'+ ' <div id="settingDivTitle" style="background: #47c1c5; color: #ffffff; width: 290px; height: 20px; position: fixed; bottom: 215px; right: 55px;">'+ ' 设定'+ ' <span id="closeSpan" style="float: right; margin: 2px; color: #ffffff; cursor: pointer;">(X)</span>'+ ' </div>'+ ' <div id="settingMain" style="background: #d8f2f3; color: #000; width: 290px; height: 188px; position: fixed; bottom: 25px; right: 55px;">'+ ' <div id="appendSC" style="margin: 2px;">'+ ' <span id="appendLabel" style="width: 65px; display: inline-block;">追加磁链:</span>'+ ' <input id="appendInput" type="text" style="width: 80px;"></div>'+ ' <div id="deleteSC" style="margin: 2px;">'+ ' <span id="deleteLabel" style="width: 65px; display: inline-block;">清空剪贴板:</span>'+ ' <input id="deleteInput" type="text" style="width: 80px;"></div>'+ ' <div id="copySC" style="margin: 2px;">'+ ' <span id="copyLabel" style="width: 65px; display: inline-block;">多行复制</span>'+ ' <input id="copyInput" type="text" style="width: 80px;"></div>'+ ' <div id="settingsSC" style="margin: 2px;">'+ ' <span id="settingsLabel" style="width: 65px; display: inline-block;">设定</span>'+ ' <input id="settingsInput" type="text" style="width: 80px;" readOnly unselectable></div>'+ ' <div id="copyTD" style="margin: 2px;">'+ ' <span id="TRLabel" style="width: 80px; display: inline-block;">只复制种子链</span>'+ ' <input id="TRCheck" type="checkbox" style="width: 80px;" ></div>'+ ' <div id="confirmTD" style="margin: 2px;">'+ ' <span id="CFLabel" style="width: 80px; display: inline-block;">复制无需确认</span>'+ ' <input id="CFCheck" type="checkbox" style="width: 80px;" ></div>'+ ' <div id="controlVisible" style="margin: 2px;">'+ ' <span id="CVLabel" style="width: 80px; display: inline-block;">显示控件图标</span>'+ ' <input id="CVCheck" type="checkbox" style="width: 80px;"></div>'+ ' </div>'+ '</div>'; return html; } //从localStorage中获取name对应的值,不存在时设为defaultValue并返回defaultValue的值 function getItemByDefault(name,defaultValue){ var item = localStorage.getItem(name); if(isNone(item)){ item = defaultValue; localStorage.setItem(name,defaultValue); } return item; } //快捷键配置的读取和保存,以及新设定快捷键的事件绑定 function shotcutSave(){ //获取设置参数 var appendSC = jQuery("#appendInput").val(); var deleteSC = jQuery("#deleteInput").val(); var copySC = jQuery("#copyInput").val(); var settingsSC = jQuery("#settingsInput").val(); //保存设置到localStorage,重新绑定键盘按键事件 Mousetrap.unbind(getItemByDefault("append","shift+f1")); localStorage.setItem("append",appendSC); Mousetrap.bind(getItemByDefault("append","shift+f1"), addLocalStorage); Mousetrap.unbind(getItemByDefault("delete","shift+f2")); localStorage.setItem("delete",deleteSC); Mousetrap.bind(getItemByDefault("delete","shift+f2"),clearLocalStorageAndClipboard); Mousetrap.unbind(getItemByDefault("copy","shift+f4")); localStorage.setItem("copy",copySC); Mousetrap.bind(getItemByDefault("copy","shift+f4"), copyMagnet); Mousetrap.unbind(getItemByDefault("settingsSC","esc")); localStorage.setItem("settingsSC",settingsSC); } //关闭并保存mio设置 function mioSaveAndClose(){ shotcutSave(); //设置界面的显示逻辑因站点变化而变化 Mousetrap.bind(getItemByDefault("settingsSC","esc"), showMioSettingDiv); var CFFlag = jQuery("#CFCheck:checked").length == 1?"true":"false"; localStorage.setItem("copyNoConfirm",CFFlag); //从dom中移除设置小窗 jQuery("#settingDiv").remove(); } //关闭并保存mio设置 function ggSaveAndClose(){ shotcutSave(); //设置界面的显示逻辑因站点变化而变化 Mousetrap.bind(getItemByDefault("settingsSC","esc"), showGGSettingDiv); //从dom中移除设置小窗 jQuery("#settingDiv").remove(); } //关闭并保存dmhy设置 function dmhySaveAndClose(){ shotcutSave(); var STFlag = jQuery("#STCheck:checked").length == 1?"true":"false"; var HTFlag = jQuery("#HTCheck:checked").length == 1?"true":"false"; var CVFlag = jQuery("#CVCheck:checked").length == 1?"true":"false"; var TRFlag = jQuery("#TRCheck:checked").length == 1?"true":"false"; var CFFlag = jQuery("#CFCheck:checked").length == 1?"true":"false"; Mousetrap.bind(getItemByDefault("settingsSC","esc"), showDmhySettingDiv); localStorage.setItem("isShowTorrentLink",STFlag); //遍历所有磁链箭头 //由于页面ready的时候就在处理磁力链的时候获得tracker并保存在磁链箭头a元素的data-tracker属性中,所以在设置保存的时候就可以处理,立即生效 jQuery(".download-arrow[title='磁力下載']").each(function(){ var temp = jQuery(this); var checkbox = temp.prev(); var magnetHref = temp.attr("href"); var checkboxValue = ""; //如果勾上“复制种子链” if('true'==TRFlag){ checkboxValue = temp.next().attr("href"); } //如果勾上“磁鏈帶Tracker” else if('true'==HTFlag){ //在磁链后带上tracker checkboxValue += temp.attr("data-tracker"); } else{ //把磁链中的tracker用空字串替换 checkboxValue = magnetHref.replace(temp.attr("data-tracker"),""); } //改变磁链箭头前复选框的value checkbox.attr("value",checkboxValue); }); //当且仅当勾上显示控件图标选项时,请求图片并加载控件 if(JSON.parse(CVFlag)){ //以图片链接,链接类型,回调函数作为参数调用方法发起去掉reffer的请求 //对图片链接进行请求后,把相应内容交由回调函数处理 requestNoReferer(copyimg,'image/png',dmhyAddOperation); } else{ jQuery(".controlIcon").remove(); } localStorage.setItem("hasTracker",HTFlag); localStorage.setItem("copyTorrent",TRFlag); localStorage.setItem("copyNoConfirm",CFFlag); localStorage.setItem("controlVisible",CVFlag); //从dom中移除设置小窗 jQuery("#settingDiv").remove(); } //关闭并保存mikan设置 function mikanSaveAndClose(){ shotcutSave(); var CVFlag = jQuery("#CVCheck:checked").length == 1?"true":"false"; var TRFlag = jQuery("#TRCheck:checked").length == 1?"true":"false"; var CFFlag = jQuery("#CFCheck:checked").length == 1?"true":"false"; Mousetrap.bind(getItemByDefault("settingsSC","esc"), showMikanSettingDiv); //遍历所有磁链箭头 //由于页面ready的时候就在处理磁力链的时候获得tracker并保存在磁链箭头a元素的data-tracker属性中,所以在设置保存的时候就可以处理,立即生效 jQuery(".checkMagnet").each(function(){ var checkbox = jQuery(this); var checkboxValue = ""; //如果勾上“复制种子链” if('true'==TRFlag){ checkboxValue = checkbox.parent().prop("href"); } else{ checkboxValue = checkbox.parent().parent().parent().find(".magnet-link").data("clipboard-text"); } //改变磁链箭头前复选框的value checkbox.attr("value",checkboxValue); }); //当且仅当勾上显示控件图标选项时,请求图片并加载控件 if(JSON.parse(CVFlag)){ //以图片链接,链接类型,回调函数作为参数调用方法发起去掉reffer的请求 //对图片链接进行请求后,把相应内容交由回调函数处理 requestNoReferer(copyimg,'image/png',mikanAddOperation); } else{ jQuery(".controlIcon").remove(); } localStorage.setItem("copyTorrent",TRFlag); localStorage.setItem("copyNoConfirm",CFFlag); localStorage.setItem("controlVisible",CVFlag); //从dom中移除设置小窗 jQuery("#settingDiv").remove(); } //mio站的磁链图标返回后调用的回调函数 function mioAddMagnetIcon(responseDetails){ //把磁链图标编码成base64,组成base64图片链,作为class为magnet的a元素的背景图片 var base64 = customBase64Encode(responseDetails.responseText); var imgstr = "data:image/gif;base64," + base64; jQuery("a.magnet").css({"background":"url(" + imgstr + ")","background-size":"contain","background-repeat":"no-repeat","padding-left":"15px"}); } //以url,返回类型和回调函数作为参数调用的函数 //用于不传referer请求,缺点是不会检查文件是否变更过(不会304) function requestNoReferer(url,accept,func){ GM_xmlhttpRequest({ method: 'GET', url: url, headers: { 'User-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36', 'Accept': accept, 'referer':'', }, onload: function(responseDetails){ func(responseDetails); } , overrideMimeType: 'text/plain; charset=x-user-defined' }); } //多行复制,不能跨页复制,不能追加,不可与追加在同一次复制中混用 function copyMagnet(){ var i = 0; var arr = new Array(""); //获取所有勾上class为checkMagnet的checkbox(每行资源所对应的checkbox),遍历 jQuery(".checkMagnet:checked:visible").each(function(){ //获取该checkbox的val,即磁链,放到数组中 arr[i] = jQuery(this).val(); i+=1; }); //把数组以换行回车连接为一个字符串 var multiMagnet = arr.join("\r\n"); //弹出确认对话框,用户选择积极选项时把字符串放入剪贴板 if(JSON.parse(getItemByDefault("copyNoConfirm","false")) || confirm(confirmText[0])){ GM_setClipboard(multiMagnet); } } //全选 function checkAll(){ //获取所有资源所对应的checkbox,遍历 jQuery(".checkMagnet:visible").each(function(){ //当全选复选框与当前复选框的勾选状态不一样时 if(jQuery(this).get(0).checked != jQuery("#checkAll").get(0).checked){ //点击当前复选框 jQuery(this).get(0).click(); } }); } //全选状态的临界状态处理,即全选到差一个全选,以及差一个全选到全选 function checkThis(){ //如果当前checkbox不被勾上 if(jQuery(this).get(0).checked === false){ //全选复选框也不可以被勾上 jQuery("#checkAll").get(0).checked=false; } //如果当前checkbox被勾上并且所有资源所对应的checkbox都被勾上 else if(jQuery(this).get(0).checked === true && jQuery(".checkMagnet:checked:visible").length == jQuery(".checkMagnet:visible").length){ //全选复选框也要被勾上 jQuery("#checkAll").get(0).checked=true; } } function isNone(str){ return str === null || str === ""; } //追加磁链 function addLocalStorage(){ var i = 0; var arr = []; //多行磁链 var multiMagnet = localStorage.getItem("multiMagnet")==null?"":localStorage.getItem("multiMagnet"); //对当前勾选的复选框 jQuery(".checkMagnet:checked:visible").each(function(){ //获取复选框元素的value,每个元素的value都是一条磁链 var thisMagnet = jQuery(this).val(); //如果页面变量和本地存储中都不存在这条磁链对应的值,防重 if( localMap[thisMagnet] === undefined && multiMagnet!=null && multiMagnet.indexOf(thisMagnet)==-1){ //这条磁链插入数组 arr[i] = thisMagnet; //并把页面变量中磁链对应的值设为true localMap[thisMagnet] = true; i += 1; } }); var add = ""; if(JSON.parse(getItemByDefault("copyNoConfirm","false")) || confirm(confirmText[1])){ //对所有不重复的磁链 if(arr.length > 0){ //用回车连接成一个字符串 add = arr.join("\r\n"); //向原有的磁链追加 var clipbordStr = (isNone(multiMagnet)?"":multiMagnet + "\r\n") + add; //写入localStorage并复制 localStorage.setItem("multiMagnet",clipbordStr); GM_setClipboard(clipbordStr); } else{ GM_setClipboard(multiMagnet); return; } } } //清除剪贴板,清除localStorage中的多行磁链,页面变量置空 function clearLocalStorageAndClipboard(){ if(confirm(confirmText[2])){ localStorage.setItem("multiMagnet",""); GM_setClipboard(""); localMap = {}; } } //简单来说就是base32翻译成base2,再翻译成base16 function base32ToHex(str){ if(str.length % 8 !== 0){ return null; } str = str.toLowerCase(); var b32 = {'a':'00000','b':'00001','c':'00010','d':'00011', 'e':'00100','f':'00101','g':'00110','h':'00111', 'i':'01000','j':'01001','k':'01010','l':'01011', 'm':'01100','n':'01101','o':'01110','p':'01111', 'q':'10000','r':'10001','s':'10010','t':'10011', 'u':'10100','v':'10101','w':'10110','x':'10111', 'y':'11000','z':'11001','2':'11010','3':'11011', '4':'11100','5':'11101','6':'11110','7':'11111'}; var b16 = {'0000':'0','0001':'1','0010':'2','0011':'3', '0100':'4','0101':'5','0110':'6','0111':'7','1000':'8', '1001':'9','1010':'a','1011':'b','1100':'c','1101':'d', '1110':'e','1111':'f'}; var bin = ""; var returnStr = ""; for(var i = 0;i < str.length;i++){ bin += b32[str.substring(i,i+1)]; } for(i = 0;i < bin.length;i+=4){ returnStr += b16[bin.substring(i,i+4)]; } return returnStr; } function customBase64Encode (inputStr) { var bbLen = 3, //3字节一组 enCharLen = 4, //3字节转换成4个base64编码字符 inpLen = inputStr.length, //图片str的长度 inx = 0, jnx, //字节读入时使用的下标 keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789+/=", //转换用字符串 output = "", //输出字符串 paddingBytes = 0; //决定最后一组等号的个数 var bytebuffer = new Array (bbLen), //三字节一组 encodedCharIndexes = new Array (enCharLen); //转换成4字符 //对图片str的每一个字节 while (inx < inpLen) { //每次把下标初始化为0,读入三个字节 for (jnx = 0; jnx < bbLen; ++jnx) { //以ascii读入三个字节,存储到数组中 if (inx < inpLen) bytebuffer[jnx] = inputStr.charCodeAt (inx++) & 0xff; //当图片str的长度不为3的倍数时,剩余的位数置零 else{ bytebuffer[jnx] = 0; inx+=1; } } //base64编码第一个字符为第一个字节右移两位 encodedCharIndexes[0] = bytebuffer[0] >> 2; //base64编码第二个字符为第一个字节和00000011b作与运算并左移四位的结果与第二个字节右移四位的结果作并运算 encodedCharIndexes[1] = ( (bytebuffer[0] & 0x3) << 4) | (bytebuffer[1] >> 4); //base64编码第三个字符为第二个字节保留右边4位并左移2位的结果与第三个字节右移6位的结果作并运算 encodedCharIndexes[2] = ( (bytebuffer[1] & 0x0f) << 2) | (bytebuffer[2] >> 6); //base64编码第四个字符为第三个字节保留右边6位 encodedCharIndexes[3] = bytebuffer[2] & 0x3f; paddingBytes = inx - inpLen; switch (paddingBytes) { case 1: encodedCharIndexes[3] = 64; break; case 2: encodedCharIndexes[3] = 64; encodedCharIndexes[2] = 64; break; default: break; // No padding - proceed } for (jnx = 0; jnx < enCharLen; ++jnx) output += keyStr.charAt ( encodedCharIndexes[jnx] ); } return output; } function debounce(func, wait, immediate) { let timeout; return function() { const context = this, args = arguments; const later = function() { timeout = null; if (!immediate) func.apply(context, args); }; const callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(context, args); }; } //update log: //1.修改js的cdn地址 })();