Другое С/С++ Вопрос - Ответ

kin4stat

mq-team · kin4@naebalovo.team
Всефорумный модератор
2,744
4,808
пкм по названию проекту - настройки. выбираешь установленый тулсет (у меня это v141), применяешь настройки. после чего выбираешь версию winsdk (у меня это 10.0.17763.0), применяешь настройки.
ПКМ по решению -> перенацелить решение
MTA-стайл - асм вместо тайпдефа
А зачем...
Ассемблером выебнуться типа?
 
  • Нравится
Реакции: sc6ut

sc6ut

неизвестный
Модератор
382
1,089
Тим, напиши пожалуйста как можно заменить эти 11 строк твоими 2
C++:
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);
}
11 строк вместо 2х
почему 2? можно и 1 😀
 
Последнее редактирование:
  • Нравится
Реакции: Vintik и bottom_text

Sana_Minotazaki

Известный
75
2
Почему не работает? Вроде же все норм делаю или нет? Когда нажимаю H игра просто виснет @SC6UT @KiN4StAt help pls
вот это:
#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;
}
 
Последнее редактирование:

sc6ut

неизвестный
Модератор
382
1,089
игра просто виснет
нельзя делать 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;
}
 
Последнее редактирование:

Sana_Minotazaki

Известный
75
2
нельзя делать 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;
}
Игра уже не виснет, но команда отправляется только тогда когда я жму H а не циклически как хотелось
 

sc6ut

неизвестный
Модератор
382
1,089
Игра уже не виснет, но команда отправляется только тогда когда я жму H а не циклически как хотелось
команда отправляется каждые 2.5 секунды, можешь проверить это добавлением логгированием в месте отправления команды
1610554444624.png

решил добавить фикс краша по адрессу 0x0072CD14 в сф плагин. заметил, что при отгрузке плагина через pfree или просто выходе из игры, то функция хука пропадает быстрее, чем сам хук снимается и игра крашится. когда я делал тоже самое в проекте с аси плагином, то всё было окей. как можно это исправить?
хук я ставлю в DLL_PROCESS_ATTACH, а снимаю в DLL_PROCESS_DETACH.
 

SR_team

like pancake
BH Team
4,801
6,472
решил добавить фикс краша по адрессу 0x0072CD14 в сф плагин. заметил, что при отгрузке плагина через pfree или просто выходе из игры, то функция хука пропадает быстрее, чем сам хук снимается и игра крашится. когда я делал тоже самое в проекте с аси плагином, то всё было окей. как можно это исправить?
хук я ставлю в DLL_PROCESS_ATTACH, а снимаю в DLL_PROCESS_DETACH.
У SF плагинов есть специальный коллбек, который выполняется перед выгрузкой
 
  • Нравится
Реакции: sc6ut