념글이나 어디에 헬망호 링크같은거 있으면 모든 게시물에 참가 아이콘 뜨는거 수정해옴



// ==UserScript==

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

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

// @version      1.3.1

// @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;

        }

    `);


    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,

            timeout: 5000,

            onload: function(response) {

                // 1. 응답받은 텍스트를 HTML 문서로 파싱합니다.

                const parser = new DOMParser();

                const doc = parser.parseFromString(response.responseText, "text/html");


                // 2. 전체 페이지가 아니라 실제 글 내용이 담긴 '.write_div' 클래스만 선택합니다.

                const contentBody = doc.querySelector('.write_div');


                // 3. 본문 영역이 존재하고, 그 안에서 링크가 발견될 때만 버튼을 생성합니다.

                if (contentBody) {

                    const match = contentBody.innerHTML.match(lobbyRegex);

                    

                    if (match) {

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

                        linkBtn.href = match[0];

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

                        linkBtn.textContent = '+탑승';

                        

                        // 이미 버튼이 있는지 다시 한번 체크 후 추가

                        if (!titleElement.querySelector('.hd-lobby-link')) {

                            titleElement.appendChild(linkBtn);

                        }

                    }

                }

            }

        });

    }


    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')) {

                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 });

    }

})();