Greasy Fork

Greasy Fork is available in English.

fuck_qingjiao

Fuck 青骄第二课堂 全自动完成所有课程+学分自动获取

当前为 2022-10-14 提交的版本,查看 最新版本

// ==UserScript==
// @name         fuck_qingjiao
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Fuck 青骄第二课堂 全自动完成所有课程+学分自动获取
// @author       WindLeaf
// @match        *://www.2-class.com/*
// @grant        none
// @license      GPL-3.0
// @require      http://cdn.staticfile.org/jquery/3.6.1/jquery.min.js
// ==/UserScript==

(function() {
  'use strict';

  function isNone(anyObj) {
    return anyObj == undefined || anyObj == null;
  }

  if (isNone($.ajax) || isNone($.isNumeric)) {
    console.error('Cannot find jQuery function!')
    return;
  }

  const error = err => {
    // sadly error occurred
    console.error(`Error has occurred! Status code [${err.status}]`, err.responseText);
    return;
  }

  let location = document.location;
  let pathname = location.pathname;
  let reqtoken = window.__DATA__.reqtoken; // so easy get dumb developer LMFAOOO

  // check url
  if (pathname === '/courses' || pathname === '/drugControlClassroom/courses') {
    taskCourses();
  } else if (pathname === '/selfCourse' || pathname === '/drugControlClassroom/selfCourse') {
    taskSelfCourses();
  } else if (pathname === '/admin/creditCenter') {
    taskCredit();
  }

  function startCourse(courseId) {
    $.ajax({
      method: 'GET',
      url: `https://www.2-class.com/api/exam/getTestPaperList?courseId=${courseId}`,
      success: resp => {
        let data = resp.data;
        let title = data.papaerTitle; // typo xD
        let testPaperList = data.testPaperList;
        if (!isNone(testPaperList)) {
          let answers = testPaperList.map(column => column.answer);
          console.debug(data);
          console.log(`Successfully get the data of course[${courseId}]: ${title}`);
          console.log('Successfully get answers:', answers);
          commit(answers);
        } else {
          startCourse(courseId);
        }
      },
      error: err => {
        console.error('Error has occurred!', err);
        return;
      }
    })

    function commit(answers) {
      console.log('Committing...')
      let data = {
        courseId,
        examCommitReqDataList: answers.map((answer, index) => {
          return {
            examId: index + 1, // examId = index + 1
            answer: $.isNumeric(answer) ? Number(answer) : answer // single answer must be a number
          }
        }),
        reqtoken
      }

      $.ajax({
        method: 'POST',
        url: 'https://www.2-class.com/api/exam/commit',
        contentType: 'application/json;charset=UTF-8', // use application/json or 415 error
        dataType: 'json', // maybe useless
        data: JSON.stringify(data), // must use JSON.stringify
        success: resp => {
          let flag = resp.data;
          if (flag) {
            console.log(`Successfully committed course [${courseId}]!`);
          } else {
            console.error(resp);
          }
        },
        error
      })
    }
  }

  function taskCourses() {
    $.ajax({
      method: 'GET',
      url: 'https://www.2-class.com/api/course/getHomepageGrade',
      success: resp1 => {
        let grades = resp1.data.map(it => it.value);
        console.debug('grades', grades);
        for (let grade of grades) {
          // get courses
          $.ajax({
            method: 'GET',
            url: `https://www.2-class.com/api/course/getHomepageCourseList?grade=${grade}&pageSize=24&pageNo=1`,
            success: resp2 => {
              let courses = resp2.data.list
                .filter(k => !k.isFinish && k.title != '期末考试') // skip finished and final exam
                .map(j => j.courseId); // courseId => list
              console.debug('courses', courses);
              for (let courseId of courses) {
                // [skip final exam]
                if (courseId == 'finalExam') {
                  console.debug('Skipped final exam.');
                  return;
                }
                // start course
                if (!isNone(courseId)) {
                  startCourse(courseId);
                } else {
                  console.error('courseId not found, skipped.');
                }
              }
            },
            error
          })
        }
      },
      error
    });
  }

  function taskSelfCourses() {
    // get all grades (bad method)
    let gradesTabElements = [];
    let timer = setInterval(() => {
      gradesTabElements = document.getElementsByClassName('ant-tabs-tab');
      if (gradesTabElements.length != 0) {
        resolveGrades();
      }
    }, 500);

    function resolveGrades() {
      clearInterval(timer);
      console.debug('grades', gradesTabElements);
      for (let element of gradesTabElements) {
        let grade = element.innerText;
        $.ajax({
          method: 'GET',
          url: `https://www.2-class.com/api/course/getHomepageCourseList?grade=自学&pageNo=1&pageSize=500&sort=&type=${grade}`,
          success: resp => {
            let courses = resp.data.list
              .filter(k => !k.isFinish && k.title != '期末考试') // skip finished and final exam
              .map(j => j.courseId); // courseId => list
            console.debug('courses', courses);
            for (let courseId of courses) {
              // [skip final exam]
              if (courseId == 'finalExam') {
                console.debug('Skipped final exam.');
                return;
              }
              // start course
              if (!isNone(courseId)) {
                startCourse(courseId);
              } else {
                console.error('courseId not found, skipped.');
              }
            }
          },
          error
        })
      }
    }
  }

  function taskCredit() {
    // medal: 领取禁毒学子勋章
    $.ajax({
      method: 'GET',
      url: 'https://www.2-class.com/api/medal/addMedal',
      success: medalResp => {
        let data = medalResp.data;
        let status = data.status;
        let num = data.medalNum;
        if (status) {
          console.log(`Successfully add medal [${num}]!`);
        } else {
          console.error(`Cannot add medal, skipped!`)
        }
      }
    });

    // resources: 心理减压, 耕读学堂 [耕读, 电影, 音乐, 体育, 美术, 自然, 公开课], 校园安全
    let categorys = [
      { categoryName: 'public_good', pageNo: 1, pageSize: 100, reqtoken, tag: 'read' },
      { categoryName: 'ma_yun_recommend', pageNo: 1, pageSize: 100, reqtoken, tag: 'labour' }, // the `ma_yun_recommend` has lots of sub-categorys
      { categoryName: 'ma_yun_recommend', pageNo: 1, pageSize: 100, reqtoken, tag: 'movie' },
      { categoryName: 'ma_yun_recommend', pageNo: 1, pageSize: 100, reqtoken, tag: 'music' },
      { categoryName: 'ma_yun_recommend', pageNo: 1, pageSize: 100, reqtoken, tag: 'physicalEducation' },
      { categoryName: 'ma_yun_recommend', pageNo: 1, pageSize: 100, reqtoken, tag: 'arts' },
      { categoryName: 'ma_yun_recommend', pageNo: 1, pageSize: 100, reqtoken, tag: 'natural' },
      { categoryName: 'ma_yun_recommend', pageNo: 1, pageSize: 100, reqtoken, tag: 'publicWelfareFoundation' },
      { categoryName: 'school_safe', pageNo: 1, pageSize: 100, reqtoken, tag: 'safeVolunteer' }
    ];
    for (let category of categorys) {
      $.ajax({
        method: 'POST',
        url: 'https://www.2-class.com/api/resource/getBeforeResourcesByCategoryName',
        contentType: 'application/json;charset=UTF-8',
        dataType: 'json',
        data: JSON.stringify(category),
        success: resourcesResp => {
          let resources = resourcesResp.data.list.map(it => {
            return {
              title: it.briefTitle, resourceId: it.resourceId
            };
          });
          for (let resource of resources) {
            let resourceId = resource.resourceId;
            // sync resource
            $.ajax({
              method: 'POST',
              url: 'https://www.2-class.com/api/growth/sync/resource',
              contentType: 'application/json;charset=UTF-8',
              dataType: 'json',
              data: JSON.stringify({
                resourceId, reqtoken
              }),
              success: resourcePostResp => {
                let result = resourcePostResp.data.result;
                if (result) {
                  console.log(`Successfully synced resource [${resourceId}]: ${resource.title}!`);
                } else {
                  console.error(`Sync resource [${resourceId}] error, skipped!`);
                }
                return;
              }
            });

            // like resource
            $.ajax({
              method: 'POST',
              url: 'https://www.2-class.com/api/resource/likePC',
              contentType: 'application/json;charset=UTF-8',
              dataType: 'json',
              data: JSON.stringify({
                resourceId, reqtoken
              }),
              success: resourceLikeResp => {
                let count = resourceLikeResp.data;
                let flag = resourceLikeResp.success;
                let already_like = !$.isNumeric(count) && count.errorCode === 'ALREADY_like';
                if ($.isNumeric(count) && flag) {
                  console.log(`Successfully liked resource [${resourceId}]: ${count}!`);
                } else {
                  console.error(`Cannot like ${resourceId}, [already_like=${already_like}], skipped!`);
                }
              },
              error
            });
          }
        },
        error
      });
    }
  }
})();