// ==UserScript== // @name 大麦抢票-完整 // @namespace https://www.jwang0614.top/scripts // @version 0.0.4 // @description 辅助购买大麦网演唱会门票 // @author Olivia Wang // @match https://m.damai.cn/app/dmfe/select-seat-biz/kylin.html* // @match https://detail.damai.cn/* // @match https://m.damai.cn/app/dmfe/h5-ultron-buy/index.html* // @grant none // @require https://cdn.staticfile.org/jquery/3.5.1/jquery.min.js // ==/UserScript== // https://seatsvc.damai.cn/tms/selectSeat?itemId=624499596673&hasPromotion=true&performId=210252620&skuId=4427321477193&projectId=624499596673&spm=a2oeg.project.projectinfo.dbuy // https://seatsvc.damai.cn/tms/selectSeat?itemId=624499596673&performId=210252601&skuId=4427321477292&projectId=624499596673 var version = "v0.1.1" var $style = $(''); document.domain = "damai.cn"; /** * 获取 select_data数据 * @param {array} data * @param { number } people_num */ function get_select_data(data, people_num) { const session_dom = $('.perform__order__select__performs .select_right>.select_right_list>.select_right_list_item.active>span') var text = session_dom.contents().filter(function() { return this.nodeType === 3; }).text().trim() if (text && text.length) { let select_data_array = [] if ('calendarPerforms' in data) { const base_array_list = data['calendarPerforms'].map(v => v.performBases); select_data_array = select_data_array.concat(...base_array_list) } else if ('performBases' in data) { select_data_array = data['performBases'] } else { console.log('无法识别数据!') } const session_list = select_data_array.map(v => v.performs); const session_list_concat = [].concat(...session_list); const session_data = session_list_concat.find(v => v.performName === text) if (session_data) { const item_id = session_data['itemId']; const perform_id = session_data['performId']; const product_id = session_data['projectId'] const sku_list = session_data['skuList']; const text_dom = $('.select_right>.select_right_list>.select_right_list_item.sku_item.active>.skuname') var sku_text = text_dom.contents().filter(function() { return this.nodeType === 3; }).text().trim() const sku_data = sku_list.find(v => v.skuName === sku_text) if (sku_data) { if (sku_data['skuTag'] && sku_data['skuTag'].includes("缺货登记")) { alert('该商品被标记为缺货状态, 暂不可购买!') } const sku_id = sku_data['skuId']; const url_format_data = { itemId: item_id, userPromotion: 'true', toDxOrder: 'true', quickBuy: '0', privilegeActId: '', channel: 'damai_app', performId: perform_id, skuId: sku_id, projectId: product_id, peopleNum: people_num }; const base_url = 'https://m.damai.cn/app/dmfe/select-seat-biz/kylin.html?' // itemId=715507859921 // userPromotion=false // toDxOrder=true // quickBuy=0 // privilegeActId= // channel=damai_app // performId=211217611 // skuId=5007407945829 // projectId=215210012 const url_format_array = Object.entries(url_format_data); const params_list = [] for(const [key, value] of url_format_array) { params_list.push(`${key}=${value}`) } return `${base_url}${params_list.join('&')}` } else { alert('获取票档信息失败!') } } else { alert('获取场次信息失败!') } } else { alert('获取场次文本信息失败!') } } Number.prototype.toHHMMSS = function() { var hours = Math.floor(this / 3600) < 10 ? ("00" + Math.floor(this / 3600)).slice(-2) : Math.floor(this / 3600); var minutes = ("00" + Math.floor((this % 3600) / 60)).slice(-2); var seconds = ("00" + (this % 3600) % 60).slice(-2); return hours + ":" + minutes + ":" + seconds; }; function create_detail_ui(data) { let start_time = data['sellStartTime'] const is_presell = start_time >= Date.now() if (is_presell) { // start_time = Date.now() + 10000; } let is_immediate = null if (is_presell) { is_immediate = data['buyBtnTextAfterCountDown'] === '选座购买' } else { is_immediate = data['buyBtnText'] === "选座购买"; } // const alert_message = is_immediate? '无法全自动选座,具体方式请看“注意”部分。不要忘了先登录,填好联系人信息,删除多余联系人。': '不要忘了先登录,填好联系人信息,删除多余联系人'; // alert(alert_message); let $service = $(".content-right .service"); let $control_container = $("
"); let $wx = $(`

