Greasy Fork

Greasy Fork is available in English.

绯月黑名单

眼不见为净

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         绯月黑名单
// @namespace    http://greasyfork.icu/zh-CN/users/453092
// @version      1.0.1
// @description  眼不见为净
// @author       ikarosf
// @require      https://unpkg.com/dexie@latest/dist/dexie.js
// @require      https://unpkg.com/dexie-export-import@latest/dist/dexie-export-import.js
// @match        https://bbs.fygal.com/*
// @match        https://bbs.bakabbs.com/*
// @match        https://bbs.365gal.com/*
// @match        https://bbs.365galgame.com/*
// @match        https://bbs.kfmax.com/*
// @match        https://bbs.9shenmi.com/*
// @match        https://bbs.kfpromax.com/*
// @match        https://kf.miaola.work/*
// @match        https://m.miaola.work/*
// @grant        GM_getResourceText
// @grant        GM_xmlhttpRequest
// @grant        unsafeWindow
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @grant        GM_listValues
// ==/UserScript==
async function kf_index_check(){
    var main_post_list_parentdiv = $("#alldiv>div:eq(2)>div:eq(1)>div:eq(0)")
    main_post_list_parentdiv.children().each(async function () {
        var thispost = $(this).find("a:first")
        var name = thispost.attr("uname")
        var itemobj = getQueryString(thispost.attr("href"))
        var tid = itemobj["tid"]
        //console.log(tid + " " + name)
        if(black_set.has(name)){
            $(this).hide();
            console.log("hide " + name)
        }
        await db_add_postdata(tid,name)
    });
}

async function kf_left_check(){
    $(".rightboxa>a").each(async function () {
        var url = $(this).attr("href")
        var itemobj = getQueryString(url)
        var tid = itemobj["tid"]
        var name = await db_get_poster(tid)
        if(name == ""){
            var newname = await html_get_poster(url)
            if(newname){
                if(black_set.has(newname)){
                    $(this).hide();
                    $(this).next().hide();
                    console.log("hide " + newname)
                }
                await db_add_postdata(tid,newname)
            }
        }else{
            if(black_set.has(name)){
                $(this).hide();
                $(this).next().hide();
                console.log("hide " + name)
            }
        }
    })
}

async function kf_thread_check(){
    //$(".thread1>tbody>tr").find("td:eq(3)>a")
    $("a.bl").each(function(){
        var name = $(this).text()
        if(black_set.has(name)){
            $(this).closest("tr").hide()
            console.log("hide " + name)
        }
    })
}

async function kf_post_check(){
    $(".readtext").each(function(){
        var name = $(this).find(".readidmsbottom:first>a").text()
        if(black_set.has(name)){
            $(this).hide()
            console.log("hide " + name)
        }
    })
}

function init_ui(){
    var menubutton= document.createElement('li')
    menubutton.innerHTML = '<a id="kfblacklistmenubutton" href="#">黑名单</a>'
    document.getElementsByClassName("topmenuo7")[0].children[0].append(menubutton)

    $("<style></style>").html(dialog_css).appendTo($("head"));
    $(`<div class="pd_cfg_box" id="fBlockUserDialog" style="display: none; top: 326px; left: 759.5px;">
  <h1>屏蔽用户 设完请刷新</h1>
<div class="pd_cfg_main" style="max-height: 867px;">
  <ul id="fBlockUserList" style="margin-top: 5px; min-width: 362px; line-height: 24px;"></ul>
  <div style="margin-top: 5px;" >
    <input id="fAddBlockUser" style="width: 200px;" type="text">
    <a class="pd_btn_link" id="fAddBlockUserButton" href="#">添加</a>
  </div>
</div>
<div class="pd_cfg_btns">
  <button id="fBlockUserDialogClose">关闭</button>
</div>
</div>`).appendTo($("body"));

    function addtolist(name){
        $(`<li>
  <input name="username" type="text" style="width: 150px; margin-left: 5px;" maxlength="15" readonly value="`+ name +`">
  <a class="pd_btn_link pd_delete" class="deleteBlockUser" href="#">删除</a>
</li>`).appendTo($("#fBlockUserList"));
        $(".pd_delete").on("click",async function (e) {
            e.preventDefault();
            var name = $(this).prev().val()
            await db.blacklist.where({name:name}).delete()
            black_set.delete(name)
            $(this).parent().remove()
        })
    }

    for (let name of black_set) {
        addtolist(name)
    }

    $("#fBlockUserDialogClose").on("click",function (e) {
        $("#fBlockUserDialog").fadeOut(200)
    })

    $("#fAddBlockUserButton").on("click",async function (e) {
        e.preventDefault();
        var name = $("#fAddBlockUser").val()
        if(!name || black_set.has(name)) return
        await db.blacklist.add({name:name})
        black_set.add(name)
        addtolist(name)
        $("#fAddBlockUser").val("")
    })

    $(menubutton).on("click",function (e) {
        e.preventDefault();
        $("#fBlockUserDialog").toggle()
    })

}

function miaola_get_tid(url){
    var reg = /[0-9]+/g
    var numberlist = url.match(reg)
    return numberlist[0]
}

async function miaola_index_check(){
    async function miaola_index_do(){
        var thispost = $(this).children("a:first")
        var name = thispost.attr("data-author")
        var tid = miaola_get_tid(thispost.attr("href"))
        //console.log(tid + " " + name)
        if(black_set.has(name)){
            $(this).hide();
            console.log("hide " + name)
        }
        await db_add_postdata(tid,name)
    }

    var panel1 = $("#newReplyPanel1")
    var panel2 = $("#newReplyPanel2")
    var panel3 = $("#newReplyPanel3")
    panel1.children().each(miaola_index_do)
    panel2.children().each(miaola_index_do)
    panel3.children().each(miaola_index_do)
}

async function miaola_bottom_check(){
    async function miaola_bottom_do() {
        var thispost = $(this).children("a:first")
        var url = thispost.attr("href")
        var tid = miaola_get_tid(url)
        var name = await db_get_poster(tid)
        if(name == ""){
            var newname = await miaola_get_poster(url)
            if(newname){
                if(black_set.has(newname)){
                    $(this).hide();
                    console.log("hide " + newname)
                }
                await db_add_postdata(tid,newname)
            }
        }else{
            if(black_set.has(name)){
                $(this).hide();
                console.log("hide " + name)
            }
        }
    }

    $("#newExtraPanel1").children().each(miaola_bottom_do)
    $("#newExtraPanel2").children().each(miaola_bottom_do)
}

function miaola_post_check(){
    $(".read-floor").each(function(){
        var name = $(this).find(".floor-user").text().trim();
        if(black_set.has(name)){
            $(this).hide()
            console.log("hide " + name)
        }
    })
}

function miaola_thread_check(){
    $(".thread-list-item").each(function(){
        var name = $(this).find(".fa-user").parent().text().trim()
        if(black_set.has(name)){
            $(this).hide()
            console.log("hide " + name)
        }
    })
}

function init_ui_miaola(){
    $(miaola_dialoghtml).appendTo($("body"))

    $(`<li class="nav-item">
          <a class="nav-link" id="openBlackDialog" href="#" role="button">
            <i class="fa fa-cog fa-fw" aria-hidden="true"></i> 黑名单
          </a>
        </li>`).appendTo($("body ul:first"))

    $("#openBlackDialog").on("click",async function (e) {
        e.preventDefault();
        $('#mainMenuTogglerBtn').click();
        $("#fblockUserDialog").toggle()
    })

    $("#fCloseBlockUserDialog").on("click",async function (e) {
        e.preventDefault();
        $("#fblockUserDialog").fadeOut(200)
    })

    function addtolist(name){
        $(miaola_linehtml.format(name)).appendTo($("#fblockUserList"));
        $(".pd_delete").on("click",async function (e) {
            e.preventDefault();
            var name = $(this).prev().find("input").val()
            await db.blacklist.where({name:name}).delete()
            black_set.delete(name)
            $(this).parent().remove()
        })
    }

    for (let name of black_set) {
        addtolist(name)
    }

    $("#fAddBlockUserButton").on("click",async function (e) {
        e.preventDefault();
        var name = $("#fAddBlockUser").val()
        if(!name || black_set.has(name)) return
        await db.blacklist.add({name:name})
        black_set.add(name)
        addtolist(name)
        $("#fAddBlockUser").val("")
    })
}

async function init_db(){
    db.version(1).stores({
        blacklist: "++id,&name",
        postdata:"++id,&tid,time"
    });

    await db.blacklist
        .each(async blackline => {
        black_set.add(blackline.name)
    });
}

async function db_add_postdata(tid,name){
    var now = getLocDate();
    try {
        await db.postdata.add({tid:tid, name:name, time:now});
    }catch(err) {

    }
}

