Greasy Fork

Greasy Fork is available in English.

老男人助手

适用于老男人游戏论坛:https://bbs.oldmanemu.net/ 的小工具

当前为 2022-02-07 提交的版本,查看 最新版本

// ==UserScript==
// @name         老男人助手
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  适用于老男人游戏论坛:https://bbs.oldmanemu.net/ 的小工具
// @author       rock128
// @match        https://bbs.oldmanemu.net/*
// @icon         data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant        none
// @require      https://cdn.bootcdn.net/ajax/libs/jscolor/2.4.7/jscolor.min.js
// @license      GPL-3.0 License
// ==/UserScript==

(function() {
    'use strict';

    var SIGN_TITLE = "签到"
    var HAS_HIDDEN_CONTENT_KEYWORD = "本帖含有隐藏内容"
    var AUTO_REPLY_MSG = []
    var BLACK_LIST = []
    var BACKGROUND_COLOR = '#C7EDCC';
    var FONT_COLOR = '#000000';

    jscolor.presets.default = {
        position: 'right',
        palette: [
            '#FFFFFF', '#FAF9DE', '#FFF2E2', '#FDE6E0', '#E3EDCD',
            '#DCE2F1', '#E9EBFE', '#EAEAEF', '#C7EDCC', '#CCE8CF',
            '#6E7B6C'
        ]
    };

    var actionArray = [
        {
            describe : "页面自动签到",
            open : false,
            matchCondition : function(){
                return isMatchPageCategory("index")
            },
            doAction : function(){
                if($("#sign_title").text() == SIGN_TITLE){
                    $.xpost(xn.url("my-sign"),"",function(message){});
                }
            },
            settingPanelHtml: '签到按钮文本:</br> <input type="text" id="sign-key" value="{SIGN_TITLE}" /> </br>'
        },
        {
            describe : "去除灯笼",
            open : false,
            matchCondition : function(){
                return true
            },
            doAction : function(){
                $(".deng") && $(".deng").remove()
            }
        },
        {
            describe : "屏蔽用户帖子",
            open : false,
            matchCondition : function(){
                return isMatchPageCategory("") || isMatchPageCategory("index")
            },
            doAction : function(){
                $(".media.thread.tap") && $(".media.thread.tap").each(function(i,item){
                    var id = $(item).children().eq(0).attr("href")
                    id = id.replace("user-","").replace(".htm","")
                    if(BLACK_LIST.indexOf(id)!=-1){
                        $(item).hide()
                    }
                })
            },
            settingPanelHtml: '黑名单列表:</br> <textarea placeholder="要屏蔽的用户id,一行一个id" class="setting-textarea" id="black-list">{BLACK_LIST}</textarea></br>'
        },
        {
            describe : "自动回复隐藏帖子",
            open : false,
            matchCondition : function(){
                return isMatchPageCategory("thread")
            },
            doAction : function(){
                if($(".alert-warning") && $(".alert-warning").text().indexOf(HAS_HIDDEN_CONTENT_KEYWORD) != -1){
                     var msg = AUTO_REPLY_MSG[Math.floor(Math.random()*AUTO_REPLY_MSG.length)];
                    $(".message .form-control").val(msg)
                    $("#quick_reply_form").submit()
                }
            },
            settingPanelHtml:'识别页面是否有隐藏内容的关键词: </br> <input type="text" id="hide-key" value="{HAS_HIDDEN_CONTENT_KEYWORD}" /> </br></br>  自动回复消息模板: </br> <textarea placeholder="页面有隐藏内容自动回复的消息,一行一条,程序将随机选一条回复" class="setting-textarea" id="auto-reply">{AUTO_REPLY_MSG}</textarea> </br>'
        },
        {
            describe : "键盘左右键翻页",
            open : false,
            matchCondition : function(){
                return true
            },
            doAction : function(){
                $(document).keydown(function(event){
                    if(event.keyCode == 37){
                        let preA = $(".page-link:contains('◀')")
                        if(preA && preA.length > 0){
                            window.location.href = preA.attr("href")
                        }
                    }else if(event.keyCode == 39){
                        let nextA = $(".page-link:contains('▶')")
                        if(nextA && nextA.length > 0){
                            window.location.href = nextA.attr("href")
                        }
                    }
                });
            }
        },
        {
            describe : "阅读模式",
            open : false,
            matchCondition : function(){
                return true
            },
            doAction : function(){
                $(document).find("*").each(function(i,item){
                    if($(item).parents('#helper-setting-panel').length > 0){
                        return
                    }
                    let oldCss = item.style.cssText || ""
                    $(item).css("cssText",oldCss+"background-color:"+BACKGROUND_COLOR+"!important;color:"+FONT_COLOR+"!important;background-image:none!important;")
                })
            },
            settingPanelHtml:'背景色: <input size="7" data-jscolor="{zIndex:9999}" id="background-color-input" value="{BACKGROUND_COLOR}"> &nbsp;&nbsp; 文字颜色: <input size="7" id="font-color-input" value="{FONT_COLOR}" data-jscolor="{zIndex:9999}"> </br>'
        }
    ]


    Function.prototype.getMultiLine = function() {
      var lines = new String(this);
      lines = lines.substring(lines.indexOf("/*") + 3, lines.lastIndexOf("*/"));
      return lines;
    }

    String.prototype.format= function() {
      if(arguments.length === 0) return this;
      var param = arguments[0], str= this;
      if(typeof(param) === 'object') {
        for(var key in param)
          str = str.replace(new RegExp("\\{" + key + "\\}", "g"), param[key]);
        return str;
      } else {
        for(var i = 0; i < arguments.length; i++)
          str = str.replace(new RegExp("\\{" + i + "\\}", "g"), arguments[i]);
        return str;
      }
    }

    function localStorageGetItem(key,defaultVal){
        let val = localStorage.getItem(key)
        return val ? val : defaultVal
    }

    function localStorageGetStringArray(key,defaultVal,split=","){
        let value = localStorage.getItem(key)
        return (value && value.length > 0) ? value.split(split) : defaultVal
    }

    function loadSettingFromLocalStorage(){
        SIGN_TITLE = localStorageGetItem("SIGN_TITLE","签到")
        HAS_HIDDEN_CONTENT_KEYWORD = localStorageGetItem("HAS_HIDDEN_CONTENT_KEYWORD","本帖含有隐藏内容")
        AUTO_REPLY_MSG = localStorageGetStringArray("AUTO_REPLY_MSG",[])
        BLACK_LIST = localStorageGetStringArray("BLACK_LIST",[])
        BACKGROUND_COLOR = localStorageGetItem("BACKGROUND_COLOR","#E3EDCD")
        FONT_COLOR = localStorageGetItem("FONT_COLOR","#000000")

        let fnOpenStatus = localStorageGetStringArray("fnOpenStatus",[])
        for(let i =0;i<fnOpenStatus.length;i++){
          actionArray[i].open = fnOpenStatus[i] == 'true'
        }
    }

    function saveSettingFromLocalStorage(){
      localStorage.setItem("SIGN_TITLE",SIGN_TITLE);
      localStorage.setItem("HAS_HIDDEN_CONTENT_KEYWORD",HAS_HIDDEN_CONTENT_KEYWORD);
      localStorage.setItem("AUTO_REPLY_MSG",AUTO_REPLY_MSG);
      localStorage.setItem("BLACK_LIST",BLACK_LIST);
      localStorage.setItem("BACKGROUND_COLOR",BACKGROUND_COLOR);
      localStorage.setItem("FONT_COLOR",FONT_COLOR);

      let fnOpenStatus = []
      actionArray.forEach(function(e){fnOpenStatus.push(e.open)})
      localStorage.setItem("fnOpenStatus",fnOpenStatus);
    }

    loadSettingFromLocalStorage()

    window.onClickFunctionSwitch = function (checkbox,fnPanelId){
        if(checkbox.checked){
            $("#"+fnPanelId).show(250)
        }else{
            $("#"+fnPanelId).hide(250)
        }
    }

    function functionListHtml(){
      /**
          <div>
            <span>{describe}<span> <input type="checkbox" id="fn-checkbox-{fnIndex}" {checked} onclick="onClickFunctionSwitch(this,'fn-panel-{fnIndex}')"/></br>
            <div style="{displayStyle}" id="fn-panel-{fnIndex}">
                {settingPanelHtml}
            </div>
          </div>
      */
    }

    function updateFunctionSwitch(){
      actionArray.forEach(function(e,i){
          e.open = $("#fn-checkbox-"+i)[0].checked
      })
    }


    function loadJSColor(){
        var input = $("[data-jscolor]");
        for(var i=0;i<input.length;i++){
            var picker = new jscolor(input[i]);
            picker.hash = true;
        }
        jscolor.init();
    }

    window.pop = function pop(){

        let settingData = {
          SIGN_TITLE:SIGN_TITLE,
          HAS_HIDDEN_CONTENT_KEYWORD:HAS_HIDDEN_CONTENT_KEYWORD,
          AUTO_REPLY_MSG:AUTO_REPLY_MSG.join("\n"),
          BLACK_LIST:BLACK_LIST.join("\n"),
          BACKGROUND_COLOR:BACKGROUND_COLOR,
          FONT_COLOR:FONT_COLOR
        }

        let html = ""
        let index = 0
        actionArray.forEach(function(e,i){
            if(index % 2 == 0){
                html += "<div style='width:100%;border:1px solid #96c2f1;background:#eff7ff'>";
            }else{
                html += "<div style='width:100%;border:1px solid #9bdf70;background:#f0fbeb'>";
            }
            e.fnIndex = i
            e.checked= e.open ? "checked='checked'" : ""
            e.displayStyle = e.open ? "" : "display:none;"
            e.settingPanelHtml = e.settingPanelHtml ? e.settingPanelHtml.format(settingData) : ""
            html += functionListHtml.getMultiLine().format(e)
            html += "</div></br>";
            index++
        })

        html = '<div id="helper-setting-panel" style="backgroundColor:white;color:black;">'+ html + '</div>'

        new $Msg({
            useHTML:true,
            content:html,
            type:"success",
            cancle:function(){},
            confirm:function(){
              SIGN_TITLE = $("#sign-key").val();
              HAS_HIDDEN_CONTENT_KEYWORD = $("#hide-key").val();
              AUTO_REPLY_MSG = $("#auto-reply").val().split("\n");
              BLACK_LIST = $("#black-list").val().split("\n");
              BACKGROUND_COLOR = $("#background-color-input").val();
              FONT_COLOR = $("#font-color-input").val();
              updateFunctionSwitch()
              saveSettingFromLocalStorage()
              window.location.reload();
              new $Msg({content:"设置已经保存",contentStyle:{
                  backgroundColor:white,
                  color:black
              }})
            }
        },function(){
            loadJSColor();
        })
    }

    // 设置按钮代码参考:http://greasyfork.icu/zh-CN/scripts/419215-%E8%87%AA%E5%8A%A8%E6%97%A0%E7%BC%9D%E7%BF%BB%E9%A1%B5
    let _style = `<style>#setting_btn {top: calc(75vh) !important;left: 0 !important;width: 32px;height: 32px;padding: 6px !important;display: flex;position: fixed !important;opacity: 0.5;transition: .2s;z-index: 9999 !important;cursor: pointer;user-select: none !important;flex-direction: column;align-items: center;justify-content: center;box-sizing: content-box;border-radius: 0 50% 50% 0;transform-origin: center !important;transform: translateX(-8px);background-color: #eee;-webkit-tap-highlight-color: transparent;box-shadow: 1px 1px 3px 0px #aaa !important;color: #000 !important;font-size: medium;} #Autopage_number:hover {opacity: 0.9;transform: translateX(0);}
    .msg__wrap{position:fixed;top:50%;left:50%;z-index:10;transition:all .3s;transform:translate(-50%,-50%) scale(0,0);max-width:50%;background:#fff;box-shadow:0 0 10px #eee;font-size:10px}.msg__wrap .msg-header{padding:10px 10px 0 10px;font-size:1.8em}.msg__wrap .msg-header .msg-header-close-button{float:right;cursor:pointer}.msg__wrap .msg-body{padding:10px 10px 10px 10px;display:flex}.msg__wrap .msg-body .msg-body-icon{width:80px}.msg__wrap .msg-body .msg-body-icon div{width:45px;height:45px;margin:0 auto;line-height:45px;color:#fff;border-radius:50% 50%;font-size:2em}.msg__wrap .msg-body .msg-body-icon .msg-body-icon-success{background:#32a323;text-align:center}.msg__wrap .msg-body .msg-body-icon .msg-body-icon-success::after{content:"成"}.msg__wrap .msg-body .msg-body-icon .msg-body-icon-wrong{background:#ff8080;text-align:center}.msg__wrap .msg-body .msg-body-icon .msg-body-icon-wrong::after{content:"误"}.msg__wrap .msg-body .msg-body-icon .msg-body-icon-info{background:#80b7ff;text-align:center}.msg__wrap .msg-body .msg-body-icon .msg-body-icon-info::after{content:"注"}.msg__wrap .msg-body .msg-body-content{min-width:200px;font-size:1.5em;word-break:break-all;display:flex;align-items:center;padding-left:10px;box-sizing:border-box}.msg__wrap .msg-footer{padding:0 10px 10px 10px;display:flex;flex-direction:row-reverse}.msg__wrap .msg-footer .msg-footer-btn{width:50px;height:30px;border:0 none;color:#fff;outline:0;font-size:1em;border-radius:2px;margin-left:5px;cursor:pointer}.msg__wrap .msg-footer .msg-footer-cancel-button{background-color:#ff3b3b}.msg__wrap .msg-footer .msg-footer-cancel-button:active{background-color:#ff6f6f}.msg__wrap .msg-footer .msg-footer-confirm-button{background-color:#4896f0}.msg__wrap .msg-footer .msg-footer-confirm-button:active{background-color:#1d5fac}.msg__overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:5;background-color:rgba(0,0,0,.4);transition:all .3s;opacity:0}
    .setting-textarea{width:350px;height:100px;}
    </style>`
    let _html = `<div id="setting_btn" onclick="window.pop();" title=""><svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="toolIconTitle"><path d="M9.74292939,13.7429294 C9.19135019,13.9101088 8.60617271,14 8,14 C4.6862915,14 2,11.3137085 2,8 C2,7.07370693 2.20990431,6.19643964 2.58474197,5.4131691 L6.94974747,9.77817459 L9.77817459,6.94974747 L5.4131691,2.58474197 C6.19643964,2.20990431 7.07370693,2 8,2 C11.3137085,2 14,4.6862915 14,8 C14,8.88040772 13.8103765,9.71652648 13.4697429,10.4697429 L20.5858636,17.5858636 C21.3669122,18.3669122 21.3669122,19.6332422 20.5858636,20.4142907 L19.9142907,21.0858636 C19.1332422,21.8669122 17.8669122,21.8669122 17.0858636,21.0858636 L9.74292939,13.7429294 Z"></path></svg></div>`
    document.documentElement.insertAdjacentHTML('beforeend', _style + _html);

    function isMatchPageCategory(pagePrefix){
        return window.location.href.startsWith(window.location.protocol + "//" + window.location.host + "/" + pagePrefix)
    }


    actionArray.forEach(function(e){
        e.open && e.matchCondition() && e.doAction()
    })
})();


