// ==UserScript==
// @name gcbt-预览
// @version 1.1.0
// @namespace https://sleazyfork.org/zh-CN/users/1461640-%E6%98%9F%E5%AE%BF%E8%80%81%E9%AD%94
// @author 星宿老魔
// @description 优化国产BT列表页面样式,添加帖子图片预览和磁力链接获取功能
// @match https://gcbt.net/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=gcbt.net
// @license MIT
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_xmlhttpRequest
// @connect www.rmdown.com
// @connect bt.azvmw.com
// @connect bt.ivcbt.com
// @connect bt.bxmho.cn
// @connect www.82bt.com
// @run-at document-start
// ==/UserScript==
(function(){"use strict";function r(m,e=[],i={}){const t=document.createElement(m);return e.length&&(t.className=e.join(" ")),Object.assign(t,i),t}function S(){return new Promise(m=>{document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>m()):m()})}const h={name:"gcbt-预览",version:"1.1.0",selectors:{postList:"article.post-list",contentArea:".content-area",entryTitle:"h2.entry-title a",metaDate:"li.meta-date time",pagination:"main .numeric-pagination",entryContent:".entry-content, .entry-wrapper, .article-content",imageSelectors:[".entry-content img",".entry-wrapper img"]},cacheTTL:1440*60*1e3,maxPreviewImages:4,concurrentLimit:12,btSites:{generalRules:[{name:"rmdown",pattern:/\/\/www\.rmdown\.com\/link\.php\?hash=([0-9a-z]+)/i,url:m=>`https:${m}`,hashExtractor:/([0-9a-z]{40})/i},{name:"azvmw",pattern:/\/\/bt\.azvmw\.com\/list\.php\?name=([0-9a-z]+)/i,url:m=>`https:${m}`,hashExtractor:/([0-9a-z]{40})/i},{name:"ivcbt",pattern:/\/\/bt\.ivcbt\.com\/list\.php\?name=([0-9a-z]+)/i,url:m=>`https:${m}`,hashExtractor:/([0-9a-z]{40})/i},{name:"bxmho",pattern:/\/\/bt\.bxmho\.cn\/list\.php\?name=([0-9a-z]+)/i,url:m=>`https:${m}`,hashExtractor:/([0-9a-z]{40})/i}],special82bt:{pattern:/\/\/www\.82bt\.com\/(?:cao\.php|dlink\.php)\?hash=([0-9a-z]+)/i,postUrl:"https://www.82bt.com/downt-m.php"}}},v=class v{static init(){this.styleInjected||(this.injectStyles(),this.styleInjected=!0)}static injectStyles(){const i=r("style",[],{id:"gcbt-styles",textContent:'article.post-list{visibility:hidden}.torrent-list-container{width:100%;margin:0;padding:0}.item-container{margin-bottom:15px;border-radius:6px;overflow:hidden;border:1px solid #e1e8ed;box-shadow:0 2px 8px rgba(0,0,0,.05);background:#fff}.item-container:hover{box-shadow:0 4px 12px rgba(0,0,0,.1)}.item-title-row{padding:15px;border-bottom:1px solid #f0f0f0;border-left:4px solid #1890ff;transition:background-color .2s}.item-container:nth-child(odd) .item-title-row{background:#f8f9fa}.item-container:nth-child(even) .item-title-row{background:#f0f8ff}.item-title-row:hover{background:#f0f8ff}.item-title{font-weight:600;color:#333;font-size:15px}.item-title a{color:#333;text-decoration:none}.item-title a:hover{color:#1890ff!important}.item-preview{padding:15px;background:#fff}.item-meta-info{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;padding-bottom:10px;border-bottom:1px dashed #eaeaea}.item-date,.item-size{padding:3px 8px;border-radius:3px;font-size:12px}.item-date{background:rgba(24,144,255,.08)}.item-size{background:rgba(230,126,34,.08);color:#e67e22;font-weight:500}.item-loading{text-align:center;padding:15px;color:#666}#gcbt-image-viewer{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.85);z-index:9999;justify-content:center;align-items:center;flex-direction:column}.gcbt-viewer-close{position:absolute;top:20px;right:20px;color:white;font-size:32px;cursor:pointer;z-index:10000}.gcbt-viewer-img-container{display:flex;justify-content:center;align-items:center;height:100%;width:100%}.gcbt-viewer-img{max-width:90%;max-height:90%;object-fit:contain}.gcbt-nav-btn{position:absolute;top:50%;transform:translateY(-50%);color:white;font-size:36px;cursor:pointer;padding:10px;z-index:10000;user-select:none}.gcbt-nav-btn.prev{left:20px}.gcbt-nav-btn.next{right:20px}.gcbt-viewer-counter{position:absolute;bottom:20px;color:white;font-size:14px;padding:5px 10px;background:rgba(0,0,0,.5);border-radius:4px;z-index:10000}.preview-content{padding:5px}.preview-img-container{display:flex;flex-wrap:wrap;gap:10px;justify-content:flex-start;padding:5px 0;margin:5px 0}.preview-img-wrapper{cursor:pointer;border-radius:4px;overflow:hidden;box-shadow:0 2px 8px rgba(0,0,0,.1);transition:transform .2s}.preview-img-wrapper:hover{transform:translateY(-3px)}.preview-img{width:180px;height:180px;object-fit:cover;border-radius:3px;border:1px solid #ddd}.preview-info-container{margin-top:15px;padding-top:12px;border-top:1px dashed #e1e8ed}.action-bar{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px}.gcbt-magnet-btn{padding:5px 14px;font-size:13px;background:#409eff;color:white;border:none;border-radius:4px;cursor:pointer;box-shadow:0 2px 4px rgba(0,0,0,.1);margin:5px 0}.gcbt-magnet-btn:hover{background:#1890ff!important;box-shadow:0 2px 6px rgba(24,144,255,.2)!important}.magnet-link-container{margin:8px 0;padding:10px 12px;display:none;width:100%;background:#f0f8ff;border-radius:4px;border:1px solid #d0e1f9;font-size:13px;word-break:break-all}.magnet-link-container a{color:#1890ff;text-decoration:none}.rollbar-item.tap-dark,.navbar-button:has(.mdi-brightness-4){display:none!important}body[class*="dark"],html[class*="dark"]{background:#fff!important;color:#333!important}'});document.documentElement.appendChild(i)}static unhidePosts(){const e=document.getElementById("gcbt-styles");e&&(e.textContent=e.textContent?.replace("article.post-list { visibility: hidden; }","")||"")}};v.styleInjected=!1;let x=v;class y{static cleanPage(){document.body.classList.remove("dark","dark-mode","night-mode"),document.documentElement.classList.remove("dark","dark-mode","night-mode"),document.body.style.backgroundColor="#fff",document.body.style.color="#333"}static optimizeListPage(){const e=document.querySelectorAll(h.selectors.postList);if(!e.length)return!1;const i=r("div",["torrent-list-container"]),t=document.querySelector(h.selectors.contentArea);if(!t)return!1;e.forEach(a=>{const p=a.querySelector(h.selectors.entryTitle);if(!p)return;const d=a.querySelector(h.selectors.metaDate),s=a.innerHTML.match(/([0-9.]+\s*(?:MB|GB|M|G))/i),l=s?s[1]:"",c=r("a",[],{href:p.href,target:"_blank",textContent:p.textContent});c.setAttribute("data-thread-url",p.href);const g=r("div",["item-title"]);if(g.appendChild(c),l){const T=r("span",["item-size"],{textContent:`【影片容量】:${l}`});T.style.marginLeft="10px",g.appendChild(T)}const u=r("div",["item-title-row"]);u.appendChild(g);const f=r("span",["item-date"],{textContent:d?d.textContent?.trim().replace(/\s*前$/,""):""}),b=r("div",["item-meta-info"]);b.appendChild(f);const k=r("div",["item-preview"]);d&&k.appendChild(b),k.appendChild(r("div",["item-loading"],{textContent:"🔄 正在加载预览..."}));const L=r("div",["item-container"]);L.append(u,k),i.appendChild(L)});const n=document.querySelector("main"),o=n?n.querySelector(h.selectors.pagination):null;if(t.innerHTML="",t.appendChild(i),o){const a=o.cloneNode(!0);a.style.margin="20px 0 0 0",t.appendChild(a)}return!0}static updateTitleSize(e,i){if(!i)return;const t=e.querySelector(".item-title");if(!t)return;let n=t.querySelector(".item-size");n||(n=r("span",["item-size"]),n.style.marginLeft="10px",t.appendChild(n)),n.textContent=`【影片容量】:${i}`}}const C=class C{static init(){if(this.initialized||document.getElementById("gcbt-image-viewer"))return;const e={images:[],currentIndex:0},i=r("img",["gcbt-viewer-img"]),t=r("div",["gcbt-viewer-counter"]),n=r("div",["gcbt-nav-btn","prev"],{innerHTML:"❮"}),o=r("div",["gcbt-nav-btn","next"],{innerHTML:"❯"}),a=r("div",[],{id:"gcbt-image-viewer"}),p=r("div",["gcbt-viewer-img-container"]),d=r("div",["gcbt-viewer-close"],{innerHTML:"×"});p.appendChild(i),a.append(d,n,o,t,p),document.body.appendChild(a);const s=c=>{if(!e.images.length)return;e.currentIndex=(c+e.images.length)%e.images.length;const g=e.images[e.currentIndex];i.src=g,t.textContent=`${e.currentIndex+1} / ${e.images.length}`;const u=e.images.length>1;n.style.display=o.style.display=u?"block":"none"},l=()=>{a.style.display="none",document.body.style.overflow=""};i.addEventListener("click",c=>c.stopPropagation()),d.addEventListener("click",l),a.addEventListener("click",l),n.addEventListener("click",c=>{c.stopPropagation(),s(e.currentIndex-1)}),o.addEventListener("click",c=>{c.stopPropagation(),s(e.currentIndex+1)}),document.addEventListener("keydown",c=>{a.style.display!=="none"&&(c.key==="Escape"?l():c.key==="ArrowLeft"?s(e.currentIndex-1):c.key==="ArrowRight"&&s(e.currentIndex+1))}),window.gcbtImageViewer={show:(c,g=0)=>{e.images=c,a.style.display="flex",document.body.style.overflow="hidden",s(g)}},this.initialized=!0}static show(e,i=0){window.gcbtImageViewer&&window.gcbtImageViewer.show(e,i)}};C.initialized=!1;let w=C;class z{static fetchPage(e){return new Promise((i,t)=>{GM_xmlhttpRequest({method:"GET",url:e,onload:n=>{if(n.status>=200&&n.status<300){const o=new DOMParser().parseFromString(n.responseText,"text/html");i(o)}else t(new Error(`请求失败,状态码: ${n.status}`))},onerror:n=>t(n),ontimeout:()=>t(new Error("请求超时"))})})}static async fetchMagnetLink(e){const t=(await this.fetchPage(e)).body.innerHTML;let n=t.match(/(magnet:\?xt=urn:btih:[a-f0-9]{40})/i);if(n)return n[0];const o=t.match(/(?:^|:|:|;|;|】|\])\s*([0-9a-zA-Z]{40})/i);if(o)return`magnet:?xt=urn:btih:${o[1]}`;const a=[];for(const d of h.btSites.generalRules){const s=t.match(d.pattern);if(s){const l=d.url(s[0]),c=await this.fetchFromGeneralBtSite(l,d.hashExtractor);c&&a.push(c)}}const p=t.match(h.btSites.special82bt.pattern);if(p){const d=await this.fetchFrom82bt(p[1]);d&&a.push(d)}return a.length>0?a[0]:null}static async fetchFromGeneralBtSite(e,i){try{return new Promise(t=>{GM_xmlhttpRequest({method:"GET",url:e,onload:n=>{if(n.status>=200&&n.status<300){const o=n.responseText.match(i);t(o?`magnet:?xt=urn:btih:${o[1]||o[0]}`:null)}else t(null)},onerror:()=>t(null),ontimeout:()=>t(null)})})}catch(t){return console.error(`[gcbt] 获取BT站点链接失败: ${e}`,t),null}}static async fetchFrom82bt(e){try{return new Promise(i=>{GM_xmlhttpRequest({method:"POST",url:h.btSites.special82bt.postUrl,headers:{Accept:"*/*",Referer:`https://www.82bt.com/dlink.php?hash=${e}`,Origin:"https://www.82bt.com","Content-Type":"application/x-www-form-urlencoded"},data:new URLSearchParams({code:e}).toString(),onload:t=>{if(t.status>=200&&t.status<300){const n=t.responseText.match(/magnet:\?xt=urn:btih:[a-zA-Z0-9]{40}/);if(n)i(n[0]);else{const o=t.responseText.match(/([a-zA-Z0-9]{40})/);i(o?`magnet:?xt=urn:btih:${o[0]}`:null)}}else i(null)},onerror:()=>i(null),ontimeout:()=>i(null)})})}catch(i){return console.error(`[gcbt] 获取82bt链接失败: ${e}`,i),null}}}class E{static async processAll(){const e=document.querySelectorAll(".torrent-list-container a[data-thread-url]"),i=[],t=[];e.forEach(n=>{const o=n.closest(".item-container");o&&this.isInViewport(o)?i.push(n):t.push(n)}),i.forEach(n=>this.processSingle(n)),t.length>0&&setTimeout(()=>{const n=h.concurrentLimit;for(let o=0;o<t.length;o+=n){const a=t.slice(o,o+n);setTimeout(()=>{a.forEach(p=>this.processSingle(p))},Math.floor(o/n)*200)}},300)}static isInViewport(e){const i=e.getBoundingClientRect();return i.top<window.innerHeight&&i.bottom>0}static async processSingle(e){const i=e.closest(".item-container"),t=i?.querySelector(".item-preview");if(!t)return;const n=e.href;let o=GM_getValue(n)||{};const a=Date.now(),p=!o.cacheTimestamp||a-o.cacheTimestamp>h.cacheTTL;try{if(p){const d=await z.fetchPage(n),s={cacheTimestamp:a},l=Array.from(d.querySelectorAll(h.selectors.imageSelectors.join(","))).slice(0,h.maxPreviewImages);s.imgUrls=l.map(f=>f.src||f.getAttribute("data-src")).filter(Boolean);const u=(d.querySelector(h.selectors.entryContent)?.textContent||"").match(/【影片(?:大小|容量)】:([0-9.]+\s*(?:MB|GB|M|G|T|TB))/i);u?.[1]&&(s.filmSize=u[1]),GM_setValue(n,s),o=s}this.renderPreview(t,i,o,n)}catch(d){t.innerHTML="加载预览失败",t.className="item-loading",t.style.color="#f56c6c",console.error(`[gcbt] 加载预览失败: ${n}`,d)}}static renderPreview(e,i,t,n){if(e.innerHTML="",!t.imgUrls||t.imgUrls.length===0){e.textContent="没有找到预览图片";return}const o=r("div",["preview-content"]),a=r("div",["preview-img-container"]);t.imgUrls.forEach((c,g)=>{const u=r("div",["preview-img-wrapper"]),f=r("img",["preview-img"]);f.src=c,u.appendChild(f),u.addEventListener("click",b=>{b.preventDefault(),b.stopPropagation(),w.show(t.imgUrls,g)}),a.appendChild(u)}),o.appendChild(a);const p=r("div",["preview-info-container"]),d=r("div",["action-bar"]),s=r("button",["gcbt-magnet-btn"]);d.appendChild(s);const l=r("div",["magnet-link-container"]);p.append(d,l),o.appendChild(p),e.appendChild(o),s.addEventListener("click",async c=>{c.preventDefault(),c.stopPropagation(),s.textContent="正在获取...",s.disabled=!0,l.innerHTML="",l.style.display="none";try{const g=await z.fetchMagnetLink(n);g?(t.link=g,GM_setValue(n,t),this.displayMagnetLink(l,g)):(l.textContent="未找到有效链接",l.style.display="block",l.style.color="#f56c6c")}catch(g){console.error("[gcbt] 获取磁力链接时出错:",g),l.textContent="获取失败",l.style.display="block",l.style.color="#f56c6c"}finally{s.textContent="重新获取",s.disabled=!1}}),t.link?(this.displayMagnetLink(l,t.link),s.textContent="重新获取"):s.textContent="获取磁力链接",t.filmSize&&y.updateTitleSize(i,t.filmSize)}static displayMagnetLink(e,i){e.innerHTML="";const t=r("a",[],{href:i,textContent:i});i.startsWith("magnet:")?(t.style.cursor="pointer",t.title="点击复制磁力链接",t.addEventListener("click",n=>{n.preventDefault(),navigator.clipboard.writeText(i).then(()=>{const o=t.textContent;t.textContent="已复制!",t.style.color="#52c41a",setTimeout(()=>{t.textContent=o,t.style.color="#1890ff"},2e3)})})):t.target="_blank",e.appendChild(t),e.style.display="block"}}class M{static async run(){console.log("[gcbt] 开始运行"),x.init(),await S();try{y.cleanPage(),document.querySelector(h.selectors.postList)&&y.optimizeListPage()&&(w.init(),await E.processAll())}catch(e){console.error("[gcbt] 脚本执行失败",e)}finally{x.unhidePosts()}}}M.run()})();