본문의 RJ 코드를 인식해서 DL 링크로 날려주는 버튼 생성 + 옆에 제목과 대표 태그 3개를 미리 볼 수 있습니다
마우스를 위로 올리면 제품 페이지의 1번 이미지와 태그 전체 목록이 전부 표시됩니다
방주글 같은 건 목록이 너무 많아 하나씩 DL에서 확인하기 힘들어서 개인적으로 만들어 쓰던 건데 공유합니다
제목 로딩 못 하고 […]으로 표시되는 경우가 있는데 새로고침하면 정상적으로 로드됩니다
하단 스크립트 그대로 다 긁어서 템퍼몽키에 붙여넣고 쓰시면 됩니다
규정은 읽어봤는데 이런 거는 공유해도 되는지 관련 규정은 잘 몰라서 혹시 위배되는 행동이라면 삭제하도록 하겠습니다
// UserScript
// @name Kone RJ → DLsite Helper Pro
// @namespace https://kone.gg/
// @version 6.0
// @description RJ 코드에 DLsite 제목/태그/이미지 표시
// @match https://kone.gg/*
// @grant GM_xmlhttpRequest
// @connect dlsite.com
// @connect www.dlsite.com
// /UserScript
(function () {
'use strict';
const memoryCache = new Map();
const requestQueue = [];
const queued = new Set();
//--------------------------------------------------
// Hover Card
//--------------------------------------------------
const preview = document.createElement('div');
preview.style.cssText = `
position: fixed;
display: none;
z-index: 999999;
background: #222;
color: white;
border: 1px solid #666;
border-radius: 8px;
padding: 8px;
max-width: 320px;
box-shadow: 0 4px 12px rgba(0,0,0,.5);
pointer-events: none;
font-size: 13px;
line-height: 1.4;
`;
document.body.appendChild(preview);
function showPreview(x, y, data) {
preview.innerHTML = '';
if (data.image) {
const img = document.createElement('img');
img.src = data.image;
img.style.width = '280px';
img.style.display = 'block';
img.style.marginBottom = '8px';
preview.appendChild(img);
}
const title = document.createElement('div');
title.style.fontWeight = 'bold';
title.style.marginBottom = '6px';
title.textContent = data.title;
preview.appendChild(title);
if (data.genres && data.genres.length) {
const genreTitle = document.createElement('div');
genreTitle.textContent = '태그';
genreTitle.style.marginBottom = '4px';
genreTitle.style.color = '#aaa';
preview.appendChild(genreTitle);
const genreList = document.createElement('div');
genreList.textContent =
data.genres.join(', ');
preview.appendChild(genreList);
}
preview.style.left = (x + 20) + 'px';
preview.style.top = (y + 20) + 'px';
preview.style.display = 'block';
}
function hidePreview() {
preview.style.display = 'none';
}
//--------------------------------------------------
// Cache
//--------------------------------------------------
function getCache(rjCode) {
if (memoryCache.has(rjCode)) {
return memoryCache.get(rjCode);
}
const saved =
localStorage.getItem(
'dlsite_' + rjCode
);
if (!saved) {
return null;
}
try {
const parsed =
JSON.parse(saved);
memoryCache.set(
rjCode,
parsed
);
return parsed;
} catch {
return null;
}
}
function setCache(rjCode, data) {
memoryCache.set(
rjCode,
data
);
localStorage.setItem(
'dlsite_' + rjCode,
JSON.stringify(data)
);
}
//--------------------------------------------------
// DLsite Fetch
//--------------------------------------------------
function fetchWork(rjCode, callback) {
const cached =
getCache(rjCode);
if (cached) {
callback(cached);
return;
}
GM_xmlhttpRequest({
method: 'GET',
url:
https://www.dlsite.com/maniax/work/=/product_id/${rjCode}.html,
onload(res) {
let title =
'제목 없음';
let image =
'';
let genres =
[];
try {
const doc =
new DOMParser()
.parseFromString(
res.responseText,
'text/html'
);
const workName =
doc.querySelector(
'#work_name'
);
if (workName) {
title =
workName.textContent.trim();
}
const ogImage =
doc.querySelector(
'meta[property="og:image"]'
);
if (ogImage) {
image =
ogImage.content;
}
genres =
[...doc.querySelectorAll('a[href*="/genre/"]')]
.map(a =>
a.textContent.trim()
)
.filter(Boolean);
}
catch (e) {
console.error(e);
}
const data = {
title,
image,
genres
};
setCache(
rjCode,
data
);
callback(data);
}
});
}
//--------------------------------------------------
// Queue
//--------------------------------------------------
setInterval(() => {
const item =
requestQueue.shift();
if (!item) {
return;
}
fetchWork(
item.rjCode,
item.callback
);
}, 500);
//--------------------------------------------------
// Process
//--------------------------------------------------
function processParagraph(p) {
if (
p.dataset.rjProcessed === '1'
) {
return;
}
const text =
p.textContent.trim();
const match =
text.match(/^(RJ\d+)/);
if (!match) {
return;
}
const rjCode =
match[1];
const link =
document.createElement('a');
link.href =
https://www.dlsite.com/maniax/work/=/product_id/${rjCode}.html;
'_blank';
link.rel =
'noopener noreferrer';
link.textContent =
' 🔗';
link.style.marginLeft =
'4px';
link.style.textDecoration =
'none';
p.appendChild(link);
const titleSpan =
document.createElement('span');
titleSpan.textContent =
' [...]';
titleSpan.style.marginLeft =
'4px';
p.appendChild(titleSpan);
function applyData(data) {
let shortTitle =
data.title;
if (
shortTitle.length > 35
) {
shortTitle =
shortTitle.substring(
0,
35
) + '...';
}
let genreText = '';
if (
data.genres &&
data.genres.length
) {
genreText =
' [' +
data.genres
.slice(0, 3)
.join(', ') +
']';
}
titleSpan.textContent =
' ' +
shortTitle +
genreText;
titleSpan.style.color =
'#888';
titleSpan.style.cursor =
'pointer';
titleSpan.onclick =
() => {
link.href,
'_blank'
);
};
function enter(e) {
showPreview(
e.clientX,
e.clientY,
data
);
}
function move(e) {
preview.style.left =
(e.clientX + 20) + 'px';
(e.clientY + 20) + 'px';
}
link.addEventListener(
'mouseenter',
enter
);
titleSpan.addEventListener(
'mouseenter',
enter
);
link.addEventListener(
'mousemove',
move
);
titleSpan.addEventListener(
'mousemove',
move
);
link.addEventListener(
'mouseleave',
hidePreview
);
titleSpan.addEventListener(
'mouseleave',
hidePreview
);
}
const cached =
getCache(rjCode);
if (cached) {
applyData(cached);
} else {
if (
!queued.has(rjCode)
) {
queued.add(rjCode);
requestQueue.push({
rjCode,
callback(data) {
applyData(
data
);
}
});
}
}
p.dataset.rjProcessed =
'1';
}
//--------------------------------------------------
// Scan
//--------------------------------------------------
function scan() {
document
.querySelectorAll(
'.tiptap.ProseMirror p'
)
.forEach(
processParagraph
);
}
scan();
const observer =
new MutationObserver(
scan
);
observer.observe(
document.body,
{
childList: true,
subtree: true
}
);
})();
s/somisoft
• 150,624명 구독중- 1. 게시물 규정 양식
업로드 시 링크 암호화 & 필수 정보를 기입할 것
- 2. 질문
국룰, 암호화 링크 등 기본사항 질문 금지, 탭 미준수시 차단 및 삭제
- 3. 요청
요청 기준 및 양식 미준수 & 댓글로만 자료 복구 요청 시 차단
- 4. 미성년자 / 근첩 / 페미 / 다중계정
조금이라도 의심되면 선 차단, 후 해명
- 5. 좆목 / 네임드화
닉언, 네임드화 등 친목질 금지
- 6. 분탕 및 어그로 / 혐짤 / 낚시 / 뇌절
해당 카테고리의 차단 기간 및 가중처벌은 처리자 재량으로 판단
- 7. 홍보 / 판촉 / 거래
허용되지 않은 모든 형태의 홍보, 거래, 교환, 조건부 공유 시 차단
- 8. 쌀먹 / 바이러스
조건부 공유 & 수익성 링크 & 고의적인 바이러스 유포 시 갱신차단
- 9. 자료 분류 / AI
미검수 시 표기 필수, 생성형 AI를 사용한 자료의 제목에 AI 미기입 시 차단
- 10. 실사 / 토들러
업로드시 갱신 차단
- 11. 기타 세부 규정은 서브 공지사항 참고