Greasy Fork

Greasy Fork is available in English.

巴哈姆特黑名單、關鍵字過濾文章留言

在巴哈姆特的B、C頁將黑名單、關鍵字過濾文章留言,在頂端列可以開關過濾器(一次性)

当前为 2018-04-23 提交的版本,查看 最新版本

// ==UserScript==
// @name         巴哈姆特黑名單、關鍵字過濾文章留言
// @namespace    https://home.gamer.com.tw/moontai0724
// @version      2.2
// @description  在巴哈姆特的B、C頁將黑名單、關鍵字過濾文章留言,在頂端列可以開關過濾器(一次性)
// @author       moontai0724
// @match        https://forum.gamer.com.tw/*
// @grant        GM_xmlhttpRequest
// @connect      home.gamer.com.tw
// @require      https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
// @supportURL   https://home.gamer.com.tw/moontai0724
// ==/UserScript==

(function () {
    'use strict';
    // 以下參數注意事項:
    // 1. 不分大小寫。
    // 2. 可換行
    // 3. 請以逗號分隔

    // 統一範例:
    // 單行範例:var ForceHideList = ['userId', 'TestId'];
    // 單行範例:var blockKeywords = ['推', '私信'];
    // 換行範例:
    // var postBlockKeywords = ['推', '私信',
    //                          '野格炸彈', '斯斯', 'BANG',
    //                          '我的最愛'];

    // 手動設定ID不隱藏名單,強制顯示優先於強制隱藏,因此如有重複也沒關係。
    var ForceShowList = [];

    // 手動設定ID隱藏名單,強制顯示優先於強制隱藏,因此如有重複也沒關係。
    var ForceHideList = [];

    // 隱藏關鍵字,如果加在這邊代表文章跟留言皆會過濾。
    var blockKeywords = [];

    // 文章隱藏關鍵字,如果加在這邊代表只有文章內文包含才會被過濾。
    var postBlockKeywords = [];

    // 留言隱藏關鍵字,如果加在這邊代表只有留言內文包含才會被過濾。
    var commentBlockKeywords = [];

    // 文章隱藏字數上限,文章內字數小於這個數量就會被隱藏,剛好等於不隱藏。
    // enable 為是否開啟功能;TextLength 為字數總數顯示下限
    // 設置 2 代表 1 個字的會被隱藏,2 個字的不會。
    var postTextLengthLimit = {
        enable: false,
        totalLength: 2
    };

    // 留言隱藏字數上限,留言內字數小於這個數量就會被隱藏,剛好等於不隱藏。
    // enable 為是否開啟功能;TextLength 為字數總數顯示下限
    // 設置 5 代表 4 個字的會被隱藏,5 個字的不會。
    var commentTextLengthLimit = {
        enable: false,
        totalLength: 5
    };

    // 以下參數請務必完全正確,大小寫相同,true 或 false。
    // 文章是否過濾關鍵字? true 為開啟,false 為關閉。
    var KeywordPostFliter = true;

    // 留言是否過濾關鍵字? true 為開啟,false 為關閉。
    var keywordCommentFliter = true;

    // 文章是否過濾黑名單? true 為開啟,false 為關閉。
    var blacklistPostFliter = true;

    // 留言是否過濾黑名單? true 為開啟,false 為關閉。
    var blacklistCommentFliter = true;

    // 程式開始
    // 加入隱藏切換
    jQuery('head').append('<style type="text/css" id="BlockHideCSS">.BlockHide { display: none !important; }</style>');
    jQuery('.BH-menuE').append('<li><a id="ShowBlock" href="javascript:;" style="display: block;" onclick="BlockDisplay(true);">關閉過濾器</a></li>');
    jQuery('.BH-menuE').append('<li><a id="HideBlock" href="javascript:;" style="display: none;" onclick="BlockDisplay(false);">開啟過濾器</a></li>');
    jQuery('body').append('<script type="text/javascript">' + function BlockDisplay(status) {
        document.getElementById('HideBlock').style.display = status ? 'block' : 'none';
        document.getElementById('ShowBlock').style.display = status ? 'none' : 'block';
        status ? document.getElementById('BlockHideCSS').innerHTML = document.getElementById('BlockHideCSS').innerHTML.replace('BlockHide', 'noBlockHide') : document.getElementById('BlockHideCSS').innerHTML = document.getElementById('BlockHideCSS').innerHTML.replace('noBlockHide', 'BlockHide');
    } + '</script>');

    // 將 blockKeywords 加入 postBlockKeywords 和 commentBlockKeywords 中
    for (let i = 0; i < blockKeywords.length; i++) postBlockKeywords[postBlockKeywords.length] = commentBlockKeywords[commentBlockKeywords.length] = blockKeywords[i];
    postBlockKeywords = postBlockKeywords.map(value => value.toLowerCase());
    commentBlockKeywords = commentBlockKeywords.map(value => value.toLowerCase());

    //BC頁分開
    switch (location.pathname) {
        case '/B.php':
            console.group('Fliter log message');
            setTimeout(() => console.groupEnd(), 250);
            // blacklist post fliter
            blacklistPostFliter ? getBlackList().then(BlackList => jQuery('.b-list__count__user>a').each((index, value) => BlackList.includes(value.innerText.toLowerCase()) ? (jQuery(value).parents('.b-list__row').addClass('BlockHide'), console.log('Hid a post with block user: ' + value.innerText.toLowerCase(), jQuery(value).parents('.b-list__row'))) : void (0))) : void (0);
            // keywords post title fliter
            KeywordPostFliter ? jQuery('.b-list__main__title').each((index, value) => postBlockKeywords.forEach(data => value.innerText.toLowerCase().includes(data) ? (jQuery(value).parents('.b-list__row').addClass('BlockHide'), console.log('Hid a post includes keyword: ' + data, jQuery(value).parents('.b-list__row'))) : void (0))) : void (0);
            break;
        case '/C.php':
            console.group('Fliter log message');
            setTimeout(() => console.groupEnd(), 250);
            // 擷取展開按鈕事件:當展開留言按鈕被點擊,執行原生展開留言指令並處理內容
            jQuery('body').append('<button id="extendCommentListener" style="display: none;"></button>');
            jQuery('.more-reply').each((index, element) => element.setAttribute("onclick", element.getAttribute("onclick") + " [document.getElementById('extendCommentListener').dataset.bsn, document.getElementById('extendCommentListener').dataset.postid] = [" + element.getAttribute('onclick').replace('extendComment(', '').replace(');', '').split(', ') + "]; jQuery('#Commendlist_" + element.getAttribute('onclick').replace('extendComment(', '').replace(');', '').split(', ')[1] + "').append('<div id=\"extendCommentAreaListener\"></div>'); document.getElementById('extendCommentListener').click();"));
            // 當按鈕點擊就執行
            document.getElementById('extendCommentListener').onclick = function () {
                let [bsn, postid] = [document.getElementById('extendCommentListener').dataset.bsn, document.getElementById('extendCommentListener').dataset.postid], times = 0, ms = 0;
                setTimeout(function restartFliter(ms) {
                    setTimeout(function () {
                        if (!document.getElementById('extendCommentAreaListener')) {
                            jQuery('#Commendlist_' + postid).each((index, element) => {
                                blacklistCommentFliter ? getBlackList().then(BlackList => jQuery(element).find('.reply-content__user').each((index, value) => BlackList.includes(value.href.replace('https://home.gamer.com.tw/', '').toLowerCase()) ? (jQuery(value).parents('.c-reply__item').addClass('BlockHide'), console.log('Hid a comment with block user: ' + value.innerText.toLowerCase(), jQuery(value).parents('.c-reply__item'))) : void (0))) : void (0);
                                keywordCommentFliter ? jQuery(element).find('.reply-content__article').each((index, value) => commentBlockKeywords.forEach(data => value.innerText.toLowerCase().includes(data) ? (jQuery(value).parents('.c-reply__item').addClass('BlockHide'), console.log('Hid a post includes keyword: ' + data, jQuery(value).parents('.c-reply__item'))) : void (0))) : void (0);
                                if (commentTextLengthLimit.enable) {
                                    jQuery(element).find('.reply-content__article').each((index, value) => {
                                        let data = value.innerText.replace(/\s/g, '').length;
                                        if (data < commentTextLengthLimit.totalLength) {
                                            jQuery(value).parents('.c-reply__item').addClass('BlockHide');
                                            console.log('Hid a comment less then setting text totalLength limit: ' + commentTextLengthLimit.totalLength, data, jQuery(value).parents('.c-reply__item'));
                                        }
                                    });
                                }
                            });
                        } else if (times++ < 50) restartFliter(100);
                    }, ms);
                });
            };

            // blacklist post fliter
            blacklistPostFliter ? getBlackList().then(BlackList => jQuery('.c-post__header__author>.userid').each((index, value) => BlackList.includes(value.innerText.toLowerCase()) ? (jQuery(value).parents('.c-section').addClass('BlockHide'), console.log('Hid a post with block user: ' + value.innerText.toLowerCase(), jQuery(value).parents('.c-section'))) : void (0))) : void (0);
            // blacklist comment fliter
            blacklistCommentFliter ? getBlackList().then(BlackList => jQuery('.reply-content__user').each((index, value) => BlackList.includes(value.href.replace('https://home.gamer.com.tw/', '').toLowerCase()) ? (jQuery(value).parents('.c-reply__item').addClass('BlockHide'), console.log('Hid a comment with block user: ' + value.innerText.toLowerCase(), jQuery(value).parents('.c-reply__item'))) : void (0))) : void (0);
            // keywords post fliter
            KeywordPostFliter ? jQuery('.c-article__content').each((index, value) => postBlockKeywords.forEach(data => value.innerText.toLowerCase().includes(data) ? (jQuery(value).parents('.c-section').addClass('BlockHide'), console.log('Hid a post includes keyword: ' + data, jQuery(value).parents('.c-section'))) : void (0))) : void (0);
            // keywords comment fliter
            keywordCommentFliter ? jQuery('.reply-content__article').each((index, value) => commentBlockKeywords.forEach(data => value.innerText.toLowerCase().includes(data) ? (jQuery(value).parents('.c-reply__item').addClass('BlockHide'), console.log('Hid a comment includes keyword: ' + data, jQuery(value).parents('.c-reply__item'))) : void (0))) : void (0);
            // post content length fliter
            if (postTextLengthLimit.enable) {
                jQuery('.c-article__content').each((index, value) => {
                    let data = value.innerText.replace(/\s/g, '').length;
                    if (data < postTextLengthLimit.totalLength) {
                        jQuery(value).parents('.c-section').addClass('BlockHide');
                        console.log('Hid a post less then setting text totalLength limit: ' + postTextLengthLimit.totalLength, data, jQuery(value).parents('.c-section'));
                    }
                });
            }
            // comment content length fliter
            if (commentTextLengthLimit.enable) {
                jQuery('.reply-content__article').each((index, value) => {
                    let data = value.innerText.replace(/\s/g, '').length;
                    if (data < commentTextLengthLimit.totalLength) {
                        jQuery(value).parents('.c-reply__item').addClass('BlockHide');
                        console.log('Hid a comment less then setting text totalLength limit: ' + commentTextLengthLimit.totalLength, data, jQuery(value).parents('.c-reply__item'));
                    }
                });
            }
            break;
        case '/Bo.php':
            console.group('Fliter log message');
            setTimeout(() => console.groupEnd(), 250);
            blacklistPostFliter ? getBlackList().then(BlackList => jQuery('.FM-blist6>a[href*="home.gamer.com.tw"]').each((index, value) => BlackList.includes(value.innerText.toLowerCase()) ? (jQuery(value).parents('tr').addClass('BlockHide'), console.log('Hid a post with block user: ' + value.innerText.toLowerCase(), jQuery(value).parents('tr'))) : void (0))) : void (0);
            KeywordPostFliter ? jQuery('.FM-blist3').each((index, value) => postBlockKeywords.forEach(data => value.innerText.toLowerCase().includes(data) ? (jQuery(value).parents('tr').addClass('BlockHide'), console.log('Hid a comment includes keyword: ' + data, jQuery(value).parents('tr'))) : void (0))) : void (0);
            break;
        case '/search.php':
            setTimeout(function restartFliter(ms) {
                setTimeout(() => jQuery('.gsc-table-cell-snippet-close').length > 0 ? (console.group('Fliter log message'), setTimeout(() => console.groupEnd(), 100), KeywordPostFliter ? jQuery('.gsc-table-cell-snippet-close').each((index, value) => postBlockKeywords.forEach(data => value.innerText.toLowerCase().includes(data) ? (jQuery(value).parents('.gsc-result').addClass('BlockHide'), console.log('Hid a comment includes keyword: ' + data, jQuery(value).parents('.gsc-result'))) : void (0))) : void (0)) : restartFliter(100), ms);
            });
            break;
    }

    function BlackListHandle(BlackList) {
        let removeNum = [];
        ForceHideList.forEach(value => BlackList.includes(value.replace(/\s/g, '').toLowerCase()) ? void (0) : BlackList[BlackList.length] = value.replace(/\s/g, '').toLowerCase());
        BlackList.forEach((value, index) => ForceShowList.includes(value.toLowerCase()) ? removeNum[removeNum.length] = index : void (0));
        for (let i = removeNum.length - 1; i >= 0; i--) BlackList.splice(removeNum[i], 1);
        localStorage.setItem('BHBlackList', JSON.stringify({ time: new Date().getTime(), BlackList: BlackList }));
        console.log('Blacklist handle process over, returned blacklist: ', BlackList);
        return BlackList;
    }

    function getBlackList(forceReload) {
        return new Promise(resolve => {
            if (localStorage.getItem('BHBlackList') && !forceReload) {
                let BHBlackList = JSON.parse(localStorage.getItem('BHBlackList')), today = new Date((new Date()).getFullYear(), (new Date()).getMonth(), (new Date()).getDate(), 0, 0, 0, 0);
                today.getTime() < BHBlackList.time && BHBlackList.time < today.getTime() + 86400000 ? (console.log('Already requested blacklist today, resolve.'), resolve(BlackListHandle(BHBlackList.BlackList))) : (console.log('Today not requested blacklist yet, start request.'), getBlackList(true).then(data => resolve(BlackListHandle(data))));
            } else GM_xmlhttpRequest({
                method: "GET",
                url: "https://home.gamer.com.tw/ajax/friend_getData.php?here=0",
                onload: data => (console.log('Get blacklist data from Bahamut server.'), resolve(BlackListHandle(data.response.includes('<div id="BMW_nlist" style="display:none;">') ? data.response.split('<div id="BMW_nlist" style="display:none;">')[1].replace('</div>', '').split(',') : [])))
            });
        });
    }
})();