원글에꺼 써봣는데 작동을 안하는거 같아서 잼민이한테 던져주니까 되길래 올려봄 





// ==UserScript==

// @name         헬망호 참가 스크립트 (Fixed)

// @namespace    http://tampermonkey.net/

// @version      1.3.0

// @description  비동기 병렬 요청 및 본문 데이터 스캔, 버튼 크기 확대 버전

// @author       Gemini

// @match        https://gall.dcinside.com/mgallery/board/lists*id=helldiversseries*

// @match        https://gall.dcinside.com/board/lists*id=helldiversseries*

// @grant        GM_xmlhttpRequest

// @grant        GM_addStyle

// ==/UserScript==


(function() {

    'use strict';


    GM_addStyle(`

        .hd-lobby-link {

            display: inline-block !important;

            margin-left: 8px !important;

            padding: 3px 8px !important;

            background-color: #f1c40f !important;

            color: #000 !important;

            font-size: 11px !important;

            font-weight: bold !important;

            border-radius: 4px !important;

            text-decoration: none !important;

            border: 1px solid #d3ac0d !important;

            vertical-align: middle !important;

            line-height: 1.2 !important;

            box-shadow: 1px 1px 2px rgba(0,0,0,0.1);

        }

        .hd-lobby-link:hover {

            background-color: #fff !important;

            color: #000 !important;

            border-color: #000 !important;

            cursor: pointer;

        }

    `);


    // 정규식 개선: steam 프로토콜을 더 확실하게 잡도록 수정

    const lobbyRegex = /steam:\/\/joinlobby\/\d+\/\d+/;

    const processedUrls = new Set();


    async function fetchLobbyLink(titleElement, postUrl) {

        if (processedUrls.has(postUrl)) return;

        processedUrls.add(postUrl);


        GM_xmlhttpRequest({

            method: "GET",

            url: postUrl,

            // 중요: Range 헤더 제거 (디시 페이지 상단 스크립트 용량이 커서 15KB로는 본문에 도달 못함)

            // 타임아웃 설정으로 무한 로딩 방지

            timeout: 5000,

            onload: function(response) {

                // 응답 텍스트에서 스팀 링크 검색

                const match = response.responseText.match(lobbyRegex);

                

                if (match) {

                    const linkBtn = document.createElement('a');

                    linkBtn.href = match[0];

                    linkBtn.className = 'hd-lobby-link';

                    linkBtn.textContent = '+탑승';

                    

                    // 제목 옆에 버튼 추가 (기존 구조를 깨지 않도록 안전하게 추가)

                    titleElement.appendChild(linkBtn);

                }

            },

            : function(err) {

                console.log("헬망호 링크 탐색 실패:", postUrl);

            }

        });

    }


    function init() {

        // 셀렉터 수정: 갤러리 리스트의 제목 부분을 더 정확하게 타겟팅

        const titles = document.querySelectorAll('.gall_tit a:not(.reply_numbox)');

        

        titles.forEach(title => {

            // 이미 처리된 요소인지 확인 (중복 추가 방지)

            if (title.href && title.href.includes('view') && !title.parentNode.querySelector('.hd-lobby-link')) {

                // 부모 요소(td)에 버튼을 달기 위해 parentNode 전달

                fetchLobbyLink(title.parentNode, title.href);

            }

        });

    }


    // 초기 실행

    init();


    // 페이지 변경/갱신 감지 (디시인사이드 리스트 갱신 대응)

    let timer = null;

    const observer = new MutationObserver(() => {

        if (timer) clearTimeout(timer);

        timer = setTimeout(init, 300); // 딜레이를 조금 주어 부하 감소

    });


    const listTable = document.querySelector('.gall_list');

    if (listTable) {

        observer.observe(listTable, { childList: true, subtree: true });

    }

})();