![]()
最近研究了如何偵測加速器程式並讓它完全失效的方法!
略有小成,我將之整理好後,就來和大家分享這小技巧嚕!
下面列出的完整程式碼是...如何偵測加速器程式.
我是用對岸的
變速齒輪v0.451這一個版本來測試的!
變速齒輪下載網址:變速齒輪官方網站這裡有偵測加速器程式碼範例可以下載:我的偵測加速器程式碼下載連結好的,下面就請慢慢理解嚕~ 要開始了!
#include "stdafx.h"
#include < windows.h >
#include < time.h >
//==========================================
// 取得CPU每秒時間內的時鐘週期數__inline LONGLONG gGetSecondCount()
{
static LARGE_INTEGER liCounter = {0};
if( 0 == liCounter.QuadPart )
QueryPerformanceFrequency( &liCounter );
return liCounter.QuadPart;
}
//==========================================
// 返回當前高精度計時器的值(單位:毫秒)DWORD64 gGetHighTime()
{
static LARGE_INTEGER liCurrent = {0};
QueryPerformanceCounter( &liCurrent );
return (DWORD64)(liCurrent.QuadPart * 1000 / gGetSecondCount());
}
//==========================================
BOOL gCheckSpeedProgram()
{
// 偵測是否使用加速器程式 SYSTEMTIME time = {0};
// 取得高精度計時器的值(毫秒) static __int64 start_time = gGetHighTime(), end_time = 0, delay_time = 1000;
static long local_start_time = -1, local_end_time = 0;
static long compute_head = 0, compute_tail = 0;
static long order_mode = 0, count = 0;
static long get_count = 0;
if( local_start_time == -1 )
{
GetLocalTime( &time );
local_start_time = time.wMilliseconds;
// 取得本地時間的毫秒 }
end_time = gGetHighTime();
// 取得高精度計時器的值(毫秒) GetLocalTime( &time );
local_end_time = time.wMilliseconds;
// 取得本地時間的毫秒 if( local_end_time == local_start_time )
{
// 無事 }
else if( local_end_time > local_start_time && order_mode == 0 )
{
// 取得本地時間毫秒的差值(後段差值) compute_tail = local_end_time - local_start_time;
}
else if( order_mode == 0 || order_mode == 1 )
{
if( local_end_time >= local_start_time )
{
// 再加上本地時間毫秒的差值(前段差值) compute_head += local_end_time - local_start_time;
// 結束此次的差值計算 order_mode = 2;
}
else
{
// 取得本地時間毫秒的差值(前段差值) compute_head = local_end_time;
order_mode = 1;
}
}
// 如果一秒的時間到時... if( (end_time - start_time) >= delay_time )
{
printf( "count= %d, time= %d, compute(%d) \n", count++, end_time - start_time, compute_head + compute_tail );
start_time = gGetHighTime();
// 取得高精度計時器的值(毫秒) GetLocalTime( &time );
local_start_time = time.wMilliseconds;
// 取得本地時間的毫秒 // 如果由系統計時器計算的一秒快過系統時鐘計算的一秒太多時, // 則可能是玩家使用加速器的結果. // 不過這也可能會有誤判機率發生,所以此550數值是測試過比較不容易誤判的範圍. if( compute_head + compute_tail < 550 )
{
order_mode = 0;
compute_head = 0;
compute_tail = 0;
/
/ 如果連續重複偵測到600次,就認定這是使用了加速器!(遊戲中才偵測600次) // 先用10次來測試 if( get_count++ >= 10 )
//(60*10) ) {
get_count = 0;
::Beep( 1000, 150 );
// 嗶一聲 return TRUE;
// 有使用加速器 }
}
else
get_count = 0;
order_mode = 0;
compute_head = 0;
compute_tail = 0;
}
return FALSE;
}
int _tmain(int argc, _TCHAR* argv[])
{
while( 1 )
{
gCheckSpeedProgram();
}
return 0;
}
其實,偵測加速器程式有可能會有一點誤差,
550這個數值,是我測試過還不錯的中庸數值,
越小表示加速器開越快時才能偵測到,也表示誤判機率越低,
越大表示誤判機率會提高,最大最好不要超過800。

另外,也可以去調整連續偵測的次數,藉此降低誤判機率!
而且,我懷疑可能有其他程式或因素會一瞬間改變系統計時器的速度,
這就是可能造成誤判的機率和原因。
所以最好將偵測條件設的嚴格一點,避免誤判喔!
至於如何使加速器程式徹底失效的方法就是...
遊戲中不使用任何種系統計時器來做為延遲之用,要用迴圈次數來延遲。因為加速器就是去攔截這些系統計時器來做修改,讓遊戲中各種部份的延遲都失效,
所以玩家玩起遊戲時,會變得超快,或是顯示不太正常...
好的~ 就簡介到此嚕~
我該去寫3D線上遊戲製作軟體 - 玩家版了!

延伸閱讀:
3D線上遊戲製作軟體 - 程式入侵修改研究 - 入門心得