// ==UserScript== // @name PKU 手动抢课小助手 // @namespace http://tampermonkey.net/ // @version 1.0.0 // @description 过滤选课列表,只显示目标课程,实时高亮课程名额状态,支持一键识别验证码 // @author goudanZ1 // @license MIT // @match https://elective.pku.edu.cn/elective2008/edu/pku/stu/elective/controller/supplement/supplement.jsp* // @match https://elective.pku.edu.cn/elective2008/edu/pku/stu/elective/controller/supplement/SupplyCancel.do* // @match https://elective.pku.edu.cn/elective2008/edu/pku/stu/elective/controller/supplement/electSupplement.do* // @match https://elective.pku.edu.cn/elective2008/edu/pku/stu/elective/controller/supplement/cancelCourse.do* // @icon https://www.pku.edu.cn/pku_logo_red.png // @grant GM_xmlhttpRequest // @connect api.ttshitu.com // @run-at document-end // @downloadURL https://update.greasyfork.icu/scripts/527300/PKU%20%E6%89%8B%E5%8A%A8%E6%8A%A2%E8%AF%BE%E5%B0%8F%E5%8A%A9%E6%89%8B.user.js // @updateURL https://update.greasyfork.icu/scripts/527300/PKU%20%E6%89%8B%E5%8A%A8%E6%8A%A2%E8%AF%BE%E5%B0%8F%E5%8A%A9%E6%89%8B.meta.js // ==/UserScript== (function () { 'use strict'; // ******************** 以下 4 项内容需要填写 ******************** // 1. 填写想抢的课程名与班号,在每页中只会显示 allowedCourses 中的课程,但如果这些课程 // 分布在不同的页上,仍然需要手动换页来查看。同一个课程名对应的班号(无论一个还是多个) // 需要写在数组(方括号)中。 const allowedCourses = { '摸鱼学导论': [6], '划水学原理': [1, 3], '投点理论与实践': [2], }; // 2. 是否禁止表格的行在光标位于其上时变成黄绿色(true/false) const banColorChange = true; // 3. 课程有名额、无名额时在“限数/已选”栏显示的背景颜色和文本颜色,默认依次为浅绿、深绿、浅红、深红 const underLimitStyle = 'background-color: #abebc6; color: #145a32'; const reachLimitStyle = 'background-color: #f5b7b1; color: #7b241c'; // 4. 填写 TT 识图账号的用户名和密码(http://www.ttshitu.com/,请确保账户有余额) const recognizerConfig = { username: 'PKUer', password: 'wasd1234', }; // ******************** 以上 4 项内容需要填写 ******************** const table = document.querySelector('table.datagrid'); const rows = table.querySelectorAll('tr.datagrid-even,tr.datagrid-odd'); const visibleRows = []; // Hide unnecessary courses rows.forEach(row => { const courseName = row.children[0].textContent.trim(); const classNumber = parseInt(row.children[5].textContent.trim()); if (courseName in allowedCourses && allowedCourses[courseName].includes(classNumber)) { visibleRows.push(row); } else { row.style.display = 'none'; } }); // Reset the color style for visible rows and optionally cancel color changes visibleRows.forEach((row, index) => { const newClass = index % 2 === 0 ? 'datagrid-even' : 'datagrid-odd'; row.className = newClass; if (banColorChange) { row.onmouseover = null; row.onmouseout = null; } else { row.onmouseover = () => { row.className = 'datagrid-all'; }; row.onmouseout = () => { row.className = newClass; }; } }); // Set the color style for 'limit/elected' grids and change a grid from red to // green when its corresponding '刷新' becomes '补选' visibleRows.forEach(row => { const numCell = row.children[9]; //