// ==UserScript== // @name 网购省钱小助手:自动查询京东、淘宝、聚划算、天猫等隐藏的优惠券;自动历史价格查询;界面优化等;低侵入、持续维护更新😈 // @name:zh 网购省钱小助手:自动查询京东、淘宝、聚划算、天猫等隐藏的优惠券;自动历史价格查询;界面优化等;低侵入、持续维护更新😈 // @name:zh-TW 網購省錢小助手:自動查詢京東、淘寶、聚划算、天貓等隱藏的優惠券;自動曆史價格查詢;界面優化等;低侵入、持續維護更新😈 // @namespace coupon_honghonghuohuo_namespace_20230625 // @version 2.2.2 // @description 用电脑端访问淘宝、天猫、京东等不会主动领取优惠券,此脚本可以把只有APP端能看到的或本来就隐藏的大额优惠券给查询出来,有券不领非好汉~ 脚本采用低侵入形式,不会破坏网页结构,大家可以放心使用 // @description:zh 用电脑端访问淘宝、天猫、京东等不会主动领取优惠券,此脚本可以把只有APP端能看到的或本来就隐藏的大额优惠券给查询出来,有券不领非好汉~ 脚本采用低侵入形式,不会破坏网页结构,大家可以放心使用 // @description:zh-TW 用電腦端訪問淘寶、天貓、京東等不會主動領取優惠券,此指令碼或直譯式程式可以把只有APP端能看到的或本來就隱藏的大額優惠券給查詢出來,有券不領非好漢~ 指令碼或直譯式程式採用低侵入形式,不會破壞網頁結構,大家可以放心使用 // @author 红红火火 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAFxklEQVR4Xu2be6gUVRzHv799nLEHJfYivTtrj+vMerMXUvaCrCA0KCuSpAdaiYUaWCEVQkpkYA9CeyGG0oOSoCcZGKhoUmYWBrfdVbG7s1cTLEgCc8/cnV/M3gfX6+7OnN3x7syt+ff8zvl9f5/5nXN2zvkt4T/+UH/8OV0sBjALwOV1mHQRaKNhleaNFG4VAFk9uZJAC/0GxcCyjCWX+rUPsx1lx48aT47zm6pIjsUuyHQd61LtFzZ72ptOXlFm+klZGGOGWZSfK/cLWQf6cSxOPT2e7ALROSramPjVTMF+UqVPGG0ra0A+pS1yA1IUuNO05FWKfUJnPrALdLYlr45TbC7gXHScSqIba6keCevAAIBqQebHC5Md/AxgVLV2hzFrYlF+FLrXqiCoLoDe6SG+Y8KU6mPya6ZlL1LwFzpTTwA5XXsL4EerKSfG90ZRXhO6qBQEeQLI68kHGPSuwphhNf0LwDbTkrcPFugJYP8Fp50ny/ahsEalqouATsOSl/T38wTgGubSYjcYl6o6C6094X6zID9w9fkDkEpuRp3tMLSB1hA2+FvGH4C0uA+M96MWaM3fL4M+5nwB6GzDmERM7GfgzBEBgfkhs2iv9T0FKutASmwAYdpIAFB2qL2ju7RPDUBaLAHj+REA4KBpyXFKu0DvTjBqKtjZFHUABKw3LHmvMoDNQOJ8PXkAoHOjDIGIFhiF0hvKAPp+D3wKxowoAygTX9lRsN0PvMrjaxfoN86mtaeI+aUIAzhiWnL0YP2KABLXEse2RxjAl8rfAkODzaVFAQw9khCIFpuF0nEZrJQBbtDZtPiQGAOraJRAsONMzXT3bGl4ClQA6NpCAq+MUuB9Wu0zeuTosQdxtDkAbWISxfBL9ADwJtOybx6qW3kKVLZDXewB0B4pCIQXzIJcEgiAvC7WMjA7UgBqXOQ0lgHp5MNgWhMlAA4lxk4sHP09kAxo9D6xVcCIsMMoyKon2w1lQN864C6Ek1oVlIpfZn49U7Sr3n43AUB7G+BI1AkQ+EHDst+rBq0JAGImgPUqb6JVthRDxuiSuUABZMfhLIqLP1oVlG+/zFvMoj21ln3DGdC3DuwEMNm3mNYYzjQt+fFJAZBPJV9mopDWCNB2MFaYxdIX9bg3lQH5tDaNmTfUcLDLtGTYs0PtQGRooJ0dEPG/xbFaBysMnpyx7F2tyXx/XpvKgN51QNsK8A3V3DF4XsayV/uT0hqrpgHkdfEcA1VL5gi0Ouw1hQEASFzPiG2L6jrQNIC+7dA9ZDilNUl8nFe3BmAr4KwwrR5fZ5dBAfgKwPQQABiQUHZ4Ske3vcNLUyAA8intCSZ+xcvZsLYzvWMWS494+QwEQMPVpl7qmmknfGYW5J1eQwQCoFJtmhDux0bKy+Fwtfst6A4EgBtUNq0tIOZVwxWglx/Tkr5i82Xk5ay/PddbSXIHmJXqjv2O72lHdJSBnSql/IEC8BQYQoP/AYTwpQyrpJOWAblU8jEQuScx94DxNRN+UJmb9SjsSYu7mOlWB3xTDCg5xBsTTGvaLfmrKr2TAiCXEgXQiTfIBBxzynRZ5kDJvVlq6MnpouavTgKWGpZcpjJw4ACyuniGgOU1RXic0dUTn09r05nZBVDzISfeZnT/c8AvhEAB+L4wGVSq6leoa5fTtW8Bvq5eHwavylj2437HDRZAKjmbiCoFiHXfErDOsOQcL7uh7TldOwzw2fUBYF/Gkr4vbgMF0PdDyEdJLa0xrdJcdQDiTwBjQgsgO06bQHHOewXGzHMyRXudl93Q9rwudjBQ949aqqdQgWaAKzivJ79h0C11gjsSl7K9/RAOqwLI6uJFAp6u1y9GuHtCQX7id+zAAXgthMQ83yjab/oVeOI6ILhO3w2mJW9TGTtwAK7zvRdD67GTy4nJFWMA2E+E3SA8W+uOTkV0Pq3Nd6cRgAsBKruJR4TlRqFU646i9rap4ngk2v4L+LTwUPWENukAAAAASUVORK5CYII= // @match *://*.taobao.com/* // @match *://*.tmall.com/* // @match *://*.tmall.hk/* // @match *://*.liangxinyao.com/* // @match *://chaoshi.detail.tmall.com/* // @match *://pages.tmall.com/wow/an/cs/search** // @match *://*.jd.com/* // @match *://*.jd.hk/* // @match *://item.jkcsjd.com/* // @match *://*.yiyaojd.com/* // @match *://www.vipglobal.hk // @match *://*.vip.com/* // @match *://detail.vip.com/detail-* // @match *://www.vipglobal.hk/detail-* // @match *://category.vip.com/suggest.php** // @match *://list.vip.com/*.html // @exclude *://jianghu.taobao.com/* // @exclude *://login.taobao.com/* // @exclude *://uland.taobao.com/* // @exclude *://map.taobao.com/* // @exclude *://creator.guanghe.taobao.com/* // @exclude *://myseller.taobao.com/* // @exclude *://qn.taobao.com/* // @exclude *://jingfen.jd.com/* // @exclude *://passport.jd.com/* // @exclude *://jmw.jd.com/* // @exclude *://passport.shop.jd.com/* // @exclude *://passport.vip.com/* // @exclude *://huodong.taobao.com/wow/z/guang/gg_publish/* // @require https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.2.1/jquery.min.js // @require https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/keypress/2.1.5/keypress.min.js // @connect tt.shuqiandiqiu.com // @connect j.jiayoushichang.com // @grant GM_openInTab // @grant GM.openInTab // @grant GM_getValue // @grant GM.getValue // @grant GM_setValue // @grant GM.setValue // @grant GM_addStyle // @grant GM_xmlhttpRequest // @grant GM.xmlHttpRequest // @grant GM_registerMenuCommand // @license AGPL License // @antifeature referral-link 【此提示为GreasyFork代码规范要求含有查券功能的脚本必须添加,实际使用无任何强制跳转,代码可查,请知悉】 // @charset UTF-8 // @run-at document-idle // ==/UserScript== (function () { 'use strict'; /** * 脚本遵循AGPL License开源协议;在协议允许的范围类,可以自由修改 * 开完万岁!! */ //共有方法,全局共享 function CommonFunction(){ this.GMgetValue = function (name, value=null) { let storageValue = value; if (typeof GM_getValue === "function") { storageValue = GM_getValue(name, value); } else if(typeof GM.setValue === "function"){ storageValue = GM.getValue(name, value); }else{ var arr = window.localStorage.getItem(name); if(arr != null){ storageValue = arr } } return storageValue; }; this.GMsetValue = function(name, value){ if (typeof GM_setValue === "function") { GM_setValue(name, value); } else if(typeof GM.setValue === "function"){ GM.setValue(name, value); }else{ window.localStorage.setItem(name, value) } }; this.GMaddStyle = function(css){ var myStyle = document.createElement('style'); myStyle.textContent = css; var doc = document.head || document.documentElement; doc.appendChild(myStyle); }; this.GMopenInTab = function(url, options={"active":true, "insert":true, "setParent":true}){ if (typeof GM_openInTab === "function") { GM_openInTab(url, options); } else { GM.openInTab(url, options); } }; this.addScript = function(url){ var s = document.createElement('script'); s.setAttribute('src',url); document.body.appendChild(s); }; this.randomNumber = function(){ return Math.ceil(Math.random()*100000000); }; this.request=function(mothed, url, param, headers={"Content-Type": "application/json;charset=UTF-8"}){ return new Promise(function(resolve, reject){ GM_xmlhttpRequest({ url: url, method: mothed, data:param, headers:headers, onload: function(response) { var status = response.status; var playurl = ""; if(status==200||status=='200'){ var responseText = response.responseText; resolve({"result":"success", "data":responseText}); }else{ reject({"result":"error", "data":null}); } } }); }) }; this.addCommonHtmlCss = function(){ var cssText = ` @keyframes fadeIn { 0% {opacity: 0} 100% {opacity: 1} } @-webkit-keyframes fadeIn { 0% {opacity: 0} 100% {opacity: 1} } @-moz-keyframes fadeIn { 0% {opacity: 0} 100% {opacity: 1} } @-o-keyframes fadeIn { 0% {opacity: 0} 100% {opacity: 1} } @-ms-keyframes fadeIn { 0% {opacity: 0} 100% {opacity: 1} } @keyframes fadeOut { 0% {opacity: 1} 100% {opacity: 0} } @-webkit-keyframes fadeOut { 0% {opacity: 1} 100% {opacity: 0} } @-moz-keyframes fadeOut { 0% {opacity: 1} 100% {opacity: 0} } @-o-keyframes fadeOut { 0% {opacity: 1} 100% {opacity: 0} } @-ms-keyframes fadeOut { 0% {opacity: 1} 100% {opacity: 0} } .web-toast-kkli9{ position: fixed; background: rgba(0, 0, 0, 0.7); color: #fff; font-size: 14px; line-height: 1; padding:10px; border-radius: 3px; left: 50%; transform: translateX(-50%); -webkit-transform: translateX(-50%); -moz-transform: translateX(-50%); -o-transform: translateX(-50%); -ms-transform: translateX(-50%); z-index: 999999999999999999999999999; white-space: nowrap; } .fadeOut{ animation: fadeOut .5s; } .fadeIn{ animation:fadeIn .5s; } `; this.GMaddStyle(cssText); }; this.webToast = function(params) { //小提示框 var time = params.time; var background = params.background; var color = params.color; var position = params.position; //center-top, center-bottom var defaultMarginValue = 50; if(time == undefined || time == ''){ time = 1500; } var el = document.createElement("div"); el.setAttribute("class", "web-toast-kkli9"); el.innerHTML = params.message; //背景颜色 if(background!=undefined && background!=''){ el.style.backgroundColor=background; } //字体颜色 if(color!=undefined && color!=''){ el.style.color=color; } //显示位置 if(position==undefined || position==''){ position = "center-bottom"; } //设置显示位置,当前有种两种形式 if(position==="center-bottom"){ el.style.bottom = defaultMarginValue+"px"; }else{ el.style.top = defaultMarginValue+"px"; } el.style.zIndex=999999; document.body.appendChild(el); el.classList.add("fadeIn"); setTimeout(function () { el.classList.remove("fadeIn"); el.classList.add("fadeOut"); /*监听动画结束,移除提示信息元素*/ el.addEventListener("animationend", function () { document.body.removeChild(el); }); el.addEventListener("webkitAnimationEnd", function () { document.body.removeChild(el); }); }, time); }; this.filterStr = function(str){ if(!str) return ""; str = str.replace(/\t/g,""); str = str.replace(/\r/g,""); return encodeURIComponent(str) }; this.getParamterQueryUrl = function(text, tag) { //查询GET请求url中的参数 if(text.indexOf("?")!=-1){ //选取?后面的字符串,兼容window.location.search,前面的?不能去掉 var textArray = text.split("?"); text = "?"+textArray[textArray.length-1]; } var t = new RegExp("(^|&)" + tag + "=([^&]*)(&|$)"); var a = text.substr(1).match(t); if (a != null){ return a[2]; } return ""; }; this.getEndHtmlIdByUrl = function(url) { //获得以html结束的ID if(url.indexOf("?")!=-1){ url = url.split("?")[0] } if(url.indexOf("#")!=-1){ url = url.split("#")[0] } var splitText = url.split("/"); var idText = splitText[splitText.length-1]; idText = idText.replace(".html",""); return idText; }; this.getEcommercePlatform=function(url = window.location.href){ let platform = ""; if(url.indexOf("detail.tmall")!=-1 || url.indexOf("tmall.hk")!=-1 || url.indexOf("pages.tmall.com")!=-1){ platform = "tmall"; }else if(url.indexOf("taobao.com")!=-1 || url.indexOf("maiyao.liangxinyao.com")!=-1){ platform = "taobao"; }else if(url.indexOf("jd.com")!=-1 || url.indexOf("npcitem.jd.hk")!=-1 || url.indexOf("yiyaojd.com")!=-1 || url.indexOf("jkcsjd.com")!=-1){ platform = "jd"; }else if(url.indexOf("detail.vip.com")!=-1 || url.indexOf("www.vipglobal.hk")!=-1){ platform = "vpinhui"; } return platform; } this.isPC = function(){ var userAgentInfo = navigator.userAgent; var Agents = ["Android", "iPhone","SymbianOS", "Windows Phone", "iPad", "iPod"]; var flag = true; for (var v = 0; v < Agents.length; v++) { if (userAgentInfo.indexOf(Agents[v]) > 0) { flag = false; break; } } return flag; }; this.getBilibiliBV=function(){ var pathname = window.location.pathname; var bv = pathname.replace("/video/","").replace("/",""); return bv; }; this.getSystemOS=function(){ var u = navigator.userAgent; if (!!u.match(/compatible/i) || u.match(/Windows/i)) { return 'windows'; } else if (!!u.match(/Macintosh/i) || u.match(/MacIntel/i)) { return 'macOS'; } else if (!!u.match(/iphone/i) || u.match(/Ipad/i)) { return 'ios'; } else if (!!u.match(/android/i)) { return 'android'; } else { return 'other'; } }; this.RPCDownloadFile = function(fileName, url, savePath="D:/", RPCURL="ws://localhost:16800/jsonrpc", RPCToken="") { const self = this; if(!savePath){ savePath = "D:/"; } if(!RPCURL){ RPCURL = "ws://localhost:16800/jsonrpc"; } let options = { //下载配置文件 "dir":savePath, "max-connection-per-server": "16", "header":["User-Agent:"+navigator.userAgent+"", "Cookie:"+document.cookie+"", "Referer:"+window.location.href+""] } if(!!fileName) { options.out = fileName; } let jsonRPC = { "jsonrpc": "2.0", "id": "huahuacat", "method": "aria2.addUri", "params": [[url], options], } if (!!RPCToken) { jsonRPC.params.unshift("token:" + RPCToken); // 必须要加在第一个 } return new Promise(function(resolve, reject) { var webSocket = new WebSocket(RPCURL); webSocket.onerror = function(event) { console.log("webSocket.onerror", event); reject("Aria2连接错误,请打开Aria2和检查RPC设置!"); } webSocket.onopen = function(){ webSocket.send(JSON.stringify(jsonRPC)); } webSocket.onmessage = function(event){ let result = JSON.parse(event.data); switch (result.method) { case "aria2.onDownloadStart": resolve("Aria2 开始下载【"+fileName+"】"); webSocket.close(); break; case "aria2.onDownloadComplete": break; default: break; } } }); }; this.getElementObject = function(selector, target=document.body, allowEmpty = true, delay=10, maxDelay=10 * 1000){ return new Promise((resolve,reject) =>{ if (selector.toUpperCase() === "BODY") { resolve(document.body); return; } if (selector.toUpperCase() === "HTML") { resolve(document.html); return; } let totalDelay = 0; let element = target.querySelector(selector); let result = allowEmpty ? !!element : (!!element && !!element.innerHTML); if(result){ resolve(element); } const elementInterval = setInterval(()=>{ if(totalDelay >= maxDelay){ clearInterval(elementInterval); resolve(null); } element = target.querySelector(selector); result = allowEmpty ? !!element : (!!element && !!element.innerHTML); if(result){ clearInterval(elementInterval); resolve(element); }else{ totalDelay += delay; } }, delay); }); }; /** * @param {Object} time * @param {Object} format * 时间格式化 * DateFormat(new Date(dateCreated), "yyyy-MM-dd hh:mm:ss") */ this.DateFormat = function(time, format) { var o = { "M+": time.getMonth() + 1, //月份 "d+": time.getDate(), //日 "h+": time.getHours(), //小时 "m+": time.getMinutes(), //分 "s+": time.getSeconds(), //秒 "q+": Math.floor((time.getMonth() + 3) / 3), //季度 "S": time.getMilliseconds() //毫秒 }; if(/(y+)/.test(format)){ format = format.replace(RegExp.$1, (time.getFullYear() + "").substr(4 - RegExp.$1.length)); } for(var k in o){ if(new RegExp("(" + k + ")").test(format)){ format = format.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); } } return format; }; this.decryptStr=function(str){ let result = atob(str); return result.split('').reverse().join(''); }; this.encryptStr=function(str){ let result = str.split('').reverse().join(''); return btoa(result); }; } //全局弹窗对象 const dialog = (function(){ class Dialog { constructor() { this.mask = document.createElement('div'); this.dialogStyle = document.createElement('style'); this.setStyle(this.mask, { "width": '100%', "height": '100%', "backgroundColor": 'rgba(0, 0, 0, .6)', "position": 'fixed', "left": "0px", "top": "0px", "bottom":"0px", "right":"0px", "z-index":"9999999999999" }); this.content = document.createElement('div'); this.setStyle(this.content, { "max-width": '450px', "width":"100%", "max-height": '600px', "backgroundColor": '#fff', "boxShadow": '0 0 2px #999', "position": 'absolute', "left": '50%', "top": '50%', "transform": 'translate(-50%,-50%)', "borderRadius": '5px' }) this.mask.appendChild(this.content); } middleBox(param) { // 先清空中间小div的内容 - 防止调用多次,出现混乱 this.content.innerHTML = ''; let title = '默认标题内容'; if({}.toString.call(param) === '[object String]') { title = param; } else if({}.toString.call(param) === '[object Object]') { title = param.title; } document.body.appendChild(this.mask); this.title = document.createElement('div'); this.setStyle(this.title, { "width": '100%', "height": '40px', "lineHeight": '40px', "boxSizing": 'border-box', "background-color":"#dedede", "color": '#000', "text-align": 'center', "font-weight":"700", "font-size":"17px", "border-radius": "4px 4px 0px 0px" }); this.title.innerText = title; this.content.appendChild(this.title); this.closeBtn = document.createElement('div'); this.closeBtn.innerText = '×'; this.setStyle(this.closeBtn, { "textDecoration": 'none', "color": '#000', "position": 'absolute', "right": '10px', "top": '0px', "fontSize": '25px', "display":"inline-block", "cursor":"pointer" }) this.title.appendChild(this.closeBtn); const self = this; this.closeBtn.onclick = function(){ self.close(); if(param.onClose && (typeof param.onClose)==="function"){ param.onClose(); } } } showMake(param) { //添加公用样式表 if(param.hasOwnProperty("styleSheet")){ this.dialogStyle.textContent = param.styleSheet; } document.querySelector("head").appendChild(this.dialogStyle); this.middleBox(param); this.dialogContent = document.createElement('div'); this.setStyle(this.dialogContent,{ "padding":"15px", "max-height":"400px" }); this.dialogContent.innerHTML = param.content; this.content.appendChild(this.dialogContent); param.onContentReady(this); } close() { document.body.removeChild(this.mask); document.querySelector("head").removeChild(this.dialogStyle); } setStyle(ele, styleObj) { for(let attr in styleObj){ ele.style[attr] = styleObj[attr]; } } } let dialog = null; return (function() { if(!dialog) { dialog = new Dialog() } return dialog; })() })(); //全局统一方法对象 const commonFunctionObject = new CommonFunction(); commonFunctionObject.addCommonHtmlCss(); //统一html、css元素添加 let functionController = null; /** * 购物助手部分功能借鉴自:https://greasyfork.org/zh-CN/scripts/428266 * 作者:洪皓儿,原脚本开源协议:AGPL License * 本脚本继承AGPL License协议并开源,在源代码基础上优化了部分逻辑,修复了部分bug,特此申明!! */ const recordBrowsingHistoryKey = "record_browsing_history_mark_key"; const browsedHtml= `