单机游戏的一个重大缺陷就在于其无法检测玩家是否更改了系统时间来作弊,如果不依靠联网查询时间的话。很多单机游戏很难检测系统时间的改动。本文将介绍一种如何在完全无网环境下检测时间作弊的方法。
在纯单机模式下,不可能依靠外部获取时间变量,所以只能从本机寻找一个在系统时间发生变动的情况下,依然不受其影响的量。
系统的启动时间,或许可以当成这个不变量。我们可以通过 sysctl
方法来获取设备上一次的开机时间,然而开机时间也会随着玩家更改系统时间而进行更改。但是,由于它们更改的量是一样的,所以系统的启动时间是一个恒定自增的,不受玩家更改系统时间而变动的量。系统的启动时间可以通过当前时间减去设备上一次的开机时间来获得。
time_tgetSystemUptimeInSecond() { struct timevalboottime; int mib[2] = {CTL_KERN, KERN_BOOTTIME}; size_tsize = sizeof(boottime); time_tnow; time_tuptime = -1; (void)time(&now); if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 && boottime.tv_sec != 0) { uptime = now - boottime.tv_sec; } return uptime; }
以上是获取系统启动时间的函数代码,其中的时间类型 time_t
为 long
类型。
既然我们获取了一个不随着玩家更改系统时间而变动的量,那么我们就可以利用它来检测玩家是否在 不关机 的情况下更改了系统时间。
我们可以在游戏退到后台的时候,记录一个时间差到缓存文件中,这个时间差为:当前系统时间戳 – 系统的启动时间。在游戏重新回到前台时,重新计算这个时间差,然后计算这两个时间差的差值,如果差值超过了一定的阈值(比如说60秒),即可认为玩家更改了系统时间。
当然这种方法有一个较大的限制,即由于系统的开机时间也随着玩家更改系统时间而更改,所以我们没有办法检测玩家是否在此阶段设备重启过。不过对于绝大多数情况而言,这也不失为一种在纯单机情况下检测玩家是否更改系统时间的好办法。