Можно поинтересоваться для чего тут ассемблер?перед использованием проверь загруженость сампа
Можно поинтересоваться для чего тут ассемблер?перед использованием проверь загруженость сампа
MTA-стайл - асм вместо тайпдефаМожно поинтересоваться для чего тут ассемблер?
ПКМ по решению -> перенацелить решениепкм по названию проекту - настройки. выбираешь установленый тулсет (у меня это v141), применяешь настройки. после чего выбираешь версию winsdk (у меня это 10.0.17763.0), применяешь настройки.
А зачем...MTA-стайл - асм вместо тайпдефа
при чём тут это? мне просто так легче было написать, вот и всёА зачем...
Ассемблером выебнуться типа?
11 строк вместо 2хмне просто так легче было написать
Тим, напиши пожалуйста как можно заменить эти 11 строк твоими 211 строк вместо 2х
дело ведь не в количестве строк 🥲11 строк вместо 2х
Я тоже не про количество, мне просто интересно как заменить это.дело ведь не в количестве строк 🥲
Тим, напиши пожалуйста как можно заменить эти 11 строк твоими 2
void add_chat_message(DWORD dwColor, LPCSTR szString, ...)
{
va_list ap;
char msg[/* SAMP_MAX_CHAT_MESSAGE*/ 144] = { 0 };
va_start(ap, szString);
vsprintf_s(msg, szString, ap);
va_end(ap);
DWORD base = reinterpret_cast<DWORD>(GetModuleHandleW(L"samp.dll"));
typedef void(__thiscall* CChat__AddEntry)(void*, int, char*, char*, DWORD, DWORD);
reinterpret_cast<CChat__AddEntry>(base + /* SAMP_PTR_FUNC_ADDTOCHATWND */ 0x64010)(*reinterpret_cast<void**>(base + /* SAMP_PTR_CHAT_INFO */ 0x21A0E4), 8, msg, 0, dwColor, 0);
}
почему 2? можно и 1 😀11 строк вместо 2х
#include <Windows.h>
#include "main.h"
SAMPFUNCS *SF = new SAMPFUNCS();
void __stdcall mainloop()
{
static bool initialized = false;
static bool activated = false;
if (!initialized)
{
if (GAME && GAME->GetSystemState() == eSystemState::GS_PLAYING_GAME && SF->getSAMP()->IsInitialized())
{
initialized = true;
SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(0, 0xAA, 0), "SAMPFUNCS Plugin loaded.");
}
}
if (SF->getGame()->isKeyPressed('H'))
{
activated = true;
}
while (activated)
{
SF->getSAMP()->getPlayers()->pLocalPlayer->Say("/edit");
Sleep(2500);
}
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReasonForCall, LPVOID lpReserved)
{
if (dwReasonForCall == DLL_PROCESS_ATTACH)
SF->initPlugin(mainloop, hModule);
return TRUE;
}
нельзя делать Sleep в mainloop, ты останавливаешь всю игру, а не только свой плагин. так же нельзя делать while в mainloop, да и нет смысла, так как mainloop вызывается постоянно. используй if и GetTickCount (функция которая берет текущее количество пройденых милисекунд с запуска системы, 1000 милисекунд = 1 секунда), вот так:игра просто виснет
#include "main.h"
SAMPFUNCS *SF = new SAMPFUNCS();
void __stdcall mainloop()
{
static bool initialized = false;
static bool activated = false;
static DWORD dwTime = 0;
if (!initialized)
{
if (GAME && GAME->GetSystemState() == eSystemState::GS_PLAYING_GAME && SF->getSAMP()->IsInitialized())
{
initialized = true;
SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(0, 0xAA, 0), "SAMPFUNCS Plugin loaded.");
}
}
else
{
if (SF->getGame()->isKeyPressed('H'))
{
// активирует и деактивирует на ту же кнопку
activated = !activated;
}
if (activated && GetTickCount() - dwTime >= /* время ожидания */ 2500)
{
SF->getSAMP()->getPlayers()->pLocalPlayer->Say("/edit");
dwTime = GetTickCount();
}
}
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReasonForCall, LPVOID lpReserved)
{
if (dwReasonForCall == DLL_PROCESS_ATTACH)
SF->initPlugin(mainloop, hModule);
return TRUE;
}
Игра уже не виснет, но команда отправляется только тогда когда я жму H а не циклически как хотелосьнельзя делать Sleep в mainloop, ты останавливаешь всю игру, а не только свой плагин. так же нельзя делать while в mainloop, да и нет смысла, так как mainloop вызывается постоянно. используй if и GetTickCount (функция которая берет текущее количество пройденых милисекунд с запуска системы, 1000 милисекунд = 1 секунда), вот так:
C++:#include "main.h" SAMPFUNCS *SF = new SAMPFUNCS(); void __stdcall mainloop() { static bool initialized = false; static bool activated = false; static DWORD dwTime = 0; if (!initialized) { if (GAME && GAME->GetSystemState() == eSystemState::GS_PLAYING_GAME && SF->getSAMP()->IsInitialized()) { initialized = true; SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(0, 0xAA, 0), "SAMPFUNCS Plugin loaded."); } } else { if (SF->getGame()->isKeyPressed('H')) { // активирует и деактивирует на ту же кнопку activated = !activated; } if (activated && GetTickCount() - dwTime > /* время ожидания */2500) { SF->getSAMP()->getPlayers()->pLocalPlayer->Say("/edit"); dwTime = GetTickCount(); } } } BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReasonForCall, LPVOID lpReserved) { if (dwReasonForCall == DLL_PROCESS_ATTACH) SF->initPlugin(mainloop, hModule); return TRUE; }
команда отправляется каждые 2.5 секунды, можешь проверить это добавлением логгированием в месте отправления командыИгра уже не виснет, но команда отправляется только тогда когда я жму H а не циклически как хотелось
У SF плагинов есть специальный коллбек, который выполняется перед выгрузкойрешил добавить фикс краша по адрессу 0x0072CD14 в сф плагин. заметил, что при отгрузке плагина через pfree или просто выходе из игры, то функция хука пропадает быстрее, чем сам хук снимается и игра крашится. когда я делал тоже самое в проекте с аси плагином, то всё было окей. как можно это исправить?
хук я ставлю в DLL_PROCESS_ATTACH, а снимаю в DLL_PROCESS_DETACH.