Greasy Fork

Greasy Fork is available in English.

Grab Venue in SZU

【使用前先看介绍/有问题可反馈】深大抢馆 (Grab Venue in SZU):抢深圳大学粤海校区体育场馆,目前仅适配了羽毛球项目,了解编程的可以自行修改配置。

当前为 2021-09-09 提交的版本,查看 最新版本

// ==UserScript==
// @name         Grab Venue in SZU
// @namespace    http://tampermonkey.net/
// @version      1.0.0
// @description  【使用前先看介绍/有问题可反馈】深大抢馆 (Grab Venue in SZU):抢深圳大学粤海校区体育场馆,目前仅适配了羽毛球项目,了解编程的可以自行修改配置。
// @author       cc
// @match        http://ehall.szu.edu.cn/publicapp/sys/tycgyyxt/index.do*
// @grant        none
// ==/UserScript==

(function () {
  const config = {
    DEBUG: false, // 是否开启调试,不要动这个选项
    neededTimeSlot: '19:00-22:00', // 所需时间段
    CQBM: '001', // 场区 ID (可能)
    CGBM: '002', // 场馆 ID (默认羽毛球馆)
    XMDM: '005', // 项目 ID (默认羽毛球)
    CYRS: 4, // 参与人数 (默认 4 人)
    XQWID: null, // 校区 ID,不用修改,由网络请求获取
    startClock: '12:30', // 开始时间
  }

  function inform(msg) {
    msg = `%c${msg}`;
    console.warn(msg, 'background-color: yellow; font-weight: bold;');
  }

  function timeFormat(milliseconds) {
    var unit = parseInt(milliseconds / 1000);
    var second = unit % 60;
    unit = parseInt(unit / 60);
    var minute = unit % 60;
    unit = parseInt(unit / 60);
    var hour = unit % 24;
    var pad = e => e.toString().padStart(2, '0');
    var ans = `${pad(second)} sec`;
    if (minute > 0)
      ans = `${pad(minute)} min ${ans}`;
    if (hour > 0)
      ans = `${pad(hour)} hour ${ans}`;
    return ans;
  }

  function requestVenue(waiting, finished) {
    console.warn('in function requestVenue...');
    if (waiting.length > 0) {
      let WID = waiting[0];
      $.ajax({
        url: 'http://ehall.szu.edu.cn/publicapp/sys/tycgyyxt/sportVenue/getOrderNum.do',
        method: 'POST',
        data: { wid: WID }
      }).then(res => {
        var DHID = res.DHID;
        var YYRQ = getYYRQ();
        var KYYSJD = getHourTimeSlot(config.neededTimeSlot);
        var [START, END] = KYYSJD.split('-');
        var [YYKS, YYJS] = [`${YYRQ} ${START}`, `${YYRQ} ${END}`];
        $.ajax({
          url: 'http://ehall.szu.edu.cn/publicapp/sys/tycgyyxt/sportVenue/insertVenueBookingInfo.do',
          method: 'POST',
          data: {
            DHID: DHID,
            YYRGH: localStorage.ampUserId,
            XQWID: config.XQWID,
            CQBM: config.CQBM,
            CGDM: config.CGBM,
            CDWID: WID,
            XMDM: config.XMDM,
            YYRQ: YYRQ,
            KYYSJD: KYYSJD,
            YYKS: YYKS,
            YYJS: YYJS,
            YYLX: 'YY_TT',
            BCXZRS: 6,
            CYRS: config.CYRS,
            QTYYR: []
          }
        }).then(res => {
          if (res.success) {
            console.warn(res);
            config.neededTimeSlot = nextTimeSlot(config.neededTimeSlot);
            if (!finishBooking(config.neededTimeSlot)) {
              requestVenue(waiting, finished);
            } else {
              inform('all tasks completed.');
            }
          } else {
            finished.push(waiting[0]);
            waiting = waiting.splice(1);
            requestVenue(waiting, finished);
          }
        });
      });
    }
  }

  function getYYRQ() {
    var now = new Date();
    if (config.DEBUG)
      now = new Date(Date.now() + 86400 * 1000);
    var month = `${now.getMonth() + 1}`.padStart(2, '0');
    var date = `${now.getDate()}`.padStart(2, '0');
    return `${now.getFullYear()}-${month}-${date}`;
  }

  function nextHourOf(hour) {
    return `${parseInt(hour.match(/\d+/)[0]) + 1}`.padStart(2, '0') + ':00';
  }

  function getHourTimeSlot(timeSlot) {
    var firstHour = parseInt(timeSlot.match(/\d+/)[0]);
    var START = `${firstHour}`.padStart(2, '0') + ':00';
    var END =  `${firstHour + 1}`.padStart(2, '0') + ':00';
    return `${START}-${END}`
  }

  function nextTimeSlot(timeSlot) {
    var [START, END] = timeSlot.match(/\d+:00/g);
    START = nextHourOf(START);
    return `${START}-${END}`;
  }

  function finishBooking(timeSlot) {
    var [start, end] = timeSlot.match(/\d+:00/g).map(e => parseInt(e.match(/\d+/)[0]));
    return start >= end;
  }

  function isInTimeSlot(neededTimeSlot, timeSlot) {
    var tsRange = timeSlot.match(/\d+:00/g).map(s => parseInt(s.substr(0, 2)));
    let neededTsRange = neededTimeSlot.match(/\d+:00/g).map(s => parseInt(s.substr(0, 2)));
    if (tsRange[0] < neededTsRange[0] || neededTsRange[1] < tsRange[1])
      return false;
    return true;
  }

  function requestWIDs() {
    console.warn('in function requestWIDs...');
    var [START, END] = config.neededTimeSlot.match(/\d{2}:00/g);
    $.ajax({
      url: 'http://ehall.szu.edu.cn/publicapp/sys/tycgyyxt/sportVenue/getCdxx.do',
      method: 'POST',
      data: {
        CGBM: config.CGBM,
        XMDM: config.XMDM,
        TYPE: 'YY_TT',
        START: START,
        END: END,
        YYRQ: getYYRQ(config),
        YYTYPE: '1.0'
      }
    }).then(res => {
      var WIDs = res.map(e => e.id);
      requestVenue(WIDs, []);
    });
  }

  function init() {
    console.warn('in function init...');
    $.ajax({
      url: 'http://ehall.szu.edu.cn/publicapp/sys/tycgyyxt/sportVenue/getSchoolZoneDic.do',
      method: 'POST',
      async: true,
    }).then(res => {
      config.XQWID = res.datas.code.rows[0].id;
    });
  }

  function run() {
    console.warn('in function run...');
    $.ajax({
      url: 'http://ehall.szu.edu.cn/publicapp/sys/tycgyyxt/sportVenue/getSjdByCg.do',
      method: 'POST',
      data: {
        CGBM: config.CGBM,
        XMDM: config.XMDM,
        TYPE: 'YY_TT',
        YYRQ: getYYRQ(config),
        YYTYPE: '1.0'
      },
    }).then(res => {
      var sjd = res.kyysjd.map(e => e.kyysjd);
      var timeslots = sjd.filter(e => isInTimeSlot(config.neededTimeSlot, e));
      if (timeslots.length == 0) {
        console.warn();
      } else {
        requestWIDs(timeslots);
      }
    });
  }

  function standBy() {
    init();
    console.warn('in function standBy...');
    var now = new Date();
    var startHourMinute = config.startClock.split(':').map(e => parseInt(e));
    var startClock = {
      hour: startHourMinute[0],
      minute: startHourMinute[1],
      second: 0
    };
    var currentClock = {
      hour: now.getHours(),
      minute: now.getMinutes(),
      second: now.getSeconds()
    }
    if (currentClock.hour < startClock.hour || (currentClock.hour == startClock.hour && currentClock.minute < startClock.minute)) {
      var diffMillis = ((startClock.hour - currentClock.hour) * 3600 + (startClock.minute - currentClock.minute) * 60 + (startClock.second - currentClock.second)) * 1000;
      console.warn(`Tasks will be executed in ${timeFormat(diffMillis)}.`)
      setTimeout(run, diffMillis);
    } else {
      inform('The time limit is exceeded and the program is no longer executed.');
    }
  }

  standBy();
})();