您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
패시브 페이지에서 '내 소유'만 보기 토글
// ==UserScript== // @name Baslimbus Owned Toggle // @match https://baslimbus.info/passive // @namespace https://dlwlsdn3642.github.io/ // @description 패시브 페이지에서 '내 소유'만 보기 토글 // @version 1.0.0 // @license MIT // @run-at document-idle // @grant none // @namespace // ==/UserScript== (function () { const SEASON_KIND = 6; const OWNED_LS_KEY = 'selectedIdentities'; const BTN_LABEL_HTML = '<span class="text-xl text-white">내 소유</span>'; const BTN_ID = 'owned-support-btn'; function injectPageScript(js) { const s = document.createElement('script'); s.textContent = js; (document.head || document.documentElement).appendChild(s); s.remove(); } injectPageScript(` (function(){ const SEASON_KIND=${SEASON_KIND}; const OWNED_LS_KEY='${OWNED_LS_KEY}'; const state={on:false,idx:null}; const norm=s=>(s??'').toString().trim().replace(/\\s+/g,'').normalize('NFC'); const loadOwned=()=>{try{return new Set(JSON.parse(localStorage.getItem(OWNED_LS_KEY)||'[]').map(Number).filter(Number.isFinite));}catch{return new Set();}}; async function buildIndex(){ if(state.idx) return state.idx; const map=new Map(); for(let p=0;p<200;p++){ const r=await fetch('https://baslimbus.store/dictionary/paginated/identity?size=100&page='+p,{cache:'no-store'}); if(!r.ok) break; const d=await r.json(); const list=d.list||d; for(const it of (list||[])){ const id=Number(it?.id); if(Number.isFinite(id)) map.set(\`\${norm(it?.character)}|\${norm(it?.name)}|\${it?.season??''}\`,id); } if(d.last===true) break; } state.idx=map; return map; } function isSkill(input,init){ try{ const u=typeof input==='string'?new URL(input,location.origin):new URL(input.url,location.origin); const m=(init&&init.method)?String(init.method).toUpperCase():'GET'; return m==='GET'&&u.pathname.startsWith('/dictionary/paginated/skill/')&&u.pathname.endsWith('/'+SEASON_KIND); }catch{return false;} } const _fetch=window.fetch; window.fetch=async function(input,init){ const res=await _fetch(input,init); if(!state.on||!isSkill(input,init)) return res; const ct=res.headers.get('content-type')||''; if(!ct.includes('application/json')) return res; let data; try{data=await res.clone().json();}catch{return res;} const list=Array.isArray(data?.list)?data.list:(Array.isArray(data)?data:null); if(!Array.isArray(list)||list.length===0) return res; const idx=await buildIndex(); const owned=loadOwned(); const filtered=list.filter(it=>{ const key=\`\${norm(it?.sinnerName)}|\${norm(it?.identityName)}|\${it?.season??''}\`; const id=idx.get(key); return id!=null&&owned.has(id); }); const body=Array.isArray(data)?filtered:{...data,list:filtered}; return new Response(JSON.stringify(body),{status:res.status,statusText:res.statusText,headers:{'Content-Type':'application/json'}}); }; window.addEventListener('message',e=>{ const m=e?.data; if(!m||m.__ownedSupport!==true) return; if(m.type==='toggle'){state.on=!!m.enabled; if(state.on&&!state.idx) buildIndex();} }); })(); `); let btn=null, on=false; function setBtn() { if (!btn) return; btn.classList.remove('bg-primary-400','border','border-primary-100','bg-primary-450'); if (on) btn.classList.add('bg-primary-400','border','border-primary-100'); else btn.classList.add('bg-primary-450'); } function mask(el, ms=100){ if(!el) return ()=>{}; const wrap=document.createElement('div'); wrap.style.position='fixed'; wrap.style.zIndex='2147483647'; wrap.style.pointerEvents='none'; const clone=el.cloneNode(true); clone.style.transition='none'; clone.style.animation='none'; clone.style.margin='0'; wrap.appendChild(clone); document.body.appendChild(wrap); let stop=false; const place=()=>{if(stop)return;const r=el.getBoundingClientRect();wrap.style.left=r.left+'px';wrap.style.top=r.top+'px';wrap.style.width=r.width+'px';wrap.style.height=r.height+'px';requestAnimationFrame(place);}; place(); const off=()=>{if(stop)return;stop=true;wrap.remove();}; setTimeout(off,ms); return off; } function fire(el){ ['pointerdown','mousedown','mouseup','click'].forEach(t=>el.dispatchEvent(new MouseEvent(t,{bubbles:true,cancelable:true,view:window}))); } function anchor(){ const g=document.querySelector('div.grid.grid-cols-3'); return g?.querySelector('button:nth-of-type(2)')||null; } function reload(){ const el=anchor(); if(!el) return; mask(el,100); fire(el); setTimeout(()=>fire(el),0); } function toggle(){ on=!on; setBtn(); window.postMessage({__ownedSupport:true,type:'toggle',enabled:on},'*'); let i=0;(function loop(){if(anchor()){reload();return;} if(++i<10)setTimeout(loop,120);})(); } function gridNode(){ return document.querySelector('div.bg-primary-500.w-full.rounded.p-4.flex.flex-col.gap-2 div.grid.grid-cols-3')||document.querySelector('div.grid.grid-cols-3'); } function upsert(){ const g=gridNode(); if(!g) return; let exist=document.getElementById(BTN_ID); if(exist && exist.parentElement!==g) g.appendChild(exist); if(!exist){ const s=g.querySelector('button, a[role="button"], a[href]'); exist=document.createElement('button'); exist.id=BTN_ID; exist.type='button'; exist.className=s?s.className:'inline-flex items-center justify-center rounded-md border px-3 py-1 text-sm font-medium transition bg-primary-450'; exist.style.whiteSpace='nowrap'; exist.innerHTML=BTN_LABEL_HTML; exist.addEventListener('click',toggle); g.appendChild(exist); } btn=exist; setBtn(); } let scheduled=false; const schedule=()=>{ if(scheduled) return; scheduled=true; requestAnimationFrame(()=>{scheduled=false; upsert();}); }; const mo=new MutationObserver(schedule); mo.observe(document.documentElement,{childList:true,subtree:true}); window.addEventListener('load',schedule); document.addEventListener('visibilitychange',schedule,{passive:true}); })();