// ==UserScript== // @name mhyX // @namespace http://tampermonkey.net/ // @version 0.1 // @description 主要提供要滑动的距离, 过元素校验 // @author tfsn20 // @match https://user.mihoyo.com/* // @icon https://user.mihoyo.com/favicon.ico // @require file://D:\OneDrive\Codes\TM\mhy_change_password.js // @require file:///storage/emulated/0/1/Codes/mhy_change_password.js // @grant GM_log // ==/UserScript== (async function () { GM_log('注入'); //常量, 账号, 密码, 身份证 const account = ''; const pwd = ''; const id = ''; //等待函数,单位毫秒 function sleep(time) { return new Promise((resolve) => setTimeout(resolve, time)); }; //定义事件 let focus = new Event('focus'); let input = new Event('input'); let change = new Event('change'); let blur = new Event('blur'); //元素存在规则校验, 按照focus, value, input, change, blur触发 async function check(element, value) { await sleep(200) element.dispatchEvent(focus); await sleep(200); element.value = value; await sleep(200); element.dispatchEvent(input); await sleep(200); element.dispatchEvent(change); await sleep(200); element.dispatchEvent(blur); await sleep(200) } //匹配登录 listen(); await sleep(2000); login(); //登录出现滑块把下面这个事件改长点 // await sleep(1000*2); // await changePassword() async function changePassword() { await sleep(2000); document.querySelectorAll('li')[3].click(); await sleep(500); document.querySelector('div[class="mhy-button is-block"]').children[0].click(); await sleep(500); let idInput = document.querySelector('input[id="account-input-id1"]'); await check(idInput, id); listen(); document.querySelector('div[class="send-catpcha"]').click(); //let catpcha = document.querySelector('input[id="account-input-id0"]'); //await check(catpcha,123456); //document.querySelector('div[class="verificationv2__button"]').click; } //监听canvas function listen() { document.addEventListener('DOMNodeInserted', listenCanvas, false) async function listenCanvas() { if (document.querySelector('canvas')) { document.removeEventListener('DOMNodeInserted', listenCanvas, false); await sleep(2000); let x = passCanvas(); let geetestText = document.querySelector('div[class="geetest_slider_tip geetest_fade"]'); geetestText.innerText = x; GM_log({ x: x }) //await slide(x) } } } //登录 async function login() { let text = document.querySelector('input[type="text"]'); let password = document.querySelector('input[type="password"]'); await check(text, account); await check(password, pwd); document.querySelector('button[type="submit"]').click() } //过canvas, 返回即要滑动的距离x function passCanvas() { //获取3个画布 let canvasBg = document.querySelector('canvas[class="geetest_canvas_bg geetest_absolute"]'); let canvasFull = document.querySelector('canvas[class="geetest_canvas_fullbg geetest_fade geetest_absolute"]'); let canvasSlice = document.querySelector('canvas[class="geetest_canvas_slice geetest_absolute"]'); //2d对象化, 获取每个像素点的r,g,b,和透明度, 260和160是canvas元素的宽和高 let originDataBg = canvasBg.getContext("2d").getImageData(0, 0, 260, 160).data; let originDataFull = canvasFull.getContext("2d").getImageData(0, 0, 260, 160).data; let originDataSlice = canvasSlice.getContext("2d").getImageData(0, 0, 260, 160).data; // GM_log(originDataBg); // GM_log(originDataFull); //灰度化, 每四个值计算一个灰度, ^0是取整数部分(位运算) let grayDataBg = [], grayDataFull = [], grayDataSlice = []; for (let i = 0; i < originDataBg.length; i += 4) { grayDataBg.push(((originDataBg[i] + originDataBg[i + 1] + originDataBg[i + 2]) / 3) ^ 0); }; for (let i = 0; i < originDataFull.length; i += 4) { grayDataFull.push(((originDataFull[i] + originDataFull[i + 1] + originDataFull[i + 2]) / 3) ^ 0); }; for (let i = 0; i < originDataSlice.length; i += 4) { grayDataSlice.push(((originDataSlice[i] + originDataSlice[i + 1] + originDataSlice[i + 2]) / 3) ^ 0); }; // GM_log(grayDataBg); // GM_log(grayDataFull); //GM_log(grayDataSlice) //灰度值列化, 方便一列一列比较 let columnBg = [], columnFull = [], columnSlice = []; for (let i = 0; i < 260; i++) { let columnDataBg = [], columnDataFull = [], columnDataSlice = []; for (let j = 0; j < 160; j++) { columnDataBg.push(grayDataBg[i + 260 * j]); columnDataFull.push(grayDataFull[i + 260 * j]); columnDataSlice.push(grayDataSlice[i + 260 * j]); } columnBg.push(columnDataBg); columnFull.push(columnDataFull); columnSlice.push(columnDataSlice); } // GM_log(columnBg); // GM_log(columnFull); //GM_log(columnSlice) //获取要滑动的距离x, credence不能超过滑块y方向的像素(hmy滑块像素为40*40), dif是两个数据的比较差值, function getX(credence = 20, dif = 5) { let iSlice = null; for (let i = 0; i < 260; i++) { let cre = null, creSlice = null; for (let j = 0; j < 160; j++) { let dValue = Math.abs(columnBg[i][j] - columnFull[i][j]); if (dValue > dif) { cre++ }; if (!iSlice && columnSlice[i][j] != 0) { creSlice++ } }; if (cre > credence) { GM_log({ x: i - iSlice }) return i - iSlice }; if (creSlice > credence) { iSlice = i GM_log({ iSlice: iSlice }) } } } return getX() } //滑动, 无效 async function slide(x) { let mouseDown = new Event('mousedown'); let mouseMove = new Event('mousemove'); let mouseUp = new Event('mouseup') let slider = document.querySelector('div[class="geetest_slider_button"]'); let div = document.querySelector('div[class="geetest_slider geetest_ready"]'); slider.dispatchEvent(mouseDown); div.className = 'geetest_slider geetest_move' await sleep(500); slider.style.transform = `translateX(${x}px)`; await sleep(2000); slider.dispatchEvent(mouseMove); await sleep(500); slider.dispatchEvent(mouseUp); div.className = 'geetest_slider geetest_lock' await sleep(500); } })();