// ==UserScript== // @name 清华社视听说 - 自动答题 // @namespace http://tampermonkey.net/ // @version 0.1 // @description 解放你的双手 // @author Hyun // @include *://www.tsinghuaelt.com/course-study-student/* // https://raw.githubusercontent.com/hyunsssssssss/ShiTingShuo/master/wk.js // @require https://cdn.staticfile.org/jquery/3.5.1/jquery.min.js // @grant GM_addStyle // @grant GM.setValue // @grant GM.getValue // @grant GM.deleteValue // @run-at document-idle // @downloadURL none // ==/UserScript== (function() { 'use strict'; let vocabulary = ['fantastic', 'error', 'whatsoever', 'arouse', 'magnificent', 'remarkable', 'schoolwork', 'ease', 'devil', 'factor', 'outstanding', 'infinite', 'infinitely', 'accomplish', 'accomplished', 'mission', 'investigate', 'mysterious', 'analysis', 'peak', 'excellence', 'credit', 'responsibility', 'amount', 'entertain', 'alternative', 'irregular', 'grant', 'cease', 'concentration', 'adapt', 'weird', 'profit', 'alter', 'performance', 'echo', 'hallway', 'await', 'abortion', 'database', 'available', 'indecision', 'ban', 'predict', 'breakthrough', 'fate', 'host', 'pose', 'instance', 'expert', 'surgery', 'naval', 'aircraft', 'target', 'spoonful', 'navigation', 'numerous', 'fluent', 'mechanic', 'advertise', 'advertising', 'waken', 'enormous', 'enormously', 'oversleep', 'survey', 'best-selling', 'filmmaker', 'prosperous', 'involve'] let phrases = ['Yes, he is', 'No, he isn\'t', 'Yes', 'No'] let getRanWord = ()=> { return vocabulary[parseInt(Math.random()*vocabulary.length)] } let getRanPhrase = ()=> { return phrases[parseInt(Math.random()*phrases.length)] } let sleep = (ms)=> { return new Promise(resolve => setTimeout(resolve, ms)); } let click_btn = ()=> { $('.wy-course-bottom .wy-course-btn-right .wy-btn').click(); } let config = { 'autodo': ['auto_tiankong', 'auto_luyin', 'auto_lytk', 'auto_roleplay', 'auto_danxuan'], 'autotryerr': true, 'autostop': false, 'delay': 10000 }; function input_in(e, txt) { if (e.type == 'textarea') { e.value= txt; } else { e.innerText= txt; } let changeEvent = null; changeEvent = document.createEvent ("HTMLEvents"); changeEvent.initEvent ("input", true, true); e.dispatchEvent (changeEvent); changeEvent = document.createEvent ("HTMLEvents"); changeEvent.initEvent ("keyup", true, true); e.dispatchEvent (changeEvent); changeEvent = document.createEvent ("HTMLEvents"); changeEvent.initEvent ("change", true, true); e.dispatchEvent (changeEvent); } async function doTopic() { let setTixing = async (t)=> { console.log('[+] 题型:', t); $('#yun_status').text('当前题型:'+t); await sleep(config.delay) // 挂机10s,增加时长 }; if($('.wy-course-bottom .wy-course-btn-right .wy-btn').text().indexOf('Submit')==-1) { $('.page-next')[1].click(); await sleep(1500) } if($('img[title="录音"]').length!=0 && config.autodo.includes('auto_luyin')) { await setTixing('录音'); await doReadRepeat(); } else if($('.lib-textarea-container').length!=0 && config.autodo.includes('auto_lytk')) { await setTixing('听力填空'); await doListenAnswer(); } else if($('.lib-fill-blank-do-input-left').length!=0 && config.autodo.includes('auto_tiankong')) { await setTixing('填空'); await doTianKone(); } else if($('.lib-single-item-img').length!=0 && config.autodo.includes('auto_danxuan')) { await setTixing('单选'); await doSingleChoose(); } else if($('.lib-role-select-item').length!=0 && config.autodo.includes('auto_roleplay')) { await setTixing('角色扮演'); await doRolePlay(); } else { await unSupposedOrSkip(); return false; } return true; } // =========================================== // 填空题 async function doTianKone() { // 先填写随机单词,获得答案 let inputs = $('.lib-fill-blank-do-input-left'); $.each(inputs, function(i,item){ input_in(item, getRanWord()); }); await sleep(500); click_btn(); // Submit await sleep(2000); let answer = [], anyAnswer = false; $('.lib-edit-score span[data-type="1"]').each((i,item)=>{ if(item.innerText.toLowerCase().indexOf('may vary')!=-1) { // 任意填空 anyAnswer = true; return false; } answer.push(item.innerText) }); if(anyAnswer) { return; } click_btn(); // Retry await sleep(2000); // 提交正确答案 inputs = $('.lib-fill-blank-do-input-left'); $(inputs).each((i,item)=>{ input_in(item, answer[i]); }); await sleep(500); click_btn(); // Submit } // 录音题 async function doReadRepeat() { let sum_record = 0; if($('.lib-oral-container-top').length!=0) { var rec_div = $('.lib-oral-container-top') } else { var rec_div = $('.lib-listen-item-right-img') } rec_div.each((i,div)=>{ if($(div).find('img[title="播放"]').length!=0){ return true; }; let click_record = (e) => { console.log('click:', e); $(e).find('img[title="录音"],img[title="停止"]').click(); } setTimeout(()=>{click_record(div);}, sum_record*5000); setTimeout(()=>{click_record(div);}, 3000 + sum_record*5000); sum_record ++; }); await sleep(2000 + sum_record*5000) click_btn(); // Submit await sleep(3000) } // 单选题 async function doSingleChoose() { let answer_map = {'A':0, 'B':1, 'C':2, 'D':3, 'E':4, 'F':5} // 随机选择以获得正确答案 $('.lib-single-item-img img').click() await sleep(500); click_btn(); // Submit await sleep(2000); let answer = [] $('.lib-single-cs-answer').each((i,item)=>{ answer.push(item.innerText) }); click_btn(); // Retry await sleep(2000); $('.lib-single-box').each((i,item)=>{ $($(item).find('.lib-single-item')[answer_map[answer[i]]]).find('img').click() }); await sleep(500); click_btn(); // Submit } // 角色扮演 async function doRolePlay() { $('.lib-role-select-item img')[0].click() $('.lib-role-select-start button').click() await sleep(30000); click_btn(); // Submit } // 听力填空 async function doListenAnswer() { let inputs = $('.lib-textarea-container'); $.each(inputs, function(i,item){ input_in(item, getRanPhrase()); }); await sleep(500); click_btn(); // Submit } // 不支持体型 async function unSupposedOrSkip(params) { console.log('[!]', '遇到不支持体型或未选择,自动跳过。。。'); } // =========================================== let running = false; async function initConf() { config = await GM.getValue('config', config); $.each(config.autodo, (index, id)=>{ $('#'+id).prop("checked",true); }); $('#set_tryerr').prop("checked", config.autotryerr); $('#set_manu').prop("checked", config.autostop); $('#set_delay').val(config.delay); } async function doLoop() { while (running) { let status = await doTopic(); if(!status && config.autostop) { $('#yun_status').text('不支持当前体型, 已停止'); break; } console.log('[*]', '已完成,切换下一题。。。'); await sleep(1500); $('.page-next')[1].click() await sleep(5000); } $('.yunPanel button').prop('disabled', false); $('#yun_status').text('IDLE'); } $(``).appendTo("head"); $(document.body).after(`
x

社听说 - 自动答题


自动完成题型:

设置


IDLE

`); $('#yun_start').click(()=>{ if($('#yun_start').text()=='开始') { $('#yun_doone').prop('disabled', true); running = true; doLoop(); $('#yun_start').text('停止') } else { $('.yunPanel button').prop('disabled', true); running = false; $('#yun_start').text('开始') } }); $('#yun_doone').click(()=>{ $('#yun_start').text('开始'); running = false; $('.yunPanel button').prop('disabled', true); doTopic().then(()=>{ $('.yunPanel button').prop('disabled', false); $('#yun_status').text('Done!'); }); }); $('.yunPanel .close').click(()=>{$('.yunPanel').hide()}); $('#yun_reset').click(()=>{ GM.deleteValue('config'); window.location.reload(); }); $('#yun_save').click(()=>{ let ids = config.autodo.slice() config.autodo = [] $.each(ids, (index, id)=>{ if($('#'+id).prop("checked")) { config.autodo.push(id); } }); config.autotryerr = $('#set_tryerr').prop("checked"); config.autostop = $('#set_manu').prop("checked"); config.delay = $('#set_delay').val(); GM.setValue('config', config); $('#yun_status').text('保存成功'); }); initConf(); // Your code here... })();