-
-
Save VanillaMaster/74392111ffcdb5c31a2b005610c2e7e9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "commons.h" | |
#include "hook.h" | |
#include "include/capi/cef_app_capi.h" | |
#include "include/capi/cef_client_capi.h" | |
#include "include/capi/cef_browser_capi.h" | |
#include "include/internal/cef_types.h" | |
#include "include/capi/cef_scheme_capi.h" | |
// BROWSER PROCESS ONLY. | |
HWND rclient_; | |
int main_browser_id_; | |
extern int remote_debugging_port_; | |
void OpenDevTools(cef_browser_t *browser); | |
void OpenRemoteDevTools(); | |
void PrepareRemoteDevTools(); | |
void RegisterAssetsSchemeHandlerFactory(); | |
void RegisterRiotClientSchemeHandlerFactory(); | |
void SetRiotClientCredentials(const wstr &appPort, const wstr &authToken); | |
static void SetUpBrowserWindow(cef_browser_t *browser) | |
{ | |
if (rclient_ != nullptr) return; | |
main_browser_id_ = browser->get_identifier(browser); | |
auto host = browser->get_host(browser); | |
// Get needed windows. | |
HWND browserWin = host->get_window_handle(host); | |
HWND rclient = (rclient_ = GetParent(browserWin)); | |
HWND widgetWin = FindWindowExA(browserWin, NULL, "Chrome_WidgetWin_0", NULL); | |
//HWND widgetHost = FindWindowExA(widgetWin, NULL, "Chrome_RenderWidgetHostHWND", NULL); | |
// Ensure transparency effect. | |
// Hide Chrome_RenderWidgetHostHWND. | |
//ShowWindow(widgetHost, SW_HIDE); | |
// Hide CefBrowserWindow. | |
ShowWindow(browserWin, SW_HIDE); | |
// Bring Chrome_WidgetWin_0 into top-level children. | |
SetParent(widgetWin, rclient); | |
// Send RCLIENT HWND to renderer. | |
auto frame = browser->get_main_frame(browser); | |
auto msg = cef_process_message_create(&u"__rclient"_s); | |
auto args = msg->get_argument_list(msg); | |
args->set_int(args, 0, (int32_t)reinterpret_cast<intptr_t>(rclient)); | |
frame->send_process_message(frame, PID_RENDERER, msg); | |
args->base.release(&args->base); | |
host->base.release(&host->base); | |
void EnableWindowShadow(HWND); | |
EnableWindowShadow(rclient); | |
PrepareRemoteDevTools(); | |
} | |
static decltype(cef_life_span_handler_t::on_after_created) OnAfterCreated; | |
static void CEF_CALLBACK Hooked_OnAfterCreated(struct _cef_life_span_handler_t* self, | |
struct _cef_browser_t* browser) | |
{ | |
OnAfterCreated(self, browser); | |
SetUpBrowserWindow(browser); | |
} | |
static void HookMainBrowserClient(cef_client_t *client) | |
{ | |
void HookKeyboardHandler(cef_client_t *client); | |
HookKeyboardHandler(client); | |
// Hook LifeSpanHandler. | |
static auto GetLifeSpanHandler = client->get_life_span_handler; | |
// Don't worry about calling convention here (stdcall). | |
client->get_life_span_handler = [](struct _cef_client_t* self) -> cef_life_span_handler_t* | |
{ | |
auto handler = GetLifeSpanHandler(self); | |
// Hook OnAfterCreated(). | |
OnAfterCreated = handler->on_after_created; | |
handler->on_after_created = Hooked_OnAfterCreated; | |
return handler; | |
}; | |
static auto OnProcessMessageReceived = client->on_process_message_received; | |
client->on_process_message_received = [](struct _cef_client_t* self, | |
struct _cef_browser_t* browser, | |
struct _cef_frame_t* frame, | |
cef_process_id_t source_process, | |
struct _cef_process_message_t* message) | |
{ | |
if (source_process == PID_RENDERER) | |
{ | |
CefScopedStr name = message->get_name(message); | |
if (name.equal(L"__open_devtools")) | |
OpenDevTools(browser); | |
else if (name.equal(L"__open_remote_devtools")) | |
OpenRemoteDevTools(); | |
else if (name.equal(L"__reload_client")) | |
browser->reload_ignore_cache(browser); | |
} | |
return OnProcessMessageReceived(self, browser, frame, source_process, message); | |
}; | |
} | |
static hook::Hook<decltype(&cef_browser_host_create_browser)> CefBrowserHost_CreateBrowser; | |
static int Hooked_CefBrowserHost_CreateBrowser( | |
const cef_window_info_t* windowInfo, | |
struct _cef_client_t* client, | |
const cef_string_t* url, | |
const struct _cef_browser_settings_t* settings, | |
struct _cef_dictionary_value_t* extra_info, | |
struct _cef_request_context_t* request_context) | |
{ | |
// Hook main browser only. | |
if (CefStr::borrow(url).search(L"^https:\\/\\/riot:.+\\/bootstrap\\.html", true)) | |
{ | |
#if _DEBUG | |
wprintf(L"main browser: %.*s\n", (int)url->length, url->str); | |
#endif | |
// Create extra info if null. | |
if (extra_info == nullptr) | |
extra_info = cef_dictionary_value_create(); | |
// Set as main browser. | |
extra_info->set_null(extra_info, &u"is_main"_s); | |
// Hook client. | |
HookMainBrowserClient(client); | |
} | |
return CefBrowserHost_CreateBrowser(windowInfo, client, url, settings, extra_info, nullptr); | |
} | |
static decltype(cef_app_t::on_before_command_line_processing) OnBeforeCommandLineProcessing; | |
static void CEF_CALLBACK Hooked_OnBeforeCommandLineProcessing( | |
struct _cef_app_t* self, | |
const cef_string_t* process_type, | |
struct _cef_command_line_t* command_line) | |
{ | |
CefScopedStr rc_port = command_line->get_switch_value(command_line, &u"riotclient-app-port"_s); | |
CefScopedStr rc_token = command_line->get_switch_value(command_line, &u"riotclient-auth-token"_s); | |
SetRiotClientCredentials(rc_port.cstr(), rc_token.cstr()); | |
// Extract args string. | |
auto args = CefScopedStr(command_line->get_command_line_string(command_line)).cstr(); | |
if (config::options::AllowProxyServer()) | |
{ | |
size_t pos = args.find(L"--no-proxy-server"); | |
if (pos != std::wstring::npos) | |
args.replace(pos, 17, L""); | |
} | |
// Rebuild it. | |
command_line->reset(command_line); | |
command_line->init_from_string(command_line, &CefStr(args)); | |
OnBeforeCommandLineProcessing(self, process_type, command_line); | |
if (remote_debugging_port_ = config::options::RemoteDebuggingPort()) | |
{ | |
// Set remote debugging port. | |
command_line->append_switch_with_value(command_line, | |
&u"remote-debugging-port"_s, &CefStr(std::to_string(remote_debugging_port_))); | |
} | |
if (config::options::DisableWebSecurity()) | |
{ | |
// Disable web security. | |
command_line->append_switch(command_line, &u"disable-web-security"_s); | |
} | |
if (config::options::IgnoreCertificateErrors()) | |
{ | |
// Ignore invalid certs. | |
command_line->append_switch(command_line, &u"ignore-certificate-errors"_s); | |
} | |
if (config::options::OptimizeClient()) | |
{ | |
// Optimize Client. | |
command_line->append_switch(command_line, &u"disable-async-dns"_s); | |
command_line->append_switch(command_line, &u"disable-plugins"_s); | |
command_line->append_switch(command_line, &u"disable-extensions"_s); | |
command_line->append_switch(command_line, &u"disable-background-networking"_s); | |
command_line->append_switch(command_line, &u"disable-background-timer-throttling"_s); | |
command_line->append_switch(command_line, &u"disable-backgrounding-occluded-windows"_s); | |
command_line->append_switch(command_line, &u"disable-renderer-backgrounding"_s); | |
command_line->append_switch(command_line, &u"disable-metrics"_s); | |
command_line->append_switch(command_line, &u"disable-component-update"_s); | |
command_line->append_switch(command_line, &u"disable-domain-reliability"_s); | |
command_line->append_switch(command_line, &u"disable-translate"_s); | |
command_line->append_switch(command_line, &u"disable-gpu-watchdog"_s); | |
command_line->append_switch(command_line, &u"disable-renderer-accessibility"_s); | |
command_line->append_switch(command_line, &u"enable-parallel-downloading"_s); | |
command_line->append_switch(command_line, &u"enable-new-download-backend"_s); | |
command_line->append_switch(command_line, &u"enable-quic"_s); | |
command_line->append_switch(command_line, &u"no-pings"_s); | |
command_line->append_switch(command_line, &u"no-sandbox"_s); | |
} | |
if (config::options::SuperLowSpecMode()) | |
{ | |
// Super Low Spec Mode. | |
command_line->append_switch(command_line, &u"disable-smooth-scrolling"_s); | |
command_line->append_switch(command_line, &u"wm-window-animations-disabled"_s); | |
command_line->append_switch_with_value(command_line, &u"animation-duration-scale"_s, &u"0"_s); | |
} | |
} | |
static int CEF_CALLBACK resource_handler_process_request(cef_resource_handler_t* self, cef_request_t* request, cef_callback_t* callback) { | |
return 1; | |
} | |
static cef_resource_handler_t* CEF_CALLBACK scheme_handler_factory_create(cef_scheme_handler_factory_t* self, cef_browser_t* browser, cef_frame_t* frame, const cef_string_t* scheme_name, cef_request_t* request) { | |
cef_resource_handler_t* handler = new cef_resource_handler_t; | |
handler->base.size = sizeof(*handler); | |
handler->process_request = resource_handler_process_request; | |
return handler; | |
} | |
static cef_scheme_handler_factory_t scheme_handler_factory; | |
static hook::Hook<decltype(&cef_initialize)> CefInitialize; | |
static int Hooked_CefInitialize(const struct _cef_main_args_t* args, | |
const struct _cef_settings_t* settings, cef_app_t* app, void* windows_sandbox_info) | |
{ | |
scheme_handler_factory.base.size = sizeof(scheme_handler_factory); | |
scheme_handler_factory.create = scheme_handler_factory_create; | |
// Hook command line. | |
OnBeforeCommandLineProcessing = app->on_before_command_line_processing; | |
app->on_before_command_line_processing = Hooked_OnBeforeCommandLineProcessing; | |
const_cast<cef_settings_t *>(settings)->cache_path = CefStr(config::cacheDir().wstring()).forward(); | |
static auto on_register_custom_schemes = app->on_register_custom_schemes; | |
app->on_register_custom_schemes = [](cef_app_t* self, cef_scheme_registrar_t* registrar) { | |
registrar->add_custom_scheme(registrar, &u"pengu"_s, CEF_SCHEME_OPTION_STANDARD | CEF_SCHEME_OPTION_SECURE | CEF_SCHEME_OPTION_CORS_ENABLED); | |
on_register_custom_schemes(self, registrar); | |
}; | |
static auto GetBrowserProcessHandler = app->get_browser_process_handler; | |
app->get_browser_process_handler = [](cef_app_t *self) | |
{ | |
auto handler = GetBrowserProcessHandler(self); | |
static auto OnContextIntialized = handler->on_context_initialized; | |
handler->on_context_initialized = [](cef_browser_process_handler_t *self) | |
{ | |
RegisterAssetsSchemeHandlerFactory(); | |
RegisterRiotClientSchemeHandlerFactory(); | |
cef_register_scheme_handler_factory(&u"pengu"_s, NULL, &scheme_handler_factory); | |
OnContextIntialized(self); | |
}; | |
return handler; | |
}; | |
return CefInitialize(args, settings, app, windows_sandbox_info); | |
} | |
void HookBrowserProcess() | |
{ | |
// Open console window. | |
#if _DEBUG | |
AllocConsole(); | |
SetConsoleTitleA("League Client (browser process)"); | |
freopen("CONOUT$", "w", stdout); | |
#endif | |
// Hook CefInitialize(). | |
CefInitialize.hook("libcef.dll", "cef_initialize", Hooked_CefInitialize); | |
// Hook CefBrowserHost::CreateBrowser(). | |
CefBrowserHost_CreateBrowser.hook("libcef.dll", "cef_browser_host_create_browser", Hooked_CefBrowserHost_CreateBrowser); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment