🎉 欢迎访问GreasyFork.Org 镜像站!本镜像站由公众号【爱吃馍】搭建,用于分享脚本。联系邮箱📮

Greasy fork 爱吃馍镜像

超星网课挂科模式

自动签到,自动统计未完成作业、未完成任务等、提前解锁章节,查看章节统计。我是热爱学习的好孩子,(配合超星网课助手可自动观看课程、自动完成作业等)

Du musst eine Erweiterung wie Tampermonkey, Greasemonkey oder Violentmonkey installieren, um dieses Skript zu installieren.

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

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

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

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

Sie müssten eine Skript Manager Erweiterung installieren damit sie dieses Skript installieren können

(Ich habe schon ein Skript Manager, Lass mich es installieren!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

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.

(I already have a user style manager, let me install it!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

// ==UserScript==
// @name         超星网课挂科模式
// @namespace    https://userscript.snomiao.com
// @version      0.2
// @description  自动签到,自动统计未完成作业、未完成任务等、提前解锁章节,查看章节统计。我是热爱学习的好孩子,(配合超星网课助手可自动观看课程、自动完成作业等)
// @author       [email protected]
// @match        *://*.chaoxing.com/*
// @match        *://mobilelearn.chaoxing.com/*
// @match        *://mooc1-1.chaoxing.com/*
// @match        *://i.mooc.chaoxing.com/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addValueChangeListener
// ==/UserScript==

// 课程列表
// http://mooc1-1.chaoxing.com/visit/interaction
//
//
// 开发中
//
///////////////////////////////
// 防多开
// var genId = '' + Math.random()

///////////////////////////////
// 异步组件
var 睡 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
var 异步防抖函数 = (异步函数, 间隔时间 = 1000) => {
  var 上次执行时间 = null;
  return async (...参列) => {
    if (上次执行时间 != null && 上次执行时间 + 间隔时间 >= +new Date())
      return null;
    上次执行时间 = +new Date();
    return await 异步函数(参列);
  };
};

// 对象操作
var 深合并 = (t, s) =>
  (t instanceof Object &&
    ([...Object.keys(s)].forEach((k) => (t[k] = 深合并(t[k], s[k]))), t)) ||
  (undefined === s && t) ||
  s;
var 键值对列转对象 = (键值对列) =>
  键值对列.reduce((a, b) => ((a[b[0]] = b[1]), a), {});
var 全部提取 = (str, reg) => {
  if (!reg.global) return null;
  var coll = [];
  while (((e) => e && coll.push(e))(reg.exec(str)));
  return coll;
};
var 提取为表 = (html, 正则表达式, 键值对函数) => ({
  ...键值对列转对象(全部提取(html, 正则表达式).map(键值对函数)),
});

///////////////////////////////
// FETCH
var GETHTML = async (url) => await (await fetch(url)).text();

// 存储
var 加载状态 = () => {
  try {
    var r = JSON.parse(GM_getValue("超星网课挂科模式"));
  } catch (e) {}
  console.log("加载状态", r);
  return r || {};
};
var 保存状态 = (json = {}) => {
  GM_setValue("超星网课挂科模式", JSON.stringify(json));
};
var 更新状态 = (函数) => 保存状态(函数(加载状态()));
var 合并状态 = (函数) => {
  var 状态 = 加载状态();
  保存状态(深合并(状态, 函数(状态)));
};

///////////////////////////////
// 更新状态

// 课程列表
var 取课程表地址 = () => `http://mooc1-1.chaoxing.com/visit/interaction`;
var 更新课程表 = (html) =>
  合并状态((状态) => ({
    课程表: 提取为表(
      html,
      /<a .*?courseId=(\d+).*?clazzid=(\d+).*?title="(.*?)"[\s\S]*?<p title="(.*?)">/g,
      ([_, courseId, clazzid, title, 教师]) => [
        clazzid,
        { courseId, classId: clazzid, title, 教师 },
      ]
    ),
  }));

// 作业列表
var 取作业表地址 = ({
  classId,
  courseId,
  isdisplaytable,
  mooc,
  ut,
  enc,
  cpi,
  openc,
}) =>
  `https://mooc1-1.chaoxing.com/work/getAllWork?classId=${classId}&courseId=${courseId}&isdisplaytable=${isdisplaytable}&mooc=${mooc}&ut=${ut}&enc=${enc}&cpi=${cpi}&openc=${openc}`;
var 更新作业表 = (html) =>
  合并状态((状态) => ({
    课程表: 提取为表(html, /id="cid" value="(\d+)"/g, ([_, classId]) => [
      classId,
      { t检查作业表: +new Date() },
    ]),
    作业表: 提取为表(
      html,
      /<a.*?href="(.*?courseId=(\d+).*?classId=(\d+).*?workId=(\d+)(?:.*?workAnswerId=(\d+))?.*?)".*?title="(.*?)"[\s\S]*?开始时间.*>(.*?)<[\s\S]*?截止时间.*?>(.*?)<[\s\S]*?作业状态[\s\S]*?<strong>\s*(.*?)\s*?</g,
      ([
        _,
        url,
        courseId,
        classId,
        workId,
        workAnswerId,
        title,
        开始时间,
        截止时间,
        作业状态,
      ]) => [
        workId,
        {
          url,
          courseId,
          classId,
          workId,
          workAnswerId,
          title,
          开始时间,
          截止时间,
          作业状态,
        },
      ]
    ),
  }));
// 签到列表
var 取签到表地址 = ({ courseId, classId }) =>
  `https://mobilelearn.chaoxing.com/widget/pcpick/stu/index?courseId=${courseId}&jclassId=${classId}`;
var 更新签到表 = (html) => {
  var 课程表 = 提取为表(
    html,
    /id="puid" value="(.*?)"[\s\S]*?id="courseId" value="(.*?)"[\s\S]*?id="classId" value="(.*?)"[\s\S]*?id="fid" value="(.*?)"[\s\S]*?id="activeId" value="(.*?)"[\s\S]*?id="appType" value="(.*?)"/g,
    ([_, puid, courseId, classId, fid, activeId, appType]) => [
      classId,
      {
        puid,
        courseId,
        classId,
        fid,
        activeId,
        appType,
        t更新签到表: +new Date(),
      },
    ]
  );
  var { puid, courseId, classId, fid, activeId, appType } =
    Object.values(课程表)[0];
  合并状态((状态) => ({
    课程表,
    签到表: 提取为表(
      html,
      /activeDetail\((\d+),2,null\)[\s\S]*?<dd class="green">(.*?)<[\s\S]*?<a.*?>(.*?)</g,
      ([_, activeId, type, title]) => [
        activeId,
        {
          activeId,
          type,
          title,
          puid,
          courseId,
          classId,
          fid,
          activeId,
          appType,
        },
      ]
    ),
  }));
};

// 更新签到状态
// 普通签到
var 取普通签到地址 = ({ activeId, classId, fid = "", courseId }) =>
  `https://mobilelearn.chaoxing.com/widget/sign/pcStuSignController/preSign?activeId=${activeId}&classId=${classId}&fid=${fid}&courseId=${courseId}`;
// 手势签到
var 取手势签到地址 = ({ courseId, classId, activeId }) =>
  `https://mobilelearn.chaoxing.com/widget/sign/pcStuSignController/signIn?&courseId=${courseId}&classId=${classId}&activeId=${activeId}`;
var 更新签到状态 = (html) =>
  合并状态((状态) => ({
    签到表: 提取为表(
      html,
      /id="activeId".*?"(.*?)"[\s\S]*?id="activeStatus".*?"(.*?)"[\s\S]*?id="courseId".*?"(.*?)"[\s\S]*?id="classId".*?"(.*?)"[\s\S]*?id="puid".*?"(.*?)"[\s\S]*?id="createUid".*?"(.*?)"[\s\S]*?id="fid".*?"(.*?)"[\s\S]*?<span.*?>(.*?)<\/span><em id="st">(.*?)</g,
      ([
        _,
        activeId,
        activeStatus,
        courseId,
        classId,
        puid,
        createUid,
        fid,
        statusText,
        succTimeRaw,
      ]) => [
        activeId,
        {
          activeId,
          activeStatus,
          courseId,
          classId,
          puid,
          createUid,
          fid,
          statusText,
          succTimeRaw,
          t签到成功: +new Date(),
        },
      ]
    ),
  }));
// 二维码、位置、拍照签到
// https://mobilelearn.chaoxing.com/pptSign/stuSignajax
var 更新签到状态2 = (html, href) =>
  合并状态((状态) => ({
    签到表: 提取为表(
      html + "~" + href,
      /(.*?)~.*?activeId=(\d+)/g,
      ([_, status, activeId]) => [
        activeId,
        { activeId, status, t签到成功: +new Date() },
      ]
    ),
  }));

// 更新课程状态
var 取课程首页地址 = () =>
  `https://mooc1-1.chaoxing.com/mycourse/studentcourse?courseId=${courseId}&clazzid=${clazzid}&vc=${vc}&cpi=${cpi}&enc=${enc}`;
var 更新课程首页 = (html) =>
  合并状态((状态) => ({
    课程表: 提取为表(
      html,
      /id="cid" value="(\d+)"[\s\S]*?(?:(待完成任务点))?/g,
      ([_, activeId, 待完成任务点]) => [
        activeId,
        { 待完成状态: !!待完成任务点, t完成状态: +new Date() },
      ]
    ),
  }));

var 更新当前页面状态 = () => {
  if (location.pathname == "/visit/interaction")
    更新课程表(document.body.innerHTML, location.href);
  if (location.pathname == "/mycourse/studentcourse")
    更新课程首页(document.body.innerHTML, location.href);
  //
  if (location.pathname == "/work/getAllWork")
    更新作业表(document.body.innerHTML, location.href);
  //
  if (location.pathname == "/widget/pcpick/stu/index")
    更新签到表(document.body.innerHTML, location.href);
  if (location.pathname == "/widget/sign/pcStuSignController/preSign")
    更新签到状态(document.body.innerHTML, location.href);
  if (location.pathname == "/widget/sign/pcStuSignController/signIn")
    更新签到状态(document.body.innerHTML, location.href);
  if (location.pathname == "/pptSign/stuSignajax")
    更新签到状态2(document.body.innerHTML, location.href);
};

var 自动签到 = async () => {
  var 状态 = 加载状态();
  // 4分半钟检查一次签到
  var 未知签到课程列 = [...Object.values(状态.课程表 || {})].filter(
    (课程) => (课程.t检查签到表 || 课程.t更新签到表 || 0) + 270e3 <= +new Date()
  );
  合并状态(() => ({
    课程表: 键值对列转对象(
      未知签到课程列.map(({ classId }) => [
        classId,
        { t检查签到表: +new Date() },
      ])
    ),
  }));
  var 课程;
  while ((课程 = 未知签到课程列.shift())) {
    const 地址 = 取签到表地址(课程);
    console.debug("正在检查签到列表", 课程, 地址);
    更新签到表(await GETHTML(地址));
    await 睡(3e3);
  }

  // 5 秒尝试一次签到
  var 未完成签到列 = [...Object.values(状态.签到表 || {})]
    .filter((签到) => (签到.t尝试签到 || 0) + 5e3 <= +new Date())
    .filter((签到) => !(签到.succTime || 签到.succTimeRaw || 签到.t签到成功));
  合并状态(() => ({
    签到表: 键值对列转对象(
      未完成签到列.map(({ activeId }) => [activeId, { t尝试签到: +new Date() }])
    ),
  }));
  var 签到;
  while ((签到 = 未完成签到列.shift())) {
    let 地址;
    if (签到.title.match("手势")) {
      地址 = 取手势签到地址(签到);
    } else {
      地址 = 取普通签到地址(签到);
    }
    console.debug("正在签到", 签到, 地址);
    // window.open(地址 + "#自动关闭")
    更新签到状态(await GETHTML(地址));
    await 睡(3e3);
  }
};
///////////////////////////////////////////////////////////////

var main = async () => {
  更新当前页面状态();
  var 状态 = 加载状态();

  var 未完成作业 = [...Object.values(状态.作业表)].filter(
    (e) => e.作业状态 != "已完成"
  );

  if (
    location.hostname == "mobilelearn.chaoxing.com" &&
    decodeURI(location.hash) == "#巡逻自动签到"
  ) {
    console.log("[超星网课挂科模式] 启动巡逻自动签到");
    var 间隔自动签到 = 异步防抖函数(自动签到, 270e3); // 最快四分半钟检查一次签到
    setInterval(async () => {
      document.body.innerHTML = new Date(+new Date()) + "#自动签到运行中...";
      if (null !== (await 间隔自动签到())) {
        console.log(new Date(), "4分半钟后重新运行");
      }
    }, 1e3);
  }
  if (decodeURI(location.hash) == "#自动签到") {
    var iframe = document.createElement("iframe");
    iframe.src = "https://mobilelearn.chaoxing.com/";
    document.body.appendChild(a);
  }
  if (decodeURI(location.hash) == "#自动巡逻") {
    console.log("3分钟后重新运行");
    setTimeout(main, 180e3);
  }
  if (decodeURI(location.hash) == "#自动关闭") {
    window.close();
  }
};

window.addEventListener("load", main);