关于反作弊
Opened this issue · 19 comments
这游戏挺有意思的,群里大伙玩了一晚上,不过有俩地方有待完善:
0x01 加密问题
虽然脚本被加密混淆了,但是可以很轻松通过
encrypt2 = encrypt;
encrypt = function(text){
console.log(text);
// 这里想干什么都行,比如把原本的分数替换为 233
return encrypt2("233" + text.substr(3,));
}
实现打印加密前的明文内容,进行修改也可以。
0x02 变量问题
脚本内的变量全都是全局变量,可以直接被外部修改,例如
setInterval(function() {
_date1 = new Date();
_gameTimeNum = 20;
}, 100);
就可以实现暂停时间,加密混淆形同虚设。
实验:排行榜第一名那个嘉然 ID 就是我(狗头
0x03 修复方法
- 使用局部变量
避免直接公开加密方法貌似没啥用
建议直接用 Swoole 一类的玩意起个 WebSocket 服务器,然后点击事件发送给服务器验证,通过判断点击时间间隔验证操作是否合法,以及是否有出现故意拖慢时间的操作,实现真 · 服务端反作弊(狗头
回家过年去了,也没个电脑,建议您来改(((
顺带一提,验证我也想过但是服务器实在吃不消,也不现实,就搁置了
有空我改改吧,WebSocket 验证其实不怎么消耗性能的,何况是这种单纯就是计算时间差和数字加减的东西,一台学生机大概就够了(
实时在线最高可达2k人,且人均一秒5到10次点击,这个数据量全验证想想还是蛮可怕的..
实际上 WS 依然无法解决作弊问题,可以很轻松通过伪造 WS 连接发送假数据实现绕过
所以……基于浏览器是基本上不可能实现安全的反作弊的……
只能尽可能地阻止一般人作弊,稍微懂一点 Js 的其实都有办法绕过……
对了,就算改了加密方式,仍然不建议直接把rsa密钥作为明文出现。
这用的免费js加密,随便跑个解码public key就出来了
在上传数据的地方做点文章吧,不过开源太好破解了(
然后大概是可以没10分上传一次包,然后最后分数只要在预估出来的范围之内就好了。
然后之后再做cps检查之类的,娱乐小游戏真要讲太多反作弊也没意思
预估范围的最终结果就是开挂的人顶着预估的上限一直刷排行榜,就跟地平线 4 的各大测速排行榜一直被刷到 348.99MPH 一样
摆了,我也没什么办法,等大佬们来pr吧
预估范围的最终结果就是开挂的人顶着预估的上限一直刷排行榜,就跟地平线 4 的各大测速排行榜一直被刷到 348.99MPH 一样
然而由此可见就算是单机游戏大厂都无法防止作弊,更别说网页游戏了,所以最多就只能把外挂的成绩尽量往下压
我的建议是:提交成绩的时候需要附上操作视频记录,可以是b站视频链接等等
然后点击事件发送给服务器验证,通过判断点击时间间隔验证操作是否合法
FYI: 点击事件完全是可以手动构造的。所以即使服务器端加了验证,也可以跑出极限分数:
let items = [];
function run() {
if (items.length === 0) {
items = [...document.querySelectorAll('.t1, .t2, .t3, .t4, .t5')];
}
const target = items.shift();
const rect = target.getBoundingClientRect();
const evt = new MouseEvent('mousedown', {
bubbles: true,
clientX: rect.left + rect.width / 2,
clientY: rect.top + rect.height / 2,
});
target.dispatchEvent(evt);
timer = setTimeout(run, 0);
}
// start
run();
// stop
clearTimeout(timer);
屏幕录像(鼠标指针也是画上去的):
recording.mp4
然后点击事件发送给服务器验证,通过判断点击时间间隔验证操作是否合法
FYI: 点击事件完全是可以手动构造的。所以即使服务器端加了验证,也可以跑出极限分数:
let items = []; function run() { if (items.length === 0) { items = [...document.querySelectorAll('.t1, .t2, .t3, .t4, .t5')]; } const target = items.shift(); const rect = target.getBoundingClientRect(); const evt = new MouseEvent('mousedown', { bubbles: true, clientX: rect.left + rect.width / 2, clientY: rect.top + rect.height / 2, }); target.dispatchEvent(evt); timer = setTimeout(run, 0); } // start run(); // stop clearTimeout(timer);屏幕录像(鼠标指针也是画上去的):
recording.mp4
但实际上改用canvas就可以彻底解决这个问题
已经在写新版本了,使用服务端生成连续图片,点击事件全部交由服务端验证,可以实现真正的反作弊(除了图片识别防不住以外,一般的修改数据作弊都能防)
拿python cv2 库简单撸了的“截图,图片识别,定位点击”的脚本最高跑到68分(
拿python cv2 库简单撸了的“截图,图片识别,定位点击”的脚本最高跑到68分(
兄啊,你这效率还不如重写Math.random
然后开连点器呢(恼
拿python cv2 库简单撸了的“截图,图片识别,定位点击”的脚本最高跑到68分(
直接取屏幕指定坐标下的 RGB 颜色,判断下是否有颜色(即不是纯白 255,255,255),有的话就模拟鼠标点击,这样都能轻松跑到 160~170 分,图片识别小题大做了属于是。。
emm看不懂你们在说啥,不过python用selenium刷分还是很方便的,榜单前三都是我 ( 狗头