轉發請保留該字樣:「[L4D WInd && OB]」 昔日的戰友OB又復活歸來。。
說點題外話:說是開源,其實本身Native Trainer就是開源的,我只是整合、修改、漢化部分代碼,所以相當的慚�,國內基本上找不到此類話題的網站,那不如從此帖開始,慢慢的整合一群志同道合的朋友,共同研究,為大家創造更多的插件,打個簡單的比方,敢於開源的人少之又少,及時開源也是過期的東西。國情就是如此,也只能感慨一番。
我相信付出都會有收穫,也因為這種精神我認識了釵h志同道合的朋友,從最初的pvpgn、bnetd project此類開源項目,讓我學習到這種精神,讓我印象最為深刻的就是SourceMod類[Half Life]插件,幾乎是共享的,有很多優秀的作品,L4D1代,我製作了LXD、Random event、viprank等插件,如當初我不開源,沒有那群志同道合的朋友,也不至於能霸佔全球rank第一如此之久,也不會在L4D2的時候還能看到我製作的hack能夠得到延續,也不會看到一批一批優秀的製作者。
所以我想說,共同進步的同時又能方便廣大玩家,何樂而不為�CSO 此帖不光開源,也會在空餘時間進行授課,對SDK進行慢慢的翻譯,逐漸更新,個人思想始終是有侷限的,期待大家的共同加入。
第一篇POST權當基礎教程,我並非是c++高手,只是趨於愛好,逐漸學習,學學忘忘。【不足之處還望指正,學習就是摸索、研究、請教】
1、什麼是Asi
Asi是Script Hook V的腳本文件,與其說是腳本,我認為不如說是DLL文件更為恰當,用Editplus類軟體編輯Asi文件時,都能看到文件頭的標準win32結構,Script Hook從字面瞭解,就能明白,通過hook(例如我給你打電話,中間需要一個基站,hook你可以看作一個偽造的基站,攔截正規基站的信息,然後對其發出修改後的指令,然後得到結果,外掛常用的一種形式)創建我們需要弁遄A讓Script Hook來識別,並在內體現出來。而Asi的書寫結構是標準的c++結構,所以說大家還是學c++吧,哈哈。
2、如何編譯Asi
安裝VS2013,打開 SourcesamplesNativeTrainer.sln 工程文件,然後如圖所示,下方會有簡要提示,無論是否編譯成央C
3、關於中文編譯
採用中文需要注意事項,首先編碼必須是utf8,然後字符集必須採用"使用 Unicode 字符集", 因為編碼的問題(這是我的猜測,我在很早以前看到過GTA系列是單字節遊戲,漢化也是採取的外掛形式,在實際測試過程中,亂碼問題,建議全部採取繁體中文書寫,如果編譯出現錯誤C2001,偶數中文背後加上英文符,或gbk to utf8字符轉換)
4、代碼基礎講解
因為代碼都是標準的C++結構,所以這裡不對最基礎的指令進行說明,只對針對遊戲有作用的代碼進行說明。首先來看一段代碼,代碼內能備註的,我都進行備註
創建菜單函數,創建菜單的方式有許多種,這裡只以其中之一進行說明,該函數涵蓋本附件源碼內的基礎功能
首先看創建菜單的一個功能
- draw_menu_line(caption, 350.0, 15.0, 18.0, 0.0, 5.0, false, true);
[color=rgb(19, 70, 138) !important]複製代碼
後面一堆參數怎麼知道表達的是什麼意思?你可以在vs中搜索draw_menu_line後會出現下方的代碼,相對應後你就知道都是什麼意思了,或者直接在vs中自己手動鍵入draw_menu_line他也會提示,那麼翻譯出現就是- //draw_menu_line(文本,寬度,高度,頂位置,左邊位置,文本位置,是否可選中,是否為標題,自動調整文本(不指定則為true))
[color=rgb(19, 70, 138) !important]複製代碼
那麼我們繼續看下面的一段代碼- void draw_menu_line(std::string caption, float lineWidth, float lineHeight, float lineTop, float lineLeft, float textLeft, bool active, bool title, bool rescaleText = true) // 定義一個名叫做 draw_menu_line的參數,並分別賦予子函數, std::string caption 代表所要創建的標題名稱,類型為string字符串,float類型為單精度浮點數,此後的linewidth等等都是按照英文字面意思解釋即可 bool為邏輯變量 active 為ture代表可以選中的,title為true代表標題項,後面還會介紹到
- {
- // default values
- int text_col[4] = {255, 255, 255, 255}, //初始值定義 字體顏色及矩形背景顏色 顏色代碼請自己google
- rect_col[4] = { 0, 0, 0, 140 }; //rect_col[4] = {70, 95, 95, 255};
- float text_scale = 0.35; //字體比例 0.1最小
- int font = 0;
- // correcting values for active line
- if (active) //如果是能選中的問題,也就是我們進入2級菜單的那些開啟無敵,永不通緝等的那種就叫做可激活(選中)的菜單
- {
- text_col[0] = 243; //對字體顏色分別進行設置
- text_col[1] = 23;
- text_col[2] = 84;
- rect_col[0] = 0; //對背景色分別進行設置
- rect_col[1] = 0;
- rect_col[2] = 0;
- rect_col[3] = 140;
- if (rescaleText) text_scale = 0.40; //如果調用參數沒有對rescaletext進行值的傳遞,也就是如 draw_menu_line(caption, 350.0, 15.0, 18.0, 0.0, 5.0, false, true); 這樣 則默認rescaletext=true 則對比例進行調整為0.4,rescaletext字面解釋為自動調整字體.
- }
- if (title) //如果title=true
- {
- rect_col[0] = 243;
- rect_col[1] = 23;
- rect_col[2] = 84;
- rect_col[3] = 140;
- if (rescaleText) text_scale = 0.50;
- font = 1;
- }
- int screen_w, screen_h; /定義兩個值
- GRAPHICS::GET_SCREEN_RESOLUTION(&screen_w, &screen_h); //GRAPHICS::GET_SCREEN_RESOLUTION 這段是怎麼來的?這裡就是調用的SDK了,SDK不需要我們自己編寫,都是一些模板化後過的代碼,直接調用即可,那麼SDK又是哪裡來的?我已經打包在源碼中了,所以你不用擔心這個問題了,因為後面還要講SDK的調用。該段代碼是獲取屏幕分辨率,分別存放在 剛才定義的 screen_w,screen_h中,
- textLeft += lineLeft; //復合賦值運算符 ,代碼可以看成是 textleft = textleft+lineleft
- float lineWidthScaled = lineWidth / (float)screen_w; // line width
- float lineTopScaled = lineTop / (float)screen_h; // line top offset
- float textLeftScaled = textLeft / (float)screen_w; // text left offset
- float lineHeightScaled = lineHeight / (float)screen_h; // line height
- float lineLeftScaled = lineLeft / (float)screen_w;
- //上面整段的作用主要是用於協調屏幕輸出在正確的位置上,該段代碼可以直接調用的,可以不用去理解他
- //SDK部分開始,因為我們是要把信息輸出到遊戲內,所以這裡需要調用的就是SDK,讓Script HookV識別後發送到遊戲內呈現出來。而我們前面做的工作就是賦值,然後現在做的工作就是傳遞給HookV
- UI::SET_TEXT_FONT(font); //定義字體
- UI::SET_TEXT_SCALE(0.0, text_scale); //定義比例
- UI::SET_TEXT_COLOUR(text_col[0], text_col[1], text_col[2], text_col[3]); //定義字體顏色
- UI::SET_TEXT_CENTRE(0); //定義中心,這裡我也沒有搞清楚是什麼作用
- UI::SET_TEXT_DROPSHADOW(0, 0, 0, 0, 0); //定義字體陰影顏色?
- UI::SET_TEXT_EDGE(0, 0, 0, 0, 0); //定義字體邊緣顏色?
- UI::_SET_TEXT_ENTRY("STRING"); //定義輸出類型 String 字符串
- UI::_ADD_TEXT_COMPONENT_STRING((LPSTR)caption.c_str()); //調用組建,不用去理解,算是一個接口
- UI::_DRAW_TEXT(textLeftScaled, (((lineTopScaled + 0.00278f) + lineHeightScaled) - 0.005f)); //對文字的輸出位置進行調整,通用不用去理解他。
- // 下面代碼部分重複,不明其意,因為不影響,所以也沒有關注,因為結尾部分不一樣,猜測是忘記刪除了,因為SDK是一個公共庫,http://www.dev-c.com/nativedb/每天都會更新,類似於UI::_0x521FB041D93DD0E4("STRING");當初不明其所指的,現在也知道含義了。不過不影響就對了,整段代碼後面都是在做一些初始化的事情,也無需多看,需要的時候直接調用即可.
- UI::SET_TEXT_FONT(font);
- UI::SET_TEXT_SCALE(0.0, text_scale);
- UI::SET_TEXT_COLOUR(text_col[0], text_col[1], text_col[2], text_col[3]);
- UI::SET_TEXT_CENTRE(0);
- UI::SET_TEXT_DROPSHADOW(0, 0, 0, 0, 0);
- UI::SET_TEXT_EDGE(0, 0, 0, 0, 0);
- UI::_0x521FB041D93DD0E4("STRING");
- UI::_ADD_TEXT_COMPONENT_STRING((LPSTR)caption.c_str());
- int num25 = UI::_0x9040DFB09BE75706(textLeftScaled, (((lineTopScaled + 0.00278f) + lineHeightScaled) - 0.005f));
- // rect
- draw_rect(lineLeftScaled, lineTopScaled + (0.00278f),
- lineWidthScaled, ((((float)(num25)* UI::_0xDB88A37483346780(text_scale, 0)) + (lineHeightScaled * 2.0f)) + 0.005f),
- rect_col[0], rect_col[1], rect_col[2], rect_col[3]);
- }
[color=rgb(19, 70, 138) !important]複製代碼
上面部分完了,只是起個拋磚引玉的作用,很多不明白的參數,可以按照我提供的方法,找到函數入口,查看對於的參數,來知道其中的意思。
那麼接著繼續,上面說到創建菜單,其中有部分SDK參數,但是我們在代碼中還發現了一個奇怪的部分,為什麼要搞那麼多次?其實我們按照邏輯分析一下,創建菜單的函數為draw_menu_line,創建輸出文字又是另外一個函數,一個的目的很單純,一個則是創建菜單,細看兩段代碼,都是很多不同之處,從這裡可以思考到一個問題,那麼以後我們在單獨製作其他的插件的時候是否也應該考慮到這個問題了?我們改變其中的參數有會得到具體的什麼表現了?不如自己嘗試修改後實下。- void update_status_text()
- {
- if (GetTickCount() < statusTextDrawTicksMax)
- {
- UI::SET_TEXT_FONT(0);
- UI::SET_TEXT_SCALE(0.55, 0.55);
- UI::SET_TEXT_COLOUR(243, 23, 84, 255);
- UI::SET_TEXT_WRAP(0.0, 1.0);
- UI::SET_TEXT_CENTRE(0);
- UI::SET_TEXT_DROPSHADOW(0, 0, 0, 0, 0);
- UI::SET_TEXT_EDGE(1, 0, 0, 0, 205);
- if (statusTextGxtEntry)
- {
- UI::_SET_TEXT_ENTRY((char *)statusText.c_str());
- } else
- {
- UI::_SET_TEXT_ENTRY("STRING");
- UI::_ADD_TEXT_COMPONENT_STRING((char *)statusText.c_str());
- }
- UI::_DRAW_TEXT(0.5, 0.5);
- }
- }
[color=rgb(19, 70, 138) !important]複製代碼
突然想起來一個嚴重的問題,那必須要說下,且到了上班的點了,也不夠時間了。- void main() //初始入口,例如我在另外一篇POST中發的online_bypass源碼,如果你需要用,那麼就需要加在這裡,我備註過(備註也等同於讓這段代碼失效)的部分就是了,
- {
- //#include "bypass.h"
- //online_bypass.h();
- reset_globals(); //這裡是對所有變量進行初始賦值,我遇到過一個BUG,直接複製粘貼進去的變量是失效的,如果遇到此類問題,建議手打,編譯的時候不會出現錯誤警告。
- while (true) //正文中我提到過,可以把asi看成一個dll,在main.cpp中一看便知,插件只會加載一次,具體見main.cpp,和本文無關不做解釋了
- {
- if (trainer_switch_pressed()) //搜索trainer_switch_pressed 得知此段代碼意思 如果f4被按下
- {
- menu_beep(); //搜索得知,播放聲音
- process_main_menu(); //執行process_main_menu參數
- }
- update_features(); 否則執行update_features()函數,有時候我們發現修改的功能失效,按下F4,再關閉後即可生效,update_features掌管了大部分的修改功能。
- WAIT(0);
- }
- }
[color=rgb(19, 70, 138) !important]複製代碼
process_main_menu() 解釋- int activeLineIndexMain = 0; //定義一個初始值
- void process_main_menu()
- {
- const float lineWidth = 300.0; //表格寬度
- const int lineCount = 10; //行數
- std::string caption = "NATIVE TRAINER (AB) PLus BY WInD"; //std string caption 記得這裡嗎?前文中創建菜單那裡提到過,標題的類型就是 std string,caption是自定義的參數名
- static LPCSTR lineCaption[lineCount] = { //創建表格
- "玩家選項",
- "武器選項",
- "載具選項",
- "世界選項",
- "時間選項",
- "天氣選項",
- "其他雜項",
- "在線解鎖",
- "等級修改",
- "增強部分 BY WInD" //結尾是沒有,號的
- };
- DWORD waitTime = 150; /定義一個變量
- while (true)
- {
- // timed menu draw, used for pause after active line switch
- DWORD maxTickCount = GetTickCount() + waitTime; //該段代碼中的GetTickCount()在main菜單中,可以看到有個參數,創建了一個隨機數種子,而GetTickCount()在update_status_text()中有有一個判斷,主要用於解決同時創建菜單造成的字體顏色混淆作用
- do
- {
- // draw menu
- draw_menu_line(caption, lineWidth, 15.0, 18.0, 0.0, 5.0, false, true); //這裡不做解釋了,上面已經解釋過了,至說明一下創建過程經過
- for (int i = 0; i < lineCount; i++) //循環,賦值i=0 如果 i<linecount 則跳出循環,否則i++後繼續執行,如果i<10,也就是執行10次後,i=10了,那麼則跳出循環。
- if (i != activeLineIndexMain) //如果I 不等於activeLineIndexMain(該值初始值為0,也就是說0不等於0的情況下) 則執行 draw_menu_line(lineCaption, lineWidth, 9.0, 60.0 + i * 36.0, 0.0, 9.0, false, false);
- draw_menu_line(lineCaption, lineWidth, 9.0, 60.0 + i * 36.0, 0.0, 9.0, false, false); //創建菜單 以此從第一項創建到10項,結尾的兩個false,則代表他們既不是標題也是可選中項目,可以這樣理解他這裡是為了防止BUG才這樣處理的, 在本段代碼開頭,如果第一次創建的話,因為按了F4以後,我們首選就是菜單的第一個項目上了,那麼接下來我們要創建的是2~9項目,用於防止重複創建,可以不用理解,直接調用即可,這裡只是做一個說明。
- draw_menu_line(lineCaption[activeLineIndexMain], lineWidth + 1.0, 11.0, 56.0 + activeLineIndexMain * 36.0, 0.0, 7.0, true, false);
- update_features(); //創建完畢後,立即執行參數,該段後面會大致講解。
- WAIT(0); //延時
- } while (GetTickCount() < maxTickCount);
- waitTime = 0;
- // process buttons
- bool bSelect, bBack, bUp, bDown; //邏輯參數 選擇 返回 前 後
- get_button_state(&bSelect, &bBack, &bUp, &bDown, NULL, NULL); //獲取key設置值,以後會講解,來不及了,要上班了
- if (bSelect) //如果按下選擇按鈕
- {
- menu_beep(); //發聲
- switch (activeLineIndexMain) //選擇
- {
- case 0:
- process_player_menu(); //第一項進入 process_player_menu()
- break;
- case 1:
- process_weapon_menu(); //第二項進入 process_weapon_menu() 後面以此類推
- break;
- case 2:
- process_veh_menu();
- break;
- case 3:
- process_world_menu();
- break;
- case 4:
- process_time_menu();
- break;
- case 5:
- process_weather_menu();
- break;
- case 6:
- process_misc_menu();
- break;
- case 7:
- set_status_text("[自用功能,不影響和諧]");
- //process_rec_menu();
- break;
- case 8:
- set_status_text("[自用功能,不影響和諧]");
- //process_level_menu();
- break;
- case 9:
- process_about_menu();
- break;
- }
- waitTime = 200;
- } else //如果沒有進行選擇操作
- if (bBack || trainer_switch_pressed()) //如果是 返回 或按下f4
- {
- menu_beep();
- break; //中段
- } else
- if (bUp) //如果按向上按鈕
- {
- menu_beep();
- if (activeLineIndexMain == 0)
- activeLineIndexMain = lineCount; //一些賦值,不說明了,可以自己對比兩個值在不同位置的作用,來做比較
- activeLineIndexMain--;
- waitTime = 150;
- } else
- if (bDown)
- {
- menu_beep();
- activeLineIndexMain++;
- if (activeLineIndexMain == lineCount)
- activeLineIndexMain = 0;
- waitTime = 150;
- }
- }
- }
[color=rgb(19, 70, 138) !important]複製代碼
前文中我們提到了- get_button_state(&bSelect, &bBack, &bUp, &bDown, NULL, NULL); //獲取key設置值,以後會講解,來不及了,要上班了
[color=rgb(19, 70, 138) !important]複製代碼
該段代碼中我們可以追蹤代碼段,得到- void get_button_state(bool *a, bool *b, bool *up, bool *down, bool *l, bool *r) //
- {
- if (a) *a = IsKeyDown(VK_NUMPAD5); //整段的作用很明確,就是為了定義熱鍵按鈕,key代碼可以在http://blog.sina.com.cn/s/blog_7006ccc10101bnmr.html中查詢
- if (b) *b = IsKeyDown(VK_NUMPAD0) || trainer_switch_pressed() || IsKeyDown(VK_BACK);
- if (up) *up = IsKeyDown(VK_NUMPAD8);
- if (down) *down = IsKeyDown(VK_NUMPAD2);
- if (r) *r = IsKeyDown(VK_NUMPAD6);
- if (l) *l = IsKeyDown(VK_NUMPAD4);
- }
[color=rgb(19, 70, 138) !important]複製代碼
前文中多次提到過update_features,那麼作為本次代碼講解的結束,我想再合適不過了- void update_features() //從名稱就可以看出,這裡主要用做刷新、更新作用,當然這些你都可以自定義的
- {
- update_status_text(); //前面提到過,不再說嘛
- update_vehicle_guns(); //本函數作用類似於我們正在講解的,也不做說明
- // changing player model if died/arrested while being in another skin, since it can cause inf loading loop
- if (skinchanger_used) //先追蹤變量,其實問中我多次用到參數變量等詞彙,有時候是一個意思,因為我不是專業寫教程的,難免有時候自己錯亂一下,可以得到 該值為true的情況下,必須是在更換過人物模型後,這2段都是為了檢查人物如果死亡後,狀態又在刷新,防止角色卡死
- check_player_model();
- // wait until player is ready, basicly to prevent using the trainer while player is dead or arrested
- while (ENTITY::IS_ENTITY_DEAD(PLAYER::PLAYER_PED_ID()) || PLAYER::IS_PLAYER_BEING_ARRESTED(PLAYER::PLAYER_ID(), TRUE)) //本段內容同上,都是為了檢查角色狀態的, 死亡或正在創建過程中 那麼腳本就繼續等待 循環判斷指令
- WAIT(0);
- // read default feature values from the game
- featureWorldRandomCops = PED::CAN_CREATE_RANDOM_COPS() == TRUE; //給featureWorldRandomCops變量賦予默認值true,並讓SDK中我們查詢得到的是否允許創建隨機的警察該值也為true.
- // common variables
- Player player = PLAYER::PLAYER_ID(); //變量定義,玩家ID,這3段主要是為了後面的書寫進行定義的,這裡的第一個Player,是SDK包含的自定義數據類型,可以看作是 DWORD數據類型
- Ped playerPed = PLAYER::PLAYER_PED_ID(); //角色模型ID 同上
- BOOL bPlayerExists = ENTITY::DOES_ENTITY_EXIST(playerPed); //邏輯數據類型玩家是否退出 傳遞
- // player invincible
- if (featurePlayerInvincibleUpdated) //追蹤該變量featurePlayerInvincibleUpdated可以知道,這段變量是用於判斷是否進行過玩家無敵的操作,作用在於,每次進行還原,再進行無敵操作,下面的代碼就能夠看的出來
- {
- if (bPlayerExists && !featurePlayerInvincible) // 玩家是否退出 並且檢查另外一個變量,上面的featurePlayerInvincibleUpdated同時還控制著 ON OFF開關的顯示
- PLAYER::SET_PLAYER_INVINCIBLE(player, FALSE); //SDK部分 禁止玩家無敵
- featurePlayerInvincibleUpdated = false;
- }
- if (featurePlayerInvincible) //同理上面那段
- {
- if (bPlayerExists) //檢查玩家是否退出遊戲
- PLAYER::SET_PLAYER_INVINCIBLE(player, TRUE); //沒有,那就無敵吧
- }
- // player never wanted
- if (featurePlayerNeverWanted) //同理上面,因為是SDK部分,所以不做說明,所以說如果能夠搞清楚遊戲的SDK,那麼你可以實現很多的功能,這是一個艱巨而漫長的過程。
- {
- if (bPlayerExists)
- PLAYER::CLEAR_PLAYER_WANTED_LEVEL(player);
- }
- // police ignore player
- if (featurePlayerIgnoredUpdated)
- {
- if (bPlayerExists)
- PLAYER::SET_POLICE_IGNORE_PLAYER(player, featurePlayerIgnored);
- featurePlayerIgnoredUpdated = false;
- }
- // player special ability
- if (featurePlayerUnlimitedAbility)
- {
- if (bPlayerExists)
- PLAYER::_RECHARGE_SPECIAL_ABILITY(player, 1);
- }
- // player no noise
- if (featurePlayerNoNoiseUpdated)
- {
- if (bPlayerExists && !featurePlayerNoNoise)
- PLAYER::SET_PLAYER_NOISE_MULTIPLIER(player, 1.0);
- featurePlayerNoNoiseUpdated = false;
- }
- if (featurePlayerNoNoise)
- PLAYER::SET_PLAYER_NOISE_MULTIPLIER(player, 0.0);
- // player fast swim
- if (featurePlayerFastSwimUpdated)
- {
- if (bPlayerExists && !featurePlayerFastSwim)
- PLAYER::_SET_SWIM_SPEED_MULTIPLIER(player, 1.0);
- featurePlayerFastSwimUpdated = false;
- }
- if (featurePlayerFastSwim)
- PLAYER::_SET_SWIM_SPEED_MULTIPLIER(player, 1.49);
- // player fast run
- if (featurePlayerFastRunUpdated)
- {
- if (bPlayerExists && !featurePlayerFastRun)
- PLAYER::_SET_MOVE_SPEED_MULTIPLIER(player, 1.0);
- featurePlayerFastRunUpdated = false;
- }
- if (featurePlayerFastRun)
- PLAYER::_SET_MOVE_SPEED_MULTIPLIER(player, 1.49);
- // player super jump
- if (featurePlayerSuperJump)
- {
- if (bPlayerExists)
- GAMEPLAY::SET_SUPER_JUMP_THIS_FRAME(player);
- }
- // weapon
- if (featureWeaponFireAmmo)
- {
- if (bPlayerExists)
- GAMEPLAY::SET_FIRE_AMMO_THIS_FRAME(player);
- }
- if (featureWeaponExplosiveAmmo)
- {
- if (bPlayerExists)
- GAMEPLAY::SET_EXPLOSIVE_AMMO_THIS_FRAME(player);
- }
- if (featureWeaponExplosiveMelee)
- {
- if (bPlayerExists)
- GAMEPLAY::SET_EXPLOSIVE_MELEE_THIS_FRAME(player);
- }
- // weapon no reload
- if (bPlayerExists && featureWeaponNoReload) //上面的都差不多,從這裡稍不一樣,那就從這裡開始
- {
- Hash cur; //hash數據類型我從來沒有接觸過,能網上百度來的,我絕對不會在這裡跟大家說
- if (WEAPON::GET_CURRENT_PED_WEAPON(playerPed, &cur, 1)) //這裡不是很清楚,那就去查SDK Any GET_CURRENT_PED_WEAPON(Ped ped, Hash *weapHash, BOOL p2) // 0xB0237302 判斷 獲取模型手上的槍的hash值,這到底是什麼參數,我暈 如果為真反正就是判斷玩家手上是否有槍就對了,並且把這把槍的值賦到cur變量中
- {
- if (WEAPON::IS_WEAPON_VALID(cur)) //如果是一把有效的槍,或者說你把槍切換出來了
- {
- int maxAmmo; //定義一個最大的子彈數
- if (WEAPON::GET_MAX_AMMO(playerPed, cur, &maxAmmo)) //獲取這把槍的最大彈藥數,這裡是獲取,而不是制定,也就說,你可以不要這段代碼,然後下面那段代碼,按照我的方法修改是同理
- {
- WEAPON::SET_PED_AMMO(playerPed, cur, maxAmmo); //這樣修改 WEAPON::SET_PED_AMMO(playerPed, cur, 10) 這樣也可以,以此類推。不過這樣改了就不能不用裝彈了,原理未知,光從代碼上看,還不足以實現無須裝彈
- maxAmmo = WEAPON::GET_MAX_AMMO_IN_CLIP(playerPed, cur, 1); //最大彈夾數
- if (maxAmmo > 0) //如果彈夾高於0
- WEAPON::SET_AMMO_IN_CLIP(playerPed, cur, maxAmmo); //那麼設置一個最大彈夾
- }
- }
- }
- }
- // player's vehicle invincible
- if (featureVehInvincibleUpdated) //載具無敵,同理上面,先進行一次還原,再進行無敵操作
- {
- if (bPlayerExists && !featureVehInvincible && PED::IS_PED_IN_ANY_VEHICLE(playerPed, 0))
- {
- Vehicle veh = PED::GET_VEHICLE_PED_IS_USING(playerPed);
- ENTITY::SET_ENTITY_INVINCIBLE(veh, FALSE);
- ENTITY::SET_ENTITY_PROOFS(veh, 0, 0, 0, 0, 0, 0, 0, 0);
- VEHICLE::SET_VEHICLE_TYRES_CAN_BURST(veh, 1);
- VEHICLE::SET_VEHICLE_WHEELS_CAN_BREAK(veh, 1);
- VEHICLE::SET_VEHICLE_CAN_BE_VISIBLY_DAMAGED(veh, 1);
- }
- featureVehInvincibleUpdated = false;
- }
- if (featureVehInvincible)
- {
- if (bPlayerExists && PED::IS_PED_IN_ANY_VEHICLE(playerPed, 0))
- {
- Vehicle veh = PED::GET_VEHICLE_PED_IS_USING(playerPed);
- ENTITY::SET_ENTITY_INVINCIBLE(veh, TRUE);
- ENTITY::SET_ENTITY_PROOFS(veh, 1, 1, 1, 1, 1, 1, 1, 1); //變動處 SDK:void SET_ENTITY_PROOFS(Entity Entity, BOOL bulletProof, BOOL fireProof, BOOL explosionProof, BOOL collisionProof, BOOL meleeProof, Any p6, Any p7, Any p8) // 0x7E9EAB66 對應SDK就一目瞭然
- VEHICLE::SET_VEHICLE_TYRES_CAN_BURST(veh, 0);
- VEHICLE::SET_VEHICLE_WHEELS_CAN_BREAK(veh, 0);
- VEHICLE::SET_VEHICLE_CAN_BE_VISIBLY_DAMAGED(veh, 0);
- }
- }
- // player's vehicle boost
- if (featureVehSpeedBoost && bPlayerExists && PED::IS_PED_IN_ANY_VEHICLE(playerPed, 0))
- {
- Vehicle veh = PED::GET_VEHICLE_PED_IS_USING(playerPed);
- DWORD model = ENTITY::GET_ENTITY_MODEL(veh);
- bool bUp = IsKeyDown(VK_NUMPAD9);
- bool bDown = IsKeyDown(VK_NUMPAD3);
- if (bUp || bDown) //這裡為汽車加速,並定義了2個熱鍵,用於實現汽車加速的
- {
- float speed = ENTITY::GET_ENTITY_SPEED(veh);
- if (bUp)
- {
- speed += speed * 0.05f; //speed=speed+speed*0.05f
- VEHICLE::SET_VEHICLE_FORWARD_SPEED(veh, speed);
- } else
- if (ENTITY::IS_ENTITY_IN_AIR(veh) || speed > 5.0)
- VEHICLE::SET_VEHICLE_FORWARD_SPEED(veh, 0.0);
- }
- }
- // time pause
- if (featureTimePausedUpdated)
- {
- TIME::PAUSE_CLOCK(featureTimePaused);
- featureTimePausedUpdated = false;
- }
- // time sync
- if (featureTimeSynced)
- {
- time_t now = time(0);
- tm t;
- localtime_s(&t, &now);
- TIME::SET_CLOCK_TIME(t.tm_hour, t.tm_min, t.tm_sec);
- }
- if (featureVehAllMod) //載具自動改造,具體自己去查SDK
- {
- Vehicle veh = PED::GET_VEHICLE_PED_IS_USING(playerPed);
- VEHICLE::SET_VEHICLE_MOD_KIT(veh, 0); // sdk 解釋 SET_VEHICLE_MOD_KIT(Vehicle vehicle, int unknown) // 0xB8132158 SDK部分都還暫時不明所以,沒人更新,如果你知道,你可以去管網更新,這樣大家以後下載最新的SDK,就有解釋
- VEHICLE::SET_VEHICLE_COLOURS(veh, 120, 120);
- VEHICLE::SET_VEHICLE_NUMBER_PLATE_TEXT(veh, (Any*)"KINKYHAX");
- VEHICLE::SET_VEHICLE_NUMBER_PLATE_TEXT_INDEX(veh, 1);
- VEHICLE::TOGGLE_VEHICLE_MOD(veh, 18, 1);
- VEHICLE::TOGGLE_VEHICLE_MOD(veh, 22, 1);
- VEHICLE::SET_VEHICLE_MOD(veh, 16, 5, 0);
- VEHICLE::SET_VEHICLE_MOD(veh, 12, 2, 0);
- VEHICLE::SET_VEHICLE_MOD(veh, 11, 3, 0);
- VEHICLE::SET_VEHICLE_MOD(veh, 14, 14, 0);
- VEHICLE::SET_VEHICLE_MOD(veh, 15, 3, 0);
- VEHICLE::SET_VEHICLE_MOD(veh, 13, 2, 0);
- VEHICLE::SET_VEHICLE_WHEEL_TYPE(veh, 6);
- VEHICLE::SET_VEHICLE_WINDOW_TINT(veh, 5);
- VEHICLE::SET_VEHICLE_MOD(veh, 23, 19, 1);
- VEHICLE::SET_VEHICLE_MOD(veh, 0, 1, 0);
- VEHICLE::SET_VEHICLE_MOD(veh, 1, 1, 0);
- VEHICLE::SET_VEHICLE_MOD(veh, 2, 1, 0);
- VEHICLE::SET_VEHICLE_MOD(veh, 3, 1, 0);
- VEHICLE::SET_VEHICLE_MOD(veh, 4, 1, 0);
- VEHICLE::SET_VEHICLE_MOD(veh, 5, 1, 0);
- VEHICLE::SET_VEHICLE_MOD(veh, 6, 1, 0);
- VEHICLE::SET_VEHICLE_MOD(veh, 7, 1, 0);
- VEHICLE::SET_VEHICLE_MOD(veh, 8, 1, 0);
- VEHICLE::SET_VEHICLE_MOD(veh, 9, 1, 0);
- VEHICLE::SET_VEHICLE_MOD(veh, 10, 1, 0);
- }
- if (featureVehSlide)
- {
- VEHICLE::SET_VEHICLE_REDUCE_GRIP(PED::GET_VEHICLE_PED_IS_IN(PLAYER::PLAYER_PED_ID(), 0), 1);
- }
- else
- {
- VEHICLE::SET_VEHICLE_REDUCE_GRIP(PED::GET_VEHICLE_PED_IS_IN(PLAYER::PLAYER_PED_ID(), 0), 0);
- }
- if (featureVehRainbow) //這裡說下彩虹冊車,說實話我還不知道update_features()是如何自動刷新的,因為代碼我還沒有全部看完,慢慢講解,慢慢自己研究看看。
- {
- Vehicle veh = PED::GET_VEHICLE_PED_IS_USING(playerPed);
- DWORD model = ENTITY::GET_ENTITY_MODEL(veh);
- if (PED::IS_PED_IN_ANY_VEHICLE) //如果玩家在車輛內,其實這裡有個BUG的,應該還要加一段判斷 PLAYER::IS_PLAYER_CONTROL_ON(player) && PED::IS_PED_IN_ANY_VEHICLE(playerPed, 0)) 這樣才不會在還沒有上車的時候就出現問題.
- {
- VEHICLE::SET_VEHICLE_CUSTOM_PRIMARY_COLOUR(veh, rand() % 255, rand() % 255, rand() % 255); //設置隨機顏色
- WAIT(150); //延時150
- VEHICLE::SET_VEHICLE_CUSTOM_SECONDARY_COLOUR(veh, rand() % 255, rand() % 255, rand() % 255);
- WAIT(150);
- }
- }
- if (featureVehStickyCar)
- {
- if (PED::IS_PED_IN_ANY_VEHICLE(PLAYER::PLAYER_PED_ID(), 0))
- {
- int myVehicle = PED::GET_VEHICLE_PED_IS_USING(PLAYER::PLAYER_PED_ID());
- VEHICLE::SET_VEHICLE_ON_GROUND_PROPERLY(myVehicle);
- }
- }
- // hide hud
- if (featureMiscHideHud)
- UI::HIDE_HUD_AND_RADAR_THIS_FRAME();
- }
[color=rgb(19, 70, 138) !important]複製代碼
5、SDK整理翻譯
網站地址:http ://www.dev-c.com/nativedb/ 該SDK由網友維護更新,可隨時去更新,這樣才會有一些新的備註,不會出現類似於unnkow情況發生.SDK部分需要很長時間研究
PLAYER [203] 玩家部分
ENTITY [150] 實體
PED [525] 角色模型
VEHICLE [476] 車輛相關
OBJECT [101] 對象
AI [274] AI
GAMEPLAY [254] 操作類
AUDIO [217] 音樂類
CUTSCENE [41] 動畫類
INTERIOR [33] 室內
CAM [191] 攝像機
WEAPON [86] 武器
ITEMSET [9]
STREAMING [112]
SCRIPT [25] 腳本
UI [407] 界面
GRAPHICS [286] 圖形
STATS [137] 統計
BRAIN [11]
MOBILE [15] 手機
APP [17]
TIME [15] 時間
PATHFIND [51]
CONTROLS [32] 控制
DATAFILE [50]
FIRE [15] 火
DECISIONEVENT [13]
ZONE [9]
ROPE [42] 範圍
WATER [6] 水
WORLDPROBE [10]
NETWORK [619] 網絡
NETWORKCASH [76] 高級網絡 金錢?
DLC1 [38]
DLC2 [7]
SYSTEM [24] 系統
DECORATOR [10]
UNK_SC [49]
UNK [8]
6、文件結構
SDK部分:
sourceincenums.h
sourceincmain.h
sourceinc
ativeCaller.h
sourceinc\natives.h SDK主要文件,網上更新也是更新該文件
sourceinc ypes.h 自定義數據類型文件
Lib文件:
sourcelibScriptHookV.lib
可編寫腳本文件:
sourcelibsamplesNativeTrainerkeyboard.h
sourcelibsamplesNativeTrainerkeyboard.cpp
sourcelibsamplesNativeTrainermain.cpp 看結構就是一個DLL
sourcelibsamplesNativeTrainerscript.cpp 主要代碼存放文件
sourcelibsamplesNativeTrainerscript.h
原始碼:
|