// 弹窗代码地址:https://www.jb51.net/article/145251.htm
(function (window, document) {
  //定义一个构造函数Msg 作为弹窗实例的构造函数。
  let Msg = function (options,callback) {
    //执行初始化操作
    this._init(options);
    callback && callback();
  }
  //定义初始化方法 并对方法传递的参数进行初始化
  Msg.prototype = {
    _init({
      content = "", //文本内容
      type = "info", //信息类型
      useHTML = false, //是否解析html字符串
      showIcon = false, //是否展示弹窗图标
      confirm = null, //确认后得回调
      cancle = null, //取消后得回调
      footer = true, //是否显示底部的确认按钮
      header = true, //是否显示头部信息及关闭按钮
      title = "提示", //弹窗标题
      contentStyle = {}, //内容样式
      contentFontSize = "1.5em", //内容字体大小
      btnName = ["确定", "取消"] //按钮文字内容
    }) {
      //将传入的值绑定到this上
      this.content = content;
      this.type = type;
      this.useHTML = useHTML;
      this.showIcon = showIcon;
      this.confirm = confirm;
      this.cancle = cancle;
      this.footer = footer;
      this.header = header;
      this.title = title;
      this.contentStyle = contentStyle;
      this.contentFontSize = contentFontSize;
      this.btnName = btnName;
      //执行创建元素方法
      this._creatElement();
      //显示弹窗及遮罩
      this._show({
        el: this._el,
        overlay: this._overlay
      });
      //绑定事件处理函数
      this._bind({
        el: this._el,
        overlay: this._overlay
      });
    },
    //创建弹窗元素方法
    _creatElement() {
      //创建最外层得包裹元素
      let wrap = document.createElement("div");
      wrap.className = "msg__wrap";
      //定义弹窗得两个按钮
      const [confirmBtnName, cancelBtnName] = this.btnName;
      //判断是否显示弹窗标题
      const headerHTML = this.header ?
        `<div class="msg-header">
            <span>${this.title}</span>
            <span class="msg-header-close-button">×</span>
          </div>` : "";
      //判断是否显示图标
      const iconHTML = this.showIcon ?
        `<div class="msg-body-icon">
          <div class="msg-body-icon-${this.type}"></div>
        </div>` : "";
      //判断是否显示弹窗底部按钮
      const footerHTML = this.footer ?
        `<div class="msg-footer">
            <button class="msg-footer-btn msg-footer-cancel-button">${cancelBtnName}</button>
            <button class="msg-footer-btn msg-footer-confirm-button">${confirmBtnName}</button>
          </div>` : "";
      //拼接完整html
      const innerHTML = `${headerHTML}
      <div class="msg-body">
        ${iconHTML}
        <div class="msg-body-content"></div>
      </div>
      ${footerHTML}`;
      //将拼接的html赋值到wrap中
      wrap.innerHTML = innerHTML;
      //把自定义的样式进行合并
      const contentStyle = {
        fontSize: this.contentFontSize,
        ...this.contentStyle
      }
      //获取内容所属DOM
      let content = wrap.querySelector(".msg-body .msg-body-content");
      //将传过来的样式添加到contentDOM
      for (const key in contentStyle) {
        if (contentStyle.hasOwnProperty(key)) {
          content.style[key] = contentStyle[key];
        }
      }
      //给弹窗的conntent赋值
      if (this.useHTML) {
        content.innerHTML = this.content;
      } else {
        content.innerText = this.content;
      }
      //创建遮罩层
      let overlay = document.createElement("div");
      overlay.className = "msg__overlay";
      //把dom挂载到当前实例上
      this._overlay = overlay;
      this._el = wrap;
    },
    //弹窗展现方法
    _show({
      el,
      overlay
    }) {
      //把弹窗的dom和遮罩插入到页面中
      document.body.appendChild(el);
      document.body.appendChild(overlay);
      //将弹窗显示出来 timeout进行异步处理显示动画
      setTimeout(() => {
        el.style.transform = "translate(-50%,-50%) scale(1,1)";
        overlay.style.opacity = "1";
      })
    },
    //关闭弹窗方法
    _close({
      el,
      overlay
    }) {
      //隐藏dom
      el.style.transform = "translate(-50%,-50%) scale(0,0)";
      overlay.style.opcity = "0";
      //根据动画时间 动画完成再移除
      setTimeout(() => {
        //把弹窗的dom和遮罩移除
        document.body.removeChild(el)
        document.body.removeChild(overlay);
      }, 300);
    },
    //事件处理函数,为DOM绑定事件
    _bind({
      el,
      overlay
    }) {
      //保存当前this
      //const _this = this;
      const cancle = (e) => {
        this.cancle && this.cancle.call(this, e);
        //隐藏弹窗
        //hideMsg();
        this._close({
          el,
          overlay
        });
      }
      //确认弹窗
      const confirm = (e) => {
        this.confirm && this.confirm.call(this, e);
        this._close({
          el,
          overlay
        });
      }
      //顶部关闭按钮绑定事件
      if (this.header) {
        el.querySelector(".msg-header-close-button").addEventListener("click", cancle);
      }
      //弹窗底部两个按钮事件监听
      if (this.footer) {
        el.querySelector(".msg-footer-cancel-button").addEventListener("click", cancle);
        el.querySelector(".msg-footer-confirm-button").addEventListener("click", confirm)
      }
    }
  }
  //将构造函数暴露到window,这样才能在全局作用域下直接调用
  window.$Msg = Msg;
})(window, document);