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

sc6ut

неизвестный
Модератор
382
1,089
специальный коллбек
не нахожу, можешь ткнуть пальцем пожалуйста

Как мне в сф сделать onServerMessage как в луа?
регистрируешь в mainloop коллбек на приходящие rpc, читаешь данные, взаимодействуешь:
C++:
// регистрируем коллбек в mainloop
SF->getRakNet()->registerRakNetCallback(RAKHOOK_TYPE_INCOMING_RPC, incomingRPC);

bool CALLBACK incomingRPC(stRakNetHookParams* params)
{
    // проверяем что пришло рпц сообщения в чат по id
    if (params->packetId == RPC_ScrClientMessage)
    {
        DWORD color; // цвет
        DWORD length; // длинна сообщения
        char message[256]; // сообщение

        // читаем данные
        params->bitStream->ResetReadPointer();
        params->bitStream->Read(color);
        params->bitStream->Read(length);
        params->bitStream->Read(message, length);
        message[length] = '\0'; // ставим в конце массава NULL чтобы превратить наш массив символов в стринг

        // взаимодействуем
    }
    return true; // возвращаем true чтобы рпц принимались
}
 
  • Нравится
Реакции: frit

ishi

Известный
493
110
Пытаюсь реализовать класс с функцией, способной вызывать другие функции по адресам, но компилятор ругается:
Код:
результатом вычисления фрагмента не является функция, принимающая 4 аргументов
Вот, что я пытался ему впарить:
C++:
class user32
{
    char* base_address;

    template <typename function>
    void call(function func, int a,const char* b, const char* c, long d)
    {
        func(a, b, c, d)();
    }
public:
    user32()
    {
        base_address = (char*)GetModuleHandleA("user32.dll");
    }
    void MessageBoxA(int a, const char* b, const char* c, long d)
    {

        call((base_address + 0x77B30),a,b,c,d);
    }
};

Копаясь в интернете, я понял, что можно как-то сделать, чтобы функция объявлялась как обычная статическая и перекидывала аргументы через fastcall, stdcall и т.д., типа ты её объявил в переменной, но аргументы перекинул как в статическую и всё на ок сработало, но в тех громоздких конструкциях я так и не нашёл минималистичного примера, который смог бы понять. Всё как-то слишком уж перегружено
Отчаянно нуждаюсь в помощи в понимании этого механизма

то, что я уже написал, это попытка сделать прямой вызов MessageBoxA, не используя исходники, но зная оффсет в библиотеке (для чего и нужна эта функция в принципе)
 

memir

🇷🇺
Всефорумный модератор
339
611

Пытаюсь реализовать класс с функцией, способной вызывать другие функции по адресам, но компилятор ругается:
Код:
результатом вычисления фрагмента не является функция, принимающая 4 аргументов
Вот, что я пытался ему впарить:
C++:
class user32
{
    char* base_address;

    template <typename function>
    void call(function func, int a,const char* b, const char* c, long d)
    {
        func(a, b, c, d)();
    }
public:
    user32()
    {
        base_address = (char*)GetModuleHandleA("user32.dll");
    }
    void MessageBoxA(int a, const char* b, const char* c, long d)
    {

        call((base_address + 0x77B30),a,b,c,d);
    }
};

Копаясь в интернете, я понял, что можно как-то сделать, чтобы функция объявлялась как обычная статическая и перекидывала аргументы через fastcall, stdcall и т.д., типа ты её объявил в переменной, но аргументы перекинул как в статическую и всё на ок сработало, но в тех громоздких конструкциях я так и не нашёл минималистичного примера, который смог бы понять. Всё как-то слишком уж перегружено
Отчаянно нуждаюсь в помощи в понимании этого механизма

то, что я уже написал, это попытка сделать прямой вызов MessageBoxA, не используя исходники, но зная оффсет в библиотеке (для чего и нужна эта функция в принципе)
C++:
#include <Windows.h>

class user32
{
    using TypeMessageBoxA = int(__stdcall *)(HWND, LPCSTR, LPCSTR, UINT);
    TypeMessageBoxA messageBoxA;
  
    template <typename F, typename... Args>
    void call(F f, Args... args)
    {
        f(args...);
    }
public:
    user32()
    {
        auto user32Module = LoadLibraryA("user32.dll");
        messageBoxA = reinterpret_cast<TypeMessageBoxA>(
            GetProcAddress(user32Module, "MessageBoxA"));
    }
    void MessageBoxA(HWND a, LPCSTR b, LPCSTR c, UINT d)
    {

        call(messageBoxA, a, b, c, d);
    }
};

int main()
{
    user32 obj;
    obj.MessageBoxA(NULL,
                    "Resource not available\nDo you want to try again?",
                    "Account details",
                    MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2);
    return 0;
}
Компилятор вычисляет тип (base_address + 0x77B30) и получает char *, а затем пытается вызвать его с четырьмя аргументами. Это приводит к ошибке.
Ты должен кастить base_address + 0x77B30, в void(__stdcall *)(int a, const char* b, const char* c, long d) чтобы всё заработало.
А ещё я бы посоветовал заменить a b c d в user32::call на вариативный шаблон с аргументами.
И у тебя скобочки в вызове лишние...
 
  • Нравится
Реакции: 4el0ve4ik и ishi

nomio

Известный
550
208
Охх как я люблю имуги,решил на плюсах пощупать имгуи,вставил рабочий код,имуги в папку с проектом,настройки для компиляции выставил.Компилирую - ошибки.Ставил старые,новые имуги,тыкал все что надо и все что не надо и в итоге пишу сюда

Visual Studio 2019
Imgui последней версии(на 1.63 такая же хуйня)
Найстроки проекта для компиляции стоят нормальные,компилил без имуги и все работало

Ошибки:
Папка с имуги файлами:
Код:

C++:
#define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS 1
#include "main.h"
#include "imgui/imgui.h"
#include "imgui/imgui_impl_dx9.h"
#include "imgui/imgui_impl_win32.h"
#include <d3d9.h>
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
#include <tchar.h>
extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

SAMPFUNCS* SF = new SAMPFUNCS();

void CALLBACK PluginFree()
{
    ImGui_ImplDX9_Shutdown();
    ImGui_ImplWin32_Shutdown();
    ImGui::DestroyContext();
}

bool CALLBACK WndProcHandler(HWND hwd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    ImGui_ImplWin32_WndProcHandler(hwd, msg, wParam, lParam);
    return true;
}

HRESULT CALLBACK Reset(D3DPRESENT_PARAMETERS* pPresentationParameters)
{
    ImGui_ImplDX9_InvalidateDeviceObjects();
    return true;
}

bool CALLBACK Present(CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion)
{
    if (SUCCEEDED(SF->getRender()->BeginRender()))
    {
        static bool menu = true, checkbox;
        ImGui_ImplDX9_NewFrame();
        ImGui_ImplWin32_NewFrame();
        ImGui::NewFrame();
        ImGui::SetNextWindowSize(ImVec2(228, 228));
        ImGui::Begin("123", &menu, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
        {
            ImGui::Checkbox("111", &checkbox);
        }
        ImGui::End();
        ImGui::EndFrame();
        ImGui::Render();
        ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
        SF->getRender()->EndRender();
    }
    return true;
}


void CALLBACK mainloop()
{
    static bool init = false;
    if (!init)
    {
        if (GAME == nullptr)
            return;
        if (GAME->GetSystemState() != eSystemState::GS_PLAYING_GAME)
            return;
        if (!SF->getSAMP()->IsInitialized())
            return;
        ImGui::CreateContext();
        ImGui_ImplWin32_Init(GetActiveWindow());
        ImGui_ImplDX9_Init(SF->getRender()->getD3DDevice());
        SF->getRender()->registerD3DCallback(eDirect3DDeviceMethods::D3DMETHOD_PRESENT, Present);
        SF->getRender()->registerD3DCallback(eDirect3DDeviceMethods::D3DMETHOD_RESET, Reset);
        SF->getGame()->registerWndProcCallback(SFGame::MEDIUM_CB_PRIORITY, WndProcHandler);
        SF->getGame()->registerGameDestructorCallback(PluginFree);
        init = true;
    }
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReasonForCall, LPVOID lpReserved)
{
    if (dwReasonForCall == DLL_PROCESS_ATTACH)
        SF->initPlugin(mainloop, hModule);

    return TRUE;
}
 

Dark_Knight

Me, me and me.
Друг
4,078
2,096
SF->getSAMP()->getMisc()->iCursorMode == true/false
а вообще в большинстве случаев, ответ уже есть на форуме, просто стоит воспользоваться поиском 😉
Никаких тру/фолсе там нет. Учи матчасть.
 
  • Нравится
Реакции: etereon

tinkoir

Участник
97
33
читаю одну книжечку по c++ и вот появился вопрос
в чем выгода работать функциям по адресу структуру, а не по ее значению? использование меньшего количества памяти?
 

SR_team

like pancake
BH Team
4,802
6,472
читаю одну книжечку по c++ и вот появился вопрос
в чем выгода работать функциям по адресу структуру, а не по ее значению? использование меньшего количества памяти?
Копирование 4х байт вместо всей структуры. Это быстрее

Как можно установить trampoline hook в удаленный процесс (gta_sa.exe)?
Так же, как и в своей, но из-за раздельного адресного пространства для обработки в своем процессе надо будет слать сообщения и блокировать работу процесса игры, из-за чего работать она будет медленнее. Если dll не вариант, то лучше все на ассемблере написать
 
  • Нравится
Реакции: tinkoir

#Northn

Pears Project — уже запущен!
Всефорумный модератор
2,650
2,535
Как лучше всего обучиться программированию на Win32 API?
Если такой вопрос задан — прости прощай разработке до тех пор, пока не будут подобные вопросы и будет интерес залезть в поисковики всемирной паутины.
 

checkdasound

Известный
Проверенный
963
410
Есть двумерный вектор, нужно узнать, входит ли в него определенная строка или нет.
C++:
std::string str = "asd";
std::vector<std::vector<std::string>>vec;
В обычном векторе использовал find, думаю, для двумерного тоже надо использовать это, только не могу допереть как именно.