大麦抢票

浏览器辅助抢购大麦网门票自动提交订单

  1. // ==UserScript==
  2. // @name 大麦抢票
  3. // @namespace 陈鸿宇fighting~!
  4. // @version 1.0.2
  5. // @description 浏览器辅助抢购大麦网门票自动提交订单
  6. // @author secret11979
  7. // @match https://buy.damai.cn/*
  8. // @match https://detail.damai.cn/*
  9. // @match https://seatsvc.damai.cn/*
  10. // @grant GM_xmlhttpRequest
  11. // @connect api.m.taobao.com
  12. // @require https://cdn.staticfile.org/jquery/3.5.1/jquery.min.js
  13. // ==/UserScript==
  14. // @license MIT
  15. // https://seatsvc.damai.cn/tms/selectSeat?itemId=624499596673&hasPromotion=true&performId=210252620&skuId=4427321477193&projectId=624499596673&spm=a2oeg.project.projectinfo.dbuy
  16. // https://seatsvc.damai.cn/tms/selectSeat?itemId=624499596673&performId=210252601&skuId=4427321477292&projectId=624499596673
  17. var version = "1.0.2"
  18. var $style = $('<style>' +
  19. '#control_container{margin: 20px 0; background:#e9e9e9;padding:20px 0;}' +
  20. 'p{margin:10px 0;}' +
  21. '#control_container button{width:80%;margin:10px 10%;padding:10px 0;font-size:30px;border-style: solid;}' +
  22. '#start_btn{color:green;}' +
  23. '#end_btn{color:red;}' +
  24. '.input_wrapper{display: flex;justify-content:center;font-size: 16px; margin-bottom:10px;}' +
  25. '.notice{margin:10px 10px;padding:10px 10px;color:darkslategrey;border-style: solid; border-width: 1px; border-color:darkslategrey;}' +
  26. '#wx{text-align: center;}' +
  27. '#countdown_wrapper {display:none; font-size: 16px; text-align:center; background:#ffeaf1;}' +
  28. '#countdown_wrapper p{width:100%;}' +
  29. '#countdown {font-size: 20px; color:#ff1268;}' +
  30. '.warning {color:red; font-weight:400;}' +
  31. 'h3 {font-weight:800;}' +
  32. '</style>');
  33. console.log("domain1", document.domain);
  34. document.domain = "damai.cn";
  35. $(document).ready(function () {
  36. var curr_url = window.location.href;
  37. if (curr_url.includes("https://detail.damai.cn/")) {
  38. var order_url = sessionStorage.getItem('order_url');
  39. if (order_url) {
  40. window.location.href = order_url;
  41. } else {
  42. if ($("div.buybtn").text() == "选座购买" || $('.service-note .service-note-name').text().includes("可选座")) {
  43. alert("无法全自动选座,请看“注意”部分。不要忘了先登录(不可用),填好联系人信息,删除多余联系人。");
  44. detail_seat_ui();
  45. } else {
  46. detail_ui();
  47. }
  48. }
  49. }
  50. if (curr_url.includes("https://buy.damai.cn/")) {
  51. if (curr_url.includes("https://buy.damai.cn/multi/flow")) {
  52. //下单挤爆了
  53. var order_url = curr_url.substring(curr_url.indexOf('=') + 1);
  54. sessionStorage.setItem('order_url', order_url);
  55. window.location.href = order_url;
  56. } else {
  57. if ($(".error-msg").length > 0) {
  58. if ($(".error-msg").text().includes("已过期")) {
  59. document.getElementsByClassName("next-row error-reload")[0].children[0].click();
  60. } else {
  61. var order_url = sessionStorage.getItem('order_url');
  62. if (order_url) {
  63. window.location.href = order_url;
  64. } else {
  65. window.location.reload();
  66. }
  67. }
  68. } else {
  69. setTimeout(fill_form, 200);
  70. }
  71. }
  72. }
  73. if (curr_url.includes("https://seatsvc.damai.cn/")) {
  74. console.log("seat")
  75. var people_num = new URLSearchParams(window.location.href).get('people_num');
  76. if (people_num == 1) {
  77. new MutationObserver(function (mutations) {
  78. if (document.querySelector("#app > div.render-result-container > div.select-result")) {
  79. console.log("found ele");
  80. $("#app > div.render-result-container > div.select-result").bind("DOMNodeInserted", seat_click_buy_btn);
  81. }
  82. }).observe(document, {childList: true, subtree: true});
  83. // $("#app > div.render-result-container > div.select-result").bind("DOMNodeInserted", seat_click_buy_btn)
  84. } else {
  85. document.onkeydown = function () {
  86. var oEvent = window.event;
  87. if (oEvent.keyCode == 32) {
  88. seat_click_buy_btn()
  89. }
  90. }
  91. }
  92. }
  93. if (curr_url.includes("https://excashier.alipay.com/")) {
  94. alert("抢购成功,记得及时付款哦!");
  95. }
  96. })
  97. function seat_click_buy_btn() {
  98. console.log("click buy");
  99. $('#app > div.render-result-container > div.select-result > div.tip-order-button > button').click();
  100. }
  101. //https://stackoverflow.com/a/31112615
  102. Number.prototype.toHHMMSS = function () {
  103. var hours = Math.floor(this / 3600) < 10 ? ("00" + Math.floor(this / 3600)).slice(-2) : Math.floor(this / 3600);
  104. var minutes = ("00" + Math.floor((this % 3600) / 60)).slice(-2);
  105. var seconds = ("00" + (this % 3600) % 60).slice(-2);
  106. return hours + ":" + minutes + ":" + seconds;
  107. };
  108. function timedUpdate() {
  109. var time_difference = Math.ceil((window.sellStartTime_timestamp - window.current_time) / 1000);
  110. //接近20开始请求网络时间
  111. if (window.current_time == undefined || time_difference < 20) {
  112. syncTime(300);
  113. } else {
  114. syncTime(2000);
  115. }
  116. }
  117. function syncTime(num) {
  118. GM_xmlhttpRequest({
  119. url: "https://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp",
  120. method: 'GET',
  121. timeout: 10000,
  122. headers: {
  123. 'Content-Type': 'application/x-www-form-urlencoded'
  124. },
  125. onload: function (responseDetails) {
  126. if (responseDetails.status == 200) {
  127. var result = JSON.parse(responseDetails.responseText.replace('fff(', '').replace(')', ''));
  128. window.current_time = result.data.t;
  129. var time_difference = Math.ceil((window.sellStartTime_timestamp - window.current_time) / 1000);
  130. console.log("相差秒数:" + time_difference);
  131. // 提前1秒开始
  132. if (time_difference < 1) {
  133. window.location.href = window.order_url;
  134. } else {
  135. var time_difference_str = time_difference.toHHMMSS();
  136. $("#countdown").text(time_difference_str);
  137. window.timer = setTimeout(timedUpdate, num);
  138. }
  139. } else {
  140. setTimeout(() => {
  141. syncTime();
  142. }, 1000);
  143. }
  144. }
  145. });
  146. }
  147. function generate_confirm_url(event, price, people_num, data_json) {
  148. var performBases = data_json["performBases"];
  149. var itemId = "";
  150. for (var i = 0; i < performBases.length; i++) {
  151. // console.log("1");
  152. var performBase = performBases[i];
  153. var performs = performBase["performs"];
  154. for (var j = 0; j < performs.length; j++) {
  155. // console.log("2");
  156. var perform = performs[j];
  157. if (perform["performName"] === event) {
  158. // console.log("3");
  159. itemId = perform["itemId"];
  160. window.itemId = itemId;
  161. var skuList = perform["skuList"];
  162. for (var k = 0; k < skuList.length; k++) {
  163. // console.log("4");
  164. var skuList_item = skuList[k];
  165. if (skuList_item["skuName"] === price) {
  166. // console.log("5");
  167. var skuId = skuList_item["skuId"];
  168. return `https://buy.damai.cn/orderConfirm?exParams=%7B%22damai%22%3A%221%22%2C%22channel%22%3A%22damai_app%22%2C%22umpChannel%22%3A%2210002%22%2C%22atomSplit%22%3A%221%22%2C%22serviceVersion%22%3A%221.8.5%22%7D&buyParam=${itemId}_${people_num}_${skuId}&buyNow=true&spm=a2oeg.project.projectinfo.dbuy`
  169. // https://buy.damai.cn/orderConfirm?exParams=%7B%22damai%22%3A%221%22%2C%22channel%22%3A%22damai_app%22%2C%22umpChannel%22%3A%2210002%22%2C%22atomSplit%22%3A%221%22%2C%22serviceVersion%22%3A%221.8.5%22%2C%22umidToken%22%3A%22T2gAPtWBhV9tC67Mptnj5AU_d_KX-57DqykfreYNo38zNk2TgBZssV-gxQlN7aEPYnPc6dXI1re5zNemlLZpfS71%22%2C%22ua%22%3A%22134%23pciI2XXwXGEkxcXNZXkwdJ0D3QROwKOlAOzBtZ26EXkEHKc8qKrQAAmvANaH6n1KGaF4vxWgMEiyvJ8h9bbkRf%2FYEV1hBueE%2BJdqKXL3ZtWwTq1qijRmNyd3OOH8qkuJ%2BJd8qcHAZXnw%2Bcy8qqK7GANE1XazXJmg%2FR%2F5Utf35L2Od6%2FG0dbS1b%2B9L5ktB6IWasdFdaIn%2BqpUTLB8ajSqUVD0dOgouDkm78TjZ0CoGokuqXVsf1xdZ9p%2Fut6sLnyD7zJR7vi3xgho3ZvGI37q7cXGmA1IjAYsrBXU2kdbCbTZygJjLhS6%2FKJ7jMrS32iAng488JzvSMYV4D5o9mt%2BYWWddusAWqInij0%2FLKPSEnpK8MgQLbC8xXqcqv9ojtBm2DseaKe6g0CAXgFjW0XXA1aAhvJVTXDVIjariuT47UsZ94G4Vve%2Byr6FmI1RmtHBHwiiTN4YufCiYcr7UMN40vCkITwrXibXJVe5IW%2BkcuFlRVaK5fToG%2BK%2FDDJNLfO7LA4OoXB5BemruIehBXZPAVBHW5VgnKKG6A7MKWG8VHBsknL77EDMTYo%2FVGR5E9KfJtMNhTuRyPEJUXqIyuBs%2BWMeerkEllrcI4tn6j%2FQvxFo%2BMmoAnu4Gz05k2yBrt45eVj3sndkBqzjSOdocl5f%2BtA18aToWalQuZqLb0x31S4Ac6ZTPkhnqSnt%2BGGodrhKgkR1IyvyfYR85d2Yxnht1kSmE7O4YIEt6srmH2We9UqUdhkkeKByPHsj4MvAe2yejlSN1HcH0Mm0K4JjF59IvjH4Aw3UKv7GGnY1EtOcPvgZ8uNf7HfoWX%3D%3D%22%7D&buyParam=624490600818_1_4598946947036&buyNow=true&spm=a2oeg.project.projectinfo.dbuy
  170. }
  171. }
  172. }
  173. }
  174. }
  175. return null;
  176. }
  177. function generate_seat_url(is_calendar, event, price, people_num, data_json) {
  178. var performBases = [];
  179. if (is_calendar) {
  180. var month = event.slice(0, 7);
  181. var calendarPerforms = data_json["calendarPerforms"];
  182. for (var i = 0; i < calendarPerforms.length; i++) {
  183. var calendarPerform = calendarPerforms[i];
  184. if (calendarPerform["month"] == month) {
  185. performBases = calendarPerform["performBases"];
  186. }
  187. }
  188. } else {
  189. performBases = data_json["performBases"];
  190. }
  191. var itemId = "";
  192. for (var i = 0; i < performBases.length; i++) {
  193. var performBase = performBases[i];
  194. var performs = performBase["performs"];
  195. for (var j = 0; j < performs.length; j++) {
  196. var perform = performs[j];
  197. var performId = perform.performId;
  198. var projectId = new URLSearchParams(window.location.href).get('id');
  199. if (perform["performName"] === event) {
  200. itemId = perform["itemId"];
  201. window.itemId = itemId;
  202. var skuList = perform["skuList"];
  203. for (var k = 0; k < skuList.length; k++) {
  204. var skuList_item = skuList[k];
  205. if (skuList_item["skuName"] === price) {
  206. var skuId = skuList_item["skuId"];
  207. return `https://seatsvc.damai.cn/tms/selectSeat?itemId=${itemId}&performId=${performId}&skuId=${skuId}&projectId=${projectId}`
  208. }
  209. }
  210. }
  211. }
  212. }
  213. return null;
  214. }
  215. function detail_ui() {
  216. var $service = $(".content-right .service");
  217. var $control_container = $("<div id='control_container'></div>");
  218. var $wx = $(`<div id="wx" class="notice"><p>陈鸿宇fighting </p><p>版本: ${version}</p></div>`);
  219. var $number_input = $('<div class="input_wrapper" id="number_input_wrapper">请输入人数:<input id="number_input" type="number" value="1" min="1" max="6"></div>');
  220. // var $email_input = $('<div class="input_wrapper" id="email_input_wrapper">email:<input id="email_input" type="email" value="example@hotmail.com"></div>');
  221. // var $name_input = $('<div class="input_wrapper" id="name_input_wrapper">联系人姓名:<input id="name_input" type="text" value="小明"></div>');
  222. // var $duration_input = $('<div class="input_wrapper" id="duration_input_wrapper">刷新间隔(ms):<input id="duration_input" type="text" value="5000"></div>');
  223. var $start_btn = $('<button id="start_btn">开始抢票</button>');
  224. var $end_btn = $('<button id="end_btn">停止抢票</button>');
  225. var $notice = $('<div id="notice" class="notice"><h3>使用步骤</h3><p>1.登录(不可用),填写购票人信息</p><p>2.选择场次->价格->填写人数</p><p>3.点击‘开始抢票’</p></div>');
  226. var $notice2 = $('<div id="notice2" class="notice"><p>已同步网络时间</p><p>若误差过大请刷新页面,更新时间</p></div>');
  227. var $countdown = $('<div id="countdown_wrapper"><p id="selected_event">event1</p><p id="selected_price">price2</p><p id="selected_number">1人</p><br><p>倒计时:</p><p id="countdown">00:00:00</p></div>');
  228. $control_container.append($style);
  229. $control_container.append($wx);
  230. $control_container.append($number_input);
  231. // $control_container.append($email_input);
  232. // $control_container.append($name_input);
  233. // $control_container.append($duration_input);
  234. $control_container.append($start_btn);
  235. $control_container.append($end_btn);
  236. $control_container.append($notice);
  237. $control_container.append($notice2);
  238. // $control_container.append($countdown);
  239. $control_container.insertBefore($service);
  240. $countdown.insertBefore($control_container);
  241. $("#start_btn").click(function () {
  242. var event = get_event();
  243. var price = get_price();
  244. var people_num = $("#number_input").val();
  245. var data_json = JSON.parse($("#dataDefault").text());
  246. window.sellStartTime_timestamp = data_json["sellStartTime"];
  247. $("#selected_event").text(event);
  248. $("#selected_price").text(price);
  249. $("#selected_number").text(people_num + "人");
  250. $("#countdown_wrapper").show();
  251. // console.log(data_json)
  252. var result = generate_confirm_url(event, price, people_num, data_json);
  253. console.log("result--" + result);
  254. if (result) {
  255. window.order_url = result;
  256. sessionStorage.setItem('order_url', result);
  257. console.log("countdown and go to confirm page");
  258. timedUpdate();
  259. } else {
  260. console.error("获取场次票价人数出错了。");
  261. alert("获取场次票价人数出错了");
  262. }
  263. });
  264. $("#end_btn").click(function () {
  265. clearTimeout(window.timer);
  266. $("#countdown_wrapper").hide();
  267. sessionStorage.clear();
  268. });
  269. }
  270. // http://cncc.bingj.com/cache.aspx?q=jquery+ignore+inner+most&d=4555311081654245&mkt=en-US&setlang=en-US&w=FZ-aM6oeDz4XhBZleDN79HoRb7ybox0E
  271. function get_text_exclude_children(css_selector_str) {
  272. return $(css_selector_str).contents().not($(css_selector_str).children()).text().trim();
  273. }
  274. function get_event() {
  275. var event_css_selector = ".perform__order__select.perform__order__select__performs .select_right_list .active>*";
  276. return get_text_exclude_children(event_css_selector);
  277. }
  278. function get_price() {
  279. var price_css_selector = ".select_right_list_item.sku_item.active .skuname";
  280. return get_text_exclude_children(price_css_selector);
  281. }
  282. function detail_seat_ui() {
  283. var $service = $(".content-right .service");
  284. var $control_container = $("<div id='control_container'></div>");
  285. var $wx = $(`<div id="wx" class="notice">陈鸿宇fighting </p><p>版本: ${version}</p></div>`);
  286. var $number_input = $('<div class="input_wrapper" id="number_input_wrapper">请输入人数:<input id="number_input" type="number" value="1" min="1" max="6"></div>');
  287. var $start_btn = $('<button id="start_btn">开始抢票</button>');
  288. var $end_btn = $('<button id="end_btn">停止抢票</button>');
  289. var $notice = $('<div id="notice" class="notice"><h3>使用步骤</h3><p>1.登录(不可用),填写购票人信息</p><p>2.选择场次->价格->填写人数</p><p>3.点击‘开始抢票’</p></div>');
  290. var $notice2 = $('<div id="notice" class="notice warning"><h3>注意</h3><p>若人数为1,选座页面手动选座后自动进入下一步</p><p>人数多于1时,选座页面手动选座后点击“确认选座”按钮或按下空格键进入下一步</p></div>');
  291. var $notice3 = $('<div id="notice2" class="notice"><p>已同步网络时间</p><p>若误差过大请刷新页面,更新时间</p></div>');
  292. var $countdown = $('<div id="countdown_wrapper"><p id="selected_event">event1</p><p id="selected_price">price2</p><p id="selected_number">1人</p><br><p>倒计时:</p><p id="countdown">00:00:00</p></div>');
  293. $control_container.append($style);
  294. $control_container.append($wx);
  295. $control_container.append($number_input);
  296. $control_container.append($start_btn);
  297. $control_container.append($end_btn);
  298. $control_container.append($notice);
  299. $control_container.append($notice2);
  300. $control_container.append($notice3);
  301. $control_container.insertBefore($service);
  302. $countdown.insertBefore($control_container);
  303. $("#start_btn").click(function () {
  304. var event = get_event();
  305. var price = get_price();
  306. var people_num = $("#number_input").val();
  307. var data_json = JSON.parse($("#dataDefault").text());
  308. window.sellStartTime_timestamp = data_json["sellStartTime"];
  309. $("#selected_event").text(event);
  310. $("#selected_price").text(price);
  311. $("#selected_number").text(people_num + "人");
  312. $("#countdown_wrapper").show();
  313. if ($("#dataDefault").text().includes("calendarPerforms")) {
  314. var result = generate_seat_url(true, event, price, people_num, data_json);
  315. } else {
  316. var result = generate_seat_url(false, event, price, people_num, data_json);
  317. }
  318. if (result) {
  319. window.order_url = `${result}&people_num=${people_num}`;
  320. sessionStorage.setItem('seat_url', result);
  321. console.log("countdown and go to confirm page");
  322. timedUpdate();
  323. } else {
  324. console.error("不知道为什么获取场次票价人数出错了呢。");
  325. alert("不知道为什么获取场次票价人数出错了呢。");
  326. }
  327. });
  328. $("#end_btn").click(function () {
  329. clearTimeout(window.timer);
  330. $("#countdown_wrapper").hide();
  331. sessionStorage.clear();
  332. });
  333. }
  334. function check_alert() {
  335. var alerts = $(".next-dialog-alert");
  336. if (alerts.length > 0 || window.current_time >= window.max_time) {
  337. window.location.reload();
  338. } else {
  339. window.current_time = window.current_time + 300;
  340. setTimeout(check_alert, 300);
  341. }
  342. }
  343. function fill_form() {
  344. var buyer_number = parseInt($(".ticket-buyer-title em").text());
  345. window.buyer_number = buyer_number;
  346. window.curr_buyer = 0;
  347. console.log("勾选下单人数:" + buyer_number);
  348. var buyer_list = $(".buyer-list-item input");
  349. for (var i = 0; i < buyer_number; i++) {
  350. console.log(buyer_list[i]);
  351. buyer_list[i].click();
  352. }
  353. setTimeout(submit_order, 200);
  354. }
  355. function submit_order() {
  356. $(".submit-wrapper button").click();
  357. setTimeout(check_alert, 200);
  358. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址