大麦(${is_immediate? '选座': '非选座'})

DBug ${version}

`); let $number_input = $('
请输入人数:
'); let $timeout_input = $('
抢票动作延时时间:
') let $time_down = $(` `); let $start_btn = $(''); let $end_btn = $(''); let $notice = $('

使用步骤

0.登录,填写购票人信息

1.选择场次

2.选择价格

3.填写人数

4.点击‘开始抢票’

'); let $notice2 = $('

注意

若人数为1,选座页面手动选座后自动进入下一步

人数多于1时,选座页面手动选座后点击“确认选座”按钮或按下空格键进入下一步

'); let $countdown = $('

event1

price2

1人


倒计时:

00:00:00

'); $control_container.append($style); $control_container.append($wx); if (is_presell) { $control_container.append($time_down) $control_container.append($timeout_input) } if (is_immediate || is_presell) { $control_container.append($number_input); } $control_container.append($start_btn); $control_container.append($end_btn); $control_container.append($notice); if (is_immediate) { $control_container.append($notice2); } // $control_container.append($notice3); $control_container.insertBefore($service); $countdown.insertBefore($control_container); const people_input = $("#number_input") const timeout_input = $('#timeout_input') const timeout_title = $('#show_donw_time') const timeout_data = { start: $('#start_time'), now: $('#now_time'), action: $('#action_time'), check: $('#check_time') } const time_for = { title: 0, data: 0 }; function start(people_num, timeout_num) { people_input.attr('disabled', 'disabled'); timeout_input.attr('disabled', 'disabled'); if (is_presell) { const presell_obj_str = localStorage.getItem('is_presell') if (!!presell_obj_str) { const presell_obj_json = JSON.parse(presell_obj_str) presell_obj_json[data.page_id] = people_num || 0 localStorage.setItem('is_presell', JSON.stringify(presell_obj_json)) } else { const obj = {} obj[data.page_id] = people_num || 0 localStorage.setItem('is_presell', JSON.stringify(obj)) } timeout_data.start.text(start_time); timeout_data.action.text(start_time + Number(timeout_num)); update_timeout_show_title() update_timeout_show_data(Number(timeout_num), people_num) $time_down.show() } else { clearTimeout(time_for.title) clearTimeout(time_for.data) jump(people_num) } } function end() { clearTimeout(time_for.title) clearTimeout(time_for.data) $time_down.hide() people_input.removeAttr('disabled'); timeout_input.removeAttr('disabled'); const store_str = localStorage.getItem('is_presell') const page_id = data.page_id let store = null if (!!store_str) { store = JSON.parse(store_str) } // if(store !== null && store.hasOwnProperty(page_id) && Date.now() - sellStartTime <= 60000) { if(!!store && store.hasOwnProperty(page_id)) { const store_data = store[page_id] delete store[page_id] localStorage.setItem('is_presell', JSON.stringify(store)) } } function update_timeout_show_title() { const time_now = Date.now(); // const time_now = performance.timeOrigin + performance.now(); const time_distance = start_time - time_now timeout_title.text(Math.floor(time_distance/1000).toHHMMSS()) time_for.title = setTimeout(update_timeout_show_title, 100) } function update_timeout_show_data(timeout_num, people_num) { const time_now = Math.floor(performance.timeOrigin + performance.now()); timeout_data.now.text(time_now) const t_time = start_time - time_now + timeout_num timeout_data.check.text(t_time) if (t_time <= 0) { clearTimeout(time_for.title) clearTimeout(time_for.data) jump(people_num) } else { time_for.data = setTimeout(update_timeout_show_data, 20, timeout_num, people_num) } } function jump(people_num) { if (is_immediate) { const url = get_select_data(data, people_num) window.open(url) } else { 7 /** https://m.damai.cn/app/dmfe/h5-ultron-buy/index.html? exParams={ "damai":"1", "channel":"damai_app", "umpChannel":"10002", "atomSplit":"1", "serviceVersion":"1.8.5", "umidToken":"T2gAx0ZjnsvRJTqkKIfLhDRdwZcKwTZsDKiw-XtyLo9eMxIpZ9Mq-OrZGB0baOasHO8=", "ua":"140#5JFoqNPZzzW9XQo2+bOz4pN8s77o89vy3CvHwHaE+YDiumH/AKXl+zVB4YLz/FBw4Fk/lp1zzqEoUoQb2FzxhoN+93h/zzrb22U3lp1xzAQiVXE/tFzx2Dc34QRYgHmijDapVrMDsX9lxqbQUlSURRBTs56ePT6myJwQ8utwCVBFxn9/rYFDEvIT3fxay2GwT9ciXP8N5aEcDli4is4WnvnHnAwVAo3NA0eBWkaNC2lQ47aSfwp/H26NDha0yYZCQ2X5l7BXru4EKMGVdGQw/4JTp41ChZFqtXgald3GU+l7Ioh5YqYR6pa/l5H6d2wl27Us9P3Aey3W+CnJKrUOZ/9PI6Usej9fiZxFdypMPI85QTK5QoI+aRCzngUqLNHqEmzyrpwuWN4JyfV7r21fCSTMjX47m5+H7k+aMTVvqtthdT7EpP2Q8V0yMIVqWThlY/07bPeh8SYt3WzCA1z5cN5/MQ16ibxIjBRM+/WxHqA27MWwZ0ahl/h48xpY3ffD+EQ+AY/lNcOB5f9z1IqUtjUYtxGS9QqrbzkE8mDUEoTYL44W7veIEHun3Bcpp5C408YC6kGK/OfcqhrZLZFEUE2EF9odQSYPO1ILaIGcs3KcL68Y3VRg6/IdRwxt+hLeQviK86AheoVXmuLAzoF05sTny4r9z9nT1f2MY998gTiXuieyC9PUHeE4N+EsdDVQZSmRMOY9ioGW0H/ImaihtDbI1mf60rK4Up6Nic83aAKIVdNh29c2NcdugRxud2KCfSgG74DVqdp2XOO93bY4GtLNiALD9BvxpMZM4nXT3MWrUsYFG5c72DBGqUFSt1w2psqCD5Xpcswoi/r=" } &buyParam=718376964923_1_5009907896149 &buyNow=true &privilegeActId= */ $('.scan-buy>.qrcode-wrapper>.buy-link').click() } } $("#start_btn").click(() =>{ let people_num = people_input.val(); let timeout_num = timeout_input.val(); console.log(data) // const url = get_select_data(data, people_num) // console.log(url) start(people_num, timeout_num) // let event = get_event(); // let price = get_price(); // let people_num = $("#number_input").val(); // let data_json = JSON.parse($("#dataDefault").text()); // window.sellStartTime_timestamp = data_json["sellStartTime"]; // $("#selected_event").text(event); // $("#selected_price").text(price); // $("#selected_number").text(people_num + "人"); // $("#countdown_wrapper").show(); }); $('#end_btn').click(() => { end() }) } function select_seat_ui() { const people_num_match = window.location.search.match(/(?<=peopleNum\=)\d/); if (people_num_match) { const people_num = Number(people_num_match[0]) if (!Number.isNaN(people_num) && people_num >= 1) { const time = setInterval(() => { if (window.goldlog && window.goldlog.record) { clearInterval(time); const source_text_dom = $('.header-bar__perform--text'); console.log(source_text_dom) const source_text = source_text_dom.text(); const update_people_num = (num) => { source_text_dom.text(`${source_text} - 需选座${num}个!`) } update_people_num(people_num) $('.select-seat__container').click(() => { setTimeout(() => { const select_list_length = $('.footer-bar-seat__item').length; update_people_num(people_num - select_list_length); if (people_num - select_list_length === 0) { setTimeout(() => { $('.footer-bar__button').click() }, 350) } }, 100) }) } else { console.log('等待异步加载数据!') } }, 300) } else { alert('购票人数解析失败!') } } else { alert('未检测到插件设置的购票人数, 插件干预失败!') } } function buy() { let num = 0; const time = setInterval(() => { if (window.goldlog && window.goldlog.record) { const buy_button_list = $('[view-name="FrameLayout"]>[view-name="TextView"]>span') const button = buy_button_list.filter((_, key) => key.innerHTML === '提交订单' ) if (button.length <= 0 && num < 50) { num++ } else { clearInterval(time); if (button.length > 0) { setTimeout(() => { const submit = button[0] const touch = new Touch({ identifier: 42, target: document.body, clientX: Math.floor(Math.random()* 400), clientY: Math.floor(Math.random()* 400), screenX: Math.floor(Math.random()* 300), screenY: Math.floor(Math.random()* 300), pageX: Math.floor(Math.random()* 200), pageY: Math.floor(Math.random()* 200), radiusX: Math.floor(Math.random()* 10), radiusY: Math.floor(Math.random()* 10) }) const simulation_event = new TouchEvent('touchstart', { cancelable: true, bubbles: true, composed: true, touches: [touch], targetTouches: [touch], changedTouches: [touch], }); submit.dispatchEvent(simulation_event); setTimeout(() => { const simulation_event = new TouchEvent('touchend', { cancelable: true, bubbles: true, composed: true, touches: [touch], targetTouches: [touch], changedTouches: [touch] }); submit.dispatchEvent(simulation_event); }, 200) }, 200) } else { console.log('超时检测!') } } } else { console.log('等待异步加载数据!') } }, 100) } function get_url_id() { const id = window.location.search.match(/(?<=id=)\d+/) return Number(id) } function buy_num(people_num) { const people = Number(people_num) const plus = $('.cafe-c-input-number-handler-up'); const $_input = $('.cafe-c-input-number input').val() console.log($_input) if(Number($_input) + 1 < people) { plus[0].dispatchEvent(new MouseEvent('click')) } else { console.log('点击购买按钮!') $('.scan-buy>.qrcode-wrapper>.buy-link').click() } setTimeout(buy_num, 200, people_num) } function sleep_buy_but(data_json, people_num) { if (data_json['buyBtnText'] === "选座购买") { const url = get_select_data(data_json, people_num) window.location.href = url } else { buy_num(people_num) } } $(document).ready(function(){ var curr_url = window.location.href; // https://m.damai.cn/app/dmfe/select-seat-biz/kylin.html 选座页 // https://m.damai.cn/app/dmfe/h5-ultron-buy/index.html 购买页 switch(true) { case curr_url.includes('detail.damai.cn'): let data_json = JSON.parse($("#dataDefault").text()); const { sellStartTime } = data_json const page_id = get_url_id() const store_str = localStorage.getItem('is_presell') let store = null if (!!store_str) { store = JSON.parse(store_str) } // if(store !== null && store.hasOwnProperty(page_id) && Date.now() - sellStartTime <= 60000) { if(!!store && store.hasOwnProperty(page_id)) { const store_data = store[page_id] delete store[page_id] localStorage.setItem('is_presell', JSON.stringify(store)) setTimeout(sleep_buy_but, 1000, data_json, store_data) break } const status = data_json['buyBtnText']; data_json['page_id'] = page_id switch(true) { case status === '选座购买' || status === "立即购买" || status === "即将开抢": create_detail_ui(data_json) break default: { alert('当前商品暂无法购买!') } } break case curr_url.includes('m.damai.cn/app/dmfe/select-seat-biz/kylin.html'): select_seat_ui() break case curr_url.includes('https://m.damai.cn/app/dmfe/h5-ultron-buy/index.html'): buy(); } // 原有错误逻辑: // if (curr_url.includes("detail.damai.cn")) { // // var order_url = sessionStorage.getItem('order_url'); // // if(order_url) { // window.location.href = order_url; // } else { // // let link_text = $('.qrcode-wrapper>.buy-link').text(); // console.log(link_text) // // if($("div.buybtn").text() == "选座购买" || $('.service-note .service-note-name').text().includes("可选座")){ // if(link_text.includes('选座')){ // // 选坐版提示信息 // alert("无法全自动选座,具体方式请看“注意”部分。不要忘了先登录,填好联系人信息,删除多余联系人。"); // detail_seat_ui(); // } else { // // 非选坐版提示信息 // alert("不要忘了先登录,填好联系人信息,删除多余联系人"); // detail_ui(); // } // } // } // if (curr_url.includes("m.damai.cn/app/dmfe/h5-ultron-buy/index.html")) { // if($(".error-msg").length > 0) { // window.location.reload(); // 如果当前页面没有错误消息,则直接刷新页面 // } else { // console.log(64, '循环调用 fill_from') // // setTimeout(fill_form, 300); // 调用fill_form // } // } // if (curr_url.includes("https://m.damai.cn/app/dmfe/select-seat-biz/kylin.html")) { // // console.log('选座页:', GM_getValue('test')) // } // if (curr_url.includes("https://seatsvc.damai.cn/")) { // console.log("seat") // var people_num = new URLSearchParams(window.location.href).get('people_num'); // if (people_num == 1) { // new MutationObserver(function(mutations) { // if (document.querySelector("#app > div.render-result-container > div.select-result")) { // console.log("found ele"); // $("#app > div.render-result-container > div.select-result").bind("DOMNodeInserted", seat_click_buy_btn); // } // }).observe(document, {childList: true, subtree: true}); // // $("#app > div.render-result-container > div.select-result").bind("DOMNodeInserted", seat_click_buy_btn) // } else { // document.onkeydown = function() { // var oEvent = window.event; // if (oEvent.keyCode == 32) { // // seat_click_buy_btn() // } // } // } // } }) function seat_click_buy_btn() { $('.select-result>.tip-order-button>button').click(); } // //https://stackoverflow.com/a/31112615 // Number.prototype.toHHMMSS = function() { // var hours = Math.floor(this / 3600) < 10 ? ("00" + Math.floor(this / 3600)).slice(-2) : Math.floor(this / 3600); // var minutes = ("00" + Math.floor((this % 3600) / 60)).slice(-2); // var seconds = ("00" + (this % 3600) % 60).slice(-2); // return hours + ":" + minutes + ":" + seconds; // }; function timedUpdate() { var current_time = Date.now(); var time_difference = Math.ceil((window.sellStartTime_timestamp - current_time)/1000); if (time_difference < 2) { window.location.href = window.order_url; } else { var time_difference_str = time_difference.toHHMMSS(); $("#countdown").text(time_difference_str); window.timer = setTimeout(timedUpdate, 1000); } } // 原有错误逻辑: // function generate_confirm_url(event, price, people_num, data_json) { // // console.log("event", event); // console.log(event, price, people_num, data_json); // var performBases = data_json["performBases"]; // var itemId = ""; // for(var i=0; i"); var $wx = $(`

