// ==UserScript== // @name 有赞自动蹲票(萤火虫漫展/虫娘小卖部等) // @namespace http://tampermonkey.net/ // @version 0.3 // @description 蹲开票之后的第n波票或掉落余票,开票时需手动刷新 // @author 浩劫者12345 // @match https://*.youzan.com/* // @icon https://img01.yzcdn.cn/v2/image/yz_fc.ico // @grant GM_setValue // @grant GM_getValue // @license MIT // @downloadURL https://update.greasyfork.icu/scripts/491988/%E6%9C%89%E8%B5%9E%E8%87%AA%E5%8A%A8%E8%B9%B2%E7%A5%A8%EF%BC%88%E8%90%A4%E7%81%AB%E8%99%AB%E6%BC%AB%E5%B1%95%E8%99%AB%E5%A8%98%E5%B0%8F%E5%8D%96%E9%83%A8%E7%AD%89%EF%BC%89.user.js // @updateURL https://update.greasyfork.icu/scripts/491988/%E6%9C%89%E8%B5%9E%E8%87%AA%E5%8A%A8%E8%B9%B2%E7%A5%A8%EF%BC%88%E8%90%A4%E7%81%AB%E8%99%AB%E6%BC%AB%E5%B1%95%E8%99%AB%E5%A8%98%E5%B0%8F%E5%8D%96%E9%83%A8%E7%AD%89%EF%BC%89.meta.js // ==/UserScript== (async function () { // 初始化购票信息 /** @type {RegExp} */ var ticketToBuy_regex try { ticketToBuy_regex = new RegExp(GM_getValue('autoBuyRegex') || '电子预售票'); } catch (error) { console.log('正则表达式解析失败,正在使用默认值') ticketToBuy_regex = /电子预售票/; } const idcard = GM_getValue('autoBuyIDCard') || ''; const realname = GM_getValue('autoBuyRealname') || ''; const phonenumber = GM_getValue('autoBuyPhonenumber') || ''; const minAcceptPrice = parseInt(GM_getValue('autoBuyMinAcceptPrice')) || 99999; function checkAutoBuyInfo() { return idcard && idcard.length == 18 && realname && realname.length >= 2 && phonenumber && phonenumber.length == 11 } function saveAutoBuyInfo() { console.log('正在保存蹲票配置') GM_setValue('autoBuyRegex', document.getElementById('settingsRegex').value) GM_setValue('autoBuyIDCard', document.getElementById('settingsIDCard').value) GM_setValue('autoBuyRealname', document.getElementById('settingsRealname').value) GM_setValue('autoBuyPhonenumber', document.getElementById('settingsPhonenumber').value) GM_setValue('autoBuyMinAcceptPrice', document.getElementById('settingsMinAcceptPrice').value) location.reload() } // 设置按钮和设置界面 const settingsEl = document.createElement('template') settingsEl.innerHTML = `
` document.body.appendChild(settingsEl.content) document.getElementById('settingsSetBtn').onclick = saveAutoBuyInfo // 所有商品页 // if (location.href.includes('/wscshop/feature/goods/all')) { // 蹲票状态覆盖层 const overlayEl = document.createElement('template') overlayEl.innerHTML = ` ` document.body.appendChild(overlayEl.content) // 检查蹲票信息是否正确,不正确则留下提示然后退出 if (!checkAutoBuyInfo()) { console.log('购票信息有误') document.getElementById('autoBuyStatus').innerHTML = '请先正确填写蹲票信息!' document.getElementById('autoBuyStatus').style.fontSize = '20px' document.getElementById('autoBuyStatus').style.color = '#ff0' return } // 申请浏览器通知权限 Notification.requestPermission().then(() => { new Notification('蹲票脚本已启动', { body: '有票时将通过浏览器通知提醒支付', }); }) // 启动 worker 以便页面挂起时也能继续蹲票 function workerInterval() { setInterval(() => { postMessage('') }, 1000); } const workerBlob = URL.createObjectURL(new Blob([`(${workerInterval.toString()})()`], { type: 'application/javascript' })); const worker = new Worker(workerBlob) let count = 0 worker.onmessage = () => { /* https://shop46404892.youzan.com/wscshop/showcase/goods/allGoods.json? pageSize=20& page=1& offlineId=0& openIndependentPrice=0& order=& json=1& uuid=a5f75232-3ec1-66c4-5ec2-b0db133d7765& activityPriceIndependent=1& order_by=algPVD30& goodsType=2& needActivity=0& clientSource=2& tagAlias=& needGroupFilter=false& needGoodsRank=true& supportCombo=true& excludedComboSubType=%5B%22none%22%5D", { */ // 获取前20个商品 fetch("/wscshop/showcase/goods/allGoods.json?json=1&order_by=createdTime", { "method": "GET", "credentials": "include" }).then(r => r.json()).then(data => { // 清空蹲票信息显示 document.getElementById('autoBuyStatus').innerHTML = `正在蹲以下票(${Notification.permission == "granted" ? '浏览器通知已启用' : '请启用浏览器通知以便接收结果'}):