一种纯单机模式下检测时间作弊的方法

单机游戏的一个重大缺陷就在于其无法检测玩家是否更改了系统时间来作弊,如果不依靠联网查询时间的话。很多单机游戏很难检测系统时间的改动。本文将介绍一种如何在完全无网环境下检测时间作弊的方法。

在纯单机模式下,不可能依靠外部获取时间变量,所以只能从本机寻找一个在系统时间发生变动的情况下,依然不受其影响的量。

系统的启动时间,或许可以当成这个不变量。我们可以通过sysctl方法来获取设备上一次的开机时间,然而开机时间也会随着玩家更改系统时间而进行更改。但是,由于它们更改的量是一样的,所以系统的启动时间是一个恒定自增的,不受玩家更改系统时间而变动的量。系统的启动时间可以通过当前时间减去设备上一次的开机时间来获得。

time_t getSystemUptimeInSecond()
{
    struct timeval boottime;
    int mib[2] = {CTL_KERN, KERN_BOOTTIME};
    size_t size = sizeof(boottime);
    time_t now;
    time_t uptime = -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_tlong类型。

既然我们获取了一个不随着玩家更改系统时间而变动的量,那么我们就可以利用它来检测玩家是否在不关机的情况下更改了系统时间。

我们可以在游戏退到后台的时候,记录一个时间差到缓存文件中,这个时间差为:当前系统时间戳 – 系统的启动时间。在游戏重新回到前台时,重新计算这个时间差,然后计算这两个时间差的差值,如果差值超过了一定的阈值(比如说60秒),即可认为玩家更改了系统时间。

当然这种方法有一个较大的限制,即由于系统的开机时间也随着玩家更改系统时间而更改,所以我们没有办法检测玩家是否在此阶段设备重启过。不过对于绝大多数情况而言,这也不失为一种在纯单机情况下检测玩家是否更改系统时间的好办法。

关注微信公众号:timind

2 responses

  1. 大概是去年年底的时候,玩战锤40K,发现他们的时间系统很有意思,专门想了一下,推测也是记录了开机时间, 和你说的这个应该是一个原理。

    • 这种方法只适用于完全单机,且对时间作弊异常敏感的游戏,因为设备重启之后,时间差将变得不可信
      一般来说,可以先在游戏启动时获取一个网络时间戳,与本机时间作对比来检测作弊。除非网络时间没有返回,才能使用此方法

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注