大麦(非选座购票模式)

DBug ${version}

`); var $number_input = $('
请输入人数:
'); // var $email_input = $('
email:
'); // var $name_input = $('
联系人姓名:
'); // var $duration_input = $('
刷新间隔(ms):
'); var $start_btn = $(''); var $end_btn = $(''); var $notice = $('

使用步骤

0.登录,填写购票人信息

1.选择场次

2.选择价格

3.填写人数

4.点击‘开始抢票’

'); var $notice2 = $('

倒计时相差1-2秒是四舍五入造成的正常现象

若误差过大请校准计算机时间,刷新页面

'); var $countdown = $('

event1

price2

1人


倒计时:

00:00:00

'); $control_container.append($style); $control_container.append($wx); $control_container.append($number_input); // $control_container.append($email_input); // $control_container.append($name_input); // $control_container.append($duration_input); $control_container.append($start_btn); $control_container.append($end_btn); $control_container.append($notice); $control_container.append($notice2); // $control_container.append($countdown); $control_container.insertBefore($service); $countdown.insertBefore($control_container); $("#start_btn").click(function(){ var event = get_event(); var price = get_price(); var people_num = $("#number_input").val(); var data_json = JSON.parse($("#dataDefault").text()); window.sellStartTime_timestamp = data_json["sellStartTime"]; $("#selected_event").text(event); $("#selected_price").text(price); $("#selected_number").text(people_num + "人"); $("#countdown_wrapper").show(); console.log(data_json) // 将原有计算链接,改为el匹配 // var result = generate_confirm_url(event, price, people_num,data_json); // // 该位置跳转至淘宝网确定订单 // // 查找按钮并返回数据 // if(result) { // window.order_url = result; // sessionStorage.setItem('order_url', result); // console.log("countdown and go to confirm page"); // timedUpdate(); // } else { // console.error("不知道为什么获取场次票价人数出错了呢。"); // alert("不知道为什么获取场次票价人数出错了呢。"); // } // console.log(result) }); $("#end_btn").click(function(){ clearTimeout(window.timer); $("#countdown_wrapper").hide(); sessionStorage.clear(); }); } function buy_el_click() { $('.scan-buy>buy-link').clik(); } // http://cncc.bingj.com/cache.aspx?q=jquery+ignore+inner+most&d=4555311081654245&mkt=en-US&setlang=en-US&w=FZ-aM6oeDz4XhBZleDN79HoRb7ybox0E function get_text_exclude_children(css_selector_str) { return $(css_selector_str).contents().not($(css_selector_str).children()).text().trim(); } function get_event() { var event_css_selector = ".perform__order__select.perform__order__select__performs .select_right_list .active>*"; return get_text_exclude_children(event_css_selector); } function get_price() { var price_css_selector = ".select_right_list_item.sku_item.active .skuname"; return get_text_exclude_children(price_css_selector); } function detail_seat_ui() { let $service = $(".content-right .service"); let $control_container = $("
"); let $wx = $(`