async function db_get_poster(tid){
    var data = await db.postdata.where({tid:tid}).first()
    if(data){
        return data["name"]
    }
    return ""
}

async function db_clear(dayss){
    console.log(dayss)
    var during_s = dayss * 24 * 60 * 60 * 1000
    var now = getLocDate()
    var old = new Date(now - during_s)
    await db.postdata.where("time").belowOrEqual(old).delete()
}

async function html_get_poster(url){
    return new Promise((resolve, reject)=>{
        console.log("getnewpost:" + url)
        setTimeout(resolve, 10*1000)
        GM_xmlhttpRequest({
            method: "get",
            url:   unsafeWindow.location.origin + "/" + url,
            headers:  {
                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
            },
            onload: function(res){
                if(res.status === 200){
                    let info = res.responseText;
                    //console.log(info)
                    var name = $(info).find(".readtext a:first").text()
                    resolve(name)
                }else{
                    console.log(res)
                }
                resolve()
            },
            onerror : function(err){
                console.log(err)
                resolve()
            },
            ontimeout : function(){
                resolve()
            }
        });
    }) //Promise end
}

async function miaola_get_poster(url){
    return new Promise((resolve, reject)=>{
        console.log("getnewpost:" + url)
        setTimeout(resolve, 10*1000)
        GM_xmlhttpRequest({
            method: "get",
            url:   unsafeWindow.location.origin + url,
            headers:  {
                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
            },
            onload: function(res){
                if(res.status === 200){
                    let info = res.responseText;
                    //console.log(info)
                    var name = $(info).find(".read-floor .floor-user:first").text().trim();
                    resolve(name)
                }else{
                    console.log(res)
                }
                resolve()
            },
            onerror : function(err){
                console.log(err)
                resolve()
            },
            ontimeout : function(){
                resolve()
            }
        });
    }) //Promise end
}

function init_string(){
    dialog_css = `
  /* 公共 */
  .pd_highlight { color: #f00 !important; }
  .pd_notice, .pd_msg .pd_notice { font-style: italic; color: #666; }
  .pd_input, .pd_cfg_main input, .pd_cfg_main select {
    vertical-align: middle; height: auto; margin-right: 0; line-height: 22px; font-size: 12px;
  }
  .pd_input[type="text"], .pd_input[type="number"], .pd_cfg_main input[type="text"], .pd_cfg_main input[type="number"] {
    height: 22px; line-height: 22px;
  }
  .pd_input:focus, .pd_cfg_main input[type="text"]:focus, .pd_cfg_main input[type="number"]:focus, .pd_cfg_main textarea:focus,
      .pd_textarea:focus { border-color: #7eb4ea; }
  .pd_textarea, .pd_cfg_main textarea { border: 1px solid #ccc; font-size: 12px; }
  .pd_btn_link { margin-left: 4px; margin-right: 4px; }

  /* 设置对话框 */
  .pd_cfg_ml { margin-left: 10px; }
  .pd_cfg_box {
    position: fixed; border: 1px solid #9191ff; display: none; z-index: 1002;
    -webkit-box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.5); -moz-box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.5); box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.5);
  }
  .pd_cfg_box h1 {
    text-align: center; font-size: 14px; background-color: #9191ff; color: #fff; line-height: 2em; margin: 0; padding-left: 20px;
  }
  .pd_cfg_box h1 span { float: right; cursor: pointer; padding: 0 10px; }
  .pd_cfg_nav { text-align: right; margin-top: 5px; margin-bottom: -5px; }
  .pd_cfg_main { background-color: #fcfcfc; padding: 0 10px; font-size: 12px; line-height: 24px; min-height: 50px; overflow: auto; }
  .pd_cfg_main fieldset { border: 1px solid #ccccff; padding: 0 6px 6px; }
  .pd_cfg_main legend { font-weight: bold; }
  .pd_cfg_main input[type="color"] { height: 18px; width: 30px; padding: 0; }
  .pd_cfg_tips { color: #51d; text-decoration: none; cursor: help; }
  .pd_cfg_tips:hover { color: #ff0000; }
  #pdConfigDialog .pd_cfg_main { overflow-x: hidden; white-space: nowrap; }
  .pd_cfg_panel { display: inline-block; width: 400px; vertical-align: top; }
  .pd_cfg_panel + .pd_cfg_panel { margin-left: 5px; }
  .pd_cfg_btns { background-color: #fcfcfc; text-align: right; padding: 5px; }
  .pd_cfg_btns input, .pd_cfg_btns button { vertical-align: middle; }
  .pd_cfg_btns button { min-width: 80px; }
  .pd_cfg_about { float: left; line-height: 24px; margin-left: 5px; }
  .pd_custom_script_header { margin: 7px 0; padding: 5px; background-color: #e8e8e8; border-radius: 5px; }
  .pd_custom_script_content { display: none; width: 750px; height: 350px; white-space: pre; }

`;
    miaola_dialoghtml = `<form>
<div class="dialog" id="fblockUserDialog" tabindex="-1" role="dialog" aria-hidden="true" aria-labelledby="blockUserDialogTitle" style="display: none;">
  <div class="container dialog-content" role="document">
    <div class="dialog-header">
      <h5 class="dialog-title" id="fblockUserDialogTitle">黑名单 设完请刷新</h5>
    </div>
    <div class="dialog-body" style="max-height: 726.25px;">

<ul class="list-unstyled" id="fblockUserList">

</ul>

<div class="input-group mb-3">
  <input class="form-control" data-toggle="tooltip" type="text" title="" aria-label="添加屏蔽用户" id="fAddBlockUser">
  <div class="input-group-append">
    <button class="btn btn-success" type="button" id="fAddBlockUserButton">添加</button>
  </div>
</div></div>
    <div class="dialog-footer">
<button class="btn btn-primary" id="fCloseBlockUserDialog">关闭</button>
  </div>
</div>
</form>`;

    miaola_linehtml = `<li class="form-group row no-gutters mb-2">
  <div class="col-7 input-group input-group-sm">
    <input class="form-control" type="text" value="{0}" maxlength="12" readonly>
  </div>
      <button class="btn btn-danger pd_delete" type="button" aria-label="删除屏蔽用户">
        <i class="fa fa-trash" aria-hidden="true"></i>
      </button>
  </li>`;
}

