// ==UserScript== // @name KTXP&dmhyTorrentLinkToMagnet // @namespace http://KTXP&dmhyTorrentLinkToMagnet/ // @version 3.3 // @description 将dmhy的超长磁链换成btih为40个字符长度的磁链,对另外两个站的列表页新增磁力链接 PS:沿用这个脚本并不是因为我认为bt.acg.gg或www.miobt.com跟极影有任何关系,只是受众有重叠 // @match http://bt.acg.gg/* // @match http://www.miobt.com/* // @match http://miobt.com/* // @match https://share.dmhy.org // @match https://share.dmhy.org/topics/list* // @require http://code.jquery.com/jquery-1.9.0.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/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 // @downloadURL none // ==/UserScript== jQuery().ready(function(){ jQuery.noConflict(); var isShowTorrent = JSON.parse(getSTCheck()); var link; var switchy; var copyimg = "https://jmnsy.github.io/black-tie-bold-2f74f123f4edd720c202dbfac55ab2a8454e5785fddb6975b2d8d1d0ebc6f45f.png"; var thisurl = window.location.href; //适配天国的极影列表页 if(jQuery(".quick-down").length > 0){ link = jQuery(".quick-down"); switchy = 1; } //适配花园列表页 else if(jQuery(".download-arrow[title='磁力下載']").length > 0){ jQuery(".jmd").hide(); 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"); } } //修改表头 jQuery("span.title").eq(3).parent().attr("width","6%"); if(isShowTorrent){ jQuery("span.title").eq(3).text("磁鏈 種子"); } link = jQuery(".download-arrow[title='磁力下載']"); var checkall = jQuery("",{type:"checkbox",id:"checkAll",title:"全選"}); //在表头添加全选复选框 jQuery("span.title").eq(3).before(checkall).parent(); //对全选复选框和其他复选框监听变更事件 jQuery("#checkAll").on("change",checkAll); jQuery(".checkMagnet").on("change",checkThis); switchy = 0; requestNoReferer(copyimg,'image/png',dmhyAddOperation); Mousetrap.stopCallback = function () { return false; }; Mousetrap.bind(getAppendShortCut(), addLocalStorage); Mousetrap.bind(getDeleteShortCut(), clearLocalStorageAndClipboard); Mousetrap.bind(getCopyShortCut(), copyMagnet); Mousetrap.bind(getSettingsShortCut(), showSettingDiv); var pageControl = jQuery("a:contains('下一頁')"); if(pageControl.length == 0){ pageControl = jQuery("a:contains('上一頁')"); } for(var i in pageControl){ if(i >= 0){ addGoToPair(i,pageControl.eq(i)); } } } //适配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)){ switchy = 2; } else if(/http[s]?:\/\/(www.)?miobt.com\/.*/.test(thisurl)){ switchy = 3; //我自己画的,有意见你就帮我画一个 //对miobt.com中,由该脚本新增的链接添加样式,使链接有足够面积被点击,并以有明显意义的图标作为背景 requestNoReferer("https://jmnsy.github.io/magnet.gif",'image/gif',mioAddMagnetIcon); } } //对列表页表格中的每一行 if(link != null){ link.each(function(){ 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","種子下載"); //获得当前资源磁链 str = jQuery(this).attr("href"); //获得当前资源发布日期时间 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); //解码后编码为HEX var b16 = base32ToHex(b32); //构成磁链 magnet = "magnet:?xt=urn:btih:" + b16;//b32;// if(JSON.parse(getHTCheck())){ magnet = magnet + tracker; } //构成种子链 var torrentLink = "//dl.dmhy.org/" + date + "/" + b16.toLowerCase() + ".torrent"; //把种子下载链接的href置为种子链 temp.attr("href",torrentLink); var check = jQuery("",{type:"checkbox",class:"checkMagnet",value:magnet}); //把磁链的href置为16位磁链,在磁链图标后加入种子下载图标 var magnetArrow = jQuery(this).attr("href",magnet).attr("data-tracker",tracker); magnetArrow.before(check); if(isShowTorrent){ 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 a = jQuery("",{href:magnet,class:"magnet"}); var icon = jQuery("",{src:"http://bt.acg.gg/images/icon_magnet.gif"}); var addEle = a.append(icon); //把整个元素放在资源页链接前 jQuery(this).before(addEle); } else if(switchy == 3){ //从资源页url中切出hex编码hash str = jQuery(this).attr("href").substring(5,45); //构成磁链 magnet = "magnet:?xt=urn:btih:" + str; //新增一个链接元素,插在资源页链接前 var a = jQuery("",{href:magnet,class:"magnet"}); jQuery(this).before(a); } }); } }); function addGoToPair(index,ele){ var href = ele.get(0).href; var prefix = href.substring(0,href.lastIndexOf("/page/")+6); var suffix = href.substring(href.lastIndexOf("?")); suffix = (suffix == href?"":suffix); var id = "index" + index; var input = jQuery("",{type:'number',min:'1',placeholder:'前往頁碼',id:id,width:'70px',height:'12px'}).on("keydown",function(event){ if(event.keyCode == 13){ eval(jQuery("#goto"+id).attr("href")); } }); var goto = jQuery("",{id:"goto"+id,href:'javascript:var pageNum = jQuery("#'+id+'").val();window.location.href = "'+prefix+'"+pageNum+"'+suffix+'";'}).text("前 往"); ele.eq(0).parent().append(jQuery("").text(" ")).append(input).append(jQuery("").text(" ")).append(goto); } //dmhy站的操作图标返回后调用的回调函数 function dmhyAddOperation(responseDetails) { var imgBin = responseDetails; var base64 = customBase64Encode(responseDetails.responseText); copyimg = "data:image/png;base64," + base64; var copyIt = jQuery("
",{id:"copySelectedMagnet",title:"多行複製",class:"controlIcon"}).on("click",copyMagnet).css({ "background":"url(" + copyimg + ") -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(" + copyimg + ") -85px -45px"}).attr({"id":"addSelectedMagnet","title":"追加磁鏈"}).on("click",addLocalStorage); var clearIt = copyIt.clone().css({"bottom":"160px","background":"url(" + copyimg + ") -565px -45px"}).attr({"id":"clearMagnet","title":"清空剪貼簿"}).on("click",clearLocalStorageAndClipboard); var settings = copyIt.clone().css({"bottom":"55px","background":"url(" + copyimg + ") -525px -45px"}).attr({"id":"settingIcon","title":"设定"}).on("click",showSettingDiv); if(JSON.parse(getCVCheck())){ jQuery("body").append(copyIt).append(addIt).append(clearIt).append(settings); } } //显示设置 function showSettingDiv(){ if(jQuery("#settingDiv").length == 0){ var all = jQuery("
",{id:"settingDiv"}).css({ "background":"#FFF", "width":"300px", "height":"200px", "position":"fixed", "bottom":"20px", "right":"50px"}); all.appendTo(jQuery("body")); var title = jQuery("
",{id:"settingDivTitle"}).css({ "background":"#247", "color":"#fff", "width":"290px", "height":"20px", "position":"fixed", "bottom":"195px", "right":"55px"}).text("设定").appendTo(all); var main = jQuery("#settingDivTitle").clone().attr("id","settingMain").css({ "background":"#cdf", "height":"168px", "color":"#000", "bottom":"25px" }).text("").appendTo(all); var closeIcon = jQuery("").text("(X)").css({ "float":"right" , "margin":"2px", "color":"#fff", "cursor":"pointer"}) .on("click",saveAndClose).appendTo(title); //配置項 var appenddiv = jQuery("
",{id:"appendSC"}).css({"margin":"2px"}); var appendlabel = jQuery("").attr("id","appendLabel").css({"width":"65px","display":"inline-block"}).text("追加磁鏈:"); var appendinput = jQuery("",{id:"appendInput",type:"text"}).css("width","80px").val(getAppendShortCut()); appenddiv.append(appendlabel).append(appendinput).appendTo(main); //多層元素必須一次添加 var deletediv = jQuery("
",{id:"deleteSC"}).css({"margin":"2px"}); var deletelabel = jQuery("").attr("id","deleteLabel").css({"width":"65px","display":"inline-block"}).text("清空剪貼簿:"); var deleteinput = jQuery("",{id:"deleteInput",type:"text"}).css("width","80px").val(getDeleteShortCut()); deletediv.append(deletelabel).append(deleteinput).appendTo(main); var copydiv = jQuery("
",{id:"copySC"}).css({"margin":"2px"}); var copylabel = jQuery("#deleteLabel").clone().attr("id","copyLabel").text("多行複製"); var copyinput = jQuery("#deleteInput").clone().attr("id","copyInput").val(getCopyShortCut()); copydiv.append(copylabel).append(copyinput).appendTo(main); var settingsdiv = jQuery("
",{id:"settingsSC"}).css({"margin":"2px"}); var settingslabel = jQuery("#deleteLabel").clone().attr("id","settingsLabel").text("设定"); var settingsinput = jQuery("#deleteInput").clone().attr("id","settingsInput").val(getSettingsShortCut()); settingsdiv.append(settingslabel).append(settingsinput).appendTo(main); var showtorrentdiv = jQuery("
",{id:"showTD"}).css({"margin":"2px"}); var showtorrentlabel = jQuery("#deleteLabel").clone().attr("id","STLabel").css("width","80px").text("顯示種子鏈"); var showtorrentcheck = jQuery("#deleteInput").clone().attr({id:"STCheck",type:"checkbox",checked:JSON.parse(getSTCheck())}); showtorrentdiv.append(showtorrentlabel).append(showtorrentcheck).appendTo(main); var hastrackerdiv = jQuery("
",{id:"hasTracker"}).css({"margin":"2px"}); var hastrackerlabel = jQuery("#deleteLabel").clone().attr("id","HTLabel").css("width","80px").text("磁鏈帶Tracker"); var hastrackercheck = jQuery("#STCheck").clone().attr({id:"HTCheck",checked:JSON.parse(getHTCheck())}); hastrackerdiv.append(hastrackerlabel).append(hastrackercheck).appendTo(main); var controlVisiblediv = jQuery("
",{id:"controlVisible"}).css({"margin":"2px"}); var controlVisiblelabel = jQuery("#deleteLabel").clone().attr("id","CVLabel").css("width","80px").text("显示控件图标"); var controlVisiblecheck = jQuery("#STCheck").clone().attr({id:"CVCheck",checked:JSON.parse(getCVCheck())}); controlVisiblediv.append(controlVisiblelabel).append(controlVisiblecheck).appendTo(main); } else{ saveAndClose(); } } function getCVCheck(){ var controlVisible = localStorage.getItem("controlVisible"); if(isNone(controlVisible)){ controlVisible = "true"; localStorage.setItem("controlVisible",controlVisible); } return controlVisible; } function getHTCheck(){ var hasTracker = localStorage.getItem("hasTracker"); if(isNone(hasTracker)){ hasTracker = "false"; localStorage.setItem("hasTracker",hasTracker); } return hasTracker; } function getSettingsShortCut(){ var settingsSC = localStorage.getItem("settingsSC"); if(isNone(settingsSC)){ settingsSC = "esc"; localStorage.setItem("settingsSC",settingsSC); } return settingsSC; } function getSTCheck(){ var isShow = localStorage.getItem("isShowTorrentLink"); if(isNone(isShow)){ isShow = "true"; localStorage.setItem("isShowTorrentLink",isShow); } return isShow; } function getAppendShortCut(){ var appendSCKey = localStorage.getItem("append"); if(isNone(appendSCKey)){ appendSCKey = "shift+f1"; localStorage.setItem("append",appendSCKey); } return appendSCKey; } function getDeleteShortCut(){ var deleteSCKey = localStorage.getItem("delete"); if(isNone(deleteSCKey)){ deleteSCKey = "shift+f2"; localStorage.setItem("delete",deleteSCKey); } return deleteSCKey; } function getCopyShortCut(){ var copySCKey = localStorage.getItem("copy"); if(isNone(copySCKey)){ copySCKey = "shift+f4"; localStorage.setItem("copy",copySCKey); } return copySCKey; } //关闭并保存设置 function saveAndClose(){ var appendSC = jQuery("#appendInput").val(); var deleteSC = jQuery("#deleteInput").val(); var copySC = jQuery("#copyInput").val(); 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"; Mousetrap.unbind(getAppendShortCut()); localStorage.setItem("append",appendSC); Mousetrap.bind(getAppendShortCut(), addLocalStorage); Mousetrap.unbind(getDeleteShortCut()); localStorage.setItem("delete",deleteSC); Mousetrap.bind(getDeleteShortCut(),clearLocalStorageAndClipboard); Mousetrap.unbind(getCopyShortCut()); localStorage.setItem("copy",copySC); Mousetrap.bind(getCopyShortCut(), copyMagnet); localStorage.setItem("isShowTorrentLink",STFlag); jQuery(".download-arrow[title='磁力下載']").each(function(){ var temp = jQuery(this); if('true'==HTFlag){ temp.attr("href",temp.attr("href")+temp.attr("data-tracker")); } else{ temp.attr("href",temp.attr("href").replace(temp.attr("data-tracker"),"")); } }); localStorage.setItem("hasTracker",HTFlag); localStorage.setItem("controlVisible",CVFlag); jQuery("#settingDiv").remove(); } //mio站的磁链图标返回后调用的回调函数 function mioAddMagnetIcon(responseDetails){ var imgBin = responseDetails; 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(""); jQuery(".checkMagnet:checked").each(function(){ arr[i] = jQuery(this).val(); i += 1; }); var multiMagnet = arr.join("\r\n"); if(confirm("即將進行磁鏈多行複製操作,確認進行?")){ GM_setClipboard(multiMagnet); } } function checkAll(){ jQuery(".checkMagnet").each(function(){ if(jQuery(this).get(0).checked != jQuery("#checkAll").get(0).checked){ jQuery(this).get(0).click(); } }); } function checkThis(){ if(jQuery(this).get(0).checked == false){ jQuery("#checkAll").get(0).checked=false; } else if(jQuery(this).get(0).checked == true && jQuery(".checkMagnet:checked").length == jQuery(".checkMagnet").length){ jQuery("#checkAll").get(0).checked=true; } } function isNone(str){ return str == null || str == ""; } var localMap = {}; function addLocalStorage(){ var i = 0; var arr = new Array(); var multiMagnet = localStorage.getItem("multiMagnet"); jQuery(".checkMagnet:checked").each(function(){ var thisMagnet = jQuery(this).val(); if( localMap[thisMagnet] == undefined){ arr[i] = thisMagnet; localMap[thisMagnet] = true; i += 1; } else if(Object.getOwnPropertyNames(localMap).length == 0){ localArr = localStorage.getItem("multiMagnet").split("\r\n"); for(var j in localArr){ localMap[localArr[j]] = true; } } }); var add = ""; if(confirm("即將追加選中的磁鏈到剪貼簿,確認進行?")){ if(arr.length > 0){ add = arr.join("\r\n"); var clipbordStr = ((multiMagnet == null) || (multiMagnet == "")?"":multiMagnet + "\r\n") + add; localStorage.setItem("multiMagnet",clipbordStr); GM_setClipboard(clipbordStr); } else{ GM_setClipboard(multiMagnet); return; } } } function clearLocalStorageAndClipboard(){ if(confirm("即將清除快取和剪貼簿中的内容,確認進行?")){ localStorage.setItem("multiMagnet",""); GM_setClipboard(""); localMap = {}; } } 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(var 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; }