會員登入 新使用者?立即註冊

這是一個充滿夢想的地方!致力於創造簡單易用、媲美商業遊戲等級的玩家版3D線上遊戲創作平台!!!(研發中)

關閉
勇者們!一起創作心目中的遊戲世界吧!!! 我要留言

3D線上遊戲製作軟體 - 如何偵測加速器程式並讓它完全失效!

分類:程式技巧
2008/09/18 01:38



最近研究了如何偵測加速器程式並讓它完全失效的方法!
略有小成,我將之整理好後,就來和大家分享這小技巧嚕!

下面列出的完整程式碼是...如何偵測加速器程式.
我是用對岸的變速齒輪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線上遊戲製作軟體 - 程式入侵修改研究 - 入門心得
下一篇
回應(7)
引用(0)

統計資料

  • 今日人數:21
  • 累計人數:87105
  • 發表文章:77
  • 相片數量:111
  • 回應數量:424

勇者居民觀察室

    Blog Look Score and Rank

     

    目前在線人數:

    who's online

我的訂閱

雅虎資訊 版權所有 © 2009 Yahoo! Taiwan All Rights Reserved
「本服務設有管理員」 服務條款 隱私權政策