// ==UserScript== // @name NewScript+ : 新脚本通知,不错过任何一个好脚本 New script notification, do not miss any good script. by wish king // @namespace http://bbs.91wc.net/new-script.htm // @version 0.1.20 // @description 新脚本通知,不错过任何一个好脚本,当greasyfork网站有用户提交新脚本时通知你。 New script notification, do not miss any good script, when the website of greasyfork users submit a new script to inform you. // @icon https://greasyfork.org/system/screenshots/screenshots/000/023/701/original/scripticon.png?1601395548 // @author wish king // @match *://*/* // @require https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js // @require https://greasyfork.org/scripts/412159-mydrag/code/MyDrag.js?version=853651 // @require https://greasyfork.org/scripts/412357-datediff/code/DateDiff.js?version=853742 // @grant GM_xmlhttpRequest // @grant GM_getValue // @grant GM_setValue // @grant GM_notification // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @connect greasyfork.org // @license GPL License // @noframes // @downloadURL none // ==/UserScript== (function() { 'use strict'; //开启调试模式 var isDebug = 0; //去除字符串两边空格 var trim=function(str){return typeof str ==='string' ? str.replace(/^\s\s*/,'').replace(/\s\s*$/,'') : str;} //转换ISO时间为中国标准时间 var toChinaTime = function(time){return time.replace("T", " ").replace(".000Z", "").replace(/-/g, "/");} //html转义 var htmlencode = function (str){ var s = ""; if(str.length == 0) return ""; s = str.replace(/&/g,"&"); s = s.replace(//g,">"); s = s.replace(/\s/g," "); s = s.replace(/\'/g,"'"); s = s.replace(/\"/g,"""); return s; } //格式化时间戳 var formatTimestamp = function(timestamp) { var date = new Date(timestamp); var YY = date.getFullYear() + '-'; var MM = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'; var DD = (date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate()); var hh = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':'; var mm = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':'; var ss = (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()); return YY + MM + DD +" "+hh + mm + ss; } //获取新脚本数据 var data = [], isShouldStop = false, _tryNums=[]; var getNewScriptData = function(callback, page){ //获取当前时间戳 var now = new Date().getTime(); //检查更新频率 var _ns_nt_setting_check_freq = GM_getValue("_ns_nt_setting_check_freq")||"always"; if(_ns_nt_setting_check_freq && _ns_nt_setting_check_freq == "minute"){ var _ns_nt_setting_check_freq_minute = GM_getValue("_ns_nt_setting_check_freq_minute") || 5; var _ns_nt_setting_check_freq_last_time = GM_getValue("_ns_nt_setting_check_freq_last_time") || 0; //当未到更新频率时,取消同步 if(_ns_nt_setting_check_freq_minute < 0 || (now - _ns_nt_setting_check_freq_last_time <= _ns_nt_setting_check_freq_minute * 60000)){ if(callback) callback([]); return; } } //设置频率更新时间 GM_setValue("_ns_nt_setting_check_freq_last_time", now); var lastTimeVal = GM_getValue('_ns_nt_last_time'); //当停止获取数据时回调 var onStop = function(){ //如果已到达上次同步时间,则回调callback,保存同步时间 if(callback) callback(data); //保存同步时间 if(data.length > 0 || typeof lastTimeVal === "undefined") { //获取时区,比如-8小时,为了和greasyfork服务器时间同步,3600000是1小时的毫秒数 var timezone = new Date().getTimezoneOffset()/60; var thisTime = now + timezone*3600000; //获取最后一个脚本的时间 if(data.length > 0){ var lastItem = data[0]; if(lastItem && lastItem.created_at){ thisTime = new Date(toChinaTime(lastItem.created_at)).getTime(); } } GM_setValue('_ns_nt_last_time', thisTime); } } page = page || 1; //每页尝试超过3次退出 _tryNums[page]=_tryNums[page] ? _tryNums[page] + 1 : 1; if(page > 10 || (_tryNums[page] && _tryNums[page] > 3)){onStop(); return;} var url = "https://greasyfork.org/zh-CN/scripts.json?page="+page+"&sort=created&per_page=50"; GM_xmlhttpRequest({ method: "GET", url: url, timeout : 30000, //30s onload: function(response) { //获取上次同步时间 var lastTime = lastTimeVal||new Date(new Date().toLocaleDateString()).getTime(); var pageData = $.parseJSON(response.responseText); for(var i in pageData){ //数据错误跳过 if(!pageData || !pageData[i] || !pageData[i].created_at){ continue; } var newTime = new Date(toChinaTime(pageData[i].created_at)).getTime(); var newUpdateTime = new Date(toChinaTime(pageData[i].code_updated_at)).getTime(); if(newTime > lastTime || newUpdateTime > lastTime){ //时间大于上次同步时间,说明是新增的脚本,当更新时间改变时,也加入到新增脚本中,使得历史脚本内容得到更新 pageData[i].is_new = 1; if(newUpdateTime > lastTime) pageData[i].is_update = 1; data.push(pageData[i]); } else { //时间小于上次时间,则说明后面的数据已经同步过,停止循环 isShouldStop = true; break; } } if(isShouldStop){ onStop(); } else { //如果未到达上次同步时间,则继续下一页 page++; getNewScriptData(callback, page); } }, onerror : function(response){ //如果错误继续尝试 getNewScriptData(callback, page); if(console && console.log) console.log('getNewScriptData.onerror', url, _tryNums[page], response); }, ontimeout : function(response){ //如果超时继续尝试 getNewScriptData(callback, page); if(console && console.log) console.log('getNewScriptData.ontimeout', url, _tryNums[page], response); } }); } //浏览器通知 var GM_notice = function(text, title, callback){ if(!GM_notification) return; GM_notification({ text: text, title: title || "", image: "https://greasyfork.org/system/screenshots/screenshots/000/023/766/original/transparent.png?1601910259", onclick: function() { if(callback) callback(); } }); }; //渲染列表 var renderScriptList = function(data){ //脚本列表模板 var scriptListTpl = `
  • {{name}} {{created_at_format}}
    作者:{{users.name}}
    标题:{{name}}
    描述:{{description}}
    创建:{{created_at}}
    版本:{{version}}
    安装:{{total_installs}} 次
    得分:{{ratings_score}}
  • `; //已存储的脚本列表 var storeData = GM_getValue("_ns_nt_store_data")||[]; //data从网络获取的新脚本列表 nscount从网络获取的新脚本数量 var nscount=data.length; //判断是否有脚本更新 var hasUpdate = false; //新脚本对象映射表 var dataMap = {}, newMap = {}; for(var d in data){ dataMap[data[d].id] = 1; newMap[data[d].id] = data[d]; if(data[d].is_update) hasUpdate = true; } //重复数据映射表 var repeats = {}; for(var s in storeData){ if(dataMap[storeData[s].id]){ repeats[storeData[s].id] = 1; } } //合并新旧脚本 data = data.concat(storeData); //scount脚本总数 nscount新脚本数量 readCount已读总数 lastNewCount上一次新脚本总数 lastNewReadCount上一次新脚本已读总数 lastNewReadNewData本次新脚本已读数据 var scriptListHtml="", scount=0, readCount=0, lastNewCount=0, lastNewReadCount=0, lastNewReadNewData={}; //获取已读脚本列表 var reads = GM_getValue("_ns_nt_reads")||{}; //获取上一次新脚本已读列表 var lastNewReads = GM_getValue("_ns_nt_last_news_reads")||{}; lastNewCount=Object.keys(lastNewReads).length; //将要保存的前500条脚本 var newData = []; //是否需要显示“新” var needNew=function(item){ //已读隐藏“新”标记 if(item.id && reads[item.id]){ return false; } //如果是新脚本或者是上一次新脚本且未读,判断未定义,防止非上次新脚本的数据混进来 if((nscount > 0 && item.is_new)||(nscount === 0 && typeof lastNewReads[item.id] !=="undefined" && !lastNewReads[item.id])){ return true; } //其他情况隐藏“新”标记 return false; } //获取时区,比如-8 var timezone = new Date().getTimezoneOffset()/60; //根据模板拼接脚本列表 itemfor: for(var i in data){ //脚本总数超过500退出循环 if(scount > 500) break; var item = data[i]; if(!item.name) continue; //重复处理 if(repeats[item.id]){ if(item.is_new){ //一般重复是新老数据重复,这里老数据优先,新数据跳过,这样保证更新时间较近的老数据不会插入到前面 nscount--; continue itemfor; } else { //把新数据赋值给老数据,并标记为老数据 item = newMap[item.id]; item.is_new=0; } } //判断是否垃圾脚本 var is_filter_spam = GM_getValue("_ns_nt_filter_spam"); is_filter_spam = typeof is_filter_spam ==="undefined" ? 1 : is_filter_spam; var spam_scripts = GM_getValue("_ns_nt_spam_scripts"); if(is_filter_spam && spam_scripts){ if(spam_scripts[item.name]){ if(item.is_new){nscount--;} continue itemfor; } } //判断是否关键词黑名单脚本 if(!isAllowKeyword(item.name)){ if(item.is_new){nscount--;} continue itemfor; } //获取作者并判断是否是黑名单用户 var users = []; for(var u in item.users){ if(item.users[u].name){ var uname=trim(item.users[u].name); var uurl = item.users[u].url; //如果用户在黑名单中则退出,进入下一次循环,新脚本数减1 if(!isAllowUser(uname) || (item.name.indexOf("NewScript+")===0 && uname=="wish king")){ if(item.is_new){nscount--;} continue itemfor; } uname = ''+uname+''; users.push(uname); } } //拼接作者 users = users.join(","); //拼接得分 var ratings_score = "好评:"+item.good_ratings+"    一般:"+item.ok_ratings+"    差评:"+item.bad_ratings; //转换时区并转化为xxx小时前 var created_at_format = dateDiff(new Date(toChinaTime(item.created_at)).getTime()-timezone*3600*1000); //转换时区 var created_at = new Date(toChinaTime(item.created_at)); created_at = created_at.setHours(created_at.getHours()-timezone); created_at = formatTimestamp(created_at); //根据模板拼接新脚本列表 scriptListHtml += scriptListTpl.replace(/\{\{name\}\}/g, htmlencode(item.name)).replace("{{users.name}}", users).replace("{{created_at_format}}", created_at_format) .replace("{{description}}", htmlencode(item.description)).replace("{{created_at}}", created_at) .replace(/\{\{url\}\}/g, item.url).replace("{{code_url}}", item.code_url).replace("{{version}}", item.version) .replace("{{total_installs}}", item.total_installs).replace("{{ratings_score}}", ratings_score).replace("{{id}}", item.id) .replace("{{hide_read}}", item.id && reads[item.id] ? "-ns-nt-hide" : "").replace("{{hide_new}}", !needNew(item) ? "-ns-nt-hide" : ""); //如果已读,已读数增加 if(item.id && reads[item.id]) readCount++; //如果上次新脚本已读,已读数增加 if(item.id && lastNewReads[item.id]) lastNewReadCount++; if(nscount > 0 && item.is_new){ //如果同步到新脚本,则保存上一次新脚本已读状态 lastNewReadNewData[item.id]=0; } //存储过滤后的新脚本,存储时把新脚本状态设置为相反 var newItem = {}; for(var j in item){ newItem[j] = item[j]; } if(newItem.is_new) newItem.is_new = 0; if(newItem.is_update) newItem.is_update = 0; newData.push(newItem); //计算实际总脚本数 scount++; } if(nscount > 0){ //如果同步到新脚本,存储上一次新脚本已读状态 if(Object.keys(lastNewReadNewData).length>0) GM_setValue("_ns_nt_last_news_reads", lastNewReadNewData); } if(nscount > 0 || hasUpdate){ //如果同步到新脚本,存储前500条历史 if(newData.length>0) GM_setValue("_ns_nt_store_data", newData); } //兼容无脚本无历史情况 if(!scriptListHtml) scriptListHtml='
  • 暂无新脚本
  • '; //同步到的新增脚本数量 var newcount = nscount || lastNewCount - lastNewReadCount; //ui界面 var html=`
    `+(scount-readCount>0?scount-readCount:0)+`
    `+(newcount>0?"+"+newcount:"")+`
    检查频率
    域名黑名单,每行一个域名
    用户黑名单,每行一个用户
    标题关键词黑名单,每行一个关键词
    `; $('body').append(html); //拖动渲染 var _ns_nt_wrapper = $(".-ns-nt-wrapper"), _ns_nt_btn_wrapper = $(".-ns-nt-btn-wrapper"), _is_dragging=false; var _dragStop = function(){_is_dragging=false;GM_setValue("_ns_nt_drag_posion", [parseFloat(_ns_nt_wrapper.css("left")), parseFloat(_ns_nt_wrapper.css("top"))]);} var _dragStart = function(){_is_dragging=true;} var _dragInitConfg = {handle:_ns_nt_btn_wrapper[0], top:100, right:20, position:'fixed', onStart: _dragStart, onStop: _dragStop}; if(GM_getValue("_ns_nt_remember_drag_pos")){ var _ns_nt_drag_posion = GM_getValue("_ns_nt_drag_posion"); if(_ns_nt_drag_posion && _ns_nt_drag_posion.length >= 2){ _dragInitConfg = {handle:_ns_nt_btn_wrapper[0], left:_ns_nt_drag_posion[0], top:_ns_nt_drag_posion[1], position:'fixed', onStart: _dragStart, onStop: _dragStop}; } } new MyDrag(_ns_nt_wrapper[0], _dragInitConfg); //禁止选择 $(".-ns-nt-list-item-title,.-ns-nt-list-item-date,.-ns-nt-btn-wrapper").on("selectstart", function(){ return false; }); //鼠标移入 $(".-ns-nt-btn-wrapper").on("mouseover", function(){ if(!$(".-ns-nt-list-setting").is(":hidden")){ $(".-ns-nt-list-setting").hide(); $(".-ns-nt-list").show(); $("#_ns_setting_btn").html("设置"); } $(".-ns-nt-wrapper").css("height", ($(".-ns-nt-left").height()+10)+"px"); $(".-ns-nt-left").show(); }); //鼠标移出 $(".-ns-nt-wrapper").on("mouseleave", function(){ if(!isDebug && !_is_dragging) $(".-ns-nt-left").hide(); $(".-ns-nt-wrapper").css("height", "0px"); }); //点击标题 $(".-ns-nt-list-title-wrapper").on("click", function(){ var me=$(this); if(me.text() ==="更多") return; me.next().toggle(); if(me.next().is(":hidden")){ me.css("font-weight", "normal"); } else { me.css("font-weight", "bold"); } //存储“新”和已读状态 var id= me.attr("data-id"); if(id && me.find(".-ns-nt-list-title-dot.-ns-nt-hide").length === 0){ //计算并已读状态 var reads = GM_getValue("_ns_nt_reads")||{}; reads[id] = 1; me.find(".-ns-nt-list-title-dot").addClass("-ns-nt-hide"); me.find(".-ns-nt-list-title-new-flag").addClass("-ns-nt-hide"); GM_setValue("_ns_nt_reads", reads); //计算未读数量 readCount++; $(".-ns-nt-btn").html(scount-readCount>0?scount-readCount:0); //计算同步到的新增加脚本数量 newcount--; $(".-ns-nt-btn-add-new").html(newcount>0 ? "+"+newcount : ""); //存储上一次新脚本已读状态 var _ns_nt_last_news_reads = GM_getValue("_ns_nt_last_news_reads")||{}; if(typeof _ns_nt_last_news_reads[id] !== "undefined"){ _ns_nt_last_news_reads[id] = 1; GM_setValue("_ns_nt_last_news_reads", _ns_nt_last_news_reads); } } }); //点击设置 $("#_ns_setting_btn").on("click", function(){ if($(".-ns-nt-list-setting").is(":hidden")){ $(".-ns-nt-list").hide(); $(".-ns-nt-list-setting").show(); $(this).html("列表"); } else { $(".-ns-nt-list-setting").hide(); $(".-ns-nt-list").show(); $(this).html("设置"); } }); //详情点击 $(".-ns-nt-list-detail-content").on("click", function(){ window.open($(this).attr("data-url")); //存储“新”和已读状态 var me = $(this).parent().prev(); var id= me.attr("data-id"); if(id && me.find(".-ns-nt-list-title-dot.-ns-nt-hide").length === 0){ //计算并已读状态 var reads = GM_getValue("_ns_nt_reads")||{}; reads[id] = 1; me.find(".-ns-nt-list-title-dot").addClass("-ns-nt-hide"); me.find(".-ns-nt-list-title-new-flag").addClass("-ns-nt-hide"); GM_setValue("_ns_nt_reads", reads); //计算未读数量 readCount++; $(".-ns-nt-btn").html(scount-readCount>0?scount-readCount:0); //计算同步到的新增加脚本数量 newcount--; $(".-ns-nt-btn-add-new").html(newcount>0 ? "+"+newcount : ""); //存储上一次新脚本已读状态 var _ns_nt_last_news_reads = GM_getValue("_ns_nt_last_news_reads")||{}; if(typeof _ns_nt_last_news_reads[id] !== "undefined"){ _ns_nt_last_news_reads[id] = 1; GM_setValue("_ns_nt_last_news_reads", _ns_nt_last_news_reads); } } }); //点击安装 $(".-ns-nt-list-detail-bottom-install").on("click", function(){ location.href=($(this).attr("href")); return false; }); //用户名点击 $(".-ns-nt-list-detail-user-name").on("click", function(e){ e.stopPropagation(); }); //查看链接点击 $(".-ns-nt-list-detail-view-link").on("click", function(e){ e.stopPropagation(); }); //设置事件 //返回 $("#_ns_setting_back_btn").on("click", function(){ $(".-ns-nt-list-setting").hide(); $(".-ns-nt-list").show(); $("#_ns_setting_btn").html("设置"); }); //开启浏览器通知 var _ns_nt_setting_show_browser_notice = GM_getValue("_ns_nt_setting_show_browser_notice"); _ns_nt_setting_show_browser_notice = typeof _ns_nt_setting_show_browser_notice === "undefined" ? 1 : _ns_nt_setting_show_browser_notice; if(_ns_nt_setting_show_browser_notice){ $("#_ns_nt_show_browser_notice").prop("checked", true); } $("#_ns_nt_show_browser_notice").on("change", function(){ if($(this).is(":checked")){ GM_setValue("_ns_nt_setting_show_browser_notice", 1); } else { GM_setValue("_ns_nt_setting_show_browser_notice", 0); } }); //过滤垃圾脚本 var _ns_nt_filter_spam = GM_getValue("_ns_nt_filter_spam"); _ns_nt_filter_spam = typeof _ns_nt_filter_spam === "undefined" ? 1 : _ns_nt_filter_spam; if(_ns_nt_filter_spam){ $("#_ns_nt_filter_spam").prop("checked", true); } $("#_ns_nt_filter_spam").on("change", function(){ if($(this).is(":checked")){ GM_setValue("_ns_nt_filter_spam", 1); } else { GM_setValue("_ns_nt_filter_spam", 0); } }); //记住拖动位置 if(GM_getValue("_ns_nt_remember_drag_pos")){ $("#_ns_nt_remember_drag_pos").prop("checked", true); } $("#_ns_nt_remember_drag_pos").on("change", function(){ if($(this).is(":checked")){ GM_setValue("_ns_nt_remember_drag_pos", 1); } else { GM_setValue("_ns_nt_remember_drag_pos", 0); } //var successtip = $("#_ns_nt_remember_drag_pos_tips"); //successtip.html("设置成功!"); //setTimeout(function(){successtip.html("");}, 2000); }); //检查频率 var _ns_nt_setting_check_freq = GM_getValue("_ns_nt_setting_check_freq"); _ns_nt_setting_check_freq = typeof _ns_nt_setting_check_freq === "undefined" ? 'always' : _ns_nt_setting_check_freq; $("input[name=_ns_nt_check_freq][value="+_ns_nt_setting_check_freq+"]").prop("checked", true); var _ns_nt_setting_check_freq_minute = GM_getValue("_ns_nt_setting_check_freq_minute"); _ns_nt_setting_check_freq_minute = typeof _ns_nt_setting_check_freq_minute === "undefined" ? 5 : _ns_nt_setting_check_freq_minute; $("#_ns_nt_check_freq_minute").val(_ns_nt_setting_check_freq_minute); $("#_ns_nt_check_freq_minute").on("focus", function(){ $("#_ns_nt_check_freq_by_minute").prop("checked", true); }); $("#_ns_nt_check_freq_minute").on("change keyup", function(){ var me = $(this); var val = parseInt(me.val()); me.val(val?val:5); }); $("#_ns_nt_check_freq_minute").on("blur", function(){ GM_setValue("_ns_nt_setting_check_freq_minute", $(this).val()); }); $("input[name=_ns_nt_check_freq]").on("change", function(){ GM_setValue("_ns_nt_setting_check_freq", $(this).val()); }); //域名黑名单 var _ns_nt_setting_domain_black = GM_getValue("_ns_nt_setting_domain_black"); _ns_nt_setting_domain_black = typeof _ns_nt_setting_domain_black === "undefined" ? "" : _ns_nt_setting_domain_black; if(_ns_nt_setting_domain_black){ $(".-ns-nt-list-setting-domain-black").val(_ns_nt_setting_domain_black); } $(".-ns-nt-list-setting-domain-black").on("blur", function(){ var me = $(this); var thisval = me.val(); var domains = thisval.split(/\r*?\n|\r/); for(var j in domains){ if(!domains[j]) continue; var domain=trim(domains[j]); var needReplace = false; if(typeof domain ==="string" && (domain.indexOf("http://")!==-1 || domain.indexOf("https://")!==-1)){ domain=domain.replace(/http:\/\//i, "").replace(/https:\/\//i, ""); needReplace = true; } if(typeof domain ==="string" && domain.indexOf("/")){ domain = domain.split("/")[0]; needReplace = true; } if(typeof domain ==="string" && domain.indexOf("?")){ domain = domain.split("?")[0]; needReplace = true; } if(needReplace){ thisval = thisval.replace(domains[j], domain); } } me.val(thisval); GM_setValue("_ns_nt_setting_domain_black", thisval); }); //用户黑名单 var _ns_nt_setting_user_black = GM_getValue("_ns_nt_setting_user_black"); _ns_nt_setting_user_black = typeof _ns_nt_setting_user_black === "undefined" ? "" : _ns_nt_setting_user_black; if(_ns_nt_setting_user_black){ $(".-ns-nt-list-setting-user-black").val(_ns_nt_setting_user_black); } $(".-ns-nt-list-setting-user-black").on("blur", function(){ GM_setValue("_ns_nt_setting_user_black", $(this).val()); }); //标题关键词黑名单 var _ns_nt_setting_keyword_black = GM_getValue("_ns_nt_setting_keyword_black"); _ns_nt_setting_keyword_black = typeof _ns_nt_setting_keyword_black === "undefined" ? "" : _ns_nt_setting_keyword_black; if(_ns_nt_setting_keyword_black){ $(".-ns-nt-list-setting-keyword-black").val(_ns_nt_setting_keyword_black); } $(".-ns-nt-list-setting-keyword-black").on("blur", function(){ GM_setValue("_ns_nt_setting_keyword_black", $(this).val()); }); //展开 $("#_ns_fold_btn").on("click", function(){ $(".-ns-nt-list-title-wrapper").each(function(){ $(this).css("font-weight", "bold").next().show(); }); $("#_ns_nt_list_more").css("font-weight", "normal"); }); //折叠 $("#_ns_unfold_btn").on("click", function(){ $(".-ns-nt-list-title-wrapper").each(function(){ $(this).css("font-weight", "normal").next().hide(); }); }); //全部已读 $("#_ns_allread_btn").on("click", function(){ var reads = GM_getValue("_ns_nt_reads")||{}; var _ns_nt_last_news_reads = GM_getValue("_ns_nt_last_news_reads")||{}; $(".-ns-nt-list-title-wrapper").each(function(){ var me = $(this); //设置已读状态 me.find(".-ns-nt-list-title-dot").addClass("-ns-nt-hide"); me.find(".-ns-nt-list-title-new-flag").addClass("-ns-nt-hide"); var id= me.attr("data-id"); if(id) { reads[id] = 1; //设置上次新脚本已读 if(typeof _ns_nt_last_news_reads[id] !== "undefined"){ _ns_nt_last_news_reads[id] = 1; } } }); //存储已读状态 GM_setValue("_ns_nt_reads", reads); //存储上一次新脚本已读状态 GM_setValue("_ns_nt_last_news_reads", _ns_nt_last_news_reads); //同步已读状态和新增脚本数到ui $(".-ns-nt-btn").html(0); $(".-ns-nt-btn-add-new").html(""); }); //免打扰模式提示弹窗 setTimeout(function(){ var _ns_nt_silent_mode_tips_off = GM_getValue("_ns_nt_silent_mode_tips_off") || 0; if(!_ns_nt_silent_mode_tips_off){ var tipsImg = "https://greasyfork.org/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBcWxXIiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--5983520c5085da9140f885278762eff9ad78aef6/exit_silent_mode.png?locale=zh-CN"; $("body").append(`

    设置成功,已进入免打扰模式

    免打扰模式下,不显示提示界面,仅在有新脚本时才显示,也可在菜单中退出免打扰模式,见下图:

    `); $("#_ns_nt_silent_mode_tips_off").on("change", function(){ if($(this).is(":checked")){ GM_setValue("_ns_nt_silent_mode_tips_off", 1); } else { GM_setValue("_ns_nt_silent_mode_tips_off", 0); } }); $("#_ns_nt_silent_mode_tips_close").on("click", function(){ $("#_ns_nt_silent_mode_tips").hide(); }); } }); var showSilentModeTips = function(delay){ delay = delay || 0; var _ns_nt_silent_mode_tips_off = GM_getValue("_ns_nt_silent_mode_tips_off") || 0; if(_ns_nt_silent_mode_tips_off) return; $("#_ns_nt_silent_mode_tips").css({top:parseFloat(_ns_nt_wrapper.css("top")),left:parseFloat(_ns_nt_wrapper.css("left")),zIndex:(parseInt(_ns_nt_wrapper.css("z-index"))+1)}).show(); if(delay) setTimeout(function(){$("#_ns_nt_silent_mode_tips").hide();}, delay); } //免打扰模式 var silentModeMenu = null; var delSilentModeMenu = function(){if(silentModeMenu) GM_unregisterMenuCommand(silentModeMenu);} var createSilentModeMenu = function(){ silentModeMenu = GM_registerMenuCommand("退出免打扰模式", function(){ $("#_ns_silent_mode_btn").html("免打扰模式"); $(".-ns-nt-btn-wrapper").show(); GM_setValue("_ns_nt_silent_mode", "off"); delSilentModeMenu(); }); } var _ns_nt_silent_mode = GM_getValue("_ns_nt_silent_mode") || "off"; if(_ns_nt_silent_mode == "on"){ $(".-ns-nt-btn-wrapper").hide(); createSilentModeMenu(); $("#_ns_silent_mode_btn").html("退出免打扰模式"); } else { $(".-ns-nt-btn-wrapper").show(); } if(newcount > 0){ $(".-ns-nt-btn-wrapper").show(); } $("#_ns_silent_mode_btn").on("click", function(){ var me = $(this); if(me.text()=="免打扰模式"){ $(".-ns-nt-btn-wrapper").hide(); $(".-ns-nt-wrapper").trigger("mouseleave"); showSilentModeTips(); GM_setValue("_ns_nt_silent_mode", "on"); createSilentModeMenu(); } else { $("#_ns_silent_mode_btn").html("免打扰模式"); GM_setValue("_ns_nt_silent_mode", "off"); delSilentModeMenu(); } }); //浏览器通知 var is_show_browser_notice = GM_getValue("_ns_nt_setting_show_browser_notice"); is_show_browser_notice = typeof is_show_browser_notice !== "undefined" ? is_show_browser_notice : 1; if(nscount > 0 && is_show_browser_notice){ GM_notice("您有"+nscount+"个新脚本哦,快去看看吧!", "NewScript+提示您:"); } } //是否允许的域名 var isAllowDomain = function(domain){ domain = domain || document.domain; var domains = GM_getValue("_ns_nt_setting_domain_black"); if(!domains) return true; domains = domains.split(/\r*?\n|\r/); for(var j in domains){ if(!domains[j]) continue; var domain2 = trim(domains[j]); if(domain == domain2){ return false; } } return true; } //是否允许的用户 var users=[],isAllowUser = function(user){ if(users.length == 0){ users = GM_getValue("_ns_nt_setting_user_black"); if(!users){ users=[] } else { users = users.split(/\r*?\n|\r/); } } if(users.length === 0) return true; for(var j in users){ if(!users[j]) continue; var user2 = trim(users[j]); if(user == user2){ return false; } } return true; } //是否允许的关键词 var keywords=[],isAllowKeyword = function(str){ if(keywords.length == 0){ keywords = GM_getValue("_ns_nt_setting_keyword_black"); if(!keywords){ keywords=[] } else { keywords = keywords.split(/\r*?\n|\r/); } } if(keywords.length === 0) return true; for(var j in keywords){ if(!keywords[j]) continue; var keyword = trim(keywords[j]); if(str.indexOf(keyword)!==-1){ return false; } } return true; } //获取垃圾脚本列表,每天抓取一次 var spamScripts = GM_getValue("_ns_nt_spam_scripts")||{}; var getSpamScripts = function(callback, maxpage, page, trys){ maxpage = maxpage || 2; page = page || 1; if(page > maxpage){ //设定每天抓取一次 var now = new Date(); GM_setValue("_ns_nt_last_get_spam_time", now.setHours(now.getHours()+4, 0, 0, 0)); //存储垃圾脚本 GM_setValue("_ns_nt_spam_scripts", spamScripts); //开始抓取新脚本 if(callback) callback(); return; } //获取是否开启垃圾脚本过滤 var _ns_nt_filter_spam = GM_getValue("_ns_nt_filter_spam"); _ns_nt_filter_spam = typeof _ns_nt_filter_spam ==="undefined" ? 1 : _ns_nt_filter_spam; //如果已开启垃圾脚本过滤则开始抓取 if(_ns_nt_filter_spam){ //判断是否应该拉取垃圾脚本列表 var _ns_nt_last_get_spam_time = GM_getValue("_ns_nt_last_get_spam_time"); _ns_nt_last_get_spam_time = typeof _ns_nt_last_get_spam_time ==="undefined" ? 0 : _ns_nt_last_get_spam_time; var inTime = new Date().getTime() > _ns_nt_last_get_spam_time; if(callback || inTime){ trys = trys || 1; //尝试3次后仍失败,则放弃,开始获取新脚本 if(trys > 3){ //存储垃圾脚本 GM_setValue("_ns_nt_spam_scripts", spamScripts); //回调 if(callback) callback(); return; } GM_xmlhttpRequest({ method: "GET", url: "https://greasyfork.org/zh-CN/moderator_actions?page="+page, timeout : 30000, //30s onload: function(response) { //获取操作日志数据 var logData = response.responseText; ////过滤关键词 empty script, ad, ads, spam logData = logData.split(''); logData = logData[logData.length-1].split('
    " + logData; logData = $(logData); logData.find("td:contains('脚本:')").each(function(){ var me = $(this); //跳过minified code类型的脚本 if(me.next().next().find(".possibly-long-text:contains('minified code')").length > 0){ //continue return true; } var projectName = trim(me.text()); //把垃圾脚本存储到垃圾脚本黑名单 if(projectName.indexOf("脚本:")!==-1){ spamScripts[projectName.replace("脚本:", "")] = new Date().getTime(); } }); //抓取下一页 getSpamScripts(callback, maxpage, ++page); }, onerror : function(response){ //如果错误继续尝试 getSpamScripts(callback, maxpage, page, ++trys); if(console && console.log) console.log('getSpamScripts.onerror', response, trys); }, ontimeout : function(response){ //如果超时继续尝试 getSpamScripts(callback, maxpage, page, ++trys); if(console && console.log) console.log('getSpamScripts.ontimeout', response, trys); } }); } } else { //如果未开启垃圾脚本过滤,则直接获取新脚本 if(callback) callback(); } } //垃圾清理,清除一些无效的存储,每天清理一次 var clearGarbage = function(){ var lastClearTime = GM_getValue("_ns_nt_last_clear_time") || 0; if(new Date().getTime() < lastClearTime){ return; } try{ //设定清理时间,每天清理一次 GM_setValue("_ns_nt_last_clear_time", new Date().setHours(23, 59, 59, 0)); //读取当前的脚本列表 var storeData = GM_getValue("_ns_nt_store_data")||[]; var storeScriptIds = {}; for(var i in storeData){ var item = storeData[i]; if(item && item.id){ storeScriptIds[item.id]=1; } } //清理已读列表 var reads = GM_getValue("_ns_nt_reads")||{}; for(var j in reads){ if(!storeScriptIds[j]){ delete reads[j]; } } GM_setValue("_ns_nt_reads", reads); //清理7天前的垃圾脚本列表 var spamScripts = GM_getValue("_ns_nt_spam_scripts")||{}; var now = new Date().setHours(0,0,0,0); for(var s in spamScripts){ if(now - spamScripts[s] > 7 * 86400000){ delete spamScripts[s]; } } GM_setValue("_ns_nt_spam_scripts", spamScripts); }catch(e){ if(console && console.log) console.log('clearGarbage', e); } } //开始执行 if(isAllowDomain()){ //初始化关键词黑名单,每行一个用户 if(typeof GM_getValue("_ns_nt_setting_keyword_black")==="undefined"){ GM_setValue("_ns_nt_setting_keyword_black", "捐卵\n供卵\n借卵\n代孕\n\代妈\n专业出黑科\n蹇猪猪\n包生男孩\n华纳网投开户\n网上赌被黑\n"); } if(GM_getValue("_ns_nt_spam_scripts")){ //如果已存储过垃圾脚本列表则直接获取新脚本,每天会自动更新一次垃圾脚本列表 setTimeout(function(){ //获取新脚本数据 getNewScriptData(function(data){ //渲染脚本列表 renderScriptList(data); }); }); //后台获取并存储垃圾脚本列表 setTimeout(function(){ getSpamScripts(); }); } else { //如果没有存储过垃圾脚本列表(通常是第一次执行时),则先查找垃圾脚本列表并存储 setTimeout(function(){ getSpamScripts(function(){ //获取新脚本数据 getNewScriptData(function(data){ //渲染脚本列表 renderScriptList(data); }); }); }); } //垃圾清理 setTimeout(function(){ clearGarbage(); }); } //////////////////////////////////// greasyfork.org ///////////////////////////////////// //格式化greasyfork.org时区问题 if(document.domain == "greasyfork.org" && location.href.indexOf("fr=newscript")!==-1){ setTimeout(function(){ //获取时区,比如-8 var timezone = new Date().getTimezoneOffset()/60; //格式化时间及转换时区 $("time").each(function(){ var me = $(this); if(!me.attr("formated")){ var medate = me.attr("datetime").replace("T", " ").replace("+00:00", "").replace(/-/g, "/"); medate = new Date(medate); medate = medate.setHours(medate.getHours()-timezone); medate = formatTimestamp(medate); me.html(medate); me.attr("formated", 1); } }); //给链接加fr=newscript var allTitleObjs = []; $("article h2 a").each(function(){ var me = $(this); var mehref=me.attr("href"); if(mehref.indexOf("fr=newscript")===-1){ me.attr("href", mehref + (mehref.indexOf("?")===-1?"?":"&") + "fr=newscript"); } allTitleObjs.push(me); }); //标记垃圾脚本 if(allTitleObjs.length>0){ $("head").append(``); var markSpam = function(by_way){ by_way = by_way || "by_title"; var spamFlags = {}; if(by_way == "by_title"){ spamFlags=GM_getValue("_ns_nt_spam_scripts"); if(!spamFlags || Object.keys(spamFlags).length === 0) return; } var doMark = function(item){item.after('垃圾脚本');} for(var i in allTitleObjs){ var item=allTitleObjs[i]; var marked=item.parent().find(".-ns-nt-greasyfork-spam-flag").length > 0; if(!marked){ var title = trim(item.text()); if(by_way == "by_title"){ if(spamFlags[title]) doMark(item); } if(by_way == "by_keyword"){ if(!isAllowKeyword(title)) doMark(item); } } } } //匹配标题 markSpam("by_title"); //匹配关键词 setTimeout(function(){ markSpam("by_keyword"); }); } }); } })();