Плохой рендер CEF

nonelike

Известный
Автор темы
51
2
plugin.hpp:
#ifndef PLUGIN_HPP
#define PLUGIN_HPP

#include <windows.h>

#include <kthook/kthook.hpp>
#include <RakHook/rakhook.hpp>

#include "overlay.hpp"

using namespace std::placeholders;


class c_plugin {

public:
    c_plugin() = default;
    ~c_plugin() { rakhook::destroy(); render::destroy(); overlay::destroy(); };

    kthook::kthook_simple<void(__cdecl*)()> update_hook { reinterpret_cast<void*>(0x561B10), std::bind(&c_plugin::update_hooked, this, _1) };
    void update_hooked(const decltype(update_hook)& hook);

    kthook::kthook_simple<HRESULT(__stdcall*)(HWND, UINT, WPARAM, LPARAM)> wnd_proc_hook{ reinterpret_cast<void*>(0x747EB0), std::bind(&c_plugin::wnd_proc_hooked, this, _1, _2, _3, _4, _5) };
    HRESULT wnd_proc_hooked(const decltype(wnd_proc_hook)& hook, HWND hwnd, UINT umsg, WPARAM wp, LPARAM lp);
};


#endif // PLUGIN_HPP
overlay.hpp:
#ifndef OVERLAY_HPP
#define OVERLAY_HPP

#include <filesystem>

#include "include/cef_app.h"
#include "render.hpp"


class c_overlay : public CefClient, public CefRenderHandler, public CefLifeSpanHandler {

public:
    c_overlay() = default;
    ~c_overlay() = default;

    virtual CefRefPtr<CefRenderHandler> GetRenderHandler() override { return this; };
    virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() override { return this; }

    virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) override { this->browser = browser; }
 
    void OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList& dirty_rects, const void* buffer, int width, int height) override;
    void GetViewRect(CefRefPtr<CefBrowser> browser, CefRect& rect) override { rect = CefRect(0, 0, 840, 660); };
 
    CefRefPtr<CefBrowser> GetBrowser() { return this->browser; };

private:
    CefRefPtr<CefBrowser> browser;

    IMPLEMENT_REFCOUNTING(c_overlay);
    DISALLOW_COPY_AND_ASSIGN(c_overlay);
};


namespace overlay {
    inline static c_overlay* cef;

    inline LPDIRECT3DTEXTURE9 texture;

    void initialize();
 
    void create_browser(std::string url = "https://url.com");
    bool wnd_proc(HWND hwnd, UINT umsg, WPARAM wp, LPARAM lp);

    void destroy();
}


#endif // !OVERLAY_HPP
plugin.cpp:
#include "plugin.hpp"


void c_plugin::update_hooked(const decltype(update_hook)& hook) {
    static bool inited = false;

    if (!inited && c_chat().reference() && rakhook::initialize()) {
        inited = true;
     
        overlay::initialize();
        render::initialize();
     
        render::on_present += []() {
            if (!overlay::texture || !render::device)
                return;

            render::device->SetTexture(0, overlay::texture);
            render::device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
            render::device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
            render::device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
            render::device->SetRenderState(D3DRS_LIGHTING, FALSE);

            struct CUSTOMVERTEX {
                FLOAT x, y, z, rhw;
                FLOAT u, v;
            };

            CUSTOMVERTEX vertices[] = {
                { 0.0f,   0.0f,   0.0f, 1.0f, 0.0f, 0.0f },
                { 840.0f, 0.0f,   0.0f, 1.0f, 1.0f, 0.0f },
                { 0.0f,   660.0f, 0.0f, 1.0f, 0.0f, 1.0f },
                { 840.0f, 660.0f, 0.0f, 1.0f, 1.0f, 1.0f }
            };

            render::device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
            render::device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertices, sizeof(CUSTOMVERTEX));
        };
    }
    return hook.call_trampoline();
}


HRESULT c_plugin::wnd_proc_hooked(const decltype(wnd_proc_hook)& hook, HWND hwnd, UINT umsg, WPARAM wp, LPARAM lp) {
    overlay::wnd_proc(hwnd, umsg, wp, lp);

    return hook.call_trampoline(hwnd, umsg, wp, lp);
}

overlay.cpp:
#include "overlay.hpp"


void c_overlay::OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList& dirty_rects, const void* buffer, int width, int height) {
    if (!overlay::texture)
        D3DXCreateTexture(render::device, width, height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &overlay::texture);

    D3DLOCKED_RECT locked_rect;
 
    overlay::texture->LockRect(0, &locked_rect, nullptr, 0);
    memcpy(locked_rect.pBits, buffer, width * height * 4);

    overlay::texture->UnlockRect(0);
}


void overlay::create_browser(std::string url) {
    CefWindowInfo window_info;
    CefBrowserSettings browser_settings;

    window_info.SetAsWindowless(nullptr);
 
    CefBrowserHost::CreateBrowser(window_info, cef, url.c_str(), browser_settings, nullptr, nullptr);
}


void overlay::initialize() {
    cef = new c_overlay();
 
    std::string work_path = std::filesystem::current_path().string();
    std::filesystem::create_directories(work_path + "\\cache");

    CefSettings settings;
 
    CefString(&settings.browser_subprocess_path).FromASCII(std::string(work_path + "\\cef-sub-process.exe").c_str());
    CefString(&settings.log_file) = work_path + "\\cef-log.log";
    CefString(&settings.cache_path).FromASCII(std::string(work_path + "\\cache").c_str());
    CefString(&settings.locales_dir_path).FromASCII(std::string(work_path + "\\locales").c_str());
    CefString(&settings.resources_dir_path) = work_path;
    CefString(&settings.locale).FromASCII("ru");
    CefString(&settings.accept_language_list).FromASCII("en-US,en,ru-RU,ru");

    settings.no_sandbox = 1;
    settings.multi_threaded_message_loop = 1;
    settings.windowless_rendering_enabled = 1;

    settings.background_color = 0;
    settings.log_severity = LOGSEVERITY_DEBUG;
    settings.command_line_args_disabled = 1;

    CefMainArgs main_args;

    CefInitialize(main_args, settings, nullptr, nullptr);
 
    create_browser();
}


bool overlay::wnd_proc(HWND hwnd, UINT umsg, WPARAM wp, LPARAM lp) {
    if (cef && cef->GetBrowser()) {
        CefRefPtr<CefBrowserHost> host = cef->GetBrowser()->GetHost();

        if (umsg >= WM_MOUSEMOVE && umsg <= WM_MBUTTONUP || umsg == WM_MOUSEWHEEL) {
            POINT point = { LOWORD(lp), HIWORD(lp) };
            ScreenToClient(hwnd, &point);

            CefMouseEvent mouse_event;
         
            mouse_event.x = point.x;
            mouse_event.y = point.y;
            mouse_event.modifiers = 0;

            switch (umsg) {
                case WM_LBUTTONDOWN: host->SendMouseClickEvent(mouse_event, MBT_LEFT, false, 1); break;
                case WM_LBUTTONUP:   host->SendMouseClickEvent(mouse_event, MBT_LEFT, true, 1); break;
                case WM_RBUTTONDOWN: host->SendMouseClickEvent(mouse_event, MBT_RIGHT, false, 1); break;
                case WM_RBUTTONUP:   host->SendMouseClickEvent(mouse_event, MBT_RIGHT, true, 1); break;
                case WM_MBUTTONDOWN: host->SendMouseClickEvent(mouse_event, MBT_MIDDLE, false, 1); break;
                case WM_MBUTTONUP:   host->SendMouseClickEvent(mouse_event, MBT_MIDDLE, true, 1); break;
                case WM_MOUSEWHEEL: {
                    int delta = GET_WHEEL_DELTA_WPARAM(wp);
                    host->SendMouseWheelEvent(mouse_event, 0, delta);
                    break;
                }
                default: {
                    host->SendMouseMoveEvent(mouse_event, false);
                    break;
                }
            }
            return true;
        }

        if (umsg >= WM_KEYDOWN && umsg <= WM_CHAR) {
            int keycode = static_cast<int>(wp);
            int modifiers = 0;

            if (GetKeyState(VK_SHIFT) & 0x8000) modifiers |= EVENTFLAG_SHIFT_DOWN;
            if (GetKeyState(VK_CONTROL) & 0x8000) modifiers |= EVENTFLAG_CONTROL_DOWN;
            if (GetKeyState(VK_MENU) & 0x8000) modifiers |= EVENTFLAG_ALT_DOWN;

            CefKeyEvent event;
         
            event.windows_key_code = keycode;
            event.native_key_code = static_cast<int>(lp);
            event.modifiers = modifiers;

            if (umsg == WM_KEYDOWN || umsg == WM_SYSKEYDOWN) { event.type = KEYEVENT_RAWKEYDOWN; }
            else if (umsg == WM_KEYUP || umsg == WM_SYSKEYUP) { event.type = KEYEVENT_KEYUP; }
            else if (umsg == WM_CHAR) { event.type = KEYEVENT_CHAR; }

            host->SendKeyEvent(event);

            return true;
        }
    }
    return false;
}


void overlay::destroy() {
    CefShutdown();
 
    if (texture)
        texture->Release();
 
    delete cef;
}

main.cpp:
#include "plugin.hpp"

c_plugin* plugin;


int __stdcall DllMain(HMODULE instance, DWORD call_reason, LPVOID reserved) {

    if (call_reason == DLL_PROCESS_ATTACH) {
        DisableThreadLibraryCalls(instance);

        plugin = new c_plugin();
    }
    else if (call_reason == DLL_PROCESS_DETACH)
        delete plugin;

    return TRUE;
}

render.hpp:
#ifndef RENDER_HPP
#define RENDER_HPP

#include <imgui_impl_dx9.h>
#include <imgui_impl_win32.h>
#include <imgui_internal.h>

#include <d3d9.h>
#include <d3dx9.h>

#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")

#include "kthook/kthook.hpp"

#include "samp.hpp"


namespace render {
    template <typename T>
    struct on_event : public std::vector<std::function<T>> {
        on_event& operator+=(std::function<T> func) {
            this->push_back(func);
            return *this;
        }
    };
    inline on_event<void()> on_present;

    inline bool initialized = false;

    inline IDirect3DDevice9* device;

    void initialize();
    void destroy();
}

#endif // !RENDER_HPP

render.cpp:
#include "render.hpp"
#include "overlay.hpp"

kthook::kthook_signal<HRESULT(__stdcall*)(IDirect3DDevice9*, const RECT*, const RECT*, HWND, const RGNDATA*)> present_hook;
kthook::kthook_signal<HRESULT(__stdcall*)(IDirect3DDevice9*, D3DPRESENT_PARAMETERS*)> reset_hook;


std::optional<HRESULT> d3d9_present_hooked(const decltype(present_hook)& hook, IDirect3DDevice9* device, CONST RECT* src_rect, CONST RECT* dest_rect, HWND dest_window, CONST RGNDATA* dirty_region) {
    if (!render::initialized) {
        render::device = device;
        render::initialized = true;
    }
    else {
        for (auto& f : render::on_present) {
            if (f) f();
        }
    }
    return std::nullopt;
}


std::optional<HRESULT> d3d9_lost_hooked(const decltype(reset_hook)& hook, LPDIRECT3DDEVICE9 device, D3DPRESENT_PARAMETERS* present_params) {
    return std::nullopt;
}


uintptr_t find_device(uint32_t length) {
    static uintptr_t base = [](size_t length) {
        std::string path(MAX_PATH, '\0');

        if (auto size = GetSystemDirectoryA(path.data(), MAX_PATH)) {
            path.resize(size);
            path += "\\d3d9.dll";

            uintptr_t object_base = reinterpret_cast<uintptr_t>(LoadLibraryA(path.c_str()));

            while (object_base++ < object_base + length) {
                if (*reinterpret_cast<uint16_t*>(object_base + 0x00) == 0x06C7 && *reinterpret_cast<uint16_t*>(object_base + 0x06) == 0x8689 && *reinterpret_cast<uint16_t*>(object_base + 0x0C) == 0x8689) {
                    object_base += 2;

                    break;
                }
            }
            return object_base;
        }
        return uintptr_t(0);
    }(length);

    return base;
}


void* get_function_address(int virtual_table_index) {
    return (*reinterpret_cast<void***>(find_device(0x128000)))[virtual_table_index];
}


void render::initialize() {
    present_hook.set_dest(get_function_address(17));
    present_hook.install();
 
    reset_hook.set_dest(get_function_address(16));
    reset_hook.install();

    present_hook.before.connect(&d3d9_present_hooked);
    reset_hook.before.connect(&d3d9_lost_hooked);
}


void render::destroy() {
}

Увидел как-то на форуме CEF который отрисовывается на imgui, решил переделать в отрисовку через directx9, но плохо рендерится(текст, мыло и все пикселится, появляется черная обводка которой нет) и ломает ESC.
 

Вложения

  • sa-mp-010.png
    sa-mp-010.png
    71.6 KB · Просмотры: 71
  • sa-mp-009.png
    sa-mp-009.png
    1.2 MB · Просмотры: 70

vmprotect

Известный
386
247
насчет фикса рендеринга

в overlay.hpp ты указываешь размер

Код:
void GetViewRect(CefRefPtr<CefBrowser> browser, CefRect& rect) override { rect = CefRect(0, 0, 1920, 1080); }; /* на месте 1920, 1080 указывать свое разрешение

ваще можно через imgui получать твое текущее разрешение, и туда вписывать
 

nonelike

Известный
Автор темы
51
2
насчет фикса рендеринга

в overlay.hpp ты указываешь размер

Код:
void GetViewRect(CefRefPtr<CefBrowser> browser, CefRect& rect) override { rect = CefRect(0, 0, 1920, 1080); }; /* на месте 1920, 1080 указывать свое разрешение

ваще можно через imgui получать твое текущее разрешение, и туда вписывать
ну я ща в GetViewRect поменял на свое разрешение монитора, и в вершинах тоже, но чето рендеру все равно плохо
 

Вложения

  • sa-mp-012.png
    sa-mp-012.png
    1.7 MB · Просмотры: 69
Последнее редактирование: