// ==UserScript== // @name 学习助手 // @namespace https://zac.social/ // @version 0.3.0 // @description 学习通测试成绩查看,批改网解除复制粘贴限制。 // @author zac517 // @match mooc1.chaoxing.com/* // @match www.pigai.org/* // @icon https://one.hfut.edu.cn/favicon.ico // @run-at document-start // @grant unsafeWindow // @downloadURL none // ==/UserScript== (function () { 'use strict'; let site = null; const siteConfigs = { 'mooc1.chaoxing.com': { config: { onPageLoaded: () => { const requiredParams = ['courseid', 'clazzid', 'cpi']; function generateNewUrl() { const urlParams = new URLSearchParams(unsafeWindow.location.search); const params = requiredParams.reduce((acc, param) => { const value = urlParams.get(param); if (value) acc[param] = value; return acc; }, {}); if (requiredParams.every(param => params[param])) { const newParams = new URLSearchParams(); for (const key in params) { if (params.hasOwnProperty(key)) { newParams.append(key, params[key]); } } newParams.append('ut', 's'); return `https://stat2-ans.chaoxing.com/exam-stastics/index?${newParams.toString()}`; } return null; } function createJumpButton() { const newUrl = generateNewUrl(); if (!newUrl) return; const button = document.createElement('a'); button.href = '#'; button.target = '_blank'; button.className = 'jb_btn jb_btn_104 createTopic fl fs14 marginRight30 '; button.style.cssText = ` z-index: 999; width: 104px; height: 36px; background: url(https://groupweb.chaoxing.com/res/course/images/discuss/jb_btn_104.png) no-repeat 0 0; position: relative; top: -29px; float: right; `; button.textContent = '查看成绩'; button.addEventListener('click', (e) => { e.preventDefault(); unsafeWindow.open(newUrl, '_blank'); }); const topBackElement = document.querySelector('.top-back'); if (topBackElement) { topBackElement.appendChild(button); } } createJumpButton(); } } }, 'www.pigai.org': { 'c=v2&a=write': { config: { onScriptLoaded: { 'script[src="https://cdn.pigai.org//res/javascript/spss.js?d=2022111501"]': { callback: () => { unsafeWindow.init_no_paste = () => { return false }; }, times: 1, } }, onPageLoaded: () => { const node = document.querySelector('#request_y'); node.unselectable = 'off'; node.onselectstart = ''; const childNode = document.querySelector('.no_paste > div'); if (childNode) childNode.style = ''; } } }, 'c=v2&a=view': { config: { data: { score: 0, }, onScriptLoaded: { 'script[src="https://cdn.pigai.org//res/javascript/view.js?d=2024112903"]': { callback: () => { unsafeWindow.init_no_paste_by_snt = () => { return false }; }, times: 1, }, }, onElementAdded: { 'b#rescoreTxt': { callback: (node) => site.data.score = node.innerText, times: 1, }, }, onPageLoaded: () => { function genPromptFromPage() { const commentElement = document.getElementById('allpingyu_txt'); const articleComment = commentElement ? commentElement.textContent.trim() : ''; const elements = document.querySelectorAll('.view3Item:not(.view3duan)'); let totalString = ''; elements.forEach(element => { const view3xh = element.querySelector('.view3xh'); const sentenceNumber = view3xh ? view3xh.textContent.trim() : ''; const view3Sent = element.querySelector('.view3Sent'); const sentTxt = view3Sent ? view3Sent.querySelector('.sentTxt') : null; const sentenceContent = sentTxt ? sentTxt.textContent.trim() : ''; const view3Error = element.querySelector('.view3Error'); const errorList = view3Error ? view3Error.querySelector('ul') : null; const errorItems = errorList ? errorList.querySelectorAll('li') : []; let relevantComments = []; errorItems.forEach(item => { if (item.classList.contains('error') || item.classList.contains('warn')) { let commentText = ''; const childNodes = item.childNodes; childNodes.forEach(node => { if (node.nodeType === Node.TEXT_NODE) { commentText += node.textContent; } else if (node.nodeType === Node.ELEMENT_NODE && !node.classList.contains('stips') && !node.classList.contains('snt_info')) { commentText += node.textContent; } }); relevantComments.push(commentText.trim().replace(/[\u0009\u000A]/g, '')); } }); if (relevantComments.length > 0) { const combinedComments = relevantComments.join('\n'); totalString += `${sentenceNumber} ${sentenceContent}\n 点评:\n${combinedComments}\n\n`; } }); let finalString = `当前作文分数为 ${site.data.score}。\n作文评语为:${articleComment}。\n可改进的句子如下:\n${totalString}` + `注意: 1. 网站给出的点评虽然说是让你检查,但实际上你不修改他就会一直扣分,所以无论你觉得对不对,一定要想办法修改。 2. 点评中,所有提到存在拼写有误的地方,如果点评中给出了具体的修改方案就按给出的方案改,没有就自己改。 3. 作文的评分系统是通过识别每个词实现的,所以被他指出有问题的词,就算你觉得没问题,为了得到更高的分也必须修改,否则会一直被指出。 4. 如果你觉得难以改正,就尝试换成其他意思相近的表达(不能还含有原被指出的拼写)。 5. 作文中应只使用英文,绝对不能出现中文,即使是在引用中文词语或俗语。 6. 回答时,英语作文使用英语回答,要给出修改后的完整文章,不省略不修改的部分。 7. 回答时,提供的其他信息(比如向我解释修改了哪些内容)必须使用中文给出。 请跟据以上相关信息和要求进行修改,提高作文的分数。`; return finalString; } console.log(genPromptFromPage()); } } } } }; const currentHostname = unsafeWindow.location.hostname; const currentPathAndQuery = unsafeWindow.location.pathname + unsafeWindow.location.search; function getEffectiveConfigRecursive(currentNode, pathQuery) { let candidateConfigsFromChildren = []; for (const key in currentNode) { if (key === 'config') continue; if (pathQuery.includes(key)) { const deeperConfig = getEffectiveConfigRecursive(currentNode[key], pathQuery); if (deeperConfig) { candidateConfigsFromChildren.push({ config: deeperConfig, specificity: key.length }); } } } if (candidateConfigsFromChildren.length > 0) { candidateConfigsFromChildren.sort((a, b) => b.specificity - a.specificity); return candidateConfigsFromChildren[0].config; } else { return currentNode.config || null; } } if (siteConfigs[currentHostname]) { const domainNode = siteConfigs[currentHostname]; site = getEffectiveConfigRecursive(domainNode, currentPathAndQuery); } if ((site?.onElementAdded && Object.keys(site.onElementAdded).length > 0) || (site?.onScriptLoaded && Object.keys(site.onScriptLoaded).length > 0)) { const callback = function (mutationsList) { const needsObserver = false; for (const mutation of mutationsList) { if (mutation.type === 'childList') { for (const addedNode of mutation.addedNodes) { if (site?.onElementAdded) { Object.keys(site.onElementAdded).forEach((element) => { if (site.onElementAdded[element].times != 0 && addedNode === document.querySelector(element)) { site.onElementAdded[element].callback(addedNode); site.onElementAdded[element].times -= 1; if (site.onElementAdded[element].times != 0) needsObserver = true; } }) } if (site?.onScriptLoaded) { Object.keys(site.onScriptLoaded).forEach((element) => { if (site.onScriptLoaded[element].times != 0 && addedNode === document.querySelector(element)) { addedNode.onload = site.onScriptLoaded[element].callback; site.onScriptLoaded[element].times -= 1; if (site.onScriptLoaded[element].times != 0) needsObserver = true; } }) } } } } }; const observer = new MutationObserver(callback); observer.observe(document, { attributes: true, childList: true, subtree: true }); } if (site?.onPageLoaded) { unsafeWindow.addEventListener('load', () => site.onPageLoaded()); }; function createMenu() { const css = ` #study-tool-menu { display: inline-block !important; margin: 0 !important; position: fixed !important; left: 40px; top: calc(50vh - 150px); width: 200px; height: 300px; border-radius: 10px !important; background-color: white !important; border: 1px solid rgba(0, 0, 0, 0.1) !important; box-shadow: 0 0 40px 0 rgba(0, 0, 0, 0.05) !important; padding: 10px !important; z-index: 9999 !important; cursor: grab; overflow: hidden !important; box-sizing: border-box !important; } #study-tool-menu.collapsed-left, #study-tool-menu.collapsed-right { height: 60px !important; } #study-tool-menu.collapsed-left { left: -190px; } #study-tool-menu.collapsed-right { left: calc(100% - 10px); } #study-tool-menu.collapsed-left:hover { left: -140px; } #study-tool-menu.collapsed-right:hover { left: calc(100% - 60px); } `; const style = document.createElement('style'); style.textContent = css; document.head.appendChild(style); const div = document.createElement('div'); div.id = 'study-tool-menu'; div.innerHTML = `