目录
之前用selenium方案和轮询方案实现了反应作弊器。
用selenium实现反应作弊器的文章链接如下。
一、问题描述
我们测反应速度时,测得的结果一般在300ms左右。
这是反应测试网站:https://humanbenchmark.com/tests/reactiontime
反应测试网站页面包括三种颜色,红(准确的rgb值为rgb(206, 38, 54))、绿(准确的rgb值为rgb(75, 219, 106))和蓝(准确的rgb值为rgb(43, 135, 209)),如图1-1,1-2和1-3。
图1-1
图1-2
图1-3
进入反应测试网站,当出现上述红色页面时,根据页面提示“Wait for green”等待即可。在随机等待几秒(大约三秒)之后,页面会自动变为绿色,并且有“Click”字样,当页面变为绿色时就应该点击页面,点击页面之后就会变为蓝色,并且页面上会记录你的反应时间。
这个反应时间是从页面由红色变为绿色开始,到点击页面为止这段时间,如图1-3,这次测试的反应时间为261ms。如果想继续测反应时间,再点击蓝色页面即可。
现在要通过监听、回调的方案,在浏览器控制台中输入代码来加快反应测试结果。更重要的是学习技术,学习知识。
二、准备工作
2.1 安装浏览器
此方案使用的浏览器是Google Chrome。
2.2 stub/mock页面
写一个简单的stub/mock页面,用于在调试作弊器时测试。在完成编写作弊器代码之前,要经过若干次的代码调试,而调试的结果虽然是可以预知的,但是在代码编写过程中可能会出现不可避免的逻辑错误、语法错误等。如果在代码编写完成并运行成功之前去用目标网站去调试,对目标网站可能造成破坏,可能会被目标网站视为恶意攻击。所以先用stub/mock页面对代码测试,如果通过stub/mock测试,并且stub/mock页面正如我们所期待的那样工作,说明我们编写的代码无错误,这时去用代码运行目标网站时也会如我们期待的一样工作,就不会对目标网站造成破坏。
页面代码见附录A。
页面功能:在一定时间间隔可以改变页面颜色(代码中设置的时间间隔是3秒)。
页面展示效果,如图2-1和图2-2,stub/mock页面颜色的rgb值与反应测试网站的rgb值相同。
图2-1
图2-2
红色和绿色下方的“反应时间”处,在点击绿色页面时会记录反应时间的毫秒数,如图2-3,手动点击,此次反应时间是380ms。
图2-3
三、技术路线
使用监听、回调的方案完成反应作弊器。
使用MutationObserver接口,监视指定的DOM节点。MutationObserver接口提供了监视DOM节点更改的能力,当观察到节点变化时,执行回调函数callback。
具体流程如下。
1.选择需要观察变动的节点。
2.配置观察器,也就是配置需要观察节点的什么变动。
3.设置回调函数callback,当观察到变动时执行回调函数。
4.创建观察器实例,并传入回调函数。
四、在stub/mock中测试
4.1 代码实现
用谷歌浏览器打开stub/mock页面,按F12或者鼠标右键,点击检查,在控制台中输入下面这段代码。
const bg = document.getElementById('bg');
const config = { attributes: true };
const callback = function(mutationsList, observer) {
for(let mutation of mutationsList) {
if (mutation.type === 'attributes') {
if(bg.style.backgroundColor == 'rgb(75, 219, 106)') {
bg.click()
}
}
}
};
const observer = new MutationObserver(callback);
observer.observe(bg, config);
代码解析。
1.通过getElementById获取到了需要监听的DOM节点。
2.配置需要观察DOM节点的attributes,设置为true。
3.设置回调函数callback。作用是当观察器监听到DOM节点发生变化,就会调用这个函数,判断页面颜色rgb值是否是rgb(75, 219, 106),如果是,触发页面点击事件。
4.创建观察器实例,并设置回调函数。
4.2 实验结果
如图4-1,在控制台中输入代码后,回车,运行程序。反应时间为1ms,达到了缩短反应时间的效果,达到预期。可以在反应测试网站测试。
图4-1
五、在反应测试网站实现
5.1 代码实现
用谷歌浏览器打开反应测试网站,按F12或者鼠标右键,点击检查,在控制台中输入下面这段代码。
const a = document.querySelector('#root > div > div:nth-child(4) > div:first-child')
const config = { attributes: true };
const callback = function(mutationsList, observer) {
for(let mutation of mutationsList) {
if (mutation.type === 'attributes') {
let styless = window.getComputedStyle(a)
let color = styless.getPropertyValue('background')
if(color == 'rgb(75, 219, 106) none repeat scroll 0% 0% / auto padding-box border-box') {
let e = document.createEvent('MouseEvents');
e.initMouseEvent( 'mousedown', true, true, window, 1, 12, 345, 7, 220, false, false, false, false, 0, null );
a.dispatchEvent(e);
}
}
}
};
const observer = new MutationObserver(callback);
observer.observe(a, config);
代码解析。
1.通过选择器获取到了需要监听的DOM节点。
2.配置需要观察DOM节点的attributes,设置为true。
3.设置回调函数callback。作用是当观察器监听到DOM节点发生变化,调用这个函数,判断页面颜色rgb值是否是rgb(75, 219, 106),如果是,创建mousedown事件,并触发。
4.创建观察器实例,并设置回调函数。
5.2 实验结果
在控制台中输入代码运行后,得到实验结果。如图5-1,反应时间为2ms,作弊器实现。
图5-1
致谢
反应作弊器系列结束,感谢我的导师杨贵福老师的指导,每天都为我指出问题,并给出建议。感谢田洪轩师兄和李娜师姐在我遇到问题时,对我的帮助。
附录A
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>测试页面</title>
<script type="text/javascript">
var timeStart;
var timeEnd;
window.onload = function() {
var bg = document.getElementById("bg");
setColor();
bg.addEventListener('click', function greenToBlue() {
if(bg.style.backgroundColor == "rgb(75, 219, 106)") {
bg.style.backgroundColor = "rgb(43, 135, 209)"
timeEnd = new Date().getTime();
document.getElementById('time').innerHTML = (timeEnd - timeStart) + 'ms';
}
})
window.setTimeout("changeColor()",3000);
}
function setColor() {
bg.style.backgroundColor="rgb(206, 38, 54)"
}
function changeColor() {
if(bg.style.backgroundColor == "rgb(206, 38, 54)") {
bg.style.backgroundColor="rgb(75, 219, 106)";
timeStart = new Date().getTime();
} else {
bg.style.backgroundColor="rgb(206, 38, 54)";
}
window.setTimeout("changeColor()",3000);
}
</script>
</head>
<body>
<div id="bg" style="width: 400px; height: 400px;">
</div>
<div id="time">反应时间</div>
</body>
</html>