大麦(选座购票模式)

DBug ${version}

`); let $number_input = $('
请输入人数:
'); let $start_btn = $(''); let $end_btn = $(''); let $notice = $('

使用步骤

0.登录,填写购票人信息

1.选择场次

2.选择价格

3.填写人数

4.点击‘开始抢票’

'); let $notice2 = $('

注意

若人数为1,选座页面手动选座后自动进入下一步

人数多于1时,选座页面手动选座后点击“确认选座”按钮或按下空格键进入下一步

'); let $notice3 = $('

倒计时相差1-2秒是四舍五入造成的正常现象

若误差过大请校准计算机时间,刷新页面

'); let $countdown = $('

event1

price2

1人


倒计时:

00:00:00

'); $control_container.append($style); $control_container.append($wx); $control_container.append($number_input); $control_container.append($start_btn); $control_container.append($end_btn); $control_container.append($notice); $control_container.append($notice2); $control_container.append($notice3); $control_container.insertBefore($service); $countdown.insertBefore($control_container); $("#start_btn").click(function(){ let event = get_event(); let price = get_price(); let people_num = $("#number_input").val(); let data_json = JSON.parse($("#dataDefault").text()); window.sellStartTime_timestamp = data_json["sellStartTime"]; $("#selected_event").text(event); $("#selected_price").text(price); $("#selected_number").text(people_num + "人"); $("#countdown_wrapper").show(); // https://m.damai.cn/app/dmfe/select-seat-biz/kylin.html? // itemId=714266271400 // itemId 可以在该 url 中进行提取 // userPromotion=true // promotions 中选择的列表使用 // toDxOrder=true // quickBuy=0 // privilegeActId= // channel=damai_app // performId=211193720 // skuId=5170661155648 // projectId=214993038 // 没有执行日期字段的情况下 // https://m.damai.cn/app/dmfe/select-seat-biz/kylin.html? // itemId=714266271400 // userPromotion=true // toDxOrder=true // quickBuy=0 // privilegeActId= // channel=damai_app // performId=211193720 // skuId=5170661155648 // projectId=214993038 // ========================================================= // https://m.damai.cn/app/dmfe/select-seat-biz/kylin.html? // itemId=712020464586 // userPromotion=true // toDxOrder=true // quickBuy=0 // &privilegeActId= // channel=damai_app // performId=211173847 // skuId=4987302676228 // projectId=214824030 // ========================================================= // https://m.damai.cn/app/dmfe/select-seat-biz/kylin.html? // itemId=714266271400 // userPromotion=true // toDxOrder=true // quickBuy=0 // privilegeActId= // channel=damai_app // performId=211193720 // skuId=5170661155648 // projectId=214993038 }); $("#end_btn").click(function(){ clearTimeout(window.timer); $("#countdown_wrapper").hide(); sessionStorage.clear(); }); } function check_alert() { var alerts = $(".next-dialog-alert"); if(alerts.length > 0 || window.current_time >= window.max_time) { window.location.reload(); } else { window.current_time = window.current_time + 500; setTimeout(check_alert, 500); } } function fill_form() { var buyer_number = parseInt($(".ticket-buyer-title em").text()); window.buyer_number = buyer_number; window.curr_buyer = 0; // console.log(buyer_number); var buyer_list = $(".buyer-list-item input"); for(var i=0; i < buyer_number; i++) { // console.log(buyer_list[i]); buyer_list[i].click(); } setTimeout(submit_order, 200); } function submit_order() { $(".submit-wrapper button").click(); setTimeout(check_alert, 500); }