关键字:游戏 服务器 客户端 防外挂加速
游戏当中有些动作要求必须间隔一定时间才能执行,比如跑步等动作。如果仅在客户端限制的话往往都被加速器(外挂)所破坏。本文假定客户端必须间隔400毫秒的数据包传输,提出服务器端解决加速问题的一种方法。
一、客户端发送若干数据包
t1=tc;
Send(…);
t2=tc;
Send(…);
…
t6=tc;
Send(…);
t1-6:每个数据包必须包含的发送时客户端当前时间值
Tc:客户端当前时间
二、服务器端接收若干数据包
Void OnConnect(void) { IsFirstData = True; } Void OnReceive(…) { ...... T=DataPack.ClientTime; //T当前数据包内的时间值 if(IsFirstData) //第一次接收? { IsFirstData = False; Tsf=Ts; //记录当前服务器时间 Tcf=T; //记录数据包内的客户端的时间值,T=t1 Tlst=T; //保存当次数据包中的时间值 }else { if(T - Tlst < 400) //时间间隔验证 OnError(); if((T-Tcf) - (Ts-Tsf ) > Tnd+ Tx) //时长验证 OnError(); if (Ts-Tsf) > MaxLong //每十分钟初始一次Tsf、Tcf,防止两端时间误差累加放大 { Tsf = ts; Tcf=T; } Tlst=T; //保存当次数据包中的时间值 } …… }
Tsf:服务器收第一个数据包时的当前时间
Ts:服务器当前时间
Tcf:客户端第一个数据包里面的时间值
T:当前接收到数据包内的客户端时间值
Tlst:上次接收到的数据包的时间值
Tnd:网络传输延时时间的最大允许值,常量
Tx:客户端和服务器端的在最大计时周期内(MaxLong)的最大允许的时间累计误差,常量
(T-Tcf):当前数据包和第一个数据包间隔时长
(Ts-Tsf ):当前服务器时间和接收第一个数据包时的间隔时长
MaxLong:最大计时周期:10分钟,常量,适当调整
正常情况下(图一),数据包间隔时间和两端时间是符合规则的。但如果外挂要想插入两个数据包(图二)t7和t8,那么t7必须等于2400,t8必须等于2800才能满足(T - Tlst >= 400)条件,这样在接收到t8的时候(T-Tcf) - (Ts-Tsf )就有800毫秒的误差,当插入的数据包超过一定数量的时候(假定Tnd + Tx=1000)就会触发阀门((T-Tcf) - (Ts-Tsf ) > Tnd + Tx)打开,将该用户列入黑名单并断线。
实际游戏中,有效数据包需要限时,有些游戏不需要,应用起来可能还要复杂些。外挂也可能还有更多的应对策略,但此法可以参考来完善游戏中的防护机制。