// 获取链接参数
function getQueryString(url) {
    let ItemArr = [];
    let ItemObj = {};
    url
        .substring(url.lastIndexOf("?") + 1, url.length)
        .split("&")
        .map((item) => {
        ItemArr.push(item.split("="));
    });
    ItemArr.map((item) => {
        ItemObj[item[0]] = item[1];
    });
    return ItemObj;
}

function getLocDate(aparam){//不传参,返回当前时间的Date变量;该方法用来代替new Date
    var thisDate;
    if (typeof(aparam) == "undefined") {
        thisDate = new Date();
    }else{
        thisDate = new Date(aparam)
    }
    //本地时间 + 本地时间与格林威治时间的时间差 + GMT+8与格林威治的时间差
    return new Date(thisDate.getTime() + new Date().getTimezoneOffset()*60*1000 + 8*60*60*1000)
}

function getLocDay(){//返回当前日期的Date变量
    var daystr = getDateString(getLocDate())
    return new Date(new Date(daystr).getTime() + new Date().getTimezoneOffset()*60*1000 + 8*60*60*1000)
}

function getDateString(thisDate){//将传入的时间戳转换为年月日字符串
    return thisDate.getFullYear() + "/" + (thisDate.getMonth()+1) + "/" + thisDate.getDate()
}

function getNowtime(){
    var date=getLocDate();
    var datetext = date.getHours()+":"+date.getMinutes()+":"+date.getSeconds();
    return datetext;
}

String.prototype['format'] = function () {
    const e = arguments;
    return !!this && this.replace(/\{(\d+)\}/g, function (t, r) {
        return e[r] ? e[r] : t;
    });
};

//---------------------main------------------------
const db = new Dexie("kffblack");
var dialog_css,miaola_dialoghtml,miaola_linehtml;
const black_set = new Set();

(async function() {
    await init_db()
    init_string()
    var hostname = unsafeWindow.location.hostname
    var pathname = unsafeWindow.location.pathname
    if(hostname.indexOf("m.miaola") != -1){
        if(pathname == "/" || pathname == "/index.php"){
            await miaola_index_check()
            await miaola_bottom_check()
        }else if(pathname.indexOf("/read/") != -1){
            await miaola_post_check()
        }else{
            await miaola_thread_check()
        }
        init_ui_miaola()
    }else{
        if(pathname == "/" || pathname == "/index.php"){
            await kf_index_check()
            await kf_left_check()
        }else if(pathname.indexOf("/read.php") != -1){
            await kf_post_check()
        }else{
            await kf_thread_check()
            await kf_left_check()
        }
        init_ui()
    }

    setTimeout(db_clear, 10*1000, 7)
})();