Смена заголовка окна на имя игрока Interlude

BIT_hack

Знающий
Местный
Сообщения
302
Розыгрыши
0
Решения
5
Репутация
211
Реакции
229
Баллы
485

Модификация заголовка окна на имя выбранного игрока+оптимизация производительности

Основные функции:

  1. Подмена заголовка окна – заголовок окна меняется на имя игрока и остается таким в не зависимости фокусе окно или нет.
  2. Оптимизация фонового режима – предотвращает подвисания при сворачивании разворачивание игры (снижает лаги при ALT+TAB).

Как это работает?

  • HookedSetText – перехватывает системный вызов изменения заголовка окна и заменяет его на имя игрока.
  • OptimizeBackgroundSleep – модифицирует функцию appSleep в движке, уменьшая нагрузку в фоне.
  • UpdatePlayerTitle – вызывается из скрипта игры и передает никнейм в DLL меня заголовок окна.
DLL C++:
Скомпилируйте файл и назовите его entry.dll. Поместите его в папку с игрой.​
C++:
#include "pch.h"
#include <Windows.h>
#include <iostream>

// Структуры для Unreal Engine
class UObject {};
struct FFrame { int* ftable; void* Node; UObject* Object; BYTE* Code; BYTE* Locals; INT LineNum; };

// Глобальные переменные
std::wstring WindowTitle = L" ▄▀▄ BITHACK 🚀 ➤ Boosty: boosty.to/hobbycode ➤ YouTube: @bithack5612 🚀";
HWND TargetWindow = nullptr;

// Типы функций
using NativeFunction = void(__stdcall*)(FFrame&, void* const);
using RegisterNativeFn = BYTE(__cdecl*)(int, const NativeFunction&);
using SetTextFn = void(__thiscall*)(void*, const wchar_t*);

// Оригинальная функция и хук
SetTextFn OriginalSetText = nullptr;

// Поиск главного окна
HWND FindMainWindow() {
    HWND window = nullptr;
    EnumWindows([](HWND hwnd, LPARAM param) -> BOOL {
        DWORD pid;
        GetWindowThreadProcessId(hwnd, &pid);
        if (pid == GetCurrentProcessId() && IsWindowVisible(hwnd)) {
            *(HWND*)param = hwnd;
            return FALSE;
        }
        return TRUE;
        }, (LPARAM)&window);
    return window;
}

// Обновление заголовка окна
void UpdateTitle() {
    if (WindowTitle.empty() || !(TargetWindow = FindMainWindow())) return;

    for (int i = 0; i < 3; i++) {
        SetWindowTextW(TargetWindow, WindowTitle.c_str());
        Sleep(50);
    }
}

// Хук для SetText
void __fastcall HookedSetText(void* thisptr, void*, const wchar_t* text) {
    TargetWindow = *(HWND*)((DWORD)thisptr + 4);
    SetWindowTextW(TargetWindow, WindowTitle.c_str());
}

// Установка хука
bool InstallHook() {
    HMODULE windowDll = GetModuleHandleW(L"Window.dll");
    if (!windowDll) return false;

    OriginalSetText = (SetTextFn)GetProcAddress(windowDll, "?SetText@WWindow@@UAEXPBG@Z");
    if (!OriginalSetText) return false;

    DWORD oldProtect;
    VirtualProtect(OriginalSetText, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
    *(BYTE*)OriginalSetText = 0xE9;
    *(DWORD*)((DWORD)OriginalSetText + 1) = (DWORD)HookedSetText - ((DWORD)OriginalSetText + 5);
    VirtualProtect(OriginalSetText, 5, oldProtect, &oldProtect);
    return true;
}

// Функция, вызываемая из игры
void __stdcall UpdatePlayerTitle(FFrame& stack, void* result) {
    stack.Code++;
    WindowTitle = *(const wchar_t**)result;
    UpdateTitle();
    CreateThread(nullptr, 0, [](LPVOID) -> DWORD {
        Sleep(500);
        UpdateTitle();
        return 0;
        }, nullptr, 0, nullptr);
}

// Оптимизация нагрузки в фоновом режиме
static float __cdecl OptimizeBackgroundSleep() {
    return .1f;
}

// Регистрация функции в движке
void RegisterNative() {
    if (HMODULE core = GetModuleHandleA("Core.dll")) {
        if (auto registerFn = (RegisterNativeFn)GetProcAddress(core, "?GRegisterNative@@YAEHABQ8UObject@@AEXAAUFFrame@@QAX@Z@Z")) {
            registerFn(2025, &UpdatePlayerTitle);
        }

        if (BYTE* LazyMode = (BYTE*)GetProcAddress(core, "?appSleep@@YAXM@Z")) {
            DWORD oldProtect;
            if (VirtualProtect(LazyMode, 5, PAGE_READWRITE, &oldProtect)) {
                *LazyMode = 0xE9;
                *(int*)(LazyMode + 1) = (BYTE*)OptimizeBackgroundSleep - (LazyMode + 5);
                VirtualProtect(LazyMode, 5, oldProtect, &oldProtect);
            }
        }
    }
}

// Точка входа DLL
BOOL APIENTRY DllMain(HMODULE, DWORD reason, LPVOID) {
    if (reason == DLL_PROCESS_ATTACH) {
        CreateThread(nullptr, 0, [](LPVOID) -> DWORD {
            Sleep(1000);
            InstallHook();
            RegisterNative();
            return 0;
            }, nullptr, 0, nullptr);
    }
    return TRUE;
}

Взаимодействие с игрой:
Игровой скрипт вызывает нативную функцию. Этот код можно добавить в любой скрипт окна игры.​
C++:
native(2025) final function string L2Title();

function PadTitleDll(string TitleExt) {
    TitleExt = L2Title();  // Передает имя игрока в заголовок окна через DLL
}

// При отображении UI передает имя игрока
function OnShow()
{
    local UserInfo Info;
    GetPlayerInfo(Info);
    PadTitleDll(Info.name);  // Меняет заголовок окна на имя игрока
}
 
Последнее редактирование:
Thanks for the code.

Do you know the login ID and password for the login screen to make an AAC style "hook"?
 
Также это возможно сделать и для HF.
Хотите что-то подобное? Пишите в личные сообщения. Обсудим детали!
Вывод любой информации из клиента в dll и обратно!
 

Вложения

  • L2TitleHF.webp
    253,7 КБ · Просмотры: 56
интересный вариант.. а я на hf и ertheia из пакета ник брал
 
Nice! Great work, it's interesting. Changing the icon would be nice too, haha.
 
Данный сайт использует cookie. Вы должны принять их для продолжения использования. Узнать больше…