stopwatch

1.get current answer 2.push notification when stop

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey, το Greasemonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Userscripts για να εγκαταστήσετε αυτόν τον κώδικα.

You will need to install an extension such as Tampermonkey to install this script.

Θα χρειαστεί να εγκαταστήσετε μια επέκταση διαχείρισης κώδικα χρήστη για να εγκαταστήσετε αυτόν τον κώδικα.

(Έχω ήδη έναν διαχειριστή κώδικα χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Έχω ήδη έναν διαχειριστή στυλ χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

// ==UserScript==
// @name         stopwatch
// @namespace    ycycorona
// @version      0.1.3
// @description  1.get current answer 2.push notification when stop
// @author       ycy
// @match   *://sdwh.zyk.yxlearning.com/learning/index*
// @match   *://sdwh.gxk.yxlearning.com/learning/index*
// @require https://cdn.staticfile.org/jquery/2.1.4/jquery.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/qs/6.9.4/qs.min.js
// @run-at  document-start
// @grant   GM_addStyle
// @grant   GM_notification
// @grant GM_xmlhttpRequest
// ==/UserScript==

(function() {
  'use strict';

var choices = [
  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'
]

$(function() {
  var $btn = $('<button type="button" id="ycy-answer-btn">当前答案</button>').css(
    {
      "position": "fixed",
      "top": "0",
      "right": "10px",
      "z-index": "99999"
    }
  )
  var $answerPop = $('<div id="ycy-answer-pop"></div>').css(
    {"position": "fixed",
    "top": "50px",
    "right": "10px",
    'width': '400px',
    'height': '600px',
    'over-flow': 'auto',
    "z-index": "99999",
    "background": "beige"
  });
  $answerPop.hide()
  $('html').append($answerPop)
  $('html').append($btn)
  $btn.click(function(e) {
    $answerPop.slideToggle()
  });
  // var opt_1 = $('#defaultBtn span.sum')
  // var opt_2 = $('div.learnhour.left')
  // console.log(opt_1, opt_2);
  // if (opt_1.length!==0) {
  //   opt_1.append($btn)
  // } else if (opt_2.length!==0) {
  //   opt_2.append($btn)
  // }
})

function timeFormat(rawTime) {
  var timeArray = String(rawTime).split(':')
  var timeSec = timeArray[timeArray.length-1]
  return '' + Math.floor(timeSec/60) + ':' + (timeSec - (Math.floor(timeSec/60)*60))
}

function rowFactory(item, index) {
  var $parentDom = $('<div></div>')
  var $ques = $('<div></div>')
  var $answer = $('<div></div>')
  var $time = $('<div></div>')
  $time.html(timeFormat(item.showTime) + '/' + timeFormat(item.wrongTime))
  $time.css({
    'font-size': '10px'
  })

  $ques.css('font-weight', '700')
  $ques.html((index+1) + '.' + item.question)


  JSON.parse(item.choices).forEach((citem, cindex) => {
    var cRow = $('<div>'+ choices[cindex] + '.' + citem.answer  +'</div>')

    if(citem.right_answer===1) {
      cRow.css('color', 'red')
    }
    $answer.append(cRow)
  })
  return $parentDom.append($ques).append($time).append($answer)
}

function StopWatch() {
      this.timerFlag = 0
      this.timerTImes = 0 // 倒计时触发前经历了多少个循环
      this.timerActivated = false // 是否已经在倒计时
      this.generateCheck = function(url) {
          if(url!=='/train/cms/my-video/cv.gson') {return}
          if (this.timerFlag!==0) {
              clearTimeout(this.timerFlag)
          }
          console.log('倒计时开始')
          this.timerTImes ++
          this.timerFlag = setTimeout(this.onTimerEnd.bind(this), 30000)
      }
      // 获取当前的答案
      this.getCurrentAnswer = function(url, reqBody) {
        if(url !== '/train/cms/my-video/sv.gson') { return }
        //if(! url.match(/v.polyv.net\/uc\/exam\/get/)) { return }
        var watchInfo = JSON.parse(Qs.parse(reqBody).watchInfo)
        console.log('getCurrentAnswer', watchInfo)
        GM_xmlhttpRequest({
          method: 'GET',
          url: `http://v.polyv.net/uc/exam/get?vid=${watchInfo.vid}`,
          onload: res => {
            var text = res.responseText;
            var json = JSON.parse(text);
            console.log(json);
            $('#ycy-answer-pop').empty()
            json.forEach((item, index) => {
              $('#ycy-answer-pop').append(rowFactory(item, index))
            })
          }
      });
      }

      this.onTimerEnd = function() {
          this.timerTImes = 0
          this.sendAlarm()
      }
      this.sendNotifitation = function(msg) {
          var notificationDetails = {
              text: msg,
              title: '学习暂停了',
              timeout: 30000,
              onclick: function() { window.focus(); },
          };
          GM_notification(notificationDetails);
      }
      this.sendAlarm = function() {
          var postData={
              text: `[${document.querySelector('.titlesname').innerText}][${document.querySelector('.pv-time-current').innerText}]/[${document.querySelector('.pv-time-duration').innerText}]`,
              desp: ''
          }
          // 创建XMLHttpRequest对象
          var xhr = new XMLHttpRequest()
          var urlEncodedData = "";
          var urlEncodedDataPairs = [];
          var name;

          // 将数据对象转换为URL编码的键/值对数组。
          for(name in postData) {
              urlEncodedDataPairs.push(encodeURIComponent(name) + '=' + encodeURIComponent(postData[name]));
          }

          // 将配对合并为单个字符串,并将所有%编码的空格替换为
          // “+”字符;匹配浏览器表单提交的行为。
          urlEncodedData = urlEncodedDataPairs.join('&').replace(/%20/g, '+');
          this.sendNotifitation(postData.text)
          // 创建一个 get 请求,true 采用异步
          GM_xmlhttpRequest({
            method: 'POST',
            //请输入自己的url
            url: `https://sc.ftqq.com/123455.send`,
            data: urlEncodedData,
            headers:  {
              "Content-Type": "application/x-www-form-urlencoded"
            },
            onload: res => {
              console.log(res.responseText)
            },
            onerror : function(err){
              console.log('error')
              console.log(err)
          }
        });

          // xhr.open('POST', 'https://javtest.cyberspideryy.workers.dev/', true)
          // xhr.onreadystatechange = function () {
          //     if (xhr.readyState === 4) {
          //         if (xhr.status === 200) {
          //             console.log(xhr.responseText)
          //         }
          //     }
          // }
          // xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
          // //发送请求

          // xhr.send(urlEncodedData) //发送格式为json字符串
      }
  }
  var stopWatch = new StopWatch()
  window._stopWatch = stopWatch;
  console.log(stopWatch);
  /**
  * 修改XMLHttpRequest发送方法
  */
  var signature = '_ycycorona_grace_';
  (function(open) {
      XMLHttpRequest.prototype.open = function() {
          stopWatch.generateCheck(arguments[1])
          // 记录下来url
          this[signature+'reqUrl'] = arguments[1]
          open.apply(this, arguments);
      };
  })(XMLHttpRequest.prototype.open);

  (function(send) {
      XMLHttpRequest.prototype.send = function() {
          stopWatch.getCurrentAnswer(this[signature+'reqUrl'], arguments[0])
          send.apply(this, arguments);
      };
  })(XMLHttpRequest.prototype.send);

// 测试
  // var a=new XMLHttpRequest();
  // var url='/train/cms/my-video/sv.gson';
  // // a.addEventListener('readystatechange',function(e){
  // //     console.log(e);
  // // });
  // // //console.log(XMLHttpRequest.XMLHttpRequestEventTarget);
  // // a.onreadystatechange=function()
  // // {
  // //     //console.log('abc');
  // // };
  // a.open('POST',url);
  // a.send('myClassId=a7727ae0-54ae-4234-a673-799c7edd2a53&myClassCourseId=3b8f3a0b-2cee-42db-b873-9bf9c3026dcd&myClassCourseVideoId=e13dccf1-0dda-4fc7-bb99-bf6885cd6a22&watchInfo=%7B%22vid%22%3A%22a18dce4e4354b3e50da4b2448d610987_a%22%2C%22pid%22%3A%221603087064279X1056258%22%2C%22playduration%22%3A0%2C%22timestamp%22%3A1603087069859%2C%22sign%22%3A%223b6d071aae83b52cac5b191638b8a61848f355f5%22%7D');

  //var b=new XMLHttpRequest();
})();