Fix stuff
This commit is contained in:
parent
0fb12bdc32
commit
fbfdc30e25
@ -1,3 +1,3 @@
|
|||||||
@echo off
|
@echo off
|
||||||
git submodule update --init --recursive
|
git submodule update --init --recursive
|
||||||
tools\premake5 %* vs2017
|
tools\premake5 %* vs2019
|
262
premake5.lua
262
premake5.lua
@ -1,131 +1,131 @@
|
|||||||
dependencies = {
|
dependencies = {
|
||||||
basePath = "./deps"
|
basePath = "./deps"
|
||||||
}
|
}
|
||||||
|
|
||||||
function dependencies.load()
|
function dependencies.load()
|
||||||
dir = path.join(dependencies.basePath, "premake/*.lua")
|
dir = path.join(dependencies.basePath, "premake/*.lua")
|
||||||
deps = os.matchfiles(dir)
|
deps = os.matchfiles(dir)
|
||||||
|
|
||||||
for i, dep in pairs(deps) do
|
for i, dep in pairs(deps) do
|
||||||
dep = dep:gsub(".lua", "")
|
dep = dep:gsub(".lua", "")
|
||||||
require(dep)
|
require(dep)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function dependencies.imports()
|
function dependencies.imports()
|
||||||
for i, proj in pairs(dependencies) do
|
for i, proj in pairs(dependencies) do
|
||||||
if type(i) == 'number' then
|
if type(i) == 'number' then
|
||||||
proj.import()
|
proj.import()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function dependencies.projects()
|
function dependencies.projects()
|
||||||
for i, proj in pairs(dependencies) do
|
for i, proj in pairs(dependencies) do
|
||||||
if type(i) == 'number' then
|
if type(i) == 'number' then
|
||||||
proj.project()
|
proj.project()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
newoption {
|
newoption {
|
||||||
trigger = "copy-to",
|
trigger = "copy-to",
|
||||||
description = "Optional, copy the EXE to a custom folder after build, define the path here if wanted.",
|
description = "Optional, copy the EXE to a custom folder after build, define the path here if wanted.",
|
||||||
value = "PATH"
|
value = "PATH"
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies.load()
|
dependencies.load()
|
||||||
|
|
||||||
workspace "open-iw5"
|
workspace "open-iw5"
|
||||||
startproject "open-iw5"
|
startproject "open-iw5"
|
||||||
location "./build"
|
location "./build"
|
||||||
objdir "%{wks.location}/obj"
|
objdir "%{wks.location}/obj"
|
||||||
targetdir "%{wks.location}/bin/%{cfg.platform}/%{cfg.buildcfg}"
|
targetdir "%{wks.location}/bin/%{cfg.platform}/%{cfg.buildcfg}"
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
"Debug",
|
"Debug",
|
||||||
"Release",
|
"Release",
|
||||||
}
|
}
|
||||||
|
|
||||||
architecture "x32"
|
architecture "x32"
|
||||||
platforms "x32"
|
platforms "x32"
|
||||||
|
|
||||||
buildoptions "/std:c++latest"
|
buildoptions "/std:c++latest"
|
||||||
systemversion "latest"
|
systemversion "latest"
|
||||||
symbols "On"
|
symbols "On"
|
||||||
staticruntime "On"
|
staticruntime "On"
|
||||||
editandcontinue "Off"
|
editandcontinue "Off"
|
||||||
warnings "Extra"
|
warnings "Extra"
|
||||||
characterset "ASCII"
|
characterset "ASCII"
|
||||||
toolset "v142"
|
toolset "v142"
|
||||||
|
|
||||||
flags {
|
flags {
|
||||||
"NoIncrementalLink",
|
"NoIncrementalLink",
|
||||||
"NoMinimalRebuild",
|
"NoMinimalRebuild",
|
||||||
"MultiProcessorCompile",
|
"MultiProcessorCompile",
|
||||||
"No64BitChecks"
|
"No64BitChecks"
|
||||||
}
|
}
|
||||||
|
|
||||||
configuration "windows"
|
configuration "windows"
|
||||||
defines {
|
defines {
|
||||||
"_WINDOWS",
|
"_WINDOWS",
|
||||||
"WIN32",
|
"WIN32",
|
||||||
}
|
}
|
||||||
|
|
||||||
configuration "Release"
|
configuration "Release"
|
||||||
optimize "Full"
|
optimize "Full"
|
||||||
|
|
||||||
defines {
|
defines {
|
||||||
"NDEBUG",
|
"NDEBUG",
|
||||||
}
|
}
|
||||||
|
|
||||||
flags {
|
flags {
|
||||||
"FatalCompileWarnings",
|
"FatalCompileWarnings",
|
||||||
}
|
}
|
||||||
|
|
||||||
configuration "Debug"
|
configuration "Debug"
|
||||||
optimize "Debug"
|
optimize "Debug"
|
||||||
|
|
||||||
defines {
|
defines {
|
||||||
"DEBUG",
|
"DEBUG",
|
||||||
"_DEBUG",
|
"_DEBUG",
|
||||||
}
|
}
|
||||||
|
|
||||||
configuration {}
|
configuration {}
|
||||||
|
|
||||||
project "open-iw5"
|
project "open-iw5"
|
||||||
kind "ConsoleApp"
|
kind "ConsoleApp"
|
||||||
language "C++"
|
language "C++"
|
||||||
|
|
||||||
pchheader "std_include.hpp"
|
pchheader "std_include.hpp"
|
||||||
pchsource "src/std_include.cpp"
|
pchsource "src/std_include.cpp"
|
||||||
|
|
||||||
linkoptions "/IGNORE:4254 /DYNAMICBASE:NO /SAFESEH:NO /LARGEADDRESSAWARE"
|
linkoptions "/IGNORE:4254 /DYNAMICBASE:NO /SAFESEH:NO /LARGEADDRESSAWARE"
|
||||||
linkoptions "/LAST:.main"
|
linkoptions "/LAST:.main"
|
||||||
|
|
||||||
|
|
||||||
files {
|
files {
|
||||||
"./src/**.rc",
|
"./src/**.rc",
|
||||||
"./src/**.hpp",
|
"./src/**.hpp",
|
||||||
"./src/**.cpp",
|
"./src/**.cpp",
|
||||||
"./src/resources/**.*"
|
"./src/resources/**.*"
|
||||||
}
|
}
|
||||||
|
|
||||||
includedirs {
|
includedirs {
|
||||||
"./src"
|
"./src"
|
||||||
}
|
}
|
||||||
|
|
||||||
resincludedirs {
|
resincludedirs {
|
||||||
"$(ProjectDir)src"
|
"$(ProjectDir)src"
|
||||||
}
|
}
|
||||||
|
|
||||||
if _OPTIONS["copy-to"] then
|
if _OPTIONS["copy-to"] then
|
||||||
postbuildcommands {
|
postbuildcommands {
|
||||||
"copy /y \"$(TargetDir)*.exe\" \"" .. _OPTIONS["copy-to"] .. "\""
|
"copy /y \"$(TargetDir)*.exe\" \"" .. _OPTIONS["copy-to"] .. "\""
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
dependencies.imports()
|
dependencies.imports()
|
||||||
|
|
||||||
group "Dependencies"
|
group "Dependencies"
|
||||||
dependencies.projects()
|
dependencies.projects()
|
||||||
|
@ -1,61 +1,61 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "bdDediAuth.hpp"
|
#include "bdDediAuth.hpp"
|
||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
#include "steam/steam.hpp"
|
#include "steam/steam.hpp"
|
||||||
#include "utils/cryptography.hpp"
|
#include "utils/cryptography.hpp"
|
||||||
|
|
||||||
namespace demonware
|
namespace demonware
|
||||||
{
|
{
|
||||||
void bdDediAuth::call_service(i_server* server, const std::string& data)
|
void bdDediAuth::call_service(i_server* server, const std::string& data)
|
||||||
{
|
{
|
||||||
bit_buffer buffer(data);
|
bit_buffer buffer(data);
|
||||||
|
|
||||||
bool more_data;
|
bool more_data;
|
||||||
buffer.set_use_data_types(false);
|
buffer.set_use_data_types(false);
|
||||||
buffer.read_bool(&more_data);
|
buffer.read_bool(&more_data);
|
||||||
buffer.set_use_data_types(true);
|
buffer.set_use_data_types(true);
|
||||||
|
|
||||||
uint32_t seed, title_id, ticket_size;
|
uint32_t seed, title_id, ticket_size;
|
||||||
buffer.read_uint32(&seed);
|
buffer.read_uint32(&seed);
|
||||||
buffer.read_uint32(&title_id);
|
buffer.read_uint32(&title_id);
|
||||||
|
|
||||||
uint8_t ticket[1024];
|
uint8_t ticket[1024];
|
||||||
buffer.read_bytes(std::min(ticket_size, static_cast<uint32_t>(sizeof(ticket))), ticket);
|
buffer.read_bytes(std::min(ticket_size, static_cast<uint32_t>(sizeof(ticket))), ticket);
|
||||||
|
|
||||||
game::native::bdAuthTicket auth_ticket{};
|
game::native::bdAuthTicket auth_ticket{};
|
||||||
std::memset(&auth_ticket, 0xA, sizeof auth_ticket);
|
std::memset(&auth_ticket, 0xA, sizeof auth_ticket);
|
||||||
|
|
||||||
auth_ticket.m_magicNumber = 0x0EFBDADDE;
|
auth_ticket.m_magicNumber = 0x0EFBDADDE;
|
||||||
auth_ticket.m_type = 0;
|
auth_ticket.m_type = 0;
|
||||||
auth_ticket.m_titleID = title_id;
|
auth_ticket.m_titleID = title_id;
|
||||||
auth_ticket.m_userID = steam::SteamUser()->GetSteamID().bits;
|
auth_ticket.m_userID = steam::SteamUser()->GetSteamID().bits;
|
||||||
auth_ticket.m_licenseID = 4;
|
auth_ticket.m_licenseID = 4;
|
||||||
|
|
||||||
auto key = utils::cryptography::tiger::compute(SERVER_CD_KEY);
|
auto key = utils::cryptography::tiger::compute(SERVER_CD_KEY);
|
||||||
|
|
||||||
strcpy_s(auth_ticket.m_username, "Open-IW5 Server");
|
strcpy_s(auth_ticket.m_username, "Open-IW5 Server");
|
||||||
std::memcpy(auth_ticket.m_sessionKey, key.data(), 24);
|
std::memcpy(auth_ticket.m_sessionKey, key.data(), 24);
|
||||||
auth_ticket.m_timeIssued = static_cast<uint32_t>(time(nullptr));
|
auth_ticket.m_timeIssued = static_cast<uint32_t>(time(nullptr));
|
||||||
|
|
||||||
uint8_t lsg_ticket[128];
|
uint8_t lsg_ticket[128];
|
||||||
ZeroMemory(&lsg_ticket, sizeof lsg_ticket);
|
ZeroMemory(&lsg_ticket, sizeof lsg_ticket);
|
||||||
std::memcpy(lsg_ticket, key.data(), 24);
|
std::memcpy(lsg_ticket, key.data(), 24);
|
||||||
|
|
||||||
const auto iv = utils::cryptography::tiger::compute(std::string(reinterpret_cast<char*>(&seed), 4));
|
const auto iv = utils::cryptography::tiger::compute(std::string(reinterpret_cast<char*>(&seed), 4));
|
||||||
|
|
||||||
const std::string enc_key(reinterpret_cast<char*>(&ticket[32]), 24);
|
const std::string enc_key(reinterpret_cast<char*>(&ticket[32]), 24);
|
||||||
auto enc_ticket = utils::cryptography::des3::encrypt(
|
auto enc_ticket = utils::cryptography::des3::encrypt(
|
||||||
std::string(reinterpret_cast<char*>(&auth_ticket), sizeof(auth_ticket)), iv, enc_key);
|
std::string(reinterpret_cast<char*>(&auth_ticket), sizeof(auth_ticket)), iv, enc_key);
|
||||||
|
|
||||||
bit_buffer response;
|
bit_buffer response;
|
||||||
response.set_use_data_types(false);
|
response.set_use_data_types(false);
|
||||||
response.write_bool(false);
|
response.write_bool(false);
|
||||||
response.write_uint32(700);
|
response.write_uint32(700);
|
||||||
response.write_uint32(seed);
|
response.write_uint32(seed);
|
||||||
response.write_bytes(enc_ticket.size(), enc_ticket.data());
|
response.write_bytes(enc_ticket.size(), enc_ticket.data());
|
||||||
response.write_bytes(sizeof(lsg_ticket), lsg_ticket);
|
response.write_bytes(sizeof(lsg_ticket), lsg_ticket);
|
||||||
|
|
||||||
auto reply = server->create_message(29);
|
auto reply = server->create_message(29);
|
||||||
reply->send(&response, false);
|
reply->send(&response, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,71 +1,71 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "bdDediRSAAuth.hpp"
|
#include "bdDediRSAAuth.hpp"
|
||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
#include "steam/steam.hpp"
|
#include "steam/steam.hpp"
|
||||||
#include "utils/cryptography.hpp"
|
#include "utils/cryptography.hpp"
|
||||||
|
|
||||||
namespace demonware
|
namespace demonware
|
||||||
{
|
{
|
||||||
void bdDediRSAAuth::call_service(i_server* server, const std::string& data)
|
void bdDediRSAAuth::call_service(i_server* server, const std::string& data)
|
||||||
{
|
{
|
||||||
bit_buffer buffer(data);
|
bit_buffer buffer(data);
|
||||||
|
|
||||||
bool more_data;
|
bool more_data;
|
||||||
buffer.set_use_data_types(false);
|
buffer.set_use_data_types(false);
|
||||||
buffer.read_bool(&more_data);
|
buffer.read_bool(&more_data);
|
||||||
buffer.set_use_data_types(true);
|
buffer.set_use_data_types(true);
|
||||||
|
|
||||||
uint32_t seed, title_id, ticket_size;
|
uint32_t seed, title_id, ticket_size;
|
||||||
buffer.read_uint32(&seed);
|
buffer.read_uint32(&seed);
|
||||||
buffer.read_uint32(&title_id);
|
buffer.read_uint32(&title_id);
|
||||||
|
|
||||||
unsigned char rsakey[140];
|
unsigned char rsakey[140];
|
||||||
buffer.read_bytes(sizeof(rsakey), rsakey);
|
buffer.read_bytes(sizeof(rsakey), rsakey);
|
||||||
|
|
||||||
uint8_t ticket[1024];
|
uint8_t ticket[1024];
|
||||||
buffer.read_bytes(std::min(ticket_size, static_cast<uint32_t>(sizeof(ticket))), ticket);
|
buffer.read_bytes(std::min(ticket_size, static_cast<uint32_t>(sizeof(ticket))), ticket);
|
||||||
|
|
||||||
game::native::bdAuthTicket auth_ticket{};
|
game::native::bdAuthTicket auth_ticket{};
|
||||||
std::memset(&auth_ticket, 0xA, sizeof auth_ticket);
|
std::memset(&auth_ticket, 0xA, sizeof auth_ticket);
|
||||||
|
|
||||||
auth_ticket.m_magicNumber = 0x0EFBDADDE;
|
auth_ticket.m_magicNumber = 0x0EFBDADDE;
|
||||||
auth_ticket.m_type = 0;
|
auth_ticket.m_type = 0;
|
||||||
auth_ticket.m_titleID = title_id;
|
auth_ticket.m_titleID = title_id;
|
||||||
auth_ticket.m_userID = steam::SteamUser()->GetSteamID().bits;
|
auth_ticket.m_userID = steam::SteamUser()->GetSteamID().bits;
|
||||||
|
|
||||||
auto key = utils::cryptography::tiger::compute(SERVER_CD_KEY);
|
auto key = utils::cryptography::tiger::compute(SERVER_CD_KEY);
|
||||||
|
|
||||||
strcpy_s(auth_ticket.m_username, "Open-IW5 Server");
|
strcpy_s(auth_ticket.m_username, "Open-IW5 Server");
|
||||||
std::memcpy(auth_ticket.m_sessionKey, key.data(), 24);
|
std::memcpy(auth_ticket.m_sessionKey, key.data(), 24);
|
||||||
auth_ticket.m_timeIssued = static_cast<uint32_t>(time(nullptr));
|
auth_ticket.m_timeIssued = static_cast<uint32_t>(time(nullptr));
|
||||||
|
|
||||||
uint8_t lsg_ticket[128];
|
uint8_t lsg_ticket[128];
|
||||||
ZeroMemory(&lsg_ticket, sizeof lsg_ticket);
|
ZeroMemory(&lsg_ticket, sizeof lsg_ticket);
|
||||||
std::memcpy(lsg_ticket, key.data(), 24);
|
std::memcpy(lsg_ticket, key.data(), 24);
|
||||||
|
|
||||||
const auto iv = utils::cryptography::tiger::compute(std::string(reinterpret_cast<char*>(&seed), 4));
|
const auto iv = utils::cryptography::tiger::compute(std::string(reinterpret_cast<char*>(&seed), 4));
|
||||||
|
|
||||||
const std::string enc_key(reinterpret_cast<char*>(&ticket[32]), 24);
|
const std::string enc_key(reinterpret_cast<char*>(&ticket[32]), 24);
|
||||||
auto enc_ticket = utils::cryptography::des3::encrypt(
|
auto enc_ticket = utils::cryptography::des3::encrypt(
|
||||||
std::string(reinterpret_cast<char*>(&auth_ticket), sizeof(auth_ticket)), iv, enc_key);
|
std::string(reinterpret_cast<char*>(&auth_ticket), sizeof(auth_ticket)), iv, enc_key);
|
||||||
|
|
||||||
register_hash(&sha1_desc);
|
register_hash(&sha1_desc);
|
||||||
register_prng(&yarrow_desc);
|
register_prng(&yarrow_desc);
|
||||||
|
|
||||||
std::string encrypted_key = utils::cryptography::rsa::encrypt(std::string(SERVER_CD_KEY, 24),
|
std::string encrypted_key = utils::cryptography::rsa::encrypt(std::string(SERVER_CD_KEY, 24),
|
||||||
std::string("DW-RSAENC", 10),
|
std::string("DW-RSAENC", 10),
|
||||||
std::string(PCHAR(rsakey), sizeof(rsakey)));
|
std::string(PCHAR(rsakey), sizeof(rsakey)));
|
||||||
|
|
||||||
bit_buffer response;
|
bit_buffer response;
|
||||||
response.set_use_data_types(false);
|
response.set_use_data_types(false);
|
||||||
response.write_bool(false);
|
response.write_bool(false);
|
||||||
response.write_uint32(700);
|
response.write_uint32(700);
|
||||||
response.write_uint32(seed);
|
response.write_uint32(seed);
|
||||||
response.write_bytes(enc_ticket.size(), enc_ticket.data());
|
response.write_bytes(enc_ticket.size(), enc_ticket.data());
|
||||||
response.write_bytes(sizeof(lsg_ticket), lsg_ticket);
|
response.write_bytes(sizeof(lsg_ticket), lsg_ticket);
|
||||||
response.write_bytes(encrypted_key.size(), encrypted_key.data());
|
response.write_bytes(encrypted_key.size(), encrypted_key.data());
|
||||||
|
|
||||||
auto reply = server->create_message(29);
|
auto reply = server->create_message(29);
|
||||||
reply->send(&response, false);
|
reply->send(&response, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,61 +1,61 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "bdSteamAuth.hpp"
|
#include "bdSteamAuth.hpp"
|
||||||
#include "game/structs.hpp"
|
#include "game/structs.hpp"
|
||||||
#include "steam/steam.hpp"
|
#include "steam/steam.hpp"
|
||||||
#include "utils/cryptography.hpp"
|
#include "utils/cryptography.hpp"
|
||||||
|
|
||||||
namespace demonware
|
namespace demonware
|
||||||
{
|
{
|
||||||
void bdSteamAuth::call_service(i_server* server, const std::string& data)
|
void bdSteamAuth::call_service(i_server* server, const std::string& data)
|
||||||
{
|
{
|
||||||
bit_buffer buffer(data);
|
bit_buffer buffer(data);
|
||||||
|
|
||||||
bool more_data;
|
bool more_data;
|
||||||
buffer.set_use_data_types(false);
|
buffer.set_use_data_types(false);
|
||||||
buffer.read_bool(&more_data);
|
buffer.read_bool(&more_data);
|
||||||
buffer.set_use_data_types(true);
|
buffer.set_use_data_types(true);
|
||||||
|
|
||||||
uint32_t seed, title_id, ticket_size;
|
uint32_t seed, title_id, ticket_size;
|
||||||
buffer.read_uint32(&seed);
|
buffer.read_uint32(&seed);
|
||||||
buffer.read_uint32(&title_id);
|
buffer.read_uint32(&title_id);
|
||||||
buffer.read_uint32(&ticket_size);
|
buffer.read_uint32(&ticket_size);
|
||||||
|
|
||||||
uint8_t ticket[1024];
|
uint8_t ticket[1024];
|
||||||
buffer.read_bytes(std::min(ticket_size, static_cast<uint32_t>(sizeof(ticket))), ticket);
|
buffer.read_bytes(std::min(ticket_size, static_cast<uint32_t>(sizeof(ticket))), ticket);
|
||||||
|
|
||||||
game::native::bdAuthTicket auth_ticket{};
|
game::native::bdAuthTicket auth_ticket{};
|
||||||
std::memset(&auth_ticket, 0xA, sizeof auth_ticket);
|
std::memset(&auth_ticket, 0xA, sizeof auth_ticket);
|
||||||
|
|
||||||
auth_ticket.m_magicNumber = 0x0EFBDADDE;
|
auth_ticket.m_magicNumber = 0x0EFBDADDE;
|
||||||
auth_ticket.m_type = 0;
|
auth_ticket.m_type = 0;
|
||||||
auth_ticket.m_titleID = title_id;
|
auth_ticket.m_titleID = title_id;
|
||||||
auth_ticket.m_userID = steam::SteamUser()->GetSteamID().bits;
|
auth_ticket.m_userID = steam::SteamUser()->GetSteamID().bits;
|
||||||
|
|
||||||
auto key = utils::cryptography::tiger::compute("Open-IW5");
|
auto key = utils::cryptography::tiger::compute("Open-IW5");
|
||||||
|
|
||||||
strcpy_s(auth_ticket.m_username, "Open-IW5 User");
|
strcpy_s(auth_ticket.m_username, "Open-IW5 User");
|
||||||
std::memcpy(auth_ticket.m_sessionKey, key.data(), 24);
|
std::memcpy(auth_ticket.m_sessionKey, key.data(), 24);
|
||||||
auth_ticket.m_timeIssued = static_cast<uint32_t>(time(nullptr));
|
auth_ticket.m_timeIssued = static_cast<uint32_t>(time(nullptr));
|
||||||
|
|
||||||
uint8_t lsg_ticket[128];
|
uint8_t lsg_ticket[128];
|
||||||
ZeroMemory(&lsg_ticket, sizeof lsg_ticket);
|
ZeroMemory(&lsg_ticket, sizeof lsg_ticket);
|
||||||
std::memcpy(lsg_ticket, key.data(), 24);
|
std::memcpy(lsg_ticket, key.data(), 24);
|
||||||
|
|
||||||
const auto iv = utils::cryptography::tiger::compute(std::string(reinterpret_cast<char*>(&seed), 4));
|
const auto iv = utils::cryptography::tiger::compute(std::string(reinterpret_cast<char*>(&seed), 4));
|
||||||
|
|
||||||
const std::string enc_key(reinterpret_cast<char*>(&ticket[32]), 24);
|
const std::string enc_key(reinterpret_cast<char*>(&ticket[32]), 24);
|
||||||
auto enc_ticket = utils::cryptography::des3::encrypt(
|
auto enc_ticket = utils::cryptography::des3::encrypt(
|
||||||
std::string(reinterpret_cast<char*>(&auth_ticket), sizeof(auth_ticket)), iv, enc_key);
|
std::string(reinterpret_cast<char*>(&auth_ticket), sizeof(auth_ticket)), iv, enc_key);
|
||||||
|
|
||||||
bit_buffer response;
|
bit_buffer response;
|
||||||
response.set_use_data_types(false);
|
response.set_use_data_types(false);
|
||||||
response.write_bool(false);
|
response.write_bool(false);
|
||||||
response.write_uint32(700);
|
response.write_uint32(700);
|
||||||
response.write_uint32(seed);
|
response.write_uint32(seed);
|
||||||
response.write_bytes(enc_ticket.size(), enc_ticket.data());
|
response.write_bytes(enc_ticket.size(), enc_ticket.data());
|
||||||
response.write_bytes(sizeof(lsg_ticket), lsg_ticket);
|
response.write_bytes(sizeof(lsg_ticket), lsg_ticket);
|
||||||
|
|
||||||
auto reply = server->create_message(29);
|
auto reply = server->create_message(29);
|
||||||
reply->send(&response, false);
|
reply->send(&response, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,374 +1,374 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "game.hpp"
|
#include "game.hpp"
|
||||||
|
|
||||||
namespace game
|
namespace game
|
||||||
{
|
{
|
||||||
namespace native
|
namespace native
|
||||||
{
|
{
|
||||||
Cmd_AddCommand_t Cmd_AddCommand;
|
Cmd_AddCommand_t Cmd_AddCommand;
|
||||||
|
|
||||||
Com_Error_t Com_Error;
|
Com_Error_t Com_Error;
|
||||||
|
|
||||||
DB_LoadXAssets_t DB_LoadXAssets;
|
DB_LoadXAssets_t DB_LoadXAssets;
|
||||||
|
|
||||||
Dvar_SetFromStringByName_t Dvar_SetFromStringByName;
|
Dvar_SetFromStringByName_t Dvar_SetFromStringByName;
|
||||||
|
|
||||||
G_RunFrame_t G_RunFrame;
|
G_RunFrame_t G_RunFrame;
|
||||||
|
|
||||||
MSG_ReadData_t MSG_ReadData;
|
MSG_ReadData_t MSG_ReadData;
|
||||||
|
|
||||||
MT_AllocIndex_t MT_AllocIndex;
|
MT_AllocIndex_t MT_AllocIndex;
|
||||||
|
|
||||||
RemoveRefToValue_t RemoveRefToValue;
|
RemoveRefToValue_t RemoveRefToValue;
|
||||||
|
|
||||||
SL_GetStringOfSize_t SL_GetStringOfSize;
|
SL_GetStringOfSize_t SL_GetStringOfSize;
|
||||||
|
|
||||||
Sys_ShowConsole_t Sys_ShowConsole;
|
Sys_ShowConsole_t Sys_ShowConsole;
|
||||||
|
|
||||||
VM_Notify_t VM_Notify;
|
VM_Notify_t VM_Notify;
|
||||||
|
|
||||||
decltype(longjmp)* _longjmp;
|
decltype(longjmp)* _longjmp;
|
||||||
|
|
||||||
int* cmd_args;
|
int* cmd_args;
|
||||||
int* cmd_argc;
|
int* cmd_argc;
|
||||||
const char*** cmd_argv;
|
const char*** cmd_argv;
|
||||||
|
|
||||||
short* scrVarGlob;
|
short* scrVarGlob;
|
||||||
char** scrMemTreePub;
|
char** scrMemTreePub;
|
||||||
char* scrMemTreeGlob;
|
char* scrMemTreeGlob;
|
||||||
|
|
||||||
scrVmPub_t* scr_VmPub;
|
scrVmPub_t* scr_VmPub;
|
||||||
|
|
||||||
scr_call_t* scr_instanceFunctions;
|
scr_call_t* scr_instanceFunctions;
|
||||||
scr_call_t* scr_globalFunctions;
|
scr_call_t* scr_globalFunctions;
|
||||||
|
|
||||||
unsigned int* levelEntityId;
|
unsigned int* levelEntityId;
|
||||||
|
|
||||||
int* g_script_error_level;
|
int* g_script_error_level;
|
||||||
jmp_buf* g_script_error;
|
jmp_buf* g_script_error;
|
||||||
|
|
||||||
scr_classStruct_t* g_classMap;
|
scr_classStruct_t* g_classMap;
|
||||||
|
|
||||||
void AddRefToValue(VariableValue* value)
|
void AddRefToValue(VariableValue* value)
|
||||||
{
|
{
|
||||||
if (value->type == SCRIPT_OBJECT)
|
if (value->type == SCRIPT_OBJECT)
|
||||||
{
|
{
|
||||||
++scrVarGlob[4 * value->u.entityId];
|
++scrVarGlob[4 * value->u.entityId];
|
||||||
}
|
}
|
||||||
else if ((value->type & ~1) == SCRIPT_STRING)
|
else if ((value->type & ~1) == SCRIPT_STRING)
|
||||||
{
|
{
|
||||||
static const auto size = is_sp() ? 16 : 12;
|
static const auto size = is_sp() ? 16 : 12;
|
||||||
const auto ref_count = reinterpret_cast<unsigned volatile *>(*scrMemTreePub + size * value
|
const auto ref_count = reinterpret_cast<unsigned volatile *>(*scrMemTreePub + size * value
|
||||||
->u.stringValue);
|
->u.stringValue);
|
||||||
InterlockedIncrement(ref_count);
|
InterlockedIncrement(ref_count);
|
||||||
}
|
}
|
||||||
else if (value->type == SCRIPT_VECTOR)
|
else if (value->type == SCRIPT_VECTOR)
|
||||||
{
|
{
|
||||||
if (!*PBYTE(value->u.vectorValue - 1))
|
if (!*PBYTE(value->u.vectorValue - 1))
|
||||||
{
|
{
|
||||||
++*PWORD(value->u.vectorValue - 4);
|
++*PWORD(value->u.vectorValue - 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(naked) unsigned int conbuf_append_text_dedicated(const char* message)
|
__declspec(naked) unsigned int conbuf_append_text_dedicated(const char* message)
|
||||||
{
|
{
|
||||||
static DWORD func = 0x53C790;
|
static DWORD func = 0x53C790;
|
||||||
|
|
||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
mov ecx, message
|
mov ecx, message
|
||||||
call func
|
call func
|
||||||
retn
|
retn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Conbuf_AppendText(const char* message)
|
void Conbuf_AppendText(const char* message)
|
||||||
{
|
{
|
||||||
if(is_dedi())
|
if(is_dedi())
|
||||||
{
|
{
|
||||||
conbuf_append_text_dedicated(message);
|
conbuf_append_text_dedicated(message);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
reinterpret_cast<void(*)(const char*)>(SELECT_VALUE(0x4C84E0, 0x5CF610, 0))(message);
|
reinterpret_cast<void(*)(const char*)>(SELECT_VALUE(0x4C84E0, 0x5CF610, 0))(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(naked) unsigned int find_variable_dedicated(unsigned int parentId, unsigned int name)
|
__declspec(naked) unsigned int find_variable_dedicated(unsigned int parentId, unsigned int name)
|
||||||
{
|
{
|
||||||
static DWORD func = 0x4E7ED0;
|
static DWORD func = 0x4E7ED0;
|
||||||
|
|
||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
mov eax, name
|
mov eax, name
|
||||||
mov ecx, parentId
|
mov ecx, parentId
|
||||||
call func
|
call func
|
||||||
retn
|
retn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int FindVariable(const unsigned int parentId, const unsigned int name)
|
unsigned int FindVariable(const unsigned int parentId, const unsigned int name)
|
||||||
{
|
{
|
||||||
if (is_dedi())
|
if (is_dedi())
|
||||||
{
|
{
|
||||||
return find_variable_dedicated(parentId, name);
|
return find_variable_dedicated(parentId, name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return reinterpret_cast<unsigned int(*)(unsigned int, unsigned int)> //
|
return reinterpret_cast<unsigned int(*)(unsigned int, unsigned int)> //
|
||||||
(SELECT_VALUE(0x4C4E70, 0x5651F0, 0x0))(parentId, name);
|
(SELECT_VALUE(0x4C4E70, 0x5651F0, 0x0))(parentId, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(naked) VariableValue get_entity_field_value_dedicated(unsigned int classnum, int entnum, int _offset)
|
__declspec(naked) VariableValue get_entity_field_value_dedicated(unsigned int classnum, int entnum, int _offset)
|
||||||
{
|
{
|
||||||
static DWORD func = 0x4F1400;
|
static DWORD func = 0x4F1400;
|
||||||
|
|
||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
push _offset
|
push _offset
|
||||||
push entnum
|
push entnum
|
||||||
mov ecx, classnum
|
mov ecx, classnum
|
||||||
call func
|
call func
|
||||||
add esp, 8h
|
add esp, 8h
|
||||||
retn
|
retn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VariableValue GetEntityFieldValue(const unsigned int classnum, const int entnum, const int offset)
|
VariableValue GetEntityFieldValue(const unsigned int classnum, const int entnum, const int offset)
|
||||||
{
|
{
|
||||||
if (is_dedi())
|
if (is_dedi())
|
||||||
{
|
{
|
||||||
return get_entity_field_value_dedicated(classnum, entnum, offset);
|
return get_entity_field_value_dedicated(classnum, entnum, offset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return reinterpret_cast<VariableValue(*)(unsigned int, int, int)> //
|
return reinterpret_cast<VariableValue(*)(unsigned int, int, int)> //
|
||||||
(SELECT_VALUE(0x530E30, 0x56AF20, 0x0))(classnum, entnum, offset);
|
(SELECT_VALUE(0x530E30, 0x56AF20, 0x0))(classnum, entnum, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void* MT_Alloc(const int numBytes, const int type)
|
void* MT_Alloc(const int numBytes, const int type)
|
||||||
{
|
{
|
||||||
return scrMemTreeGlob + 12 * size_t(MT_AllocIndex(numBytes, type));
|
return scrMemTreeGlob + 12 * size_t(MT_AllocIndex(numBytes, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
const float* Scr_AllocVector(const float* v)
|
const float* Scr_AllocVector(const float* v)
|
||||||
{
|
{
|
||||||
const auto mem = static_cast<DWORD*>(MT_Alloc(16, 2));
|
const auto mem = static_cast<DWORD*>(MT_Alloc(16, 2));
|
||||||
*mem = 0;
|
*mem = 0;
|
||||||
|
|
||||||
const auto array = reinterpret_cast<float*>(mem + 1);
|
const auto array = reinterpret_cast<float*>(mem + 1);
|
||||||
array[0] = v[0];
|
array[0] = v[0];
|
||||||
array[1] = v[1];
|
array[1] = v[1];
|
||||||
array[2] = v[2];
|
array[2] = v[2];
|
||||||
|
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scr_ClearOutParams()
|
void Scr_ClearOutParams()
|
||||||
{
|
{
|
||||||
const auto num_params = scr_VmPub->outparamcount;
|
const auto num_params = scr_VmPub->outparamcount;
|
||||||
for (unsigned int i = num_params; i > 0; --i)
|
for (unsigned int i = num_params; i > 0; --i)
|
||||||
{
|
{
|
||||||
const auto value = scr_VmPub->top[i - 1];
|
const auto value = scr_VmPub->top[i - 1];
|
||||||
RemoveRefToValue(value.type, value.u);
|
RemoveRefToValue(value.type, value.u);
|
||||||
}
|
}
|
||||||
|
|
||||||
scr_VmPub->top -= num_params;
|
scr_VmPub->top -= num_params;
|
||||||
}
|
}
|
||||||
|
|
||||||
scr_entref_t Scr_GetEntityIdRef(const unsigned int id)
|
scr_entref_t Scr_GetEntityIdRef(const unsigned int id)
|
||||||
{
|
{
|
||||||
static auto class_array = reinterpret_cast<DWORD*>(SELECT_VALUE(0x19AFC84, 0x1E72184, 0x1D3C804));
|
static auto class_array = reinterpret_cast<DWORD*>(SELECT_VALUE(0x19AFC84, 0x1E72184, 0x1D3C804));
|
||||||
static auto ent_array = reinterpret_cast<WORD*>(SELECT_VALUE(0x19AFC82, 0x1E72182, 0x1D3C802));
|
static auto ent_array = reinterpret_cast<WORD*>(SELECT_VALUE(0x19AFC82, 0x1E72182, 0x1D3C802));
|
||||||
|
|
||||||
scr_entref_t result{};
|
scr_entref_t result{};
|
||||||
result.raw.classnum = static_cast<unsigned short>(class_array[2 * id]) >> 8;
|
result.raw.classnum = static_cast<unsigned short>(class_array[2 * id]) >> 8;
|
||||||
result.raw.entnum = ent_array[4 * id];
|
result.raw.entnum = ent_array[4 * id];
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
scr_call_t Scr_GetFunc(const unsigned int index)
|
scr_call_t Scr_GetFunc(const unsigned int index)
|
||||||
{
|
{
|
||||||
if (index > 0x1C7)
|
if (index > 0x1C7)
|
||||||
{
|
{
|
||||||
return scr_instanceFunctions[index];
|
return scr_instanceFunctions[index];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return scr_globalFunctions[index];
|
return scr_globalFunctions[index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(naked) void scr_notify_id_multiplayer(unsigned int id, unsigned int stringValue,
|
__declspec(naked) void scr_notify_id_multiplayer(unsigned int id, unsigned int stringValue,
|
||||||
unsigned int paramcount)
|
unsigned int paramcount)
|
||||||
{
|
{
|
||||||
static DWORD func = 0x56B5E0;
|
static DWORD func = 0x56B5E0;
|
||||||
|
|
||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
mov eax, paramcount
|
mov eax, paramcount
|
||||||
push stringValue
|
push stringValue
|
||||||
push id
|
push id
|
||||||
call func
|
call func
|
||||||
add esp, 8h
|
add esp, 8h
|
||||||
retn
|
retn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(naked) void scr_notify_id_singleplayer(unsigned int id, unsigned int stringValue,
|
__declspec(naked) void scr_notify_id_singleplayer(unsigned int id, unsigned int stringValue,
|
||||||
unsigned int paramcount)
|
unsigned int paramcount)
|
||||||
{
|
{
|
||||||
static DWORD func = 0x610980;
|
static DWORD func = 0x610980;
|
||||||
|
|
||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
mov eax, paramcount
|
mov eax, paramcount
|
||||||
push stringValue
|
push stringValue
|
||||||
push id
|
push id
|
||||||
call func
|
call func
|
||||||
add esp, 8h
|
add esp, 8h
|
||||||
retn
|
retn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scr_NotifyId(unsigned int id, unsigned int stringValue, unsigned int paramcount)
|
void Scr_NotifyId(unsigned int id, unsigned int stringValue, unsigned int paramcount)
|
||||||
{
|
{
|
||||||
if (is_mp())
|
if (is_mp())
|
||||||
{
|
{
|
||||||
return scr_notify_id_multiplayer(id, stringValue, paramcount);
|
return scr_notify_id_multiplayer(id, stringValue, paramcount);
|
||||||
}
|
}
|
||||||
else if (is_sp())
|
else if (is_sp())
|
||||||
{
|
{
|
||||||
return scr_notify_id_singleplayer(id, stringValue, paramcount);
|
return scr_notify_id_singleplayer(id, stringValue, paramcount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return reinterpret_cast<void(*)(unsigned int, unsigned int, unsigned int)>(0x4EFAA0)(id, stringValue, paramcount);
|
return reinterpret_cast<void(*)(unsigned int, unsigned int, unsigned int)>(0x4EFAA0)(id, stringValue, paramcount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(naked) int scr_set_object_field_dedicated(unsigned int classnum, int entnum, int _offset)
|
__declspec(naked) int scr_set_object_field_dedicated(unsigned int classnum, int entnum, int _offset)
|
||||||
{
|
{
|
||||||
static DWORD func = 0x4B15C0;
|
static DWORD func = 0x4B15C0;
|
||||||
|
|
||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
mov ecx, _offset
|
mov ecx, _offset
|
||||||
mov eax, entnum
|
mov eax, entnum
|
||||||
push classnum
|
push classnum
|
||||||
call func
|
call func
|
||||||
add esp, 4h
|
add esp, 4h
|
||||||
retn
|
retn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Scr_SetObjectField(const unsigned int classnum, const int entnum, const int offset)
|
int Scr_SetObjectField(const unsigned int classnum, const int entnum, const int offset)
|
||||||
{
|
{
|
||||||
if (is_dedi())
|
if (is_dedi())
|
||||||
{
|
{
|
||||||
return scr_set_object_field_dedicated(classnum, entnum, offset);
|
return scr_set_object_field_dedicated(classnum, entnum, offset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return reinterpret_cast<int(*)(unsigned int, int, int)> //
|
return reinterpret_cast<int(*)(unsigned int, int, int)> //
|
||||||
(SELECT_VALUE(0x42CAD0, 0x52BCC0, 0x0))(classnum, entnum, offset);
|
(SELECT_VALUE(0x42CAD0, 0x52BCC0, 0x0))(classnum, entnum, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* SL_ConvertToString(const unsigned int stringValue)
|
const char* SL_ConvertToString(const unsigned int stringValue)
|
||||||
{
|
{
|
||||||
if (!stringValue) return nullptr;
|
if (!stringValue) return nullptr;
|
||||||
|
|
||||||
static const auto size = is_sp() ? 16 : 12;
|
static const auto size = is_sp() ? 16 : 12;
|
||||||
return *scrMemTreePub + size * stringValue + 4;
|
return *scrMemTreePub + size * stringValue + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int SL_GetString(const char* str, const unsigned int user)
|
unsigned int SL_GetString(const char* str, const unsigned int user)
|
||||||
{
|
{
|
||||||
return SL_GetStringOfSize(str, user, strlen(str) + 1, 7);
|
return SL_GetStringOfSize(str, user, strlen(str) + 1, 7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
launcher::mode mode = launcher::mode::none;
|
launcher::mode mode = launcher::mode::none;
|
||||||
|
|
||||||
launcher::mode get_mode()
|
launcher::mode get_mode()
|
||||||
{
|
{
|
||||||
if(mode == launcher::mode::none)
|
if(mode == launcher::mode::none)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Launcher mode not valid. Something must be wrong.");
|
throw std::runtime_error("Launcher mode not valid. Something must be wrong.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_mp()
|
bool is_mp()
|
||||||
{
|
{
|
||||||
return get_mode() == launcher::mode::multiplayer;
|
return get_mode() == launcher::mode::multiplayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_sp()
|
bool is_sp()
|
||||||
{
|
{
|
||||||
return get_mode() == launcher::mode::singleplayer;
|
return get_mode() == launcher::mode::singleplayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_dedi()
|
bool is_dedi()
|
||||||
{
|
{
|
||||||
return get_mode() == launcher::mode::server;
|
return get_mode() == launcher::mode::server;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initialize(const launcher::mode _mode)
|
void initialize(const launcher::mode _mode)
|
||||||
{
|
{
|
||||||
mode = _mode;
|
mode = _mode;
|
||||||
|
|
||||||
native::Cmd_AddCommand = native::Cmd_AddCommand_t(SELECT_VALUE(0x558820, 0x545DF0, 0));
|
native::Cmd_AddCommand = native::Cmd_AddCommand_t(SELECT_VALUE(0x558820, 0x545DF0, 0));
|
||||||
|
|
||||||
native::Com_Error = native::Com_Error_t(SELECT_VALUE(0x425540, 0x555450, 0x4D93F0));
|
native::Com_Error = native::Com_Error_t(SELECT_VALUE(0x425540, 0x555450, 0x4D93F0));
|
||||||
|
|
||||||
native::DB_LoadXAssets = native::DB_LoadXAssets_t(SELECT_VALUE(0x48A8E0, 0x4CD020, 0x44F770));
|
native::DB_LoadXAssets = native::DB_LoadXAssets_t(SELECT_VALUE(0x48A8E0, 0x4CD020, 0x44F770));
|
||||||
|
|
||||||
native::Dvar_SetFromStringByName = native::Dvar_SetFromStringByName_t(SELECT_VALUE(0x4DD090, 0x5BF740, 0x518DF0));
|
native::Dvar_SetFromStringByName = native::Dvar_SetFromStringByName_t(SELECT_VALUE(0x4DD090, 0x5BF740, 0x518DF0));
|
||||||
|
|
||||||
native::G_RunFrame = native::G_RunFrame_t(SELECT_VALUE(0x52EAA0, 0x50CB70, 0x48AD60));
|
native::G_RunFrame = native::G_RunFrame_t(SELECT_VALUE(0x52EAA0, 0x50CB70, 0x48AD60));
|
||||||
|
|
||||||
native::MSG_ReadData = native::MSG_ReadData_t(SELECT_VALUE(0, 0x5592A0, 0));
|
native::MSG_ReadData = native::MSG_ReadData_t(SELECT_VALUE(0, 0x5592A0, 0));
|
||||||
|
|
||||||
native::MT_AllocIndex = native::MT_AllocIndex_t(SELECT_VALUE(0x4B9610, 0x562080, 0x4E6C30));
|
native::MT_AllocIndex = native::MT_AllocIndex_t(SELECT_VALUE(0x4B9610, 0x562080, 0x4E6C30));
|
||||||
|
|
||||||
native::RemoveRefToValue = native::RemoveRefToValue_t(SELECT_VALUE(0x477EA0, 0x565730, 0x4E8A40));
|
native::RemoveRefToValue = native::RemoveRefToValue_t(SELECT_VALUE(0x477EA0, 0x565730, 0x4E8A40));
|
||||||
|
|
||||||
native::SL_GetStringOfSize = native::SL_GetStringOfSize_t(SELECT_VALUE(0x4E13F0, 0x564650, 0x4E7490));
|
native::SL_GetStringOfSize = native::SL_GetStringOfSize_t(SELECT_VALUE(0x4E13F0, 0x564650, 0x4E7490));
|
||||||
|
|
||||||
native::Sys_ShowConsole = native::Sys_ShowConsole_t(SELECT_VALUE(0x470AF0, 0x5CF590, 0));
|
native::Sys_ShowConsole = native::Sys_ShowConsole_t(SELECT_VALUE(0x470AF0, 0x5CF590, 0));
|
||||||
|
|
||||||
native::VM_Notify = native::VM_Notify_t(SELECT_VALUE(0x610200, 0x569720, 0x4EF450));
|
native::VM_Notify = native::VM_Notify_t(SELECT_VALUE(0x610200, 0x569720, 0x4EF450));
|
||||||
|
|
||||||
native::_longjmp = reinterpret_cast<decltype(longjmp)*>(SELECT_VALUE(0x73AC20, 0x7363BC, 0x655558));
|
native::_longjmp = reinterpret_cast<decltype(longjmp)*>(SELECT_VALUE(0x73AC20, 0x7363BC, 0x655558));
|
||||||
|
|
||||||
native::cmd_args = reinterpret_cast<int*>(SELECT_VALUE(0x1750750, 0x1C978D0, 0x1B455F8));
|
native::cmd_args = reinterpret_cast<int*>(SELECT_VALUE(0x1750750, 0x1C978D0, 0x1B455F8));
|
||||||
native::cmd_argc = reinterpret_cast<int*>(SELECT_VALUE(0x1750794, 0x1C97914, 0x1B4563C));
|
native::cmd_argc = reinterpret_cast<int*>(SELECT_VALUE(0x1750794, 0x1C97914, 0x1B4563C));
|
||||||
native::cmd_argv = reinterpret_cast<const char***>(SELECT_VALUE(0x17507B4, 0x1C97934, 0x1B4565C));
|
native::cmd_argv = reinterpret_cast<const char***>(SELECT_VALUE(0x17507B4, 0x1C97934, 0x1B4565C));
|
||||||
|
|
||||||
native::scrVarGlob = reinterpret_cast<short*>(SELECT_VALUE(0x19AFC80, 0x1E72180, 0x1D3C800));
|
native::scrVarGlob = reinterpret_cast<short*>(SELECT_VALUE(0x19AFC80, 0x1E72180, 0x1D3C800));
|
||||||
native::scrMemTreePub = reinterpret_cast<char**>(SELECT_VALUE(0x196FB00, 0x1E32000, 0x1C152A4));
|
native::scrMemTreePub = reinterpret_cast<char**>(SELECT_VALUE(0x196FB00, 0x1E32000, 0x1C152A4));
|
||||||
native::scrMemTreeGlob = reinterpret_cast<char*>(SELECT_VALUE(0x186DA00, 0x1D6FF00, 0x1C16600));
|
native::scrMemTreeGlob = reinterpret_cast<char*>(SELECT_VALUE(0x186DA00, 0x1D6FF00, 0x1C16600));
|
||||||
|
|
||||||
native::scr_VmPub = reinterpret_cast<native::scrVmPub_t*>(SELECT_VALUE(0x1BF2580, 0x20B4A80, 0x1F5B080));
|
native::scr_VmPub = reinterpret_cast<native::scrVmPub_t*>(SELECT_VALUE(0x1BF2580, 0x20B4A80, 0x1F5B080));
|
||||||
|
|
||||||
native::scr_instanceFunctions = reinterpret_cast<native::scr_call_t*>( SELECT_VALUE(0x184CDB0, 0x1D4F258,
|
native::scr_instanceFunctions = reinterpret_cast<native::scr_call_t*>( SELECT_VALUE(0x184CDB0, 0x1D4F258,
|
||||||
0x1BF59C8));
|
0x1BF59C8));
|
||||||
native::scr_globalFunctions = reinterpret_cast<native::scr_call_t*>( SELECT_VALUE(0x186C68C, 0x1D6EB34,
|
native::scr_globalFunctions = reinterpret_cast<native::scr_call_t*>( SELECT_VALUE(0x186C68C, 0x1D6EB34,
|
||||||
0x1C152A4
|
0x1C152A4
|
||||||
));
|
));
|
||||||
|
|
||||||
native::g_script_error_level = reinterpret_cast<int*>(SELECT_VALUE(0x1BEFCFC, 0x20B21FC, 0x1F5B058));
|
native::g_script_error_level = reinterpret_cast<int*>(SELECT_VALUE(0x1BEFCFC, 0x20B21FC, 0x1F5B058));
|
||||||
native::g_script_error = reinterpret_cast<jmp_buf*>(SELECT_VALUE(0x1BF1D18, 0x20B4218, 0x1F5A818));
|
native::g_script_error = reinterpret_cast<jmp_buf*>(SELECT_VALUE(0x1BF1D18, 0x20B4218, 0x1F5A818));
|
||||||
|
|
||||||
native::g_classMap = reinterpret_cast<native::scr_classStruct_t*>(SELECT_VALUE(0x92D140, 0x8B4300, 0x7C0408));
|
native::g_classMap = reinterpret_cast<native::scr_classStruct_t*>(SELECT_VALUE(0x92D140, 0x8B4300, 0x7C0408));
|
||||||
|
|
||||||
native::levelEntityId = reinterpret_cast<unsigned int*>(SELECT_VALUE(0x1BCBCA4, 0x208E1A4, 0x1CD873C));
|
native::levelEntityId = reinterpret_cast<unsigned int*>(SELECT_VALUE(0x1BCBCA4, 0x208E1A4, 0x1CD873C));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,95 +1,95 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "structs.hpp"
|
#include "structs.hpp"
|
||||||
#include "launcher/launcher.hpp"
|
#include "launcher/launcher.hpp"
|
||||||
|
|
||||||
#define SELECT_VALUE(sp, mp, dedi) (game::is_sp() ? (sp) : (game::is_mp() ? (mp) : (dedi)))
|
#define SELECT_VALUE(sp, mp, dedi) (game::is_sp() ? (sp) : (game::is_mp() ? (mp) : (dedi)))
|
||||||
|
|
||||||
#define SERVER_CD_KEY "Open-IW5-CD-Key"
|
#define SERVER_CD_KEY "Open-IW5-CD-Key"
|
||||||
|
|
||||||
namespace game
|
namespace game
|
||||||
{
|
{
|
||||||
namespace native
|
namespace native
|
||||||
{
|
{
|
||||||
typedef void (*Cmd_AddCommand_t)(const char* cmdName, void (*function)(), cmd_function_t* allocedCmd);
|
typedef void (*Cmd_AddCommand_t)(const char* cmdName, void (*function)(), cmd_function_t* allocedCmd);
|
||||||
extern Cmd_AddCommand_t Cmd_AddCommand;
|
extern Cmd_AddCommand_t Cmd_AddCommand;
|
||||||
|
|
||||||
typedef void (*Com_Error_t)(int code, const char* fmt, ...);
|
typedef void (*Com_Error_t)(int code, const char* fmt, ...);
|
||||||
extern Com_Error_t Com_Error;
|
extern Com_Error_t Com_Error;
|
||||||
|
|
||||||
typedef void (*DB_LoadXAssets_t)(XZoneInfo* zoneInfo, unsigned int zoneCount, int sync);
|
typedef void (*DB_LoadXAssets_t)(XZoneInfo* zoneInfo, unsigned int zoneCount, int sync);
|
||||||
extern DB_LoadXAssets_t DB_LoadXAssets;
|
extern DB_LoadXAssets_t DB_LoadXAssets;
|
||||||
|
|
||||||
typedef void (*Dvar_SetFromStringByName_t)(const char *dvarName, const char *string);
|
typedef void (*Dvar_SetFromStringByName_t)(const char *dvarName, const char *string);
|
||||||
extern Dvar_SetFromStringByName_t Dvar_SetFromStringByName;
|
extern Dvar_SetFromStringByName_t Dvar_SetFromStringByName;
|
||||||
|
|
||||||
typedef int (*G_RunFrame_t)(int, int);
|
typedef int (*G_RunFrame_t)(int, int);
|
||||||
extern G_RunFrame_t G_RunFrame;
|
extern G_RunFrame_t G_RunFrame;
|
||||||
|
|
||||||
typedef void (*MSG_ReadData_t)(msg_t* msg, void* data, int len);
|
typedef void (*MSG_ReadData_t)(msg_t* msg, void* data, int len);
|
||||||
extern MSG_ReadData_t MSG_ReadData;
|
extern MSG_ReadData_t MSG_ReadData;
|
||||||
|
|
||||||
typedef void* (*MT_AllocIndex_t)(int numBytes, int type);
|
typedef void* (*MT_AllocIndex_t)(int numBytes, int type);
|
||||||
extern MT_AllocIndex_t MT_AllocIndex;
|
extern MT_AllocIndex_t MT_AllocIndex;
|
||||||
|
|
||||||
typedef void (*RemoveRefToValue_t)(scriptType_e type, VariableUnion u);
|
typedef void (*RemoveRefToValue_t)(scriptType_e type, VariableUnion u);
|
||||||
extern RemoveRefToValue_t RemoveRefToValue;
|
extern RemoveRefToValue_t RemoveRefToValue;
|
||||||
|
|
||||||
typedef unsigned int (*SL_GetStringOfSize_t)(const char* str, unsigned int user, unsigned int len, int type);
|
typedef unsigned int (*SL_GetStringOfSize_t)(const char* str, unsigned int user, unsigned int len, int type);
|
||||||
extern SL_GetStringOfSize_t SL_GetStringOfSize;
|
extern SL_GetStringOfSize_t SL_GetStringOfSize;
|
||||||
|
|
||||||
typedef void (*Sys_ShowConsole_t)();
|
typedef void (*Sys_ShowConsole_t)();
|
||||||
extern Sys_ShowConsole_t Sys_ShowConsole;
|
extern Sys_ShowConsole_t Sys_ShowConsole;
|
||||||
|
|
||||||
typedef void (*VM_Notify_t)(unsigned int notifyListOwnerId, unsigned int stringValue, VariableValue* top);
|
typedef void (*VM_Notify_t)(unsigned int notifyListOwnerId, unsigned int stringValue, VariableValue* top);
|
||||||
extern VM_Notify_t VM_Notify;
|
extern VM_Notify_t VM_Notify;
|
||||||
|
|
||||||
extern decltype(longjmp)* _longjmp;
|
extern decltype(longjmp)* _longjmp;
|
||||||
|
|
||||||
extern int* cmd_args;
|
extern int* cmd_args;
|
||||||
extern int* cmd_argc;
|
extern int* cmd_argc;
|
||||||
extern const char*** cmd_argv;
|
extern const char*** cmd_argv;
|
||||||
|
|
||||||
extern short* scrVarGlob;
|
extern short* scrVarGlob;
|
||||||
extern char** scrMemTreePub;
|
extern char** scrMemTreePub;
|
||||||
extern char* scrMemTreeGlob;
|
extern char* scrMemTreeGlob;
|
||||||
|
|
||||||
extern scrVmPub_t* scr_VmPub;
|
extern scrVmPub_t* scr_VmPub;
|
||||||
|
|
||||||
extern scr_call_t* scr_instanceFunctions;
|
extern scr_call_t* scr_instanceFunctions;
|
||||||
extern scr_call_t* scr_globalFunctions;
|
extern scr_call_t* scr_globalFunctions;
|
||||||
|
|
||||||
extern unsigned int* levelEntityId;
|
extern unsigned int* levelEntityId;
|
||||||
|
|
||||||
extern int* g_script_error_level;
|
extern int* g_script_error_level;
|
||||||
extern jmp_buf* g_script_error;
|
extern jmp_buf* g_script_error;
|
||||||
|
|
||||||
extern scr_classStruct_t* g_classMap;
|
extern scr_classStruct_t* g_classMap;
|
||||||
|
|
||||||
void AddRefToValue(VariableValue* value);
|
void AddRefToValue(VariableValue* value);
|
||||||
|
|
||||||
void Conbuf_AppendText(const char* message);
|
void Conbuf_AppendText(const char* message);
|
||||||
|
|
||||||
unsigned int FindVariable(unsigned int parentId, unsigned int name);
|
unsigned int FindVariable(unsigned int parentId, unsigned int name);
|
||||||
|
|
||||||
VariableValue GetEntityFieldValue(unsigned int classnum, int entnum, int offset);
|
VariableValue GetEntityFieldValue(unsigned int classnum, int entnum, int offset);
|
||||||
|
|
||||||
void* MT_Alloc(int numBytes, int type);
|
void* MT_Alloc(int numBytes, int type);
|
||||||
|
|
||||||
const float* Scr_AllocVector(const float* v);
|
const float* Scr_AllocVector(const float* v);
|
||||||
void Scr_ClearOutParams();
|
void Scr_ClearOutParams();
|
||||||
scr_entref_t Scr_GetEntityIdRef(unsigned int id);
|
scr_entref_t Scr_GetEntityIdRef(unsigned int id);
|
||||||
scr_call_t Scr_GetFunc(unsigned int index);
|
scr_call_t Scr_GetFunc(unsigned int index);
|
||||||
void Scr_NotifyId(unsigned int id, unsigned int stringValue, unsigned int paramcount);
|
void Scr_NotifyId(unsigned int id, unsigned int stringValue, unsigned int paramcount);
|
||||||
int Scr_SetObjectField(unsigned int classnum, int entnum, int offset);
|
int Scr_SetObjectField(unsigned int classnum, int entnum, int offset);
|
||||||
|
|
||||||
const char* SL_ConvertToString(unsigned int stringValue);
|
const char* SL_ConvertToString(unsigned int stringValue);
|
||||||
unsigned int SL_GetString(const char* str, unsigned int user);
|
unsigned int SL_GetString(const char* str, unsigned int user);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_mp();
|
bool is_mp();
|
||||||
bool is_sp();
|
bool is_sp();
|
||||||
bool is_dedi();
|
bool is_dedi();
|
||||||
|
|
||||||
void initialize(launcher::mode mode);
|
void initialize(launcher::mode mode);
|
||||||
}
|
}
|
||||||
|
@ -1,115 +1,115 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "html_frame.hpp"
|
#include "html_frame.hpp"
|
||||||
|
|
||||||
doc_host_ui_handler::doc_host_ui_handler(html_frame* frame): frame_(frame)
|
doc_host_ui_handler::doc_host_ui_handler(html_frame* frame): frame_(frame)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT doc_host_ui_handler::QueryInterface(REFIID riid, LPVOID* ppvObj)
|
HRESULT doc_host_ui_handler::QueryInterface(REFIID riid, LPVOID* ppvObj)
|
||||||
{
|
{
|
||||||
auto client_site = this->frame_->get_client_site();
|
auto client_site = this->frame_->get_client_site();
|
||||||
if (client_site)
|
if (client_site)
|
||||||
{
|
{
|
||||||
return client_site->QueryInterface(riid, ppvObj);
|
return client_site->QueryInterface(riid, ppvObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG doc_host_ui_handler::AddRef()
|
ULONG doc_host_ui_handler::AddRef()
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG doc_host_ui_handler::Release()
|
ULONG doc_host_ui_handler::Release()
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT doc_host_ui_handler::ShowContextMenu(DWORD /*dwID*/, POINT* /*ppt*/, IUnknown* /*pcmdtReserved*/,
|
HRESULT doc_host_ui_handler::ShowContextMenu(DWORD /*dwID*/, POINT* /*ppt*/, IUnknown* /*pcmdtReserved*/,
|
||||||
IDispatch* /*pdispReserved*/)
|
IDispatch* /*pdispReserved*/)
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT doc_host_ui_handler::ShowUI(DWORD /*dwID*/, IOleInPlaceActiveObject* /*pActiveObject*/,
|
HRESULT doc_host_ui_handler::ShowUI(DWORD /*dwID*/, IOleInPlaceActiveObject* /*pActiveObject*/,
|
||||||
IOleCommandTarget* /*pCommandTarget*/,
|
IOleCommandTarget* /*pCommandTarget*/,
|
||||||
IOleInPlaceFrame* /*pFrame*/, IOleInPlaceUIWindow* /*pDoc*/)
|
IOleInPlaceFrame* /*pFrame*/, IOleInPlaceUIWindow* /*pDoc*/)
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT doc_host_ui_handler::HideUI()
|
HRESULT doc_host_ui_handler::HideUI()
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT doc_host_ui_handler::UpdateUI()
|
HRESULT doc_host_ui_handler::UpdateUI()
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT doc_host_ui_handler::EnableModeless(BOOL /*fEnable*/)
|
HRESULT doc_host_ui_handler::EnableModeless(BOOL /*fEnable*/)
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT doc_host_ui_handler::OnDocWindowActivate(BOOL /*fActivate*/)
|
HRESULT doc_host_ui_handler::OnDocWindowActivate(BOOL /*fActivate*/)
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT doc_host_ui_handler::OnFrameWindowActivate(BOOL /*fActivate*/)
|
HRESULT doc_host_ui_handler::OnFrameWindowActivate(BOOL /*fActivate*/)
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT doc_host_ui_handler::ResizeBorder(LPCRECT /*prcBorder*/, IOleInPlaceUIWindow* /*pUIWindow*/,
|
HRESULT doc_host_ui_handler::ResizeBorder(LPCRECT /*prcBorder*/, IOleInPlaceUIWindow* /*pUIWindow*/,
|
||||||
BOOL /*fRameWindow*/)
|
BOOL /*fRameWindow*/)
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT doc_host_ui_handler::TranslateAcceleratorA(LPMSG /*lpMsg*/, const GUID* pguidCmdGroup, DWORD /*nCmdID*/)
|
HRESULT doc_host_ui_handler::TranslateAcceleratorA(LPMSG /*lpMsg*/, const GUID* pguidCmdGroup, DWORD /*nCmdID*/)
|
||||||
{
|
{
|
||||||
pguidCmdGroup = nullptr;
|
pguidCmdGroup = nullptr;
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT doc_host_ui_handler::GetOptionKeyPath(LPOLESTR* /*pchKey*/, DWORD /*dw*/)
|
HRESULT doc_host_ui_handler::GetOptionKeyPath(LPOLESTR* /*pchKey*/, DWORD /*dw*/)
|
||||||
{
|
{
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT doc_host_ui_handler::GetDropTarget(IDropTarget* /*pDropTarget*/, IDropTarget** /*ppDropTarget*/)
|
HRESULT doc_host_ui_handler::GetDropTarget(IDropTarget* /*pDropTarget*/, IDropTarget** /*ppDropTarget*/)
|
||||||
{
|
{
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT doc_host_ui_handler::GetExternal(IDispatch** ppDispatch)
|
HRESULT doc_host_ui_handler::GetExternal(IDispatch** ppDispatch)
|
||||||
{
|
{
|
||||||
*ppDispatch = this->frame_->get_html_dispatch();
|
*ppDispatch = this->frame_->get_html_dispatch();
|
||||||
return (*ppDispatch) ? S_OK : S_FALSE;
|
return (*ppDispatch) ? S_OK : S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT doc_host_ui_handler::FilterDataObject(IDataObject* /*pDO*/, IDataObject** ppDORet)
|
HRESULT doc_host_ui_handler::FilterDataObject(IDataObject* /*pDO*/, IDataObject** ppDORet)
|
||||||
{
|
{
|
||||||
*ppDORet = nullptr;
|
*ppDORet = nullptr;
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE doc_host_ui_handler::TranslateUrl(DWORD /*dwTranslate*/, OLECHAR __RPC_FAR* /*pchURLIn*/,
|
HRESULT STDMETHODCALLTYPE doc_host_ui_handler::TranslateUrl(DWORD /*dwTranslate*/, OLECHAR __RPC_FAR* /*pchURLIn*/,
|
||||||
OLECHAR __RPC_FAR* __RPC_FAR* ppchURLOut)
|
OLECHAR __RPC_FAR* __RPC_FAR* ppchURLOut)
|
||||||
{
|
{
|
||||||
*ppchURLOut = nullptr;
|
*ppchURLOut = nullptr;
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT doc_host_ui_handler::GetHostInfo(DOCHOSTUIINFO __RPC_FAR * pInfo)
|
HRESULT doc_host_ui_handler::GetHostInfo(DOCHOSTUIINFO __RPC_FAR * pInfo)
|
||||||
{
|
{
|
||||||
pInfo->cbSize = sizeof(DOCHOSTUIINFO);
|
pInfo->cbSize = sizeof(DOCHOSTUIINFO);
|
||||||
pInfo->dwFlags = DOCHOSTUIFLAG_NO3DBORDER | DOCHOSTUIFLAG_DPI_AWARE | DOCHOSTUIFLAG_SCROLL_NO;
|
pInfo->dwFlags = DOCHOSTUIFLAG_NO3DBORDER | DOCHOSTUIFLAG_DPI_AWARE | DOCHOSTUIFLAG_SCROLL_NO;
|
||||||
pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
|
pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -1,47 +1,47 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
class html_frame;
|
class html_frame;
|
||||||
|
|
||||||
class doc_host_ui_handler final : public IDocHostUIHandler
|
class doc_host_ui_handler final : public IDocHostUIHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
doc_host_ui_handler(html_frame* frame);
|
doc_host_ui_handler(html_frame* frame);
|
||||||
virtual ~doc_host_ui_handler() = default;
|
virtual ~doc_host_ui_handler() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
html_frame* frame_;
|
html_frame* frame_;
|
||||||
|
|
||||||
public: // IDocHostUIHandler interface
|
public: // IDocHostUIHandler interface
|
||||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID* ppvObj) override;
|
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID* ppvObj) override;
|
||||||
ULONG STDMETHODCALLTYPE AddRef() override;
|
ULONG STDMETHODCALLTYPE AddRef() override;
|
||||||
ULONG STDMETHODCALLTYPE Release() override;
|
ULONG STDMETHODCALLTYPE Release() override;
|
||||||
HRESULT STDMETHODCALLTYPE ShowContextMenu(
|
HRESULT STDMETHODCALLTYPE ShowContextMenu(
|
||||||
DWORD dwID,
|
DWORD dwID,
|
||||||
POINT __RPC_FAR * ppt,
|
POINT __RPC_FAR * ppt,
|
||||||
IUnknown __RPC_FAR * pcmdtReserved,
|
IUnknown __RPC_FAR * pcmdtReserved,
|
||||||
IDispatch __RPC_FAR * pdispReserved) override;
|
IDispatch __RPC_FAR * pdispReserved) override;
|
||||||
HRESULT STDMETHODCALLTYPE ShowUI(
|
HRESULT STDMETHODCALLTYPE ShowUI(
|
||||||
DWORD dwID,
|
DWORD dwID,
|
||||||
IOleInPlaceActiveObject __RPC_FAR * pActiveObject,
|
IOleInPlaceActiveObject __RPC_FAR * pActiveObject,
|
||||||
IOleCommandTarget __RPC_FAR * pCommandTarget,
|
IOleCommandTarget __RPC_FAR * pCommandTarget,
|
||||||
IOleInPlaceFrame __RPC_FAR * pFrame,
|
IOleInPlaceFrame __RPC_FAR * pFrame,
|
||||||
IOleInPlaceUIWindow __RPC_FAR * pDoc) override;
|
IOleInPlaceUIWindow __RPC_FAR * pDoc) override;
|
||||||
HRESULT STDMETHODCALLTYPE GetHostInfo(DOCHOSTUIINFO __RPC_FAR * pInfo) override;
|
HRESULT STDMETHODCALLTYPE GetHostInfo(DOCHOSTUIINFO __RPC_FAR * pInfo) override;
|
||||||
HRESULT STDMETHODCALLTYPE HideUI() override;
|
HRESULT STDMETHODCALLTYPE HideUI() override;
|
||||||
HRESULT STDMETHODCALLTYPE UpdateUI() override;
|
HRESULT STDMETHODCALLTYPE UpdateUI() override;
|
||||||
HRESULT STDMETHODCALLTYPE EnableModeless(BOOL fEnable) override;
|
HRESULT STDMETHODCALLTYPE EnableModeless(BOOL fEnable) override;
|
||||||
HRESULT STDMETHODCALLTYPE OnDocWindowActivate(BOOL fActivate) override;
|
HRESULT STDMETHODCALLTYPE OnDocWindowActivate(BOOL fActivate) override;
|
||||||
HRESULT STDMETHODCALLTYPE OnFrameWindowActivate(BOOL fActivate) override;
|
HRESULT STDMETHODCALLTYPE OnFrameWindowActivate(BOOL fActivate) override;
|
||||||
HRESULT STDMETHODCALLTYPE ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow __RPC_FAR * pUIWindow,
|
HRESULT STDMETHODCALLTYPE ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow __RPC_FAR * pUIWindow,
|
||||||
BOOL fRameWindow) override;
|
BOOL fRameWindow) override;
|
||||||
HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpMsg, const GUID __RPC_FAR * pguidCmdGroup, DWORD nCmdID)
|
HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpMsg, const GUID __RPC_FAR * pguidCmdGroup, DWORD nCmdID)
|
||||||
override;
|
override;
|
||||||
HRESULT STDMETHODCALLTYPE GetOptionKeyPath(LPOLESTR __RPC_FAR * pchKey, DWORD dw) override;
|
HRESULT STDMETHODCALLTYPE GetOptionKeyPath(LPOLESTR __RPC_FAR * pchKey, DWORD dw) override;
|
||||||
HRESULT STDMETHODCALLTYPE GetDropTarget(IDropTarget __RPC_FAR * pDropTarget,
|
HRESULT STDMETHODCALLTYPE GetDropTarget(IDropTarget __RPC_FAR * pDropTarget,
|
||||||
IDropTarget __RPC_FAR *__RPC_FAR * ppDropTarget) override;
|
IDropTarget __RPC_FAR *__RPC_FAR * ppDropTarget) override;
|
||||||
HRESULT STDMETHODCALLTYPE GetExternal(IDispatch __RPC_FAR *__RPC_FAR * ppDispatch) override;
|
HRESULT STDMETHODCALLTYPE GetExternal(IDispatch __RPC_FAR *__RPC_FAR * ppDispatch) override;
|
||||||
HRESULT STDMETHODCALLTYPE TranslateUrl(DWORD dwTranslate, OLECHAR __RPC_FAR * pchURLIn,
|
HRESULT STDMETHODCALLTYPE TranslateUrl(DWORD dwTranslate, OLECHAR __RPC_FAR * pchURLIn,
|
||||||
OLECHAR __RPC_FAR *__RPC_FAR * ppchURLOut) override;
|
OLECHAR __RPC_FAR *__RPC_FAR * ppchURLOut) override;
|
||||||
HRESULT STDMETHODCALLTYPE FilterDataObject(IDataObject __RPC_FAR * pDO, IDataObject __RPC_FAR *__RPC_FAR * ppDORet)
|
HRESULT STDMETHODCALLTYPE FilterDataObject(IDataObject __RPC_FAR * pDO, IDataObject __RPC_FAR *__RPC_FAR * ppDORet)
|
||||||
override;
|
override;
|
||||||
};
|
};
|
||||||
|
@ -1,48 +1,48 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "html_argument.hpp"
|
#include "html_argument.hpp"
|
||||||
|
|
||||||
html_argument::html_argument(VARIANT* val) : value_(val)
|
html_argument::html_argument(VARIANT* val) : value_(val)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool html_argument::is_empty() const
|
bool html_argument::is_empty() const
|
||||||
{
|
{
|
||||||
return this->value_ == nullptr || this->value_->vt == VT_EMPTY;
|
return this->value_ == nullptr || this->value_->vt == VT_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool html_argument::is_string() const
|
bool html_argument::is_string() const
|
||||||
{
|
{
|
||||||
if (this->is_empty()) return false;
|
if (this->is_empty()) return false;
|
||||||
return this->value_->vt == VT_BSTR;
|
return this->value_->vt == VT_BSTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool html_argument::is_number() const
|
bool html_argument::is_number() const
|
||||||
{
|
{
|
||||||
if (this->is_empty()) return false;
|
if (this->is_empty()) return false;
|
||||||
return this->value_->vt == VT_I4;
|
return this->value_->vt == VT_I4;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool html_argument::is_bool() const
|
bool html_argument::is_bool() const
|
||||||
{
|
{
|
||||||
if (this->is_empty()) return false;
|
if (this->is_empty()) return false;
|
||||||
return this->value_->vt == VT_BOOL;
|
return this->value_->vt == VT_BOOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string html_argument::get_string() const
|
std::string html_argument::get_string() const
|
||||||
{
|
{
|
||||||
if (!this->is_string()) return {};
|
if (!this->is_string()) return {};
|
||||||
std::wstring wide_string(this->value_->bstrVal);
|
std::wstring wide_string(this->value_->bstrVal);
|
||||||
return std::string(wide_string.begin(), wide_string.end());
|
return std::string(wide_string.begin(), wide_string.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
int html_argument::get_number() const
|
int html_argument::get_number() const
|
||||||
{
|
{
|
||||||
if (!this->is_number()) return 0;
|
if (!this->is_number()) return 0;
|
||||||
return this->value_->intVal;
|
return this->value_->intVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool html_argument::get_bool() const
|
bool html_argument::get_bool() const
|
||||||
{
|
{
|
||||||
if(!this->is_bool()) return false;
|
if(!this->is_bool()) return false;
|
||||||
return this->value_->boolVal != FALSE;
|
return this->value_->boolVal != FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
class html_argument final
|
class html_argument final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
html_argument(VARIANT* val);
|
html_argument(VARIANT* val);
|
||||||
|
|
||||||
bool is_empty() const;
|
bool is_empty() const;
|
||||||
|
|
||||||
bool is_string() const;
|
bool is_string() const;
|
||||||
bool is_number() const;
|
bool is_number() const;
|
||||||
bool is_bool() const;
|
bool is_bool() const;
|
||||||
|
|
||||||
std::string get_string() const;
|
std::string get_string() const;
|
||||||
int get_number() const;
|
int get_number() const;
|
||||||
bool get_bool() const;
|
bool get_bool() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VARIANT* value_;
|
VARIANT* value_;
|
||||||
};
|
};
|
||||||
|
@ -1,61 +1,61 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "html_frame.hpp"
|
#include "html_frame.hpp"
|
||||||
|
|
||||||
html_dispatch::html_dispatch(html_frame* frame) : frame_(frame)
|
html_dispatch::html_dispatch(html_frame* frame) : frame_(frame)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT html_dispatch::QueryInterface(const IID& riid, LPVOID* ppvObj)
|
HRESULT html_dispatch::QueryInterface(const IID& riid, LPVOID* ppvObj)
|
||||||
{
|
{
|
||||||
if (!memcmp(&riid, &IID_IUnknown, sizeof(GUID)) ||
|
if (!memcmp(&riid, &IID_IUnknown, sizeof(GUID)) ||
|
||||||
!memcmp(&riid, &IID_IDispatch, sizeof(GUID)))
|
!memcmp(&riid, &IID_IDispatch, sizeof(GUID)))
|
||||||
{
|
{
|
||||||
*ppvObj = this;
|
*ppvObj = this;
|
||||||
this->AddRef();
|
this->AddRef();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
*ppvObj = nullptr;
|
*ppvObj = nullptr;
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG html_dispatch::AddRef()
|
ULONG html_dispatch::AddRef()
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG html_dispatch::Release()
|
ULONG html_dispatch::Release()
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT html_dispatch::GetTypeInfoCount(UINT* pctinfo)
|
HRESULT html_dispatch::GetTypeInfoCount(UINT* pctinfo)
|
||||||
{
|
{
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT html_dispatch::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
|
HRESULT html_dispatch::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
|
||||||
{
|
{
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT html_dispatch::GetIDsOfNames(const IID& riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
|
HRESULT html_dispatch::GetIDsOfNames(const IID& riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < cNames; ++i)
|
for (unsigned int i = 0; i < cNames; ++i)
|
||||||
{
|
{
|
||||||
std::wstring wide_name(rgszNames[i]);
|
std::wstring wide_name(rgszNames[i]);
|
||||||
std::string name(wide_name.begin(), wide_name.end());
|
std::string name(wide_name.begin(), wide_name.end());
|
||||||
|
|
||||||
rgDispId[i] = this->frame_->get_callback_id(name);
|
rgDispId[i] = this->frame_->get_callback_id(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT html_dispatch::Invoke(DISPID dispIdMember, const IID& riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
|
HRESULT html_dispatch::Invoke(DISPID dispIdMember, const IID& riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
|
||||||
VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
|
VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
|
||||||
{
|
{
|
||||||
html_frame::callback_params params(pDispParams, pVarResult);
|
html_frame::callback_params params(pDispParams, pVarResult);
|
||||||
this->frame_->invoke_callback(dispIdMember, ¶ms);
|
this->frame_->invoke_callback(dispIdMember, ¶ms);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
class html_frame;
|
class html_frame;
|
||||||
|
|
||||||
class html_dispatch final : public IDispatch
|
class html_dispatch final : public IDispatch
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
html_dispatch(html_frame* frame);
|
html_dispatch(html_frame* frame);
|
||||||
virtual ~html_dispatch() = default;
|
virtual ~html_dispatch() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
html_frame* frame_;
|
html_frame* frame_;
|
||||||
|
|
||||||
public: // IDispatch interface
|
public: // IDispatch interface
|
||||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID FAR* ppvObj) override;
|
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID FAR* ppvObj) override;
|
||||||
ULONG STDMETHODCALLTYPE AddRef() override;
|
ULONG STDMETHODCALLTYPE AddRef() override;
|
||||||
ULONG STDMETHODCALLTYPE Release() override;
|
ULONG STDMETHODCALLTYPE Release() override;
|
||||||
HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT* pctinfo) override;
|
HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT* pctinfo) override;
|
||||||
HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) override;
|
HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) override;
|
||||||
HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
|
HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
|
||||||
override;
|
override;
|
||||||
HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
|
HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
|
||||||
VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) override;
|
VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) override;
|
||||||
};
|
};
|
||||||
|
@ -1,262 +1,262 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "html_frame.hpp"
|
#include "html_frame.hpp"
|
||||||
#include "utils/nt.hpp"
|
#include "utils/nt.hpp"
|
||||||
|
|
||||||
std::atomic<int> html_frame::frame_count_ = 0;
|
std::atomic<int> html_frame::frame_count_ = 0;
|
||||||
|
|
||||||
html_frame::callback_params::callback_params(DISPPARAMS* params, VARIANT* res) : result(res)
|
html_frame::callback_params::callback_params(DISPPARAMS* params, VARIANT* res) : result(res)
|
||||||
{
|
{
|
||||||
for (auto i = params->cArgs; i > 0; --i)
|
for (auto i = params->cArgs; i > 0; --i)
|
||||||
{
|
{
|
||||||
auto param = ¶ms->rgvarg[i - 1];
|
auto param = ¶ms->rgvarg[i - 1];
|
||||||
this->arguments.emplace_back(param);
|
this->arguments.emplace_back(param);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html_frame::html_frame() : in_place_frame_(this), in_place_site_(this), ui_handler_(this), client_site_(this),
|
html_frame::html_frame() : in_place_frame_(this), in_place_site_(this), ui_handler_(this), client_site_(this),
|
||||||
html_dispatch_(this)
|
html_dispatch_(this)
|
||||||
{
|
{
|
||||||
if (frame_count_++ == 0 && OleInitialize(nullptr) != S_OK)
|
if (frame_count_++ == 0 && OleInitialize(nullptr) != S_OK)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Unable to initialize the OLE library");
|
throw std::runtime_error("Unable to initialize the OLE library");
|
||||||
}
|
}
|
||||||
|
|
||||||
set_browser_feature("FEATURE_BROWSER_EMULATION", 11000);
|
set_browser_feature("FEATURE_BROWSER_EMULATION", 11000);
|
||||||
set_browser_feature("FEATURE_GPU_RENDERING", 1);
|
set_browser_feature("FEATURE_GPU_RENDERING", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
html_frame::~html_frame()
|
html_frame::~html_frame()
|
||||||
{
|
{
|
||||||
if (--frame_count_ <= 0)
|
if (--frame_count_ <= 0)
|
||||||
{
|
{
|
||||||
frame_count_ = 0;
|
frame_count_ = 0;
|
||||||
OleUninitialize();
|
OleUninitialize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void html_frame::object_deleter(IUnknown* object)
|
void html_frame::object_deleter(IUnknown* object)
|
||||||
{
|
{
|
||||||
if (object)
|
if (object)
|
||||||
{
|
{
|
||||||
object->Release();
|
object->Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HWND html_frame::get_window() const
|
HWND html_frame::get_window() const
|
||||||
{
|
{
|
||||||
return this->window_;
|
return this->window_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IOleObject> html_frame::get_browser_object() const
|
std::shared_ptr<IOleObject> html_frame::get_browser_object() const
|
||||||
{
|
{
|
||||||
return this->browser_object_;
|
return this->browser_object_;
|
||||||
}
|
}
|
||||||
|
|
||||||
ole_in_place_frame* html_frame::get_in_place_frame()
|
ole_in_place_frame* html_frame::get_in_place_frame()
|
||||||
{
|
{
|
||||||
return &this->in_place_frame_;
|
return &this->in_place_frame_;
|
||||||
}
|
}
|
||||||
|
|
||||||
ole_in_place_site* html_frame::get_in_place_site()
|
ole_in_place_site* html_frame::get_in_place_site()
|
||||||
{
|
{
|
||||||
return &this->in_place_site_;
|
return &this->in_place_site_;
|
||||||
}
|
}
|
||||||
|
|
||||||
doc_host_ui_handler* html_frame::get_ui_handler()
|
doc_host_ui_handler* html_frame::get_ui_handler()
|
||||||
{
|
{
|
||||||
return &this->ui_handler_;
|
return &this->ui_handler_;
|
||||||
}
|
}
|
||||||
|
|
||||||
ole_client_site* html_frame::get_client_site()
|
ole_client_site* html_frame::get_client_site()
|
||||||
{
|
{
|
||||||
return &this->client_site_;
|
return &this->client_site_;
|
||||||
}
|
}
|
||||||
|
|
||||||
html_dispatch* html_frame::get_html_dispatch()
|
html_dispatch* html_frame::get_html_dispatch()
|
||||||
{
|
{
|
||||||
return &this->html_dispatch_;
|
return &this->html_dispatch_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IWebBrowser2> html_frame::get_web_browser() const
|
std::shared_ptr<IWebBrowser2> html_frame::get_web_browser() const
|
||||||
{
|
{
|
||||||
if (!this->browser_object_) return {};
|
if (!this->browser_object_) return {};
|
||||||
|
|
||||||
IWebBrowser2* web_browser = nullptr;
|
IWebBrowser2* web_browser = nullptr;
|
||||||
if (this->browser_object_->QueryInterface(IID_IWebBrowser2, reinterpret_cast<void**>(&web_browser)) || !web_browser)
|
if (this->browser_object_->QueryInterface(IID_IWebBrowser2, reinterpret_cast<void**>(&web_browser)) || !web_browser)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
return std::shared_ptr<IWebBrowser2>(web_browser, object_deleter);
|
return std::shared_ptr<IWebBrowser2>(web_browser, object_deleter);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IDispatch> html_frame::get_dispatch() const
|
std::shared_ptr<IDispatch> html_frame::get_dispatch() const
|
||||||
{
|
{
|
||||||
const auto web_browser = this->get_web_browser();
|
const auto web_browser = this->get_web_browser();
|
||||||
if (!web_browser) return {};
|
if (!web_browser) return {};
|
||||||
|
|
||||||
IDispatch* dispatch = nullptr;
|
IDispatch* dispatch = nullptr;
|
||||||
if (web_browser->get_Document(&dispatch) || !dispatch) return {};
|
if (web_browser->get_Document(&dispatch) || !dispatch) return {};
|
||||||
|
|
||||||
return std::shared_ptr<IDispatch>(dispatch, object_deleter);
|
return std::shared_ptr<IDispatch>(dispatch, object_deleter);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IHTMLDocument2> html_frame::get_document() const
|
std::shared_ptr<IHTMLDocument2> html_frame::get_document() const
|
||||||
{
|
{
|
||||||
const auto dispatch = this->get_dispatch();
|
const auto dispatch = this->get_dispatch();
|
||||||
if (!dispatch) return {};
|
if (!dispatch) return {};
|
||||||
|
|
||||||
IHTMLDocument2* document = nullptr;
|
IHTMLDocument2* document = nullptr;
|
||||||
if (dispatch->QueryInterface(IID_IHTMLDocument2, reinterpret_cast<void**>(&document)) || !document) return {};
|
if (dispatch->QueryInterface(IID_IHTMLDocument2, reinterpret_cast<void**>(&document)) || !document) return {};
|
||||||
|
|
||||||
return std::shared_ptr<IHTMLDocument2>(document, object_deleter);
|
return std::shared_ptr<IHTMLDocument2>(document, object_deleter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void html_frame::initialize(const HWND window)
|
void html_frame::initialize(const HWND window)
|
||||||
{
|
{
|
||||||
if (this->window_) return;
|
if (this->window_) return;
|
||||||
this->window_ = window;
|
this->window_ = window;
|
||||||
|
|
||||||
this->create_browser();
|
this->create_browser();
|
||||||
this->initialize_browser();
|
this->initialize_browser();
|
||||||
}
|
}
|
||||||
|
|
||||||
void html_frame::create_browser()
|
void html_frame::create_browser()
|
||||||
{
|
{
|
||||||
LPCLASSFACTORY class_factory = nullptr;
|
LPCLASSFACTORY class_factory = nullptr;
|
||||||
if (CoGetClassObject(CLSID_WebBrowser, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, nullptr, IID_IClassFactory,
|
if (CoGetClassObject(CLSID_WebBrowser, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, nullptr, IID_IClassFactory,
|
||||||
reinterpret_cast<void **>(&class_factory)) || !class_factory)
|
reinterpret_cast<void **>(&class_factory)) || !class_factory)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Unable to get the class factory");
|
throw std::runtime_error("Unable to get the class factory");
|
||||||
}
|
}
|
||||||
|
|
||||||
IOleObject* browser_object = nullptr;
|
IOleObject* browser_object = nullptr;
|
||||||
class_factory->CreateInstance(nullptr, IID_IOleObject, reinterpret_cast<void**>(&browser_object));
|
class_factory->CreateInstance(nullptr, IID_IOleObject, reinterpret_cast<void**>(&browser_object));
|
||||||
class_factory->Release();
|
class_factory->Release();
|
||||||
|
|
||||||
if (!browser_object)
|
if (!browser_object)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Unable to create browser object");
|
throw std::runtime_error("Unable to create browser object");
|
||||||
}
|
}
|
||||||
|
|
||||||
this->browser_object_ = std::shared_ptr<IOleObject>(browser_object, [](IOleObject* browser_object)
|
this->browser_object_ = std::shared_ptr<IOleObject>(browser_object, [](IOleObject* browser_object)
|
||||||
{
|
{
|
||||||
if (browser_object)
|
if (browser_object)
|
||||||
{
|
{
|
||||||
browser_object->Close(OLECLOSE_NOSAVE);
|
browser_object->Close(OLECLOSE_NOSAVE);
|
||||||
object_deleter(browser_object);
|
object_deleter(browser_object);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void html_frame::initialize_browser()
|
void html_frame::initialize_browser()
|
||||||
{
|
{
|
||||||
this->browser_object_->SetClientSite(this->get_client_site());
|
this->browser_object_->SetClientSite(this->get_client_site());
|
||||||
this->browser_object_->SetHostNames(L"Hostname", nullptr);
|
this->browser_object_->SetHostNames(L"Hostname", nullptr);
|
||||||
|
|
||||||
RECT rect;
|
RECT rect;
|
||||||
GetClientRect(this->get_window(), &rect);
|
GetClientRect(this->get_window(), &rect);
|
||||||
OleSetContainedObject(this->browser_object_.get(), TRUE);
|
OleSetContainedObject(this->browser_object_.get(), TRUE);
|
||||||
|
|
||||||
this->browser_object_->DoVerb(OLEIVERB_SHOW, nullptr, this->get_client_site(), -1, this->get_window(), &rect);
|
this->browser_object_->DoVerb(OLEIVERB_SHOW, nullptr, this->get_client_site(), -1, this->get_window(), &rect);
|
||||||
this->resize(rect.right, rect.bottom);
|
this->resize(rect.right, rect.bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
void html_frame::set_browser_feature(const std::string& feature, DWORD value)
|
void html_frame::set_browser_feature(const std::string& feature, DWORD value)
|
||||||
{
|
{
|
||||||
const auto registry_path = R"(SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\)" + feature;
|
const auto registry_path = R"(SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\)" + feature;
|
||||||
|
|
||||||
HKEY key = nullptr;
|
HKEY key = nullptr;
|
||||||
if (RegOpenKeyExA(
|
if (RegOpenKeyExA(
|
||||||
HKEY_CURRENT_USER, registry_path.data(), 0,
|
HKEY_CURRENT_USER, registry_path.data(), 0,
|
||||||
KEY_ALL_ACCESS, &key) != ERROR_SUCCESS)
|
KEY_ALL_ACCESS, &key) != ERROR_SUCCESS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const utils::nt::module self;
|
const utils::nt::module self;
|
||||||
const auto name = self.get_name();
|
const auto name = self.get_name();
|
||||||
RegSetValueExA(key, name.data(), 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof(value));
|
RegSetValueExA(key, name.data(), 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof(value));
|
||||||
|
|
||||||
RegCloseKey(key);
|
RegCloseKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void html_frame::resize(const DWORD width, const DWORD height) const
|
void html_frame::resize(const DWORD width, const DWORD height) const
|
||||||
{
|
{
|
||||||
auto web_browser = this->get_web_browser();
|
auto web_browser = this->get_web_browser();
|
||||||
if (web_browser)
|
if (web_browser)
|
||||||
{
|
{
|
||||||
web_browser->put_Left(0);
|
web_browser->put_Left(0);
|
||||||
web_browser->put_Top(0);
|
web_browser->put_Top(0);
|
||||||
web_browser->put_Width(width);
|
web_browser->put_Width(width);
|
||||||
web_browser->put_Height(height);
|
web_browser->put_Height(height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool html_frame::load_url(const std::string& url) const
|
bool html_frame::load_url(const std::string& url) const
|
||||||
{
|
{
|
||||||
auto web_browser = this->get_web_browser();
|
auto web_browser = this->get_web_browser();
|
||||||
if (!web_browser) return false;
|
if (!web_browser) return false;
|
||||||
|
|
||||||
std::wstring wide_url(url.begin(), url.end());
|
std::wstring wide_url(url.begin(), url.end());
|
||||||
|
|
||||||
VARIANT my_url;
|
VARIANT my_url;
|
||||||
VariantInit(&my_url);
|
VariantInit(&my_url);
|
||||||
my_url.vt = VT_BSTR;
|
my_url.vt = VT_BSTR;
|
||||||
my_url.bstrVal = SysAllocString(wide_url.data());
|
my_url.bstrVal = SysAllocString(wide_url.data());
|
||||||
|
|
||||||
const auto _ = gsl::finally([&my_url]() { VariantClear(&my_url); });
|
const auto _ = gsl::finally([&my_url]() { VariantClear(&my_url); });
|
||||||
if (!my_url.bstrVal) return false;
|
if (!my_url.bstrVal) return false;
|
||||||
|
|
||||||
return SUCCEEDED(web_browser->Navigate2(&my_url, nullptr, nullptr, nullptr, nullptr));
|
return SUCCEEDED(web_browser->Navigate2(&my_url, nullptr, nullptr, nullptr, nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool html_frame::load_html(const std::string& html) const
|
bool html_frame::load_html(const std::string& html) const
|
||||||
{
|
{
|
||||||
if (!this->load_url("about:blank")) return false;
|
if (!this->load_url("about:blank")) return false;
|
||||||
|
|
||||||
const auto document = this->get_document();
|
const auto document = this->get_document();
|
||||||
if (!document) return false;
|
if (!document) return false;
|
||||||
|
|
||||||
SAFEARRAYBOUND safe_array_bound = {1, 0};
|
SAFEARRAYBOUND safe_array_bound = {1, 0};
|
||||||
auto safe_array = SafeArrayCreate(VT_VARIANT, 1, &safe_array_bound);
|
auto safe_array = SafeArrayCreate(VT_VARIANT, 1, &safe_array_bound);
|
||||||
if (!safe_array) return false;
|
if (!safe_array) return false;
|
||||||
|
|
||||||
const auto _ = gsl::finally([safe_array]() { SafeArrayDestroy(safe_array); });
|
const auto _ = gsl::finally([safe_array]() { SafeArrayDestroy(safe_array); });
|
||||||
|
|
||||||
VARIANT* variant = nullptr;
|
VARIANT* variant = nullptr;
|
||||||
if (SafeArrayAccessData(safe_array, reinterpret_cast<void**>(&variant)) || !variant) return false;
|
if (SafeArrayAccessData(safe_array, reinterpret_cast<void**>(&variant)) || !variant) return false;
|
||||||
|
|
||||||
std::wstring wide_html(html.begin(), html.end());
|
std::wstring wide_html(html.begin(), html.end());
|
||||||
|
|
||||||
variant->vt = VT_BSTR;
|
variant->vt = VT_BSTR;
|
||||||
variant->bstrVal = SysAllocString(wide_html.data());
|
variant->bstrVal = SysAllocString(wide_html.data());
|
||||||
if (!variant->bstrVal) return false;
|
if (!variant->bstrVal) return false;
|
||||||
|
|
||||||
document->write(safe_array);
|
document->write(safe_array);
|
||||||
document->close();
|
document->close();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int html_frame::get_callback_id(const std::string& name)
|
int html_frame::get_callback_id(const std::string& name)
|
||||||
{
|
{
|
||||||
for (auto i = 0u; i < this->callbacks_.size(); ++i)
|
for (auto i = 0u; i < this->callbacks_.size(); ++i)
|
||||||
{
|
{
|
||||||
if (this->callbacks_[i].first == name)
|
if (this->callbacks_[i].first == name)
|
||||||
{
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void html_frame::invoke_callback(const int id, callback_params* params)
|
void html_frame::invoke_callback(const int id, callback_params* params)
|
||||||
{
|
{
|
||||||
if (id >= 0 && static_cast<unsigned int>(id) < this->callbacks_.size())
|
if (id >= 0 && static_cast<unsigned int>(id) < this->callbacks_.size())
|
||||||
{
|
{
|
||||||
this->callbacks_[id].second(params);
|
this->callbacks_[id].second(params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void html_frame::register_callback(const std::string& name, const std::function<void(callback_params*)>& callback)
|
void html_frame::register_callback(const std::string& name, const std::function<void(callback_params*)>& callback)
|
||||||
{
|
{
|
||||||
this->callbacks_.emplace_back(name, callback);
|
this->callbacks_.emplace_back(name, callback);
|
||||||
}
|
}
|
||||||
|
@ -1,67 +1,67 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "ole_in_place_frame.hpp"
|
#include "ole_in_place_frame.hpp"
|
||||||
#include "ole_in_place_site.hpp"
|
#include "ole_in_place_site.hpp"
|
||||||
#include "doc_host_ui_handler.hpp"
|
#include "doc_host_ui_handler.hpp"
|
||||||
#include "ole_client_site.hpp"
|
#include "ole_client_site.hpp"
|
||||||
#include "html_dispatch.hpp"
|
#include "html_dispatch.hpp"
|
||||||
#include "html_argument.hpp"
|
#include "html_argument.hpp"
|
||||||
|
|
||||||
class html_frame
|
class html_frame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
class callback_params final
|
class callback_params final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
callback_params(DISPPARAMS* params, VARIANT* res);
|
callback_params(DISPPARAMS* params, VARIANT* res);
|
||||||
|
|
||||||
std::vector<html_argument> arguments;
|
std::vector<html_argument> arguments;
|
||||||
html_argument result;
|
html_argument result;
|
||||||
};
|
};
|
||||||
|
|
||||||
html_frame();
|
html_frame();
|
||||||
virtual ~html_frame();
|
virtual ~html_frame();
|
||||||
|
|
||||||
void initialize(HWND window);
|
void initialize(HWND window);
|
||||||
|
|
||||||
void resize(DWORD width, DWORD height) const;
|
void resize(DWORD width, DWORD height) const;
|
||||||
bool load_url(const std::string& url) const;
|
bool load_url(const std::string& url) const;
|
||||||
bool load_html(const std::string& html) const;
|
bool load_html(const std::string& html) const;
|
||||||
|
|
||||||
HWND get_window() const;
|
HWND get_window() const;
|
||||||
|
|
||||||
std::shared_ptr<IOleObject> get_browser_object() const;
|
std::shared_ptr<IOleObject> get_browser_object() const;
|
||||||
std::shared_ptr<IWebBrowser2> get_web_browser() const;
|
std::shared_ptr<IWebBrowser2> get_web_browser() const;
|
||||||
std::shared_ptr<IDispatch> get_dispatch() const;
|
std::shared_ptr<IDispatch> get_dispatch() const;
|
||||||
std::shared_ptr<IHTMLDocument2> get_document() const;
|
std::shared_ptr<IHTMLDocument2> get_document() const;
|
||||||
|
|
||||||
ole_in_place_frame* get_in_place_frame();
|
ole_in_place_frame* get_in_place_frame();
|
||||||
ole_in_place_site* get_in_place_site();
|
ole_in_place_site* get_in_place_site();
|
||||||
doc_host_ui_handler* get_ui_handler();
|
doc_host_ui_handler* get_ui_handler();
|
||||||
ole_client_site* get_client_site();
|
ole_client_site* get_client_site();
|
||||||
html_dispatch* get_html_dispatch();
|
html_dispatch* get_html_dispatch();
|
||||||
|
|
||||||
int get_callback_id(const std::string& name);
|
int get_callback_id(const std::string& name);
|
||||||
void invoke_callback(int id, callback_params* params);
|
void invoke_callback(int id, callback_params* params);
|
||||||
|
|
||||||
void register_callback(const std::string& name, const std::function<void(callback_params*)>& callback);
|
void register_callback(const std::string& name, const std::function<void(callback_params*)>& callback);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HWND window_ = nullptr;
|
HWND window_ = nullptr;
|
||||||
std::shared_ptr<IOleObject> browser_object_;
|
std::shared_ptr<IOleObject> browser_object_;
|
||||||
|
|
||||||
ole_in_place_frame in_place_frame_;
|
ole_in_place_frame in_place_frame_;
|
||||||
ole_in_place_site in_place_site_;
|
ole_in_place_site in_place_site_;
|
||||||
doc_host_ui_handler ui_handler_;
|
doc_host_ui_handler ui_handler_;
|
||||||
ole_client_site client_site_;
|
ole_client_site client_site_;
|
||||||
html_dispatch html_dispatch_;
|
html_dispatch html_dispatch_;
|
||||||
|
|
||||||
std::vector<std::pair<std::string, std::function<void(callback_params*)>>> callbacks_;
|
std::vector<std::pair<std::string, std::function<void(callback_params*)>>> callbacks_;
|
||||||
|
|
||||||
void create_browser();
|
void create_browser();
|
||||||
void initialize_browser();
|
void initialize_browser();
|
||||||
|
|
||||||
static void set_browser_feature(const std::string& feature, DWORD value);
|
static void set_browser_feature(const std::string& feature, DWORD value);
|
||||||
static void object_deleter(IUnknown* object);
|
static void object_deleter(IUnknown* object);
|
||||||
|
|
||||||
static std::atomic<int> frame_count_;
|
static std::atomic<int> frame_count_;
|
||||||
};
|
};
|
||||||
|
@ -1,29 +1,29 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "html_window.hpp"
|
#include "html_window.hpp"
|
||||||
|
|
||||||
window* html_window::get_window()
|
window* html_window::get_window()
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
html_frame* html_window::get_html_frame()
|
html_frame* html_window::get_html_frame()
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT html_window::processor(const UINT message, const WPARAM w_param, const LPARAM l_param)
|
LRESULT html_window::processor(const UINT message, const WPARAM w_param, const LPARAM l_param)
|
||||||
{
|
{
|
||||||
if (message == WM_SIZE)
|
if (message == WM_SIZE)
|
||||||
{
|
{
|
||||||
this->resize(LOWORD(l_param), HIWORD(l_param));
|
this->resize(LOWORD(l_param), HIWORD(l_param));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message == WM_CREATE)
|
if (message == WM_CREATE)
|
||||||
{
|
{
|
||||||
this->initialize(*this);
|
this->initialize(*this);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return window::processor(message, w_param, l_param);
|
return window::processor(message, w_param, l_param);
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "../window.hpp"
|
#include "../window.hpp"
|
||||||
#include "html_frame.hpp"
|
#include "html_frame.hpp"
|
||||||
|
|
||||||
class html_window final : public window, public html_frame
|
class html_window final : public window, public html_frame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
~html_window() = default;
|
~html_window() = default;
|
||||||
|
|
||||||
window* get_window();
|
window* get_window();
|
||||||
html_frame* get_html_frame();
|
html_frame* get_html_frame();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LRESULT processor(UINT message, WPARAM w_param, LPARAM l_param) override;
|
LRESULT processor(UINT message, WPARAM w_param, LPARAM l_param) override;
|
||||||
};
|
};
|
||||||
|
@ -1,77 +1,77 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "html_frame.hpp"
|
#include "html_frame.hpp"
|
||||||
|
|
||||||
ole_client_site::ole_client_site(html_frame* frame): frame_(frame)
|
ole_client_site::ole_client_site(html_frame* frame): frame_(frame)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_client_site::QueryInterface(REFIID riid, LPVOID* ppvObject)
|
HRESULT ole_client_site::QueryInterface(REFIID riid, LPVOID* ppvObject)
|
||||||
{
|
{
|
||||||
if (!memcmp(&riid, &IID_IUnknown, sizeof(GUID)) ||
|
if (!memcmp(&riid, &IID_IUnknown, sizeof(GUID)) ||
|
||||||
!memcmp(&riid, &IID_IOleClientSite, sizeof(GUID)))
|
!memcmp(&riid, &IID_IOleClientSite, sizeof(GUID)))
|
||||||
{
|
{
|
||||||
*ppvObject = this;
|
*ppvObject = this;
|
||||||
this->AddRef();
|
this->AddRef();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!memcmp(&riid, &IID_IOleInPlaceSite, sizeof(GUID)))
|
if (!memcmp(&riid, &IID_IOleInPlaceSite, sizeof(GUID)))
|
||||||
{
|
{
|
||||||
auto in_place_site = this->frame_->get_in_place_site();
|
auto in_place_site = this->frame_->get_in_place_site();
|
||||||
in_place_site->AddRef();
|
in_place_site->AddRef();
|
||||||
*ppvObject = in_place_site;
|
*ppvObject = in_place_site;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!memcmp(&riid, &IID_IDocHostUIHandler, sizeof(GUID)))
|
if (!memcmp(&riid, &IID_IDocHostUIHandler, sizeof(GUID)))
|
||||||
{
|
{
|
||||||
auto ui_handler = this->frame_->get_ui_handler();
|
auto ui_handler = this->frame_->get_ui_handler();
|
||||||
ui_handler->AddRef();
|
ui_handler->AddRef();
|
||||||
*ppvObject = ui_handler;
|
*ppvObject = ui_handler;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
*ppvObject = nullptr;
|
*ppvObject = nullptr;
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG ole_client_site::AddRef()
|
ULONG ole_client_site::AddRef()
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG ole_client_site::Release()
|
ULONG ole_client_site::Release()
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_client_site::SaveObject()
|
HRESULT ole_client_site::SaveObject()
|
||||||
{
|
{
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_client_site::GetMoniker(DWORD /*dwAssign*/, DWORD /*dwWhichMoniker*/, IMoniker** /*ppmk*/)
|
HRESULT ole_client_site::GetMoniker(DWORD /*dwAssign*/, DWORD /*dwWhichMoniker*/, IMoniker** /*ppmk*/)
|
||||||
{
|
{
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_client_site::GetContainer(LPOLECONTAINER* ppContainer)
|
HRESULT ole_client_site::GetContainer(LPOLECONTAINER* ppContainer)
|
||||||
{
|
{
|
||||||
*ppContainer = nullptr;
|
*ppContainer = nullptr;
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_client_site::ShowObject()
|
HRESULT ole_client_site::ShowObject()
|
||||||
{
|
{
|
||||||
return NOERROR;
|
return NOERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_client_site::OnShowWindow(BOOL /*fShow*/)
|
HRESULT ole_client_site::OnShowWindow(BOOL /*fShow*/)
|
||||||
{
|
{
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_client_site::RequestNewObjectLayout()
|
HRESULT ole_client_site::RequestNewObjectLayout()
|
||||||
{
|
{
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
class html_frame;
|
class html_frame;
|
||||||
|
|
||||||
class ole_client_site final : public IOleClientSite
|
class ole_client_site final : public IOleClientSite
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ole_client_site(html_frame* frame);
|
ole_client_site(html_frame* frame);
|
||||||
virtual ~ole_client_site() = default;
|
virtual ~ole_client_site() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
html_frame* frame_;
|
html_frame* frame_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID* ppvObject) override;
|
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID* ppvObject) override;
|
||||||
ULONG STDMETHODCALLTYPE AddRef() override;
|
ULONG STDMETHODCALLTYPE AddRef() override;
|
||||||
ULONG STDMETHODCALLTYPE Release() override;
|
ULONG STDMETHODCALLTYPE Release() override;
|
||||||
HRESULT STDMETHODCALLTYPE SaveObject() override;
|
HRESULT STDMETHODCALLTYPE SaveObject() override;
|
||||||
HRESULT STDMETHODCALLTYPE GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker** ppmk) override;
|
HRESULT STDMETHODCALLTYPE GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker** ppmk) override;
|
||||||
HRESULT STDMETHODCALLTYPE GetContainer(LPOLECONTAINER FAR* ppContainer) override;
|
HRESULT STDMETHODCALLTYPE GetContainer(LPOLECONTAINER FAR* ppContainer) override;
|
||||||
HRESULT STDMETHODCALLTYPE ShowObject() override;
|
HRESULT STDMETHODCALLTYPE ShowObject() override;
|
||||||
HRESULT STDMETHODCALLTYPE OnShowWindow(BOOL fShow) override;
|
HRESULT STDMETHODCALLTYPE OnShowWindow(BOOL fShow) override;
|
||||||
HRESULT STDMETHODCALLTYPE RequestNewObjectLayout() override;
|
HRESULT STDMETHODCALLTYPE RequestNewObjectLayout() override;
|
||||||
};
|
};
|
||||||
|
@ -1,82 +1,82 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "html_frame.hpp"
|
#include "html_frame.hpp"
|
||||||
|
|
||||||
ole_in_place_frame::ole_in_place_frame(html_frame* frame): frame_(frame)
|
ole_in_place_frame::ole_in_place_frame(html_frame* frame): frame_(frame)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_frame::QueryInterface(REFIID /*riid*/, LPVOID* /*ppvObj*/)
|
HRESULT ole_in_place_frame::QueryInterface(REFIID /*riid*/, LPVOID* /*ppvObj*/)
|
||||||
{
|
{
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG ole_in_place_frame::AddRef()
|
ULONG ole_in_place_frame::AddRef()
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG ole_in_place_frame::Release()
|
ULONG ole_in_place_frame::Release()
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_frame::GetWindow(HWND* lphwnd)
|
HRESULT ole_in_place_frame::GetWindow(HWND* lphwnd)
|
||||||
{
|
{
|
||||||
*lphwnd = this->frame_->get_window();
|
*lphwnd = this->frame_->get_window();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_frame::ContextSensitiveHelp(BOOL /*fEnterMode*/)
|
HRESULT ole_in_place_frame::ContextSensitiveHelp(BOOL /*fEnterMode*/)
|
||||||
{
|
{
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_frame::GetBorder(LPRECT /*lprectBorder*/)
|
HRESULT ole_in_place_frame::GetBorder(LPRECT /*lprectBorder*/)
|
||||||
{
|
{
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_frame::RequestBorderSpace(LPCBORDERWIDTHS /*pborderwidths*/)
|
HRESULT ole_in_place_frame::RequestBorderSpace(LPCBORDERWIDTHS /*pborderwidths*/)
|
||||||
{
|
{
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_frame::SetBorderSpace(LPCBORDERWIDTHS /*pborderwidths*/)
|
HRESULT ole_in_place_frame::SetBorderSpace(LPCBORDERWIDTHS /*pborderwidths*/)
|
||||||
{
|
{
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_frame::SetActiveObject(IOleInPlaceActiveObject* /*pActiveObject*/, LPCOLESTR /*pszObjName*/)
|
HRESULT ole_in_place_frame::SetActiveObject(IOleInPlaceActiveObject* /*pActiveObject*/, LPCOLESTR /*pszObjName*/)
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_frame::InsertMenus(HMENU /*hmenuShared*/, LPOLEMENUGROUPWIDTHS /*lpMenuWidths*/)
|
HRESULT ole_in_place_frame::InsertMenus(HMENU /*hmenuShared*/, LPOLEMENUGROUPWIDTHS /*lpMenuWidths*/)
|
||||||
{
|
{
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_frame::SetMenu(HMENU /*hmenuShared*/, HOLEMENU /*holemenu*/, HWND /*hwndActiveObject*/)
|
HRESULT ole_in_place_frame::SetMenu(HMENU /*hmenuShared*/, HOLEMENU /*holemenu*/, HWND /*hwndActiveObject*/)
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_frame::RemoveMenus(HMENU /*hmenuShared*/)
|
HRESULT ole_in_place_frame::RemoveMenus(HMENU /*hmenuShared*/)
|
||||||
{
|
{
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_frame::SetStatusText(LPCOLESTR /*pszStatusText*/)
|
HRESULT ole_in_place_frame::SetStatusText(LPCOLESTR /*pszStatusText*/)
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_frame::EnableModeless(BOOL /*fEnable*/)
|
HRESULT ole_in_place_frame::EnableModeless(BOOL /*fEnable*/)
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_frame::TranslateAcceleratorA(LPMSG /*lpmsg*/, WORD /*wID*/)
|
HRESULT ole_in_place_frame::TranslateAcceleratorA(LPMSG /*lpmsg*/, WORD /*wID*/)
|
||||||
{
|
{
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,30 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
class html_frame;
|
class html_frame;
|
||||||
|
|
||||||
class ole_in_place_frame final : public IOleInPlaceFrame
|
class ole_in_place_frame final : public IOleInPlaceFrame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ole_in_place_frame(html_frame* frame);
|
ole_in_place_frame(html_frame* frame);
|
||||||
virtual ~ole_in_place_frame() = default;
|
virtual ~ole_in_place_frame() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
html_frame* frame_;
|
html_frame* frame_;
|
||||||
|
|
||||||
public: // IOleInPlaceFrame interface
|
public: // IOleInPlaceFrame interface
|
||||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID FAR* ppvObj) override;
|
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID FAR* ppvObj) override;
|
||||||
ULONG STDMETHODCALLTYPE AddRef() override;
|
ULONG STDMETHODCALLTYPE AddRef() override;
|
||||||
ULONG STDMETHODCALLTYPE Release() override;
|
ULONG STDMETHODCALLTYPE Release() override;
|
||||||
HRESULT STDMETHODCALLTYPE GetWindow(HWND FAR* lphwnd) override;
|
HRESULT STDMETHODCALLTYPE GetWindow(HWND FAR* lphwnd) override;
|
||||||
HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode) override;
|
HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode) override;
|
||||||
HRESULT STDMETHODCALLTYPE GetBorder(LPRECT lprectBorder) override;
|
HRESULT STDMETHODCALLTYPE GetBorder(LPRECT lprectBorder) override;
|
||||||
HRESULT STDMETHODCALLTYPE RequestBorderSpace(LPCBORDERWIDTHS pborderwidths) override;
|
HRESULT STDMETHODCALLTYPE RequestBorderSpace(LPCBORDERWIDTHS pborderwidths) override;
|
||||||
HRESULT STDMETHODCALLTYPE SetBorderSpace(LPCBORDERWIDTHS pborderwidths) override;
|
HRESULT STDMETHODCALLTYPE SetBorderSpace(LPCBORDERWIDTHS pborderwidths) override;
|
||||||
HRESULT STDMETHODCALLTYPE SetActiveObject(IOleInPlaceActiveObject* pActiveObject, LPCOLESTR pszObjName) override;
|
HRESULT STDMETHODCALLTYPE SetActiveObject(IOleInPlaceActiveObject* pActiveObject, LPCOLESTR pszObjName) override;
|
||||||
HRESULT STDMETHODCALLTYPE InsertMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths) override;
|
HRESULT STDMETHODCALLTYPE InsertMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths) override;
|
||||||
HRESULT STDMETHODCALLTYPE SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject) override;
|
HRESULT STDMETHODCALLTYPE SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject) override;
|
||||||
HRESULT STDMETHODCALLTYPE RemoveMenus(HMENU hmenuShared) override;
|
HRESULT STDMETHODCALLTYPE RemoveMenus(HMENU hmenuShared) override;
|
||||||
HRESULT STDMETHODCALLTYPE SetStatusText(LPCOLESTR pszStatusText) override;
|
HRESULT STDMETHODCALLTYPE SetStatusText(LPCOLESTR pszStatusText) override;
|
||||||
HRESULT STDMETHODCALLTYPE EnableModeless(BOOL fEnable) override;
|
HRESULT STDMETHODCALLTYPE EnableModeless(BOOL fEnable) override;
|
||||||
HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpmsg, WORD wID) override;
|
HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpmsg, WORD wID) override;
|
||||||
};
|
};
|
||||||
|
@ -1,105 +1,105 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "html_frame.hpp"
|
#include "html_frame.hpp"
|
||||||
|
|
||||||
ole_in_place_site::ole_in_place_site(html_frame* frame) : frame_(frame)
|
ole_in_place_site::ole_in_place_site(html_frame* frame) : frame_(frame)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_site::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
|
HRESULT ole_in_place_site::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
|
||||||
{
|
{
|
||||||
auto client_site = this->frame_->get_client_site();
|
auto client_site = this->frame_->get_client_site();
|
||||||
if (client_site)
|
if (client_site)
|
||||||
{
|
{
|
||||||
return client_site->QueryInterface(riid, ppvObj);
|
return client_site->QueryInterface(riid, ppvObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG ole_in_place_site::AddRef()
|
ULONG ole_in_place_site::AddRef()
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG ole_in_place_site::Release()
|
ULONG ole_in_place_site::Release()
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_site::GetWindow(HWND* lphwnd)
|
HRESULT ole_in_place_site::GetWindow(HWND* lphwnd)
|
||||||
{
|
{
|
||||||
*lphwnd = this->frame_->get_window();
|
*lphwnd = this->frame_->get_window();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_site::ContextSensitiveHelp(BOOL /*fEnterMode*/)
|
HRESULT ole_in_place_site::ContextSensitiveHelp(BOOL /*fEnterMode*/)
|
||||||
{
|
{
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_site::CanInPlaceActivate()
|
HRESULT ole_in_place_site::CanInPlaceActivate()
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_site::OnInPlaceActivate()
|
HRESULT ole_in_place_site::OnInPlaceActivate()
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_site::OnUIActivate()
|
HRESULT ole_in_place_site::OnUIActivate()
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_site::GetWindowContext(LPOLEINPLACEFRAME* lplpFrame, LPOLEINPLACEUIWINDOW* lplpDoc,
|
HRESULT ole_in_place_site::GetWindowContext(LPOLEINPLACEFRAME* lplpFrame, LPOLEINPLACEUIWINDOW* lplpDoc,
|
||||||
LPRECT /*lprcPosRect*/, LPRECT /*lprcClipRect*/,
|
LPRECT /*lprcPosRect*/, LPRECT /*lprcClipRect*/,
|
||||||
LPOLEINPLACEFRAMEINFO lpFrameInfo)
|
LPOLEINPLACEFRAMEINFO lpFrameInfo)
|
||||||
{
|
{
|
||||||
*lplpFrame = this->frame_->get_in_place_frame();
|
*lplpFrame = this->frame_->get_in_place_frame();
|
||||||
*lplpDoc = nullptr;
|
*lplpDoc = nullptr;
|
||||||
|
|
||||||
lpFrameInfo->fMDIApp = FALSE;
|
lpFrameInfo->fMDIApp = FALSE;
|
||||||
lpFrameInfo->hwndFrame = this->frame_->get_window();
|
lpFrameInfo->hwndFrame = this->frame_->get_window();
|
||||||
lpFrameInfo->haccel = nullptr;
|
lpFrameInfo->haccel = nullptr;
|
||||||
lpFrameInfo->cAccelEntries = 0;
|
lpFrameInfo->cAccelEntries = 0;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_site::Scroll(SIZE /*scrollExtent*/)
|
HRESULT ole_in_place_site::Scroll(SIZE /*scrollExtent*/)
|
||||||
{
|
{
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_site::OnUIDeactivate(BOOL /*fUndoable*/)
|
HRESULT ole_in_place_site::OnUIDeactivate(BOOL /*fUndoable*/)
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_site::OnInPlaceDeactivate()
|
HRESULT ole_in_place_site::OnInPlaceDeactivate()
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_site::DiscardUndoState()
|
HRESULT ole_in_place_site::DiscardUndoState()
|
||||||
{
|
{
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_site::DeactivateAndUndo()
|
HRESULT ole_in_place_site::DeactivateAndUndo()
|
||||||
{
|
{
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ole_in_place_site::OnPosRectChange(LPCRECT lprcPosRect)
|
HRESULT ole_in_place_site::OnPosRectChange(LPCRECT lprcPosRect)
|
||||||
{
|
{
|
||||||
IOleInPlaceObject* in_place = nullptr;
|
IOleInPlaceObject* in_place = nullptr;
|
||||||
if (!this->frame_->get_browser_object()->QueryInterface(IID_IOleInPlaceObject, reinterpret_cast<void**>(&in_place)))
|
if (!this->frame_->get_browser_object()->QueryInterface(IID_IOleInPlaceObject, reinterpret_cast<void**>(&in_place)))
|
||||||
{
|
{
|
||||||
in_place->SetObjectRects(lprcPosRect, lprcPosRect);
|
in_place->SetObjectRects(lprcPosRect, lprcPosRect);
|
||||||
in_place->Release();
|
in_place->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,32 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
class html_frame;
|
class html_frame;
|
||||||
|
|
||||||
class ole_in_place_site final : public IOleInPlaceSite
|
class ole_in_place_site final : public IOleInPlaceSite
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ole_in_place_site(html_frame* frame);
|
ole_in_place_site(html_frame* frame);
|
||||||
virtual ~ole_in_place_site() = default;
|
virtual ~ole_in_place_site() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
html_frame* frame_;
|
html_frame* frame_;
|
||||||
|
|
||||||
public: // IOleInPlaceSite interface
|
public: // IOleInPlaceSite interface
|
||||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID FAR* ppvObj) override;
|
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID FAR* ppvObj) override;
|
||||||
ULONG STDMETHODCALLTYPE AddRef() override;
|
ULONG STDMETHODCALLTYPE AddRef() override;
|
||||||
ULONG STDMETHODCALLTYPE Release() override;
|
ULONG STDMETHODCALLTYPE Release() override;
|
||||||
HRESULT STDMETHODCALLTYPE GetWindow(HWND FAR* lphwnd) override;
|
HRESULT STDMETHODCALLTYPE GetWindow(HWND FAR* lphwnd) override;
|
||||||
HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode) override;
|
HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode) override;
|
||||||
HRESULT STDMETHODCALLTYPE CanInPlaceActivate() override;
|
HRESULT STDMETHODCALLTYPE CanInPlaceActivate() override;
|
||||||
HRESULT STDMETHODCALLTYPE OnInPlaceActivate() override;
|
HRESULT STDMETHODCALLTYPE OnInPlaceActivate() override;
|
||||||
HRESULT STDMETHODCALLTYPE OnUIActivate() override;
|
HRESULT STDMETHODCALLTYPE OnUIActivate() override;
|
||||||
HRESULT STDMETHODCALLTYPE GetWindowContext(LPOLEINPLACEFRAME FAR* lplpFrame, LPOLEINPLACEUIWINDOW FAR* lplpDoc,
|
HRESULT STDMETHODCALLTYPE GetWindowContext(LPOLEINPLACEFRAME FAR* lplpFrame, LPOLEINPLACEUIWINDOW FAR* lplpDoc,
|
||||||
LPRECT lprcPosRect, LPRECT lprcClipRect,
|
LPRECT lprcPosRect, LPRECT lprcClipRect,
|
||||||
LPOLEINPLACEFRAMEINFO lpFrameInfo) override;
|
LPOLEINPLACEFRAMEINFO lpFrameInfo) override;
|
||||||
HRESULT STDMETHODCALLTYPE Scroll(SIZE scrollExtent) override;
|
HRESULT STDMETHODCALLTYPE Scroll(SIZE scrollExtent) override;
|
||||||
HRESULT STDMETHODCALLTYPE OnUIDeactivate(BOOL fUndoable) override;
|
HRESULT STDMETHODCALLTYPE OnUIDeactivate(BOOL fUndoable) override;
|
||||||
HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate() override;
|
HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate() override;
|
||||||
HRESULT STDMETHODCALLTYPE DiscardUndoState() override;
|
HRESULT STDMETHODCALLTYPE DiscardUndoState() override;
|
||||||
HRESULT STDMETHODCALLTYPE DeactivateAndUndo() override;
|
HRESULT STDMETHODCALLTYPE DeactivateAndUndo() override;
|
||||||
HRESULT STDMETHODCALLTYPE OnPosRectChange(LPCRECT lprcPosRect) override;
|
HRESULT STDMETHODCALLTYPE OnPosRectChange(LPCRECT lprcPosRect) override;
|
||||||
};
|
};
|
||||||
|
@ -1,88 +1,88 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "launcher.hpp"
|
#include "launcher.hpp"
|
||||||
#include "utils/nt.hpp"
|
#include "utils/nt.hpp"
|
||||||
|
|
||||||
launcher::launcher()
|
launcher::launcher()
|
||||||
{
|
{
|
||||||
this->create_settings_menu();
|
this->create_settings_menu();
|
||||||
this->create_main_menu();
|
this->create_main_menu();
|
||||||
}
|
}
|
||||||
|
|
||||||
void launcher::create_main_menu()
|
void launcher::create_main_menu()
|
||||||
{
|
{
|
||||||
this->main_window_.register_callback("selectMode", [this](html_frame::callback_params* params)
|
this->main_window_.register_callback("selectMode", [this](html_frame::callback_params* params)
|
||||||
{
|
{
|
||||||
if (params->arguments.empty()) return;
|
if (params->arguments.empty()) return;
|
||||||
|
|
||||||
const auto param = params->arguments[0];
|
const auto param = params->arguments[0];
|
||||||
if (!param.is_number()) return;
|
if (!param.is_number()) return;
|
||||||
|
|
||||||
const auto number = param.get_number();
|
const auto number = param.get_number();
|
||||||
if (number == singleplayer || number == multiplayer)
|
if (number == singleplayer || number == multiplayer)
|
||||||
{
|
{
|
||||||
this->select_mode(static_cast<mode>(number));
|
this->select_mode(static_cast<mode>(number));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this->main_window_.register_callback("showSettings", [this](html_frame::callback_params*)
|
this->main_window_.register_callback("showSettings", [this](html_frame::callback_params*)
|
||||||
{
|
{
|
||||||
this->settings_window_.show();
|
this->settings_window_.show();
|
||||||
});
|
});
|
||||||
|
|
||||||
this->main_window_.set_callback(
|
this->main_window_.set_callback(
|
||||||
[](window* window, const UINT message, const WPARAM w_param, const LPARAM l_param) -> LRESULT
|
[](window* window, const UINT message, const WPARAM w_param, const LPARAM l_param) -> LRESULT
|
||||||
{
|
{
|
||||||
if (message == WM_CLOSE)
|
if (message == WM_CLOSE)
|
||||||
{
|
{
|
||||||
window::close_all();
|
window::close_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
return DefWindowProcA(*window, message, w_param, l_param);
|
return DefWindowProcA(*window, message, w_param, l_param);
|
||||||
});
|
});
|
||||||
|
|
||||||
this->main_window_.create("Open-IW5", 615, 300);
|
this->main_window_.create("Open-IW5", 615, 300);
|
||||||
this->main_window_.load_html(load_content(MENU_MAIN));
|
this->main_window_.load_html(load_content(MENU_MAIN));
|
||||||
this->main_window_.show();
|
this->main_window_.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void launcher::create_settings_menu()
|
void launcher::create_settings_menu()
|
||||||
{
|
{
|
||||||
this->settings_window_.set_callback(
|
this->settings_window_.set_callback(
|
||||||
[](window* window, const UINT message, const WPARAM w_param, const LPARAM l_param) -> LRESULT
|
[](window* window, const UINT message, const WPARAM w_param, const LPARAM l_param) -> LRESULT
|
||||||
{
|
{
|
||||||
if (message == WM_CLOSE)
|
if (message == WM_CLOSE)
|
||||||
{
|
{
|
||||||
window->hide();
|
window->hide();
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DefWindowProcA(*window, message, w_param, l_param);
|
return DefWindowProcA(*window, message, w_param, l_param);
|
||||||
});
|
});
|
||||||
|
|
||||||
this->settings_window_.create("Open-IW5 Settings", 400, 200, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU);
|
this->settings_window_.create("Open-IW5 Settings", 400, 200, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU);
|
||||||
this->settings_window_.load_html(load_content(MENU_SETTINGS));
|
this->settings_window_.load_html(load_content(MENU_SETTINGS));
|
||||||
}
|
}
|
||||||
|
|
||||||
launcher::mode launcher::run() const
|
launcher::mode launcher::run() const
|
||||||
{
|
{
|
||||||
window::run();
|
window::run();
|
||||||
return this->mode_;
|
return this->mode_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void launcher::select_mode(const mode mode)
|
void launcher::select_mode(const mode mode)
|
||||||
{
|
{
|
||||||
this->mode_ = mode;
|
this->mode_ = mode;
|
||||||
this->settings_window_.close();
|
this->settings_window_.close();
|
||||||
this->main_window_.close();
|
this->main_window_.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string launcher::load_content(const int res)
|
std::string launcher::load_content(const int res)
|
||||||
{
|
{
|
||||||
const auto resource = FindResource(utils::nt::module(), MAKEINTRESOURCE(res), RT_RCDATA);
|
const auto resource = FindResource(utils::nt::module(), MAKEINTRESOURCE(res), RT_RCDATA);
|
||||||
if (!resource) return {};
|
if (!resource) return {};
|
||||||
|
|
||||||
const auto handle = LoadResource(nullptr, resource);
|
const auto handle = LoadResource(nullptr, resource);
|
||||||
if (!handle) return {};
|
if (!handle) return {};
|
||||||
|
|
||||||
return std::string(LPSTR(LockResource(handle)), SizeofResource(nullptr, resource));
|
return std::string(LPSTR(LockResource(handle)), SizeofResource(nullptr, resource));
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,31 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "html/html_window.hpp"
|
#include "html/html_window.hpp"
|
||||||
|
|
||||||
class launcher final
|
class launcher final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum mode
|
enum mode
|
||||||
{
|
{
|
||||||
none,
|
none,
|
||||||
singleplayer,
|
singleplayer,
|
||||||
multiplayer,
|
multiplayer,
|
||||||
server,
|
server,
|
||||||
};
|
};
|
||||||
|
|
||||||
launcher();
|
launcher();
|
||||||
|
|
||||||
mode run() const;
|
mode run() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mode mode_ = none;
|
mode mode_ = none;
|
||||||
|
|
||||||
html_window main_window_;
|
html_window main_window_;
|
||||||
html_window settings_window_;
|
html_window settings_window_;
|
||||||
|
|
||||||
void select_mode(mode mode);
|
void select_mode(mode mode);
|
||||||
|
|
||||||
void create_main_menu();
|
void create_main_menu();
|
||||||
void create_settings_menu();
|
void create_settings_menu();
|
||||||
|
|
||||||
static std::string load_content(int res);
|
static std::string load_content(int res);
|
||||||
};
|
};
|
||||||
|
@ -1,180 +1,180 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "window.hpp"
|
#include "window.hpp"
|
||||||
|
|
||||||
std::mutex window::mutex_;
|
std::mutex window::mutex_;
|
||||||
std::vector<window*> window::windows_;
|
std::vector<window*> window::windows_;
|
||||||
|
|
||||||
window::window()
|
window::window()
|
||||||
{
|
{
|
||||||
ZeroMemory(&this->wc_, sizeof(this->wc_));
|
ZeroMemory(&this->wc_, sizeof(this->wc_));
|
||||||
|
|
||||||
this->classname_ = "window-base-" + std::to_string(time(nullptr));
|
this->classname_ = "window-base-" + std::to_string(time(nullptr));
|
||||||
|
|
||||||
this->wc_.cbSize = sizeof(this->wc_);
|
this->wc_.cbSize = sizeof(this->wc_);
|
||||||
this->wc_.style = CS_HREDRAW | CS_VREDRAW;
|
this->wc_.style = CS_HREDRAW | CS_VREDRAW;
|
||||||
this->wc_.lpfnWndProc = static_processor;
|
this->wc_.lpfnWndProc = static_processor;
|
||||||
this->wc_.hInstance = GetModuleHandle(nullptr);
|
this->wc_.hInstance = GetModuleHandle(nullptr);
|
||||||
this->wc_.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
this->wc_.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||||
this->wc_.hIcon = LoadIcon(this->wc_.hInstance, MAKEINTRESOURCE(102));
|
this->wc_.hIcon = LoadIcon(this->wc_.hInstance, MAKEINTRESOURCE(102));
|
||||||
this->wc_.hIconSm = this->wc_.hIcon;
|
this->wc_.hIconSm = this->wc_.hIcon;
|
||||||
this->wc_.hbrBackground = HBRUSH(COLOR_WINDOW);
|
this->wc_.hbrBackground = HBRUSH(COLOR_WINDOW);
|
||||||
this->wc_.lpszClassName = this->classname_.data();
|
this->wc_.lpszClassName = this->classname_.data();
|
||||||
RegisterClassEx(&this->wc_);
|
RegisterClassEx(&this->wc_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void window::create(const std::string& title, const int width, const int height, const long flags)
|
void window::create(const std::string& title, const int width, const int height, const long flags)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
std::lock_guard _(mutex_);
|
std::lock_guard _(mutex_);
|
||||||
windows_.push_back(this);
|
windows_.push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto x = (GetSystemMetrics(SM_CXSCREEN) - width) / 2;
|
const auto x = (GetSystemMetrics(SM_CXSCREEN) - width) / 2;
|
||||||
const auto y = (GetSystemMetrics(SM_CYSCREEN) - height) / 2;
|
const auto y = (GetSystemMetrics(SM_CYSCREEN) - height) / 2;
|
||||||
|
|
||||||
this->handle_ = CreateWindowExA(NULL, this->wc_.lpszClassName, title.data(), flags, x, y, width, height, nullptr,
|
this->handle_ = CreateWindowExA(NULL, this->wc_.lpszClassName, title.data(), flags, x, y, width, height, nullptr,
|
||||||
nullptr, this->wc_.hInstance, this);
|
nullptr, this->wc_.hInstance, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
window::~window()
|
window::~window()
|
||||||
{
|
{
|
||||||
this->close();
|
this->close();
|
||||||
UnregisterClass(this->wc_.lpszClassName, this->wc_.hInstance);
|
UnregisterClass(this->wc_.lpszClassName, this->wc_.hInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
void window::close()
|
void window::close()
|
||||||
{
|
{
|
||||||
if (!this->handle_) return;
|
if (!this->handle_) return;
|
||||||
|
|
||||||
SendMessageA(this->handle_, WM_KILL_WINDOW, NULL, NULL);
|
SendMessageA(this->handle_, WM_KILL_WINDOW, NULL, NULL);
|
||||||
this->handle_ = nullptr;
|
this->handle_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void window::run()
|
void window::run()
|
||||||
{
|
{
|
||||||
MSG msg;
|
MSG msg;
|
||||||
while (GetMessage(&msg, nullptr, 0, 0))
|
while (GetMessage(&msg, nullptr, 0, 0))
|
||||||
{
|
{
|
||||||
TranslateMessage(&msg);
|
TranslateMessage(&msg);
|
||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void window::close_all()
|
void window::close_all()
|
||||||
{
|
{
|
||||||
std::unique_lock lock(mutex_);
|
std::unique_lock lock(mutex_);
|
||||||
auto window_list = windows_;
|
auto window_list = windows_;
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
const auto current_thread_id = GetCurrentThreadId();
|
const auto current_thread_id = GetCurrentThreadId();
|
||||||
for (auto& window : window_list)
|
for (auto& window : window_list)
|
||||||
{
|
{
|
||||||
const auto thread_id = GetWindowThreadProcessId(*window, nullptr);
|
const auto thread_id = GetWindowThreadProcessId(*window, nullptr);
|
||||||
|
|
||||||
if (thread_id == current_thread_id)
|
if (thread_id == current_thread_id)
|
||||||
{
|
{
|
||||||
window->close();
|
window->close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void window::remove_window(const window* window)
|
void window::remove_window(const window* window)
|
||||||
{
|
{
|
||||||
std::lock_guard _(mutex_);
|
std::lock_guard _(mutex_);
|
||||||
|
|
||||||
for (auto i = windows_.begin(); i != windows_.end(); ++i)
|
for (auto i = windows_.begin(); i != windows_.end(); ++i)
|
||||||
{
|
{
|
||||||
if (*i == window)
|
if (*i == window)
|
||||||
{
|
{
|
||||||
windows_.erase(i);
|
windows_.erase(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int window::get_window_count()
|
int window::get_window_count()
|
||||||
{
|
{
|
||||||
std::lock_guard _(mutex_);
|
std::lock_guard _(mutex_);
|
||||||
|
|
||||||
auto count = 0;
|
auto count = 0;
|
||||||
const auto current_thread_id = GetCurrentThreadId();
|
const auto current_thread_id = GetCurrentThreadId();
|
||||||
|
|
||||||
for (const auto& window : windows_)
|
for (const auto& window : windows_)
|
||||||
{
|
{
|
||||||
const auto thread_id = GetWindowThreadProcessId(*window, nullptr);
|
const auto thread_id = GetWindowThreadProcessId(*window, nullptr);
|
||||||
|
|
||||||
if (thread_id == current_thread_id)
|
if (thread_id == current_thread_id)
|
||||||
{
|
{
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void window::show() const
|
void window::show() const
|
||||||
{
|
{
|
||||||
ShowWindow(this->handle_, SW_SHOW);
|
ShowWindow(this->handle_, SW_SHOW);
|
||||||
UpdateWindow(this->handle_);
|
UpdateWindow(this->handle_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void window::hide() const
|
void window::hide() const
|
||||||
{
|
{
|
||||||
ShowWindow(this->handle_, SW_HIDE);
|
ShowWindow(this->handle_, SW_HIDE);
|
||||||
UpdateWindow(this->handle_);
|
UpdateWindow(this->handle_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void window::set_callback(const std::function<LRESULT(window*, UINT, WPARAM, LPARAM)>& callback)
|
void window::set_callback(const std::function<LRESULT(window*, UINT, WPARAM, LPARAM)>& callback)
|
||||||
{
|
{
|
||||||
this->callback_ = callback;
|
this->callback_ = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT window::processor(const UINT message, const WPARAM w_param, const LPARAM l_param)
|
LRESULT window::processor(const UINT message, const WPARAM w_param, const LPARAM l_param)
|
||||||
{
|
{
|
||||||
if (message == WM_DESTROY)
|
if (message == WM_DESTROY)
|
||||||
{
|
{
|
||||||
remove_window(this);
|
remove_window(this);
|
||||||
|
|
||||||
if (get_window_count() == 0)
|
if (get_window_count() == 0)
|
||||||
{
|
{
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message == WM_KILL_WINDOW)
|
if (message == WM_KILL_WINDOW)
|
||||||
{
|
{
|
||||||
DestroyWindow(*this);
|
DestroyWindow(*this);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->callback_)
|
if (this->callback_)
|
||||||
{
|
{
|
||||||
return this->callback_(this, message, w_param, l_param);
|
return this->callback_(this, message, w_param, l_param);
|
||||||
}
|
}
|
||||||
|
|
||||||
return DefWindowProc(*this, message, w_param, l_param);
|
return DefWindowProc(*this, message, w_param, l_param);
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK window::static_processor(HWND hwnd, UINT message, WPARAM w_param, LPARAM l_param)
|
LRESULT CALLBACK window::static_processor(HWND hwnd, UINT message, WPARAM w_param, LPARAM l_param)
|
||||||
{
|
{
|
||||||
if (message == WM_CREATE)
|
if (message == WM_CREATE)
|
||||||
{
|
{
|
||||||
auto data = reinterpret_cast<LPCREATESTRUCT>(l_param);
|
auto data = reinterpret_cast<LPCREATESTRUCT>(l_param);
|
||||||
SetWindowLongPtrA(hwnd, GWLP_USERDATA, LONG_PTR(data->lpCreateParams));
|
SetWindowLongPtrA(hwnd, GWLP_USERDATA, LONG_PTR(data->lpCreateParams));
|
||||||
|
|
||||||
reinterpret_cast<window*>(data->lpCreateParams)->handle_ = hwnd;
|
reinterpret_cast<window*>(data->lpCreateParams)->handle_ = hwnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto self = reinterpret_cast<window*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
|
const auto self = reinterpret_cast<window*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
|
||||||
if (self) return self->processor(message, w_param, l_param);
|
if (self) return self->processor(message, w_param, l_param);
|
||||||
|
|
||||||
return DefWindowProc(hwnd, message, w_param, l_param);
|
return DefWindowProc(hwnd, message, w_param, l_param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
window::operator HWND() const
|
window::operator HWND() const
|
||||||
{
|
{
|
||||||
return this->handle_;
|
return this->handle_;
|
||||||
}
|
}
|
||||||
|
@ -1,42 +1,42 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define WM_KILL_WINDOW (WM_USER+0)
|
#define WM_KILL_WINDOW (WM_USER+0)
|
||||||
|
|
||||||
class window
|
class window
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
window();
|
window();
|
||||||
virtual ~window();
|
virtual ~window();
|
||||||
|
|
||||||
void create(const std::string& title, int width, int height,
|
void create(const std::string& title, int width, int height,
|
||||||
long flags = (WS_OVERLAPPEDWINDOW & ~(WS_THICKFRAME | WS_MAXIMIZEBOX)));
|
long flags = (WS_OVERLAPPEDWINDOW & ~(WS_THICKFRAME | WS_MAXIMIZEBOX)));
|
||||||
|
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
void show() const;
|
void show() const;
|
||||||
void hide() const;
|
void hide() const;
|
||||||
|
|
||||||
void set_callback(const std::function<LRESULT(window*, UINT, WPARAM, LPARAM)>& callback);
|
void set_callback(const std::function<LRESULT(window*, UINT, WPARAM, LPARAM)>& callback);
|
||||||
|
|
||||||
operator HWND() const;
|
operator HWND() const;
|
||||||
|
|
||||||
static void run();
|
static void run();
|
||||||
static void close_all();
|
static void close_all();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual LRESULT processor(UINT message, WPARAM w_param, LPARAM l_param);
|
virtual LRESULT processor(UINT message, WPARAM w_param, LPARAM l_param);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WNDCLASSEX wc_{};
|
WNDCLASSEX wc_{};
|
||||||
HWND handle_ = nullptr;
|
HWND handle_ = nullptr;
|
||||||
std::string classname_;
|
std::string classname_;
|
||||||
std::function<LRESULT(window*, UINT, WPARAM, LPARAM)> callback_;
|
std::function<LRESULT(window*, UINT, WPARAM, LPARAM)> callback_;
|
||||||
|
|
||||||
static LRESULT CALLBACK static_processor(HWND hwnd, UINT message, WPARAM w_param, LPARAM l_param);
|
static LRESULT CALLBACK static_processor(HWND hwnd, UINT message, WPARAM w_param, LPARAM l_param);
|
||||||
|
|
||||||
static std::mutex mutex_;
|
static std::mutex mutex_;
|
||||||
static std::vector<window*> windows_;
|
static std::vector<window*> windows_;
|
||||||
|
|
||||||
static void remove_window(const window* window);
|
static void remove_window(const window* window);
|
||||||
static int get_window_count();
|
static int get_window_count();
|
||||||
};
|
};
|
||||||
|
@ -1,121 +1,121 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "binary_loader.hpp"
|
#include "binary_loader.hpp"
|
||||||
#include "utils/nt.hpp"
|
#include "utils/nt.hpp"
|
||||||
#include "utils/io.hpp"
|
#include "utils/io.hpp"
|
||||||
#include "utils/cryptography.hpp"
|
#include "utils/cryptography.hpp"
|
||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
#include "utils/compression.hpp"
|
#include "utils/compression.hpp"
|
||||||
|
|
||||||
#define DEDI_HASH "F271C305117B79242E254E9F64BD5AA2993CAC8E57975243EBD44CD576418D20"
|
#define DEDI_HASH "F271C305117B79242E254E9F64BD5AA2993CAC8E57975243EBD44CD576418D20"
|
||||||
|
|
||||||
namespace binary_loader
|
namespace binary_loader
|
||||||
{
|
{
|
||||||
std::string load_resource(const int id)
|
std::string load_resource(const int id)
|
||||||
{
|
{
|
||||||
const auto res = FindResource(::utils::nt::module(), MAKEINTRESOURCE(id), RT_RCDATA);
|
const auto res = FindResource(::utils::nt::module(), MAKEINTRESOURCE(id), RT_RCDATA);
|
||||||
if (!res) return {};
|
if (!res) return {};
|
||||||
|
|
||||||
const auto handle = LoadResource(nullptr, res);
|
const auto handle = LoadResource(nullptr, res);
|
||||||
if (!handle) return {};
|
if (!handle) return {};
|
||||||
|
|
||||||
return std::string(LPSTR(LockResource(handle)), SizeofResource(nullptr, res));
|
return std::string(LPSTR(LockResource(handle)), SizeofResource(nullptr, res));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string load_delta(const launcher::mode mode)
|
std::string load_delta(const launcher::mode mode)
|
||||||
{
|
{
|
||||||
if (mode == launcher::mode::singleplayer)
|
if (mode == launcher::mode::singleplayer)
|
||||||
{
|
{
|
||||||
return load_resource(BINARY_SP);
|
return load_resource(BINARY_SP);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == launcher::mode::multiplayer)
|
if (mode == launcher::mode::multiplayer)
|
||||||
{
|
{
|
||||||
return load_resource(BINARY_MP);
|
return load_resource(BINARY_MP);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string load_base(const bool verify = true)
|
std::string load_base(const bool verify = true)
|
||||||
{
|
{
|
||||||
std::string data;
|
std::string data;
|
||||||
if (!utils::io::read_file("iw5mp_server.exe", &data))
|
if (!utils::io::read_file("iw5mp_server.exe", &data))
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Unable to load iw5mp_server.exe");
|
throw std::runtime_error("Unable to load iw5mp_server.exe");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verify && utils::cryptography::sha256::compute(data, true) != DEDI_HASH)
|
if (verify && utils::cryptography::sha256::compute(data, true) != DEDI_HASH)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Your iw5mp_server.exe is incompatible with this client.");
|
throw std::runtime_error("Your iw5mp_server.exe is incompatible with this client.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void create_for_file(const std::string& file, const std::string& base)
|
void create_for_file(const std::string& file, const std::string& base)
|
||||||
{
|
{
|
||||||
std::string data;
|
std::string data;
|
||||||
if (!utils::io::read_file(file, &data))
|
if (!utils::io::read_file(file, &data))
|
||||||
{
|
{
|
||||||
throw std::runtime_error(utils::string::va("Unable to load file %s!", file.data()));
|
throw std::runtime_error(utils::string::va("Unable to load file %s!", file.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto new_data = reinterpret_cast<const unsigned char*>(data.data());
|
const auto new_data = reinterpret_cast<const unsigned char*>(data.data());
|
||||||
const auto old_data = reinterpret_cast<const unsigned char*>(base.data());
|
const auto old_data = reinterpret_cast<const unsigned char*>(base.data());
|
||||||
|
|
||||||
std::vector<unsigned char> diff;
|
std::vector<unsigned char> diff;
|
||||||
create_diff(new_data, new_data + data.size(), old_data, old_data + base.size(), diff);
|
create_diff(new_data, new_data + data.size(), old_data, old_data + base.size(), diff);
|
||||||
|
|
||||||
const unsigned long long size = data.size();
|
const unsigned long long size = data.size();
|
||||||
|
|
||||||
std::string result(reinterpret_cast<char*>(diff.data()), diff.size());
|
std::string result(reinterpret_cast<char*>(diff.data()), diff.size());
|
||||||
result.append(reinterpret_cast<const char*>(&size), sizeof(size));
|
result.append(reinterpret_cast<const char*>(&size), sizeof(size));
|
||||||
result = utils::compression::zlib::compress(result);
|
result = utils::compression::zlib::compress(result);
|
||||||
|
|
||||||
utils::io::write_file(file + ".diff", result);
|
utils::io::write_file(file + ".diff", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void create()
|
void create()
|
||||||
{
|
{
|
||||||
const auto base = load_base(false);
|
const auto base = load_base(false);
|
||||||
|
|
||||||
utils::io::write_file("hash.txt", utils::cryptography::sha256::compute(base, true));
|
utils::io::write_file("hash.txt", utils::cryptography::sha256::compute(base, true));
|
||||||
|
|
||||||
create_for_file("iw5sp.exe", base);
|
create_for_file("iw5sp.exe", base);
|
||||||
create_for_file("iw5mp.exe", base);
|
create_for_file("iw5mp.exe", base);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string build_binary(const std::string& base, const std::string& diff)
|
std::string build_binary(const std::string& base, const std::string& diff)
|
||||||
{
|
{
|
||||||
const auto* size = reinterpret_cast<const unsigned long long*>(diff.data() + diff.size() - sizeof(unsigned long
|
const auto* size = reinterpret_cast<const unsigned long long*>(diff.data() + diff.size() - sizeof(unsigned long
|
||||||
long));
|
long));
|
||||||
|
|
||||||
std::string binary;
|
std::string binary;
|
||||||
binary.resize(size_t(*size));
|
binary.resize(size_t(*size));
|
||||||
|
|
||||||
const auto new_data = reinterpret_cast<unsigned char*>(binary.data());
|
const auto new_data = reinterpret_cast<unsigned char*>(binary.data());
|
||||||
const auto old_data = reinterpret_cast<const unsigned char*>(base.data());
|
const auto old_data = reinterpret_cast<const unsigned char*>(base.data());
|
||||||
const auto diff_data = reinterpret_cast<const unsigned char*>(diff.data());
|
const auto diff_data = reinterpret_cast<const unsigned char*>(diff.data());
|
||||||
|
|
||||||
if (patch(new_data, new_data + binary.size(), old_data, old_data + base.size(), diff_data,
|
if (patch(new_data, new_data + binary.size(), old_data, old_data + base.size(), diff_data,
|
||||||
diff_data + diff.size() - sizeof(*size)) == hpatch_FALSE || binary.empty())
|
diff_data + diff.size() - sizeof(*size)) == hpatch_FALSE || binary.empty())
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Unable to create binary from patch!");
|
throw std::runtime_error("Unable to create binary from patch!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return binary;
|
return binary;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string load(const launcher::mode mode)
|
std::string load(const launcher::mode mode)
|
||||||
{
|
{
|
||||||
auto base = load_base();
|
auto base = load_base();
|
||||||
if (mode == launcher::mode::server)
|
if (mode == launcher::mode::server)
|
||||||
{
|
{
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto delta = load_delta(mode);
|
auto delta = load_delta(mode);
|
||||||
delta = utils::compression::zlib::decompress(delta);
|
delta = utils::compression::zlib::decompress(delta);
|
||||||
return build_binary(base, delta);
|
return build_binary(base, delta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "launcher/launcher.hpp"
|
#include "launcher/launcher.hpp"
|
||||||
|
|
||||||
namespace binary_loader
|
namespace binary_loader
|
||||||
{
|
{
|
||||||
void create();
|
void create();
|
||||||
std::string load(launcher::mode mode);
|
std::string load(launcher::mode mode);
|
||||||
}
|
}
|
||||||
|
@ -1,165 +1,165 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "loader.hpp"
|
#include "loader.hpp"
|
||||||
#include "binary_loader.hpp"
|
#include "binary_loader.hpp"
|
||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
|
|
||||||
loader::loader(const launcher::mode mode) : mode_(mode)
|
loader::loader(const launcher::mode mode) : mode_(mode)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
FARPROC loader::load(const utils::nt::module& module) const
|
FARPROC loader::load(const utils::nt::module& module) const
|
||||||
{
|
{
|
||||||
const auto buffer = binary_loader::load(this->mode_);
|
const auto buffer = binary_loader::load(this->mode_);
|
||||||
if (buffer.empty()) return nullptr;
|
if (buffer.empty()) return nullptr;
|
||||||
|
|
||||||
utils::nt::module source(HMODULE(buffer.data()));
|
utils::nt::module source(HMODULE(buffer.data()));
|
||||||
if (!source) return nullptr;
|
if (!source) return nullptr;
|
||||||
|
|
||||||
this->load_sections(module, source);
|
this->load_sections(module, source);
|
||||||
this->load_imports(module, source);
|
this->load_imports(module, source);
|
||||||
|
|
||||||
if (source.get_optional_header()->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size)
|
if (source.get_optional_header()->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size)
|
||||||
{
|
{
|
||||||
const auto target_tls = reinterpret_cast<PIMAGE_TLS_DIRECTORY>(module.get_ptr() + module
|
const auto target_tls = reinterpret_cast<PIMAGE_TLS_DIRECTORY>(module.get_ptr() + module
|
||||||
.get_optional_header()
|
.get_optional_header()
|
||||||
->
|
->
|
||||||
DataDirectory
|
DataDirectory
|
||||||
[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
|
[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
|
||||||
const auto source_tls = reinterpret_cast<PIMAGE_TLS_DIRECTORY>(module.get_ptr() + source
|
const auto source_tls = reinterpret_cast<PIMAGE_TLS_DIRECTORY>(module.get_ptr() + source
|
||||||
.get_optional_header()
|
.get_optional_header()
|
||||||
->
|
->
|
||||||
DataDirectory
|
DataDirectory
|
||||||
[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
|
[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
|
||||||
|
|
||||||
const auto tls_size = source_tls->EndAddressOfRawData - source_tls->StartAddressOfRawData;
|
const auto tls_size = source_tls->EndAddressOfRawData - source_tls->StartAddressOfRawData;
|
||||||
const auto tls_index = *reinterpret_cast<DWORD*>(target_tls->AddressOfIndex);
|
const auto tls_index = *reinterpret_cast<DWORD*>(target_tls->AddressOfIndex);
|
||||||
*reinterpret_cast<DWORD*>(source_tls->AddressOfIndex) = tls_index;
|
*reinterpret_cast<DWORD*>(source_tls->AddressOfIndex) = tls_index;
|
||||||
|
|
||||||
if (tls_size > TLS_PAYLOAD_SIZE)
|
if (tls_size > TLS_PAYLOAD_SIZE)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(utils::string::va(
|
throw std::runtime_error(utils::string::va(
|
||||||
"TLS data is of size 0x%X, but we have only reserved 0x%X bytes!", tls_size, TLS_PAYLOAD_SIZE));
|
"TLS data is of size 0x%X, but we have only reserved 0x%X bytes!", tls_size, TLS_PAYLOAD_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD old_protect;
|
DWORD old_protect;
|
||||||
VirtualProtect(PVOID(target_tls->StartAddressOfRawData),
|
VirtualProtect(PVOID(target_tls->StartAddressOfRawData),
|
||||||
source_tls->EndAddressOfRawData - source_tls->StartAddressOfRawData, PAGE_READWRITE,
|
source_tls->EndAddressOfRawData - source_tls->StartAddressOfRawData, PAGE_READWRITE,
|
||||||
&old_protect);
|
&old_protect);
|
||||||
|
|
||||||
const auto tls_base = *reinterpret_cast<LPVOID*>(__readfsdword(0x2C) + 4 * tls_index);
|
const auto tls_base = *reinterpret_cast<LPVOID*>(__readfsdword(0x2C) + 4 * tls_index);
|
||||||
std::memmove(tls_base, PVOID(source_tls->StartAddressOfRawData), tls_size);
|
std::memmove(tls_base, PVOID(source_tls->StartAddressOfRawData), tls_size);
|
||||||
std::memmove(PVOID(target_tls->StartAddressOfRawData), PVOID(source_tls->StartAddressOfRawData), tls_size);
|
std::memmove(PVOID(target_tls->StartAddressOfRawData), PVOID(source_tls->StartAddressOfRawData), tls_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD oldProtect;
|
DWORD oldProtect;
|
||||||
VirtualProtect(module.get_nt_headers(), 0x1000, PAGE_EXECUTE_READWRITE, &oldProtect);
|
VirtualProtect(module.get_nt_headers(), 0x1000, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||||
|
|
||||||
module.get_optional_header()->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] = source
|
module.get_optional_header()->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] = source
|
||||||
.get_optional_header()->DataDirectory[
|
.get_optional_header()->DataDirectory[
|
||||||
IMAGE_DIRECTORY_ENTRY_IMPORT];
|
IMAGE_DIRECTORY_ENTRY_IMPORT];
|
||||||
std::memmove(module.get_nt_headers(), source.get_nt_headers(),
|
std::memmove(module.get_nt_headers(), source.get_nt_headers(),
|
||||||
sizeof(IMAGE_NT_HEADERS) + (source.get_nt_headers()->FileHeader.NumberOfSections * (sizeof(
|
sizeof(IMAGE_NT_HEADERS) + (source.get_nt_headers()->FileHeader.NumberOfSections * (sizeof(
|
||||||
IMAGE_SECTION_HEADER))));
|
IMAGE_SECTION_HEADER))));
|
||||||
|
|
||||||
return FARPROC(module.get_ptr() + source.get_relative_entry_point());
|
return FARPROC(module.get_ptr() + source.get_relative_entry_point());
|
||||||
}
|
}
|
||||||
|
|
||||||
void loader::set_import_resolver(const std::function<FARPROC(const std::string&, const std::string&)>& resolver)
|
void loader::set_import_resolver(const std::function<FARPROC(const std::string&, const std::string&)>& resolver)
|
||||||
{
|
{
|
||||||
this->import_resolver_ = resolver;
|
this->import_resolver_ = resolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
void loader::load_section(const utils::nt::module& target, const utils::nt::module& source,
|
void loader::load_section(const utils::nt::module& target, const utils::nt::module& source,
|
||||||
IMAGE_SECTION_HEADER* section)
|
IMAGE_SECTION_HEADER* section)
|
||||||
{
|
{
|
||||||
void* target_ptr = target.get_ptr() + section->VirtualAddress;
|
void* target_ptr = target.get_ptr() + section->VirtualAddress;
|
||||||
const void* source_ptr = source.get_ptr() + section->PointerToRawData;
|
const void* source_ptr = source.get_ptr() + section->PointerToRawData;
|
||||||
|
|
||||||
if (PBYTE(target_ptr) >= (target.get_ptr() + BINARY_PAYLOAD_SIZE))
|
if (PBYTE(target_ptr) >= (target.get_ptr() + BINARY_PAYLOAD_SIZE))
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Section exceeds the binary payload size, please increase it!");
|
throw std::runtime_error("Section exceeds the binary payload size, please increase it!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (section->SizeOfRawData > 0)
|
if (section->SizeOfRawData > 0)
|
||||||
{
|
{
|
||||||
const auto size_of_data = std::min(section->SizeOfRawData, section->Misc.VirtualSize);
|
const auto size_of_data = std::min(section->SizeOfRawData, section->Misc.VirtualSize);
|
||||||
std::memmove(target_ptr, source_ptr, size_of_data);
|
std::memmove(target_ptr, source_ptr, size_of_data);
|
||||||
|
|
||||||
DWORD old_protect;
|
DWORD old_protect;
|
||||||
VirtualProtect(target_ptr, size_of_data, PAGE_EXECUTE_READWRITE, &old_protect);
|
VirtualProtect(target_ptr, size_of_data, PAGE_EXECUTE_READWRITE, &old_protect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void loader::load_sections(const utils::nt::module& target, const utils::nt::module& source) const
|
void loader::load_sections(const utils::nt::module& target, const utils::nt::module& source) const
|
||||||
{
|
{
|
||||||
for (auto& section : source.get_section_headers())
|
for (auto& section : source.get_section_headers())
|
||||||
{
|
{
|
||||||
this->load_section(target, source, section);
|
this->load_section(target, source, section);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void loader::load_imports(const utils::nt::module& target, const utils::nt::module& source) const
|
void loader::load_imports(const utils::nt::module& target, const utils::nt::module& source) const
|
||||||
{
|
{
|
||||||
const auto import_directory = &source.get_optional_header()->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
|
const auto import_directory = &source.get_optional_header()->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
|
||||||
|
|
||||||
auto descriptor = PIMAGE_IMPORT_DESCRIPTOR(target.get_ptr() + import_directory->VirtualAddress);
|
auto descriptor = PIMAGE_IMPORT_DESCRIPTOR(target.get_ptr() + import_directory->VirtualAddress);
|
||||||
|
|
||||||
while (descriptor->Name)
|
while (descriptor->Name)
|
||||||
{
|
{
|
||||||
std::string name = LPSTR(target.get_ptr() + descriptor->Name);
|
std::string name = LPSTR(target.get_ptr() + descriptor->Name);
|
||||||
|
|
||||||
auto name_table_entry = reinterpret_cast<uintptr_t*>(target.get_ptr() + descriptor->OriginalFirstThunk);
|
auto name_table_entry = reinterpret_cast<uintptr_t*>(target.get_ptr() + descriptor->OriginalFirstThunk);
|
||||||
auto address_table_entry = reinterpret_cast<uintptr_t*>(target.get_ptr() + descriptor->FirstThunk);
|
auto address_table_entry = reinterpret_cast<uintptr_t*>(target.get_ptr() + descriptor->FirstThunk);
|
||||||
|
|
||||||
if (!descriptor->OriginalFirstThunk)
|
if (!descriptor->OriginalFirstThunk)
|
||||||
{
|
{
|
||||||
name_table_entry = reinterpret_cast<uintptr_t*>(target.get_ptr() + descriptor->FirstThunk);
|
name_table_entry = reinterpret_cast<uintptr_t*>(target.get_ptr() + descriptor->FirstThunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*name_table_entry)
|
while (*name_table_entry)
|
||||||
{
|
{
|
||||||
FARPROC function = nullptr;
|
FARPROC function = nullptr;
|
||||||
std::string function_name;
|
std::string function_name;
|
||||||
|
|
||||||
// is this an ordinal-only import?
|
// is this an ordinal-only import?
|
||||||
if (IMAGE_SNAP_BY_ORDINAL(*name_table_entry))
|
if (IMAGE_SNAP_BY_ORDINAL(*name_table_entry))
|
||||||
{
|
{
|
||||||
auto module = utils::nt::module::load(name);
|
auto module = utils::nt::module::load(name);
|
||||||
if (module)
|
if (module)
|
||||||
{
|
{
|
||||||
function = GetProcAddress(module, MAKEINTRESOURCEA(IMAGE_ORDINAL(*name_table_entry)));
|
function = GetProcAddress(module, MAKEINTRESOURCEA(IMAGE_ORDINAL(*name_table_entry)));
|
||||||
}
|
}
|
||||||
|
|
||||||
function_name = "#" + std::to_string(IMAGE_ORDINAL(*name_table_entry));
|
function_name = "#" + std::to_string(IMAGE_ORDINAL(*name_table_entry));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto import = PIMAGE_IMPORT_BY_NAME(target.get_ptr() + *name_table_entry);
|
auto import = PIMAGE_IMPORT_BY_NAME(target.get_ptr() + *name_table_entry);
|
||||||
function_name = import->Name;
|
function_name = import->Name;
|
||||||
|
|
||||||
if (this->import_resolver_) function = this->import_resolver_(name, function_name);
|
if (this->import_resolver_) function = this->import_resolver_(name, function_name);
|
||||||
if (!function)
|
if (!function)
|
||||||
{
|
{
|
||||||
auto module = utils::nt::module::load(name);
|
auto module = utils::nt::module::load(name);
|
||||||
if (module)
|
if (module)
|
||||||
{
|
{
|
||||||
function = GetProcAddress(module, function_name.data());
|
function = GetProcAddress(module, function_name.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!function)
|
if (!function)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(utils::string::va("Unable to load import '%s' from module '%s'",
|
throw std::runtime_error(utils::string::va("Unable to load import '%s' from module '%s'",
|
||||||
function_name.data(), name.data()));
|
function_name.data(), name.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
*address_table_entry = reinterpret_cast<uintptr_t>(function);
|
*address_table_entry = reinterpret_cast<uintptr_t>(function);
|
||||||
|
|
||||||
name_table_entry++;
|
name_table_entry++;
|
||||||
address_table_entry++;
|
address_table_entry++;
|
||||||
}
|
}
|
||||||
|
|
||||||
descriptor++;
|
descriptor++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "utils/nt.hpp"
|
#include "utils/nt.hpp"
|
||||||
#include "launcher/launcher.hpp"
|
#include "launcher/launcher.hpp"
|
||||||
|
|
||||||
class loader final
|
class loader final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit loader(launcher::mode mode);
|
explicit loader(launcher::mode mode);
|
||||||
|
|
||||||
FARPROC load(const utils::nt::module& module) const;
|
FARPROC load(const utils::nt::module& module) const;
|
||||||
|
|
||||||
void set_import_resolver(const std::function<FARPROC(const std::string&, const std::string&)>& resolver);
|
void set_import_resolver(const std::function<FARPROC(const std::string&, const std::string&)>& resolver);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
launcher::mode mode_;
|
launcher::mode mode_;
|
||||||
std::function<FARPROC(const std::string&, const std::string&)> import_resolver_;
|
std::function<FARPROC(const std::string&, const std::string&)> import_resolver_;
|
||||||
|
|
||||||
static void load_section(const utils::nt::module& target, const utils::nt::module& source,
|
static void load_section(const utils::nt::module& target, const utils::nt::module& source,
|
||||||
IMAGE_SECTION_HEADER* section);
|
IMAGE_SECTION_HEADER* section);
|
||||||
void load_sections(const utils::nt::module& target, const utils::nt::module& source) const;
|
void load_sections(const utils::nt::module& target, const utils::nt::module& source) const;
|
||||||
void load_imports(const utils::nt::module& target, const utils::nt::module& source) const;
|
void load_imports(const utils::nt::module& target, const utils::nt::module& source) const;
|
||||||
};
|
};
|
||||||
|
@ -1,100 +1,100 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "module_loader.hpp"
|
#include "module_loader.hpp"
|
||||||
|
|
||||||
std::vector<std::unique_ptr<module>>* module_loader::modules_ = nullptr;
|
std::vector<std::unique_ptr<module>>* module_loader::modules_ = nullptr;
|
||||||
|
|
||||||
void module_loader::register_module(std::unique_ptr<module>&& module_)
|
void module_loader::register_module(std::unique_ptr<module>&& module_)
|
||||||
{
|
{
|
||||||
if (!modules_)
|
if (!modules_)
|
||||||
{
|
{
|
||||||
modules_ = new std::vector<std::unique_ptr<module>>();
|
modules_ = new std::vector<std::unique_ptr<module>>();
|
||||||
atexit(destroy_modules);
|
atexit(destroy_modules);
|
||||||
}
|
}
|
||||||
|
|
||||||
modules_->push_back(std::move(module_));
|
modules_->push_back(std::move(module_));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool module_loader::post_start()
|
bool module_loader::post_start()
|
||||||
{
|
{
|
||||||
static auto handled = false;
|
static auto handled = false;
|
||||||
if (handled || !modules_) return true;
|
if (handled || !modules_) return true;
|
||||||
handled = true;
|
handled = true;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
for (const auto& module_ : *modules_)
|
for (const auto& module_ : *modules_)
|
||||||
{
|
{
|
||||||
module_->post_start();
|
module_->post_start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(premature_shutdown_trigger&)
|
catch(premature_shutdown_trigger&)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool module_loader::post_load()
|
bool module_loader::post_load()
|
||||||
{
|
{
|
||||||
static auto handled = false;
|
static auto handled = false;
|
||||||
if (handled || !modules_) return true;
|
if (handled || !modules_) return true;
|
||||||
handled = true;
|
handled = true;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
for (const auto& module_ : *modules_)
|
for (const auto& module_ : *modules_)
|
||||||
{
|
{
|
||||||
module_->post_load();
|
module_->post_load();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (premature_shutdown_trigger&)
|
catch (premature_shutdown_trigger&)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void module_loader::pre_destroy()
|
void module_loader::pre_destroy()
|
||||||
{
|
{
|
||||||
static auto handled = false;
|
static auto handled = false;
|
||||||
if (handled || !modules_) return;
|
if (handled || !modules_) return;
|
||||||
handled = true;
|
handled = true;
|
||||||
|
|
||||||
for (const auto& module_ : *modules_)
|
for (const auto& module_ : *modules_)
|
||||||
{
|
{
|
||||||
module_->pre_destroy();
|
module_->pre_destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void* module_loader::load_import(const std::string& module, const std::string& function)
|
void* module_loader::load_import(const std::string& module, const std::string& function)
|
||||||
{
|
{
|
||||||
void* function_ptr = nullptr;
|
void* function_ptr = nullptr;
|
||||||
|
|
||||||
for (const auto& module_ : *modules_)
|
for (const auto& module_ : *modules_)
|
||||||
{
|
{
|
||||||
const auto module_function_ptr = module_->load_import(module, function);
|
const auto module_function_ptr = module_->load_import(module, function);
|
||||||
if(module_function_ptr)
|
if(module_function_ptr)
|
||||||
{
|
{
|
||||||
function_ptr = module_function_ptr;
|
function_ptr = module_function_ptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return function_ptr;
|
return function_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void module_loader::destroy_modules()
|
void module_loader::destroy_modules()
|
||||||
{
|
{
|
||||||
pre_destroy();
|
pre_destroy();
|
||||||
|
|
||||||
if (!modules_) return;
|
if (!modules_) return;
|
||||||
|
|
||||||
delete modules_;
|
delete modules_;
|
||||||
modules_ = nullptr;
|
modules_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void module_loader::trigger_premature_shutdown()
|
void module_loader::trigger_premature_shutdown()
|
||||||
{
|
{
|
||||||
throw premature_shutdown_trigger();
|
throw premature_shutdown_trigger();
|
||||||
}
|
}
|
||||||
|
264
src/main.cpp
264
src/main.cpp
@ -1,132 +1,132 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "launcher/launcher.hpp"
|
#include "launcher/launcher.hpp"
|
||||||
#include "loader/loader.hpp"
|
#include "loader/loader.hpp"
|
||||||
#include "loader/module_loader.hpp"
|
#include "loader/module_loader.hpp"
|
||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
#include "loader/binary_loader.hpp"
|
#include "loader/binary_loader.hpp"
|
||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
#include "utils/flags.hpp"
|
#include "utils/flags.hpp"
|
||||||
|
|
||||||
//#define GENERATE_DIFFS
|
//#define GENERATE_DIFFS
|
||||||
|
|
||||||
DECLSPEC_NORETURN void WINAPI exit_hook(const int code)
|
DECLSPEC_NORETURN void WINAPI exit_hook(const int code)
|
||||||
{
|
{
|
||||||
module_loader::pre_destroy();
|
module_loader::pre_destroy();
|
||||||
exit(code);
|
exit(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
void verify_tls()
|
void verify_tls()
|
||||||
{
|
{
|
||||||
utils::nt::module self;
|
utils::nt::module self;
|
||||||
const auto self_tls = reinterpret_cast<PIMAGE_TLS_DIRECTORY>(self.get_ptr() + self
|
const auto self_tls = reinterpret_cast<PIMAGE_TLS_DIRECTORY>(self.get_ptr() + self
|
||||||
.get_optional_header()
|
.get_optional_header()
|
||||||
->
|
->
|
||||||
DataDirectory
|
DataDirectory
|
||||||
[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
|
[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
|
||||||
|
|
||||||
const auto ref = DWORD(&tls_data);
|
const auto ref = DWORD(&tls_data);
|
||||||
const auto tls_index = *reinterpret_cast<DWORD*>(self_tls->AddressOfIndex);
|
const auto tls_index = *reinterpret_cast<DWORD*>(self_tls->AddressOfIndex);
|
||||||
const auto tls_vector = *reinterpret_cast<DWORD*>(__readfsdword(0x2C) + 4 * tls_index);
|
const auto tls_vector = *reinterpret_cast<DWORD*>(__readfsdword(0x2C) + 4 * tls_index);
|
||||||
const auto offset = ref - tls_vector;
|
const auto offset = ref - tls_vector;
|
||||||
|
|
||||||
if (offset != 0 && offset != 8) // Actually 8 is bad, but I think msvc places custom stuff before
|
if (offset != 0 && offset != 8) // Actually 8 is bad, but I think msvc places custom stuff before
|
||||||
{
|
{
|
||||||
throw std::runtime_error(utils::string::va("TLS payload is at offset 0x%X, but should be at 0!",
|
throw std::runtime_error(utils::string::va("TLS payload is at offset 0x%X, but should be at 0!",
|
||||||
offset));
|
offset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
launcher::mode detect_mode_from_arguments()
|
launcher::mode detect_mode_from_arguments()
|
||||||
{
|
{
|
||||||
if (utils::flags::has_flag("dedicated"))
|
if (utils::flags::has_flag("dedicated"))
|
||||||
{
|
{
|
||||||
return launcher::mode::server;
|
return launcher::mode::server;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (utils::flags::has_flag("multiplayer"))
|
if (utils::flags::has_flag("multiplayer"))
|
||||||
{
|
{
|
||||||
return launcher::mode::multiplayer;
|
return launcher::mode::multiplayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (utils::flags::has_flag("singleplayer"))
|
if (utils::flags::has_flag("singleplayer"))
|
||||||
{
|
{
|
||||||
return launcher::mode::singleplayer;
|
return launcher::mode::singleplayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
return launcher::mode::none;
|
return launcher::mode::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
FARPROC load_binary(const launcher::mode mode)
|
FARPROC load_binary(const launcher::mode mode)
|
||||||
{
|
{
|
||||||
loader loader(mode);
|
loader loader(mode);
|
||||||
utils::nt::module self;
|
utils::nt::module self;
|
||||||
|
|
||||||
loader.set_import_resolver([self](const std::string& module, const std::string& function) -> FARPROC
|
loader.set_import_resolver([self](const std::string& module, const std::string& function) -> FARPROC
|
||||||
{
|
{
|
||||||
if (module == "steam_api.dll")
|
if (module == "steam_api.dll")
|
||||||
{
|
{
|
||||||
return self.get_proc<FARPROC>(function);
|
return self.get_proc<FARPROC>(function);
|
||||||
}
|
}
|
||||||
else if (function == "ExitProcess")
|
else if (function == "ExitProcess")
|
||||||
{
|
{
|
||||||
return FARPROC(exit_hook);
|
return FARPROC(exit_hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FARPROC(module_loader::load_import(module, function));
|
return FARPROC(module_loader::load_import(module, function));
|
||||||
});
|
});
|
||||||
|
|
||||||
return loader.load(self);
|
return loader.load(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
FARPROC entry_point;
|
FARPROC entry_point;
|
||||||
|
|
||||||
{
|
{
|
||||||
auto premature_shutdown = true;
|
auto premature_shutdown = true;
|
||||||
const auto _ = gsl::finally([&premature_shutdown]()
|
const auto _ = gsl::finally([&premature_shutdown]()
|
||||||
{
|
{
|
||||||
if (premature_shutdown)
|
if (premature_shutdown)
|
||||||
{
|
{
|
||||||
module_loader::pre_destroy();
|
module_loader::pre_destroy();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
#ifdef GENERATE_DIFFS
|
#ifdef GENERATE_DIFFS
|
||||||
binary_loader::create();
|
binary_loader::create();
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
verify_tls();
|
verify_tls();
|
||||||
if (!module_loader::post_start()) return 0;
|
if (!module_loader::post_start()) return 0;
|
||||||
|
|
||||||
auto mode = detect_mode_from_arguments();
|
auto mode = detect_mode_from_arguments();
|
||||||
if (mode == launcher::mode::none)
|
if (mode == launcher::mode::none)
|
||||||
{
|
{
|
||||||
launcher launcher;
|
launcher launcher;
|
||||||
mode = launcher.run();
|
mode = launcher.run();
|
||||||
if (mode == launcher::mode::none) return 0;
|
if (mode == launcher::mode::none) return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry_point = load_binary(mode);
|
entry_point = load_binary(mode);
|
||||||
if (!entry_point)
|
if (!entry_point)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Unable to load binary into memory");
|
throw std::runtime_error("Unable to load binary into memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
game::initialize(mode);
|
game::initialize(mode);
|
||||||
if (!module_loader::post_load()) return 0;
|
if (!module_loader::post_load()) return 0;
|
||||||
|
|
||||||
premature_shutdown = false;
|
premature_shutdown = false;
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
MessageBoxA(nullptr, e.what(), "ERROR", MB_ICONERROR);
|
MessageBoxA(nullptr, e.what(), "ERROR", MB_ICONERROR);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry_point();
|
return entry_point();
|
||||||
}
|
}
|
||||||
|
@ -1,90 +1,90 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "loader/module_loader.hpp"
|
#include "loader/module_loader.hpp"
|
||||||
#include "utils/hook.hpp"
|
#include "utils/hook.hpp"
|
||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
|
|
||||||
class ceg final : public module
|
class ceg final : public module
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void post_load() override
|
void post_load() override
|
||||||
{
|
{
|
||||||
// Only SP has CEG
|
// Only SP has CEG
|
||||||
// CEG in MP has accidentally been removed due to CVE-2018-10718
|
// CEG in MP has accidentally been removed due to CVE-2018-10718
|
||||||
if (!game::is_sp()) return;
|
if (!game::is_sp()) return;
|
||||||
|
|
||||||
utils::hook::signature signature(0x401000, 0x3E1000);
|
utils::hook::signature signature(0x401000, 0x3E1000);
|
||||||
|
|
||||||
signature.add({
|
signature.add({
|
||||||
"\x56\xE8\x00\x00\x00\x00\x8B\xF0\xE8\x00\x00\x00\x00\x50\x56\xE8", "xx????xxx????xxx", [](char* address)
|
"\x56\xE8\x00\x00\x00\x00\x8B\xF0\xE8\x00\x00\x00\x00\x50\x56\xE8", "xx????xxx????xxx", [](char* address)
|
||||||
{
|
{
|
||||||
utils::hook::set<DWORD>(address, 0xC301B0);
|
utils::hook::set<DWORD>(address, 0xC301B0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Generic killer caller.
|
// Generic killer caller.
|
||||||
signature.add({
|
signature.add({
|
||||||
"\x55\x8B\xEC\x80\x7D\x08\x00\x75\x55", "xxxxxx?xx", [](char* address)
|
"\x55\x8B\xEC\x80\x7D\x08\x00\x75\x55", "xxxxxx?xx", [](char* address)
|
||||||
{
|
{
|
||||||
utils::hook::set<DWORD>(address, 0xC301B0);
|
utils::hook::set<DWORD>(address, 0xC301B0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// CEG initialization.
|
// CEG initialization.
|
||||||
signature.add({
|
signature.add({
|
||||||
"\x55\x8B\xEC\x83\xEC\x18\x53\x56\x57\xE8\x00\x00\x00\x00", "xxxxxxxxxx????", [](char* address)
|
"\x55\x8B\xEC\x83\xEC\x18\x53\x56\x57\xE8\x00\x00\x00\x00", "xxxxxxxxxx????", [](char* address)
|
||||||
{
|
{
|
||||||
utils::hook::set<BYTE>(address, 0xC3);
|
utils::hook::set<BYTE>(address, 0xC3);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Some odd trap.
|
// Some odd trap.
|
||||||
signature.add({
|
signature.add({
|
||||||
"\x55\x8B\xEC\x81\xEC\x00\x00\x00\x00\x53\x56\x57\x8B\x3D", "xxxxx??xxxxxxx", [](char* address)
|
"\x55\x8B\xEC\x81\xEC\x00\x00\x00\x00\x53\x56\x57\x8B\x3D", "xxxxx??xxxxxxx", [](char* address)
|
||||||
{
|
{
|
||||||
utils::hook::set<DWORD>(address, 0xC301B0);
|
utils::hook::set<DWORD>(address, 0xC301B0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Custom shit
|
// Custom shit
|
||||||
signature.add({
|
signature.add({
|
||||||
"\x55\x8B\xEC\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x64\xFF\x35\x00\x00\x00\x00\x64\x89\x25\x00\x00\x00\x00\xE8",
|
"\x55\x8B\xEC\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x64\xFF\x35\x00\x00\x00\x00\x64\x89\x25\x00\x00\x00\x00\xE8",
|
||||||
"xxxx????x????xxx????xxx????x", [](char* address)
|
"xxxx????x????xxx????xxx????x", [](char* address)
|
||||||
{
|
{
|
||||||
utils::hook::set<BYTE>(address, 0xC3);
|
utils::hook::set<BYTE>(address, 0xC3);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// hkcr guid check
|
// hkcr guid check
|
||||||
signature.add({
|
signature.add({
|
||||||
"\x55\x8B\xEC\xB8\x00\x00\x00\x00\xE8\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x84\xC0\x75\x06",
|
"\x55\x8B\xEC\xB8\x00\x00\x00\x00\xE8\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x84\xC0\x75\x06",
|
||||||
"xxxx????x????x????xxxx", [](char* address)
|
"xxxx????x????x????xxxx", [](char* address)
|
||||||
{
|
{
|
||||||
utils::hook::nop(address + 0xD, 5); // Call
|
utils::hook::nop(address + 0xD, 5); // Call
|
||||||
utils::hook::nop(address + 0x14, 2); // Jump
|
utils::hook::nop(address + 0x14, 2); // Jump
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// hkcr guid check 2
|
// hkcr guid check 2
|
||||||
signature.add({
|
signature.add({
|
||||||
"\x55\x8B\xEC\x81\xEC\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x84\xC0\x75\x06", "xxxxx????x????xxxx", [
|
"\x55\x8B\xEC\x81\xEC\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x84\xC0\x75\x06", "xxxxx????x????xxxx", [
|
||||||
](char* address)
|
](char* address)
|
||||||
{
|
{
|
||||||
utils::hook::nop(address + 0x9, 5); // Call
|
utils::hook::nop(address + 0x9, 5); // Call
|
||||||
utils::hook::nop(address + 0x10, 2); // Jump
|
utils::hook::nop(address + 0x10, 2); // Jump
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
signature.process();
|
signature.process();
|
||||||
|
|
||||||
// Function fixup
|
// Function fixup
|
||||||
utils::hook(0x4CA310, game::native::DB_LoadXAssets, HOOK_JUMP).install()->quick();
|
utils::hook(0x4CA310, game::native::DB_LoadXAssets, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
// Some value obfuscation
|
// Some value obfuscation
|
||||||
utils::hook(0x493B81, 0x493BFC, HOOK_JUMP).install()->quick();
|
utils::hook(0x493B81, 0x493BFC, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
// CEG uninitialization
|
// CEG uninitialization
|
||||||
utils::hook::set<BYTE>(0x527110, 0xC3);
|
utils::hook::set<BYTE>(0x527110, 0xC3);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_MODULE(ceg)
|
REGISTER_MODULE(ceg)
|
||||||
|
@ -1,115 +1,115 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "loader/module_loader.hpp"
|
#include "loader/module_loader.hpp"
|
||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
#include "scheduler.hpp"
|
#include "scheduler.hpp"
|
||||||
|
|
||||||
class console final : public module
|
class console final : public module
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
console()
|
console()
|
||||||
{
|
{
|
||||||
ShowWindow(GetConsoleWindow(), SW_HIDE);
|
ShowWindow(GetConsoleWindow(), SW_HIDE);
|
||||||
|
|
||||||
_pipe(this->handles_, 1024, _O_TEXT);
|
_pipe(this->handles_, 1024, _O_TEXT);
|
||||||
_dup2(this->handles_[1], 1);
|
_dup2(this->handles_[1], 1);
|
||||||
_dup2(this->handles_[1], 2);
|
_dup2(this->handles_[1], 2);
|
||||||
|
|
||||||
//setvbuf(stdout, nullptr, _IONBF, 0);
|
//setvbuf(stdout, nullptr, _IONBF, 0);
|
||||||
//setvbuf(stderr, nullptr, _IONBF, 0);
|
//setvbuf(stderr, nullptr, _IONBF, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void post_start() override
|
void post_start() override
|
||||||
{
|
{
|
||||||
scheduler::on_frame(std::bind(&console::log_messages, this));
|
scheduler::on_frame(std::bind(&console::log_messages, this));
|
||||||
this->console_runner_ = std::thread(std::bind(&console::runner, this));
|
this->console_runner_ = std::thread(std::bind(&console::runner, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
void pre_destroy() override
|
void pre_destroy() override
|
||||||
{
|
{
|
||||||
this->terminate_runner_ = true;
|
this->terminate_runner_ = true;
|
||||||
|
|
||||||
printf("\r\n");
|
printf("\r\n");
|
||||||
_flushall();
|
_flushall();
|
||||||
|
|
||||||
_close(this->handles_[0]);
|
_close(this->handles_[0]);
|
||||||
_close(this->handles_[1]);
|
_close(this->handles_[1]);
|
||||||
|
|
||||||
if (this->console_runner_.joinable())
|
if (this->console_runner_.joinable())
|
||||||
{
|
{
|
||||||
this->console_runner_.join();
|
this->console_runner_.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void post_load() override
|
void post_load() override
|
||||||
{
|
{
|
||||||
if (!game::is_dedi())
|
if (!game::is_dedi())
|
||||||
{
|
{
|
||||||
game::native::Sys_ShowConsole();
|
game::native::Sys_ShowConsole();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard _(this->mutex_);
|
std::lock_guard _(this->mutex_);
|
||||||
this->console_initialized_ = true;
|
this->console_initialized_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool console_initialized_ = false;
|
bool console_initialized_ = false;
|
||||||
bool terminate_runner_ = false;
|
bool terminate_runner_ = false;
|
||||||
|
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
std::thread console_runner_;
|
std::thread console_runner_;
|
||||||
std::queue<std::string> message_queue_;
|
std::queue<std::string> message_queue_;
|
||||||
|
|
||||||
int handles_[2]{};
|
int handles_[2]{};
|
||||||
|
|
||||||
void log_messages()
|
void log_messages()
|
||||||
{
|
{
|
||||||
while (this->console_initialized_ && !this->message_queue_.empty())
|
while (this->console_initialized_ && !this->message_queue_.empty())
|
||||||
{
|
{
|
||||||
std::queue<std::string> message_queue_copy;
|
std::queue<std::string> message_queue_copy;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard _(this->mutex_);
|
std::lock_guard _(this->mutex_);
|
||||||
message_queue_copy = this->message_queue_;
|
message_queue_copy = this->message_queue_;
|
||||||
this->message_queue_ = {};
|
this->message_queue_ = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!message_queue_copy.empty())
|
while (!message_queue_copy.empty())
|
||||||
{
|
{
|
||||||
log_message(message_queue_copy.front());
|
log_message(message_queue_copy.front());
|
||||||
message_queue_copy.pop();
|
message_queue_copy.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void log_message(const std::string& message)
|
static void log_message(const std::string& message)
|
||||||
{
|
{
|
||||||
OutputDebugStringA(message.data());
|
OutputDebugStringA(message.data());
|
||||||
game::native::Conbuf_AppendText(message.data());
|
game::native::Conbuf_AppendText(message.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void runner()
|
void runner()
|
||||||
{
|
{
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
|
|
||||||
while (!this->terminate_runner_ && this->handles_[0])
|
while (!this->terminate_runner_ && this->handles_[0])
|
||||||
{
|
{
|
||||||
const auto len = _read(this->handles_[0], buffer, sizeof(buffer));
|
const auto len = _read(this->handles_[0], buffer, sizeof(buffer));
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
{
|
{
|
||||||
std::lock_guard _(this->mutex_);
|
std::lock_guard _(this->mutex_);
|
||||||
this->message_queue_.push(std::string(buffer, len));
|
this->message_queue_.push(std::string(buffer, len));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::this_thread::sleep_for(10ms);
|
std::this_thread::sleep_for(10ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::this_thread::yield();
|
std::this_thread::yield();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_MODULE(console)
|
REGISTER_MODULE(console)
|
||||||
|
@ -1,50 +1,50 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include <discord_rpc.h>
|
#include <discord_rpc.h>
|
||||||
#include "loader/module_loader.hpp"
|
#include "loader/module_loader.hpp"
|
||||||
#include "scheduler.hpp"
|
#include "scheduler.hpp"
|
||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
|
|
||||||
class discord final : public module
|
class discord final : public module
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void post_load() override
|
void post_load() override
|
||||||
{
|
{
|
||||||
if (game::is_dedi()) return;
|
if (game::is_dedi()) return;
|
||||||
|
|
||||||
DiscordEventHandlers handlers;
|
DiscordEventHandlers handlers;
|
||||||
ZeroMemory(&handlers, sizeof(handlers));
|
ZeroMemory(&handlers, sizeof(handlers));
|
||||||
handlers.ready = ready;
|
handlers.ready = ready;
|
||||||
handlers.errored = errored;
|
handlers.errored = errored;
|
||||||
handlers.disconnected = errored;
|
handlers.disconnected = errored;
|
||||||
handlers.joinGame = nullptr;
|
handlers.joinGame = nullptr;
|
||||||
handlers.spectateGame = nullptr;
|
handlers.spectateGame = nullptr;
|
||||||
handlers.joinRequest = nullptr;
|
handlers.joinRequest = nullptr;
|
||||||
|
|
||||||
Discord_Initialize("531526691319971880", &handlers, 1, nullptr);
|
Discord_Initialize("531526691319971880", &handlers, 1, nullptr);
|
||||||
|
|
||||||
scheduler::on_frame(Discord_RunCallbacks);
|
scheduler::on_frame(Discord_RunCallbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pre_destroy() override
|
void pre_destroy() override
|
||||||
{
|
{
|
||||||
Discord_Shutdown();
|
Discord_Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void ready(const DiscordUser* request)
|
static void ready(const DiscordUser* request)
|
||||||
{
|
{
|
||||||
DiscordRichPresence discord_presence;
|
DiscordRichPresence discord_presence;
|
||||||
ZeroMemory(&discord_presence, sizeof(discord_presence));
|
ZeroMemory(&discord_presence, sizeof(discord_presence));
|
||||||
|
|
||||||
discord_presence.state = game::is_mp() ? "Multiplayer" : "Singleplayer";
|
discord_presence.state = game::is_mp() ? "Multiplayer" : "Singleplayer";
|
||||||
discord_presence.instance = 1;
|
discord_presence.instance = 1;
|
||||||
Discord_UpdatePresence(&discord_presence);
|
Discord_UpdatePresence(&discord_presence);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void errored(const int error_code, const char* message)
|
static void errored(const int error_code, const char* message)
|
||||||
{
|
{
|
||||||
printf("Discord: (%i) %s", error_code, message);
|
printf("Discord: (%i) %s", error_code, message);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//REGISTER_MODULE(discord)
|
//REGISTER_MODULE(discord)
|
||||||
|
@ -1,60 +1,60 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "loader/module_loader.hpp"
|
#include "loader/module_loader.hpp"
|
||||||
#include "game/structs.hpp"
|
#include "game/structs.hpp"
|
||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
#include "utils/hook.hpp"
|
#include "utils/hook.hpp"
|
||||||
|
|
||||||
static __declspec(naked) void db_load_stub_client(game::native::XZoneInfo*, unsigned int, int)
|
static __declspec(naked) void db_load_stub_client(game::native::XZoneInfo*, unsigned int, int)
|
||||||
{
|
{
|
||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
sub esp, 0Ch
|
sub esp, 0Ch
|
||||||
mov eax, [esp + 18h]
|
mov eax, [esp + 18h]
|
||||||
|
|
||||||
mov ecx, game::native::DB_LoadXAssets
|
mov ecx, game::native::DB_LoadXAssets
|
||||||
add ecx, 7h
|
add ecx, 7h
|
||||||
push ecx
|
push ecx
|
||||||
retn
|
retn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static __declspec(naked) void db_load_stub_server(game::native::XZoneInfo*, unsigned int, int)
|
static __declspec(naked) void db_load_stub_server(game::native::XZoneInfo*, unsigned int, int)
|
||||||
{
|
{
|
||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
sub esp, 10h
|
sub esp, 10h
|
||||||
mov eax, [esp + 1Ch]
|
mov eax, [esp + 1Ch]
|
||||||
|
|
||||||
mov ecx, game::native::DB_LoadXAssets
|
mov ecx, game::native::DB_LoadXAssets
|
||||||
add ecx, 7h
|
add ecx, 7h
|
||||||
push ecx
|
push ecx
|
||||||
retn
|
retn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class fastfiles final : public module
|
class fastfiles final : public module
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void post_load() override
|
void post_load() override
|
||||||
{
|
{
|
||||||
utils::hook(game::native::DB_LoadXAssets, db_load_stub, HOOK_JUMP).install()->quick();
|
utils::hook(game::native::DB_LoadXAssets, db_load_stub, HOOK_JUMP).install()->quick();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void db_load_stub(game::native::XZoneInfo* zone_info, const unsigned int zone_count, const int sync)
|
static void db_load_stub(game::native::XZoneInfo* zone_info, const unsigned int zone_count, const int sync)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < zone_count; ++i)
|
for (unsigned int i = 0; i < zone_count; ++i)
|
||||||
{
|
{
|
||||||
if (zone_info[i].name)
|
if (zone_info[i].name)
|
||||||
{
|
{
|
||||||
printf("Loading FastFile: %s (0x%X | 0x%X)\n", zone_info[i].name, zone_info[i].allocFlags,
|
printf("Loading FastFile: %s (0x%X | 0x%X)\n", zone_info[i].name, zone_info[i].allocFlags,
|
||||||
zone_info[i].freeFlags);
|
zone_info[i].freeFlags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (game::is_dedi()) return db_load_stub_server(zone_info, zone_count, sync);
|
if (game::is_dedi()) return db_load_stub_server(zone_info, zone_count, sync);
|
||||||
else return db_load_stub_client(zone_info, zone_count, sync);
|
else return db_load_stub_client(zone_info, zone_count, sync);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_MODULE(fastfiles)
|
REGISTER_MODULE(fastfiles)
|
||||||
|
@ -1,37 +1,37 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "loader/module_loader.hpp"
|
#include "loader/module_loader.hpp"
|
||||||
#include "utils/hook.hpp"
|
#include "utils/hook.hpp"
|
||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
|
|
||||||
class fov final : public module
|
class fov final : public module
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void post_load() override
|
void post_load() override
|
||||||
{
|
{
|
||||||
if (game::is_dedi()) return;
|
if (game::is_dedi()) return;
|
||||||
|
|
||||||
// Set dvar flag
|
// Set dvar flag
|
||||||
utils::hook::set<BYTE>(SELECT_VALUE(0x4302C5, 0x455155, 0), 0x1 | (game::is_mp() ? 0x40 : 0));
|
utils::hook::set<BYTE>(SELECT_VALUE(0x4302C5, 0x455155, 0), 0x1 | (game::is_mp() ? 0x40 : 0));
|
||||||
|
|
||||||
if (game::is_mp())
|
if (game::is_mp())
|
||||||
{
|
{
|
||||||
// Set dvar limit
|
// Set dvar limit
|
||||||
static const auto cg_fov_limit = 90.0f;
|
static const auto cg_fov_limit = 90.0f;
|
||||||
utils::hook::set(0x455148, &cg_fov_limit);
|
utils::hook::set(0x455148, &cg_fov_limit);
|
||||||
|
|
||||||
// Prevent value change via internal scripts
|
// Prevent value change via internal scripts
|
||||||
utils::hook(0x4698BA, &set_server_command_dvar_stub, HOOK_CALL).install()->quick();
|
utils::hook(0x4698BA, &set_server_command_dvar_stub, HOOK_CALL).install()->quick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void set_server_command_dvar_stub(const char* dvar, const char* value)
|
static void set_server_command_dvar_stub(const char* dvar, const char* value)
|
||||||
{
|
{
|
||||||
if (strcmp(dvar, "cg_fov") != 0 || strcmp(value, "65") != 0)
|
if (strcmp(dvar, "cg_fov") != 0 || strcmp(value, "65") != 0)
|
||||||
{
|
{
|
||||||
game::native::Dvar_SetFromStringByName(dvar, value);
|
game::native::Dvar_SetFromStringByName(dvar, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_MODULE(fov)
|
REGISTER_MODULE(fov)
|
||||||
|
@ -1,61 +1,61 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "loader/module_loader.hpp"
|
#include "loader/module_loader.hpp"
|
||||||
#include "utils/hook.hpp"
|
#include "utils/hook.hpp"
|
||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
|
|
||||||
class patches final : public module
|
class patches final : public module
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void post_load() override
|
void post_load() override
|
||||||
{
|
{
|
||||||
if (!game::is_dedi()) this->patch_clients();
|
if (!game::is_dedi()) this->patch_clients();
|
||||||
|
|
||||||
if (game::is_sp()) this->patch_sp();
|
if (game::is_sp()) this->patch_sp();
|
||||||
else if (game::is_mp()) this->patch_mp();
|
else if (game::is_mp()) this->patch_mp();
|
||||||
else if (game::is_dedi()) this->patch_dedi();
|
else if (game::is_dedi()) this->patch_dedi();
|
||||||
|
|
||||||
utils::hook(game::native::_longjmp, long_jump_stub, HOOK_JUMP).install()->quick();
|
utils::hook(game::native::_longjmp, long_jump_stub, HOOK_JUMP).install()->quick();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void patch_clients() const
|
void patch_clients() const
|
||||||
{
|
{
|
||||||
// Remove improper quit check
|
// Remove improper quit check
|
||||||
utils::hook::nop(SELECT_VALUE(0x53444A, 0x5CCDC0, 0), 9);
|
utils::hook::nop(SELECT_VALUE(0x53444A, 0x5CCDC0, 0), 9);
|
||||||
|
|
||||||
// Ignore sdm files
|
// Ignore sdm files
|
||||||
utils::hook::nop(SELECT_VALUE(0x4438BA, 0x6371EA, 0), 2);
|
utils::hook::nop(SELECT_VALUE(0x4438BA, 0x6371EA, 0), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void patch_sp() const
|
void patch_sp() const
|
||||||
{
|
{
|
||||||
// SP doesn't initialize WSA
|
// SP doesn't initialize WSA
|
||||||
WSADATA wsa_data;
|
WSADATA wsa_data;
|
||||||
WSAStartup(MAKEWORD(2, 2), &wsa_data);
|
WSAStartup(MAKEWORD(2, 2), &wsa_data);
|
||||||
|
|
||||||
// Disable remote storage
|
// Disable remote storage
|
||||||
utils::hook::set<BYTE>(0x663B5A, 0xEB);
|
utils::hook::set<BYTE>(0x663B5A, 0xEB);
|
||||||
utils::hook::set<BYTE>(0x663C54, 0xEB);
|
utils::hook::set<BYTE>(0x663C54, 0xEB);
|
||||||
}
|
}
|
||||||
|
|
||||||
void patch_mp() const
|
void patch_mp() const
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void patch_dedi() const
|
void patch_dedi() const
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static __declspec(noreturn) void long_jump_stub(jmp_buf buf, const int value) noexcept(false)
|
static __declspec(noreturn) void long_jump_stub(jmp_buf buf, const int value) noexcept(false)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
{
|
{
|
||||||
printf("Unwinding the stack...\n");
|
printf("Unwinding the stack...\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
longjmp(buf, value);
|
longjmp(buf, value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_MODULE(patches)
|
REGISTER_MODULE(patches)
|
||||||
|
@ -1,162 +1,162 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "loader/module_loader.hpp"
|
#include "loader/module_loader.hpp"
|
||||||
#include "utils/hook.hpp"
|
#include "utils/hook.hpp"
|
||||||
#include "utils/io.hpp"
|
#include "utils/io.hpp"
|
||||||
#include "game/scripting/context.hpp"
|
#include "game/scripting/context.hpp"
|
||||||
#include "scheduler.hpp"
|
#include "scheduler.hpp"
|
||||||
|
|
||||||
class scripting final : public module
|
class scripting final : public module
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void post_load() override
|
void post_load() override
|
||||||
{
|
{
|
||||||
start_hook_.initialize(SELECT_VALUE(0x50C575, 0x50D4F2, 0x48A026), &start_execution_stub, HOOK_CALL) //
|
start_hook_.initialize(SELECT_VALUE(0x50C575, 0x50D4F2, 0x48A026), &start_execution_stub, HOOK_CALL) //
|
||||||
->install() //
|
->install() //
|
||||||
->quick();
|
->quick();
|
||||||
|
|
||||||
stop_hook_.initialize(SELECT_VALUE(0x528B04, 0x569E46, 0x4F03FA), &stop_execution_stub, HOOK_CALL) //
|
stop_hook_.initialize(SELECT_VALUE(0x528B04, 0x569E46, 0x4F03FA), &stop_execution_stub, HOOK_CALL) //
|
||||||
->install() //
|
->install() //
|
||||||
->quick();
|
->quick();
|
||||||
|
|
||||||
utils::hook(SELECT_VALUE(0x4F9706, 0x5772A0, 0x4FAB88), &frame_stub, HOOK_CALL).install()->quick();
|
utils::hook(SELECT_VALUE(0x4F9706, 0x5772A0, 0x4FAB88), &frame_stub, HOOK_CALL).install()->quick();
|
||||||
utils::hook(SELECT_VALUE(0x4FFA48, 0x5774AB, 0x4FEFD7), &frame_stub, HOOK_CALL).install()->quick(); // Only relevant one?
|
utils::hook(SELECT_VALUE(0x4FFA48, 0x5774AB, 0x4FEFD7), &frame_stub, HOOK_CALL).install()->quick(); // Only relevant one?
|
||||||
|
|
||||||
utils::hook(SELECT_VALUE(0x6109F3, 0x56B637, 0x4EDFF7), &vm_notify_stub, HOOK_CALL).install()->quick();
|
utils::hook(SELECT_VALUE(0x6109F3, 0x56B637, 0x4EDFF7), &vm_notify_stub, HOOK_CALL).install()->quick();
|
||||||
utils::hook(SELECT_VALUE(0x6128BE, 0x56D541, 0x4EFAF9), &vm_notify_stub, HOOK_CALL).install()->quick();
|
utils::hook(SELECT_VALUE(0x6128BE, 0x56D541, 0x4EFAF9), &vm_notify_stub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
if (game::is_sp())
|
if (game::is_sp())
|
||||||
{
|
{
|
||||||
utils::hook(0x50C57E, &frame_stub, HOOK_CALL).install()->quick();
|
utils::hook(0x50C57E, &frame_stub, HOOK_CALL).install()->quick();
|
||||||
utils::hook(0x6523A3, &frame_stub, HOOK_CALL).install()->quick();
|
utils::hook(0x6523A3, &frame_stub, HOOK_CALL).install()->quick();
|
||||||
utils::hook(0x5145D2, &frame_stub, HOOK_CALL).install()->quick();
|
utils::hook(0x5145D2, &frame_stub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
utils::hook(0x610970, &vm_notify_stub, HOOK_JUMP).install()->quick();
|
utils::hook(0x610970, &vm_notify_stub, HOOK_JUMP).install()->quick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pre_destroy() override
|
void pre_destroy() override
|
||||||
{
|
{
|
||||||
this->scripts_.clear();
|
this->scripts_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::unique_ptr<game::scripting::context>> scripts_;
|
std::vector<std::unique_ptr<game::scripting::context>> scripts_;
|
||||||
|
|
||||||
void load_scripts()
|
void load_scripts()
|
||||||
{
|
{
|
||||||
const auto scripts = utils::io::list_files("open-iw5/scripts/");
|
const auto scripts = utils::io::list_files("open-iw5/scripts/");
|
||||||
|
|
||||||
for (const auto& script : scripts)
|
for (const auto& script : scripts)
|
||||||
{
|
{
|
||||||
if (script.substr(script.find_last_of('.') + 1) == "chai")
|
if (script.substr(script.find_last_of('.') + 1) == "chai")
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto context = std::make_unique<game::scripting::context>();
|
auto context = std::make_unique<game::scripting::context>();
|
||||||
context->get_chai()->eval_file(script);
|
context->get_chai()->eval_file(script);
|
||||||
this->scripts_.push_back(std::move(context));
|
this->scripts_.push_back(std::move(context));
|
||||||
}
|
}
|
||||||
catch (chaiscript::exception::eval_error& e)
|
catch (chaiscript::exception::eval_error& e)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(e.pretty_print());
|
throw std::runtime_error(e.pretty_print());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_execution()
|
void start_execution()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this->load_scripts();
|
this->load_scripts();
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
propagate_error(e);
|
propagate_error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop_execution()
|
void stop_execution()
|
||||||
{
|
{
|
||||||
this->scripts_.clear();
|
this->scripts_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void run_frame()
|
void run_frame()
|
||||||
{
|
{
|
||||||
for (const auto& script : this->scripts_)
|
for (const auto& script : this->scripts_)
|
||||||
{
|
{
|
||||||
script->get_scheduler()->run_frame();
|
script->get_scheduler()->run_frame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispatch(game::scripting::event* event)
|
void dispatch(game::scripting::event* event)
|
||||||
{
|
{
|
||||||
for (const auto& script : this->scripts_)
|
for (const auto& script : this->scripts_)
|
||||||
{
|
{
|
||||||
script->get_event_handler()->dispatch(event);
|
script->get_event_handler()->dispatch(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static utils::hook start_hook_;
|
static utils::hook start_hook_;
|
||||||
static utils::hook stop_hook_;
|
static utils::hook stop_hook_;
|
||||||
|
|
||||||
static void propagate_error(const std::exception& e)
|
static void propagate_error(const std::exception& e)
|
||||||
{
|
{
|
||||||
printf("\n******* Script execution error *******\n");
|
printf("\n******* Script execution error *******\n");
|
||||||
printf("%s\n", e.what());
|
printf("%s\n", e.what());
|
||||||
printf("**************************************\n\n");
|
printf("**************************************\n\n");
|
||||||
|
|
||||||
scheduler::error("Script execution error\n(see console for actual details)\n", 5);
|
scheduler::error("Script execution error\n(see console for actual details)\n", 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_execution_stub()
|
static void start_execution_stub()
|
||||||
{
|
{
|
||||||
module_loader::get<scripting>()->start_execution();
|
module_loader::get<scripting>()->start_execution();
|
||||||
reinterpret_cast<void(*)()>(start_hook_.get_original())();
|
reinterpret_cast<void(*)()>(start_hook_.get_original())();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stop_execution_stub()
|
static void stop_execution_stub()
|
||||||
{
|
{
|
||||||
module_loader::get<scripting>()->stop_execution();
|
module_loader::get<scripting>()->stop_execution();
|
||||||
reinterpret_cast<void(*)()>(stop_hook_.get_original())();
|
reinterpret_cast<void(*)()>(stop_hook_.get_original())();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vm_notify_stub(const unsigned int notify_id, const unsigned short type,
|
static void vm_notify_stub(const unsigned int notify_id, const unsigned short type,
|
||||||
game::native::VariableValue* stack)
|
game::native::VariableValue* stack)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
game::scripting::event e;
|
game::scripting::event e;
|
||||||
e.name = game::native::SL_ConvertToString(type);
|
e.name = game::native::SL_ConvertToString(type);
|
||||||
e.entity_id = notify_id;
|
e.entity_id = notify_id;
|
||||||
|
|
||||||
if (e.name == "touch") return; // Skip that for now
|
if (e.name == "touch") return; // Skip that for now
|
||||||
|
|
||||||
//printf("%X: %s\n", e.entity_id, e.name.data());
|
//printf("%X: %s\n", e.entity_id, e.name.data());
|
||||||
|
|
||||||
for (auto value = stack; value->type != game::native::SCRIPT_END; --value)
|
for (auto value = stack; value->type != game::native::SCRIPT_END; --value)
|
||||||
{
|
{
|
||||||
e.arguments.emplace_back(*value);
|
e.arguments.emplace_back(*value);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_loader::get<scripting>()->dispatch(&e);
|
module_loader::get<scripting>()->dispatch(&e);
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
propagate_error(e);
|
propagate_error(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
game::native::VM_Notify(notify_id, type, stack);
|
game::native::VM_Notify(notify_id, type, stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int frame_stub(int a1, int a2)
|
static int frame_stub(int a1, int a2)
|
||||||
{
|
{
|
||||||
module_loader::get<scripting>()->run_frame();
|
module_loader::get<scripting>()->run_frame();
|
||||||
return game::native::G_RunFrame(a1, a2);
|
return game::native::G_RunFrame(a1, a2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
utils::hook scripting::start_hook_;
|
utils::hook scripting::start_hook_;
|
||||||
utils::hook scripting::stop_hook_;
|
utils::hook scripting::stop_hook_;
|
||||||
|
|
||||||
REGISTER_MODULE(scripting)
|
REGISTER_MODULE(scripting)
|
||||||
|
@ -1,25 +1,25 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "loader/module_loader.hpp"
|
#include "loader/module_loader.hpp"
|
||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
#include "utils/hook.hpp"
|
#include "utils/hook.hpp"
|
||||||
|
|
||||||
class security final : public module
|
class security final : public module
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void post_load() override
|
void post_load() override
|
||||||
{
|
{
|
||||||
if(game::is_mp())
|
if(game::is_mp())
|
||||||
{
|
{
|
||||||
utils::hook(0x4AECD4, read_p2p_auth_ticket_stub, HOOK_JUMP).install()->quick();
|
utils::hook(0x4AECD4, read_p2p_auth_ticket_stub, HOOK_JUMP).install()->quick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void read_p2p_auth_ticket_stub(game::native::msg_t* msg, void* data, const int len)
|
static void read_p2p_auth_ticket_stub(game::native::msg_t* msg, void* data, const int len)
|
||||||
{
|
{
|
||||||
if (len < 0) return;
|
if (len < 0) return;
|
||||||
return game::native::MSG_ReadData(msg, data, std::min(len, 200));
|
return game::native::MSG_ReadData(msg, data, std::min(len, 200));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_MODULE(security)
|
REGISTER_MODULE(security)
|
||||||
|
@ -1,178 +1,178 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "loader/module_loader.hpp"
|
#include "loader/module_loader.hpp"
|
||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
#include "utils/nt.hpp"
|
#include "utils/nt.hpp"
|
||||||
#include "steam/steam.hpp"
|
#include "steam/steam.hpp"
|
||||||
#include "steam/interface.hpp"
|
#include "steam/interface.hpp"
|
||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
#include "scheduler.hpp"
|
#include "scheduler.hpp"
|
||||||
|
|
||||||
class steam_proxy final : public module
|
class steam_proxy final : public module
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void post_start() override
|
void post_start() override
|
||||||
{
|
{
|
||||||
if (game::is_dedi()) return;
|
if (game::is_dedi()) return;
|
||||||
|
|
||||||
this->run_mod();
|
this->run_mod();
|
||||||
this->load_client();
|
this->load_client();
|
||||||
|
|
||||||
this->clean_up_on_error();
|
this->clean_up_on_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
void post_load() override
|
void post_load() override
|
||||||
{
|
{
|
||||||
if (game::is_dedi()) return;
|
if (game::is_dedi()) return;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (game::is_sp())
|
if (game::is_sp())
|
||||||
{
|
{
|
||||||
this->start_mod("Open-IW5 Singleplayer", 42680);
|
this->start_mod("Open-IW5 Singleplayer", 42680);
|
||||||
}
|
}
|
||||||
else if (game::is_mp())
|
else if (game::is_mp())
|
||||||
{
|
{
|
||||||
this->start_mod("Open-IW5 Multiplayer", 42690);
|
this->start_mod("Open-IW5 Multiplayer", 42690);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
printf("Steam: %s\n", e.what());
|
printf("Steam: %s\n", e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pre_destroy() override
|
void pre_destroy() override
|
||||||
{
|
{
|
||||||
if (this->steam_client_module_)
|
if (this->steam_client_module_)
|
||||||
{
|
{
|
||||||
if (this->steam_pipe_)
|
if (this->steam_pipe_)
|
||||||
{
|
{
|
||||||
if (this->global_user_)
|
if (this->global_user_)
|
||||||
{
|
{
|
||||||
this->steam_client_module_.invoke<void>("Steam_ReleaseUser", this->steam_pipe_, this->global_user_);
|
this->steam_client_module_.invoke<void>("Steam_ReleaseUser", this->steam_pipe_, this->global_user_);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->steam_client_module_.invoke<bool>("Steam_BReleaseSteamPipe", this->steam_pipe_);
|
this->steam_client_module_.invoke<bool>("Steam_BReleaseSteamPipe", this->steam_pipe_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
utils::nt::module steam_client_module_;
|
utils::nt::module steam_client_module_;
|
||||||
|
|
||||||
steam::interface client_engine_;
|
steam::interface client_engine_;
|
||||||
steam::interface client_user_;
|
steam::interface client_user_;
|
||||||
steam::interface client_utils_;
|
steam::interface client_utils_;
|
||||||
|
|
||||||
void* steam_pipe_ = nullptr;
|
void* steam_pipe_ = nullptr;
|
||||||
void* global_user_ = nullptr;
|
void* global_user_ = nullptr;
|
||||||
|
|
||||||
void run_mod() const
|
void run_mod() const
|
||||||
{
|
{
|
||||||
const auto command = "-proc ";
|
const auto command = "-proc ";
|
||||||
const char* parent_proc = strstr(GetCommandLineA(), command);
|
const char* parent_proc = strstr(GetCommandLineA(), command);
|
||||||
|
|
||||||
if (parent_proc)
|
if (parent_proc)
|
||||||
{
|
{
|
||||||
const auto pid = atoi(parent_proc + strlen(command));
|
const auto pid = atoi(parent_proc + strlen(command));
|
||||||
const auto process_handle = OpenProcess(SYNCHRONIZE, FALSE, pid);
|
const auto process_handle = OpenProcess(SYNCHRONIZE, FALSE, pid);
|
||||||
if (process_handle && process_handle != INVALID_HANDLE_VALUE)
|
if (process_handle && process_handle != INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
WaitForSingleObject(process_handle, INFINITE);
|
WaitForSingleObject(process_handle, INFINITE);
|
||||||
CloseHandle(process_handle);
|
CloseHandle(process_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_loader::trigger_premature_shutdown();
|
module_loader::trigger_premature_shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void* load_client_engine() const
|
void* load_client_engine() const
|
||||||
{
|
{
|
||||||
if (!this->steam_client_module_) return nullptr;
|
if (!this->steam_client_module_) return nullptr;
|
||||||
|
|
||||||
for (auto i = 1; i > 0; ++i)
|
for (auto i = 1; i > 0; ++i)
|
||||||
{
|
{
|
||||||
std::string name = utils::string::va("CLIENTENGINE_INTERFACE_VERSION%03i", i);
|
std::string name = utils::string::va("CLIENTENGINE_INTERFACE_VERSION%03i", i);
|
||||||
const auto client_engine = this->steam_client_module_
|
const auto client_engine = this->steam_client_module_
|
||||||
.invoke<void*>("CreateInterface", name.data(), nullptr);
|
.invoke<void*>("CreateInterface", name.data(), nullptr);
|
||||||
if (client_engine) return client_engine;
|
if (client_engine) return client_engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_client()
|
void load_client()
|
||||||
{
|
{
|
||||||
const auto steam_path = ::steam::get_steam_install_directory();
|
const auto steam_path = ::steam::get_steam_install_directory();
|
||||||
if (steam_path.empty()) return;
|
if (steam_path.empty()) return;
|
||||||
|
|
||||||
utils::nt::module::load(steam_path + "tier0_s.dll");
|
utils::nt::module::load(steam_path + "tier0_s.dll");
|
||||||
utils::nt::module::load(steam_path + "vstdlib_s.dll");
|
utils::nt::module::load(steam_path + "vstdlib_s.dll");
|
||||||
this->steam_client_module_ = utils::nt::module::load(steam_path + "steamclient.dll");
|
this->steam_client_module_ = utils::nt::module::load(steam_path + "steamclient.dll");
|
||||||
if (!this->steam_client_module_) return;
|
if (!this->steam_client_module_) return;
|
||||||
|
|
||||||
this->client_engine_ = load_client_engine();
|
this->client_engine_ = load_client_engine();
|
||||||
if (!this->client_engine_) return;
|
if (!this->client_engine_) return;
|
||||||
|
|
||||||
this->steam_pipe_ = this->steam_client_module_.invoke<void*>("Steam_CreateSteamPipe");
|
this->steam_pipe_ = this->steam_client_module_.invoke<void*>("Steam_CreateSteamPipe");
|
||||||
this->global_user_ = this->steam_client_module_.invoke<void*>("Steam_ConnectToGlobalUser", this->steam_pipe_);
|
this->global_user_ = this->steam_client_module_.invoke<void*>("Steam_ConnectToGlobalUser", this->steam_pipe_);
|
||||||
this->client_user_ = this->client_engine_.invoke<void*>(8, this->steam_pipe_, this->global_user_,
|
this->client_user_ = this->client_engine_.invoke<void*>(8, this->steam_pipe_, this->global_user_,
|
||||||
"CLIENTUSER_INTERFACE_VERSION001"); // GetIClientUser
|
"CLIENTUSER_INTERFACE_VERSION001"); // GetIClientUser
|
||||||
this->client_utils_ = this->client_engine_.invoke<void*>(13, this->steam_pipe_,
|
this->client_utils_ = this->client_engine_.invoke<void*>(13, this->steam_pipe_,
|
||||||
"CLIENTUTILS_INTERFACE_VERSION001"); // GetIClientUtils
|
"CLIENTUTILS_INTERFACE_VERSION001"); // GetIClientUtils
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_mod(const std::string& title, size_t app_id)
|
void start_mod(const std::string& title, size_t app_id)
|
||||||
{
|
{
|
||||||
if (!this->client_utils_ || !this->client_user_) return;
|
if (!this->client_utils_ || !this->client_user_) return;
|
||||||
|
|
||||||
if (!this->client_user_.invoke<bool>("BIsSubscribedApp", app_id))
|
if (!this->client_user_.invoke<bool>("BIsSubscribedApp", app_id))
|
||||||
{
|
{
|
||||||
app_id = 480; // Spacewar
|
app_id = 480; // Spacewar
|
||||||
}
|
}
|
||||||
|
|
||||||
this->client_utils_.invoke<void>("SetAppIDForCurrentPipe", app_id, false);
|
this->client_utils_.invoke<void>("SetAppIDForCurrentPipe", app_id, false);
|
||||||
|
|
||||||
utils::nt::module self;
|
utils::nt::module self;
|
||||||
const auto path = self.get_path();
|
const auto path = self.get_path();
|
||||||
|
|
||||||
char our_directory[MAX_PATH] = {0};
|
char our_directory[MAX_PATH] = {0};
|
||||||
GetCurrentDirectoryA(sizeof(our_directory), our_directory);
|
GetCurrentDirectoryA(sizeof(our_directory), our_directory);
|
||||||
|
|
||||||
const std::string cmdline = utils::string::va("\"%s\" -proc %d", path.data(), GetCurrentProcessId());
|
const std::string cmdline = utils::string::va("\"%s\" -proc %d", path.data(), GetCurrentProcessId());
|
||||||
|
|
||||||
game_id game_id;
|
game_id game_id;
|
||||||
game_id.raw.type = 1; // k_EGameIDTypeGameMod
|
game_id.raw.type = 1; // k_EGameIDTypeGameMod
|
||||||
game_id.raw.app_id = app_id & 0xFFFFFF;
|
game_id.raw.app_id = app_id & 0xFFFFFF;
|
||||||
|
|
||||||
const auto mod_id = "OIW5";
|
const auto mod_id = "OIW5";
|
||||||
game_id.raw.mod_id = *reinterpret_cast<const unsigned int*>(mod_id) | 0x80000000;
|
game_id.raw.mod_id = *reinterpret_cast<const unsigned int*>(mod_id) | 0x80000000;
|
||||||
|
|
||||||
this->client_user_.invoke<bool>("SpawnProcess", self.get_path().data(), cmdline.data(), 0, our_directory,
|
this->client_user_.invoke<bool>("SpawnProcess", self.get_path().data(), cmdline.data(), 0, our_directory,
|
||||||
game_id.bits, title.data(), app_id, 0, 0);
|
game_id.bits, title.data(), app_id, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clean_up_on_error()
|
void clean_up_on_error()
|
||||||
{
|
{
|
||||||
if (this->steam_client_module_
|
if (this->steam_client_module_
|
||||||
&& this->steam_pipe_
|
&& this->steam_pipe_
|
||||||
&& this->global_user_
|
&& this->global_user_
|
||||||
&& this->steam_client_module_.invoke<bool>("Steam_BConnected", this->global_user_, this->steam_pipe_)
|
&& this->steam_client_module_.invoke<bool>("Steam_BConnected", this->global_user_, this->steam_pipe_)
|
||||||
&& this->steam_client_module_.invoke<bool>("Steam_BLoggedOn", this->global_user_, this->steam_pipe_))
|
&& this->steam_client_module_.invoke<bool>("Steam_BLoggedOn", this->global_user_, this->steam_pipe_))
|
||||||
{
|
{
|
||||||
scheduler::once(std::bind(&steam_proxy::clean_up_on_error, this));
|
scheduler::once(std::bind(&steam_proxy::clean_up_on_error, this));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->client_engine_ = nullptr;
|
this->client_engine_ = nullptr;
|
||||||
this->client_user_ = nullptr;
|
this->client_user_ = nullptr;
|
||||||
this->client_utils_ = nullptr;
|
this->client_utils_ = nullptr;
|
||||||
|
|
||||||
this->steam_pipe_ = nullptr;
|
this->steam_pipe_ = nullptr;
|
||||||
this->global_user_ = nullptr;
|
this->global_user_ = nullptr;
|
||||||
|
|
||||||
this->steam_client_module_ = utils::nt::module{nullptr};
|
this->steam_client_module_ = utils::nt::module{nullptr};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//REGISTER_MODULE(steam_proxy)
|
//REGISTER_MODULE(steam_proxy)
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define BINARY_SP 300
|
#define BINARY_SP 300
|
||||||
#define BINARY_MP 301
|
#define BINARY_MP 301
|
||||||
|
|
||||||
#define DW_HEATMAP 302
|
#define DW_HEATMAP 302
|
||||||
#define DW_MOTD 303
|
#define DW_MOTD 303
|
||||||
#define DW_IMG 304
|
#define DW_IMG 304
|
||||||
#define DW_WAD 305
|
#define DW_WAD 305
|
||||||
#define DW_PLAYLIST 306
|
#define DW_PLAYLIST 306
|
||||||
#define DW_CONFIG 307
|
#define DW_CONFIG 307
|
||||||
#define DW_IOTD_TXT 308
|
#define DW_IOTD_TXT 308
|
||||||
#define DW_IOTD_IMG 309
|
#define DW_IOTD_IMG 309
|
||||||
|
|
||||||
#define MENU_MAIN 310
|
#define MENU_MAIN 310
|
||||||
#define MENU_SETTINGS 311
|
#define MENU_SETTINGS 311
|
||||||
|
234
src/resource.rc
234
src/resource.rc
@ -1,117 +1,117 @@
|
|||||||
// Microsoft Visual C++ generated resource script.
|
// Microsoft Visual C++ generated resource script.
|
||||||
//
|
//
|
||||||
#pragma code_page(65001)
|
#pragma code_page(65001)
|
||||||
|
|
||||||
#define APSTUDIO_READONLY_SYMBOLS
|
#define APSTUDIO_READONLY_SYMBOLS
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Generated from the TEXTINCLUDE 2 resource.
|
// Generated from the TEXTINCLUDE 2 resource.
|
||||||
//
|
//
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
#include "resource.hpp"
|
#include "resource.hpp"
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
#undef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// English (United States) resources
|
// English (United States) resources
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// TEXTINCLUDE
|
// TEXTINCLUDE
|
||||||
//
|
//
|
||||||
|
|
||||||
1 TEXTINCLUDE
|
1 TEXTINCLUDE
|
||||||
BEGIN
|
BEGIN
|
||||||
"#include ""windows.h""\r\n"
|
"#include ""windows.h""\r\n"
|
||||||
"\0"
|
"\0"
|
||||||
END
|
END
|
||||||
|
|
||||||
2 TEXTINCLUDE
|
2 TEXTINCLUDE
|
||||||
BEGIN
|
BEGIN
|
||||||
"\r\n"
|
"\r\n"
|
||||||
"\0"
|
"\0"
|
||||||
END
|
END
|
||||||
|
|
||||||
#endif // APSTUDIO_INVOKED
|
#endif // APSTUDIO_INVOKED
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Version
|
// Version
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,0,0,0
|
FILEVERSION 1,0,0,0
|
||||||
PRODUCTVERSION 1,0,0,0
|
PRODUCTVERSION 1,0,0,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
#else
|
#else
|
||||||
FILEFLAGS 0x0L
|
FILEFLAGS 0x0L
|
||||||
#endif
|
#endif
|
||||||
FILEOS 0x40004L
|
FILEOS 0x40004L
|
||||||
FILETYPE VFT_DLL
|
FILETYPE VFT_DLL
|
||||||
FILESUBTYPE 0x0L
|
FILESUBTYPE 0x0L
|
||||||
BEGIN
|
BEGIN
|
||||||
BLOCK "StringFileInfo"
|
BLOCK "StringFileInfo"
|
||||||
BEGIN
|
BEGIN
|
||||||
BLOCK "040904b0"
|
BLOCK "040904b0"
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "momo5502"
|
VALUE "CompanyName", "momo5502"
|
||||||
VALUE "FileDescription", "Open-IW5"
|
VALUE "FileDescription", "Open-IW5"
|
||||||
VALUE "FileVersion", "1.0.0.0"
|
VALUE "FileVersion", "1.0.0.0"
|
||||||
VALUE "InternalName", "Open-IW5"
|
VALUE "InternalName", "Open-IW5"
|
||||||
VALUE "LegalCopyright", "All rights reserved."
|
VALUE "LegalCopyright", "All rights reserved."
|
||||||
VALUE "OriginalFilename", "open-iw5.exe"
|
VALUE "OriginalFilename", "open-iw5.exe"
|
||||||
VALUE "ProductName", "open-iw5"
|
VALUE "ProductName", "open-iw5"
|
||||||
VALUE "ProductVersion", "1.0.0.0"
|
VALUE "ProductVersion", "1.0.0.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "Translation", 0x409, 1200
|
VALUE "Translation", 0x409, 1200
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Binary Data
|
// Binary Data
|
||||||
//
|
//
|
||||||
|
|
||||||
102 ICON "resources/icon.ico"
|
102 ICON "resources/icon.ico"
|
||||||
|
|
||||||
BINARY_SP RCDATA "resources/iw5sp.exe.diff"
|
BINARY_SP RCDATA "resources/iw5sp.exe.diff"
|
||||||
BINARY_MP RCDATA "resources/iw5mp.exe.diff"
|
BINARY_MP RCDATA "resources/iw5mp.exe.diff"
|
||||||
|
|
||||||
DW_HEATMAP RCDATA "resources/dw/heatmap.raw"
|
DW_HEATMAP RCDATA "resources/dw/heatmap.raw"
|
||||||
DW_MOTD RCDATA "resources/dw/motd-english.txt"
|
DW_MOTD RCDATA "resources/dw/motd-english.txt"
|
||||||
DW_IMG RCDATA "resources/dw/online_mp.img"
|
DW_IMG RCDATA "resources/dw/online_mp.img"
|
||||||
DW_WAD RCDATA "resources/dw/online_tu14_mp_english.wad"
|
DW_WAD RCDATA "resources/dw/online_tu14_mp_english.wad"
|
||||||
DW_PLAYLIST RCDATA "resources/dw/playlists.aggr"
|
DW_PLAYLIST RCDATA "resources/dw/playlists.aggr"
|
||||||
DW_CONFIG RCDATA "resources/dw/social_tu1.cfg"
|
DW_CONFIG RCDATA "resources/dw/social_tu1.cfg"
|
||||||
DW_IOTD_TXT RCDATA "resources/dw/iotd-english.txt"
|
DW_IOTD_TXT RCDATA "resources/dw/iotd-english.txt"
|
||||||
DW_IOTD_IMG RCDATA "resources/dw/iotd-english.jpg"
|
DW_IOTD_IMG RCDATA "resources/dw/iotd-english.jpg"
|
||||||
|
|
||||||
MENU_MAIN RCDATA "resources/main.html"
|
MENU_MAIN RCDATA "resources/main.html"
|
||||||
MENU_SETTINGS RCDATA "resources/settings.html"
|
MENU_SETTINGS RCDATA "resources/settings.html"
|
||||||
|
|
||||||
|
|
||||||
#endif // English (United States) resources
|
#endif // English (United States) resources
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef APSTUDIO_INVOKED
|
#ifndef APSTUDIO_INVOKED
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Generated from the TEXTINCLUDE 3 resource.
|
// Generated from the TEXTINCLUDE 3 resource.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
#endif // not APSTUDIO_INVOKED
|
#endif // not APSTUDIO_INVOKED
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -1,44 +1,44 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
|
|
||||||
<title>Open-IW5 Settings</title>
|
<title>Open-IW5 Settings</title>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
* {
|
* {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background-color: #2D2D2D;
|
background-color: #2D2D2D;
|
||||||
color: white;
|
color: white;
|
||||||
|
|
||||||
font-family: "Segoe UI Light", "Segoe UI", "Lucida Sans", Arial, sans-serif;
|
font-family: "Segoe UI Light", "Segoe UI", "Lucida Sans", Arial, sans-serif;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: lighter;
|
font-weight: lighter;
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h1>No settings, yet!</h1>
|
<h1>No settings, yet!</h1>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
@ -1,143 +1,143 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "steam/steam.hpp"
|
#include "steam/steam.hpp"
|
||||||
#include "module/dw.hpp"
|
#include "module/dw.hpp"
|
||||||
|
|
||||||
namespace steam
|
namespace steam
|
||||||
{
|
{
|
||||||
std::string auth_ticket;
|
std::string auth_ticket;
|
||||||
|
|
||||||
int user::GetHSteamUser()
|
int user::GetHSteamUser()
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool user::LoggedOn()
|
bool user::LoggedOn()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
steam_id user::GetSteamID()
|
steam_id user::GetSteamID()
|
||||||
{
|
{
|
||||||
steam_id id;
|
steam_id id;
|
||||||
id.bits = 0x110000100000000 | (0x1377 & ~0x80000000);
|
id.bits = 0x110000100000000 | (0x1377 & ~0x80000000);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
int user::InitiateGameConnection(void* pAuthBlob, int cbMaxAuthBlob, steam_id steamIDGameServer,
|
int user::InitiateGameConnection(void* pAuthBlob, int cbMaxAuthBlob, steam_id steamIDGameServer,
|
||||||
unsigned int unIPServer, unsigned short usPortServer, bool bSecure)
|
unsigned int unIPServer, unsigned short usPortServer, bool bSecure)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void user::TerminateGameConnection(unsigned int unIPServer, unsigned short usPortServer)
|
void user::TerminateGameConnection(unsigned int unIPServer, unsigned short usPortServer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void user::TrackAppUsageEvent(steam_id gameID, int eAppUsageEvent, const char* pchExtraInfo)
|
void user::TrackAppUsageEvent(steam_id gameID, int eAppUsageEvent, const char* pchExtraInfo)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool user::GetUserDataFolder(char* pchBuffer, int cubBuffer)
|
bool user::GetUserDataFolder(char* pchBuffer, int cubBuffer)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void user::StartVoiceRecording()
|
void user::StartVoiceRecording()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void user::StopVoiceRecording()
|
void user::StopVoiceRecording()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int user::GetAvailableVoice(unsigned int* pcbCompressed, unsigned int* pcbUncompressed,
|
int user::GetAvailableVoice(unsigned int* pcbCompressed, unsigned int* pcbUncompressed,
|
||||||
unsigned int nUncompressedVoiceDesiredSampleRate)
|
unsigned int nUncompressedVoiceDesiredSampleRate)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int user::GetVoice(bool bWantCompressed, void* pDestBuffer, unsigned int cbDestBufferSize,
|
int user::GetVoice(bool bWantCompressed, void* pDestBuffer, unsigned int cbDestBufferSize,
|
||||||
unsigned int* nBytesWritten, bool bWantUncompressed, void* pUncompressedDestBuffer,
|
unsigned int* nBytesWritten, bool bWantUncompressed, void* pUncompressedDestBuffer,
|
||||||
unsigned int cbUncompressedDestBufferSize, unsigned int* nUncompressBytesWritten,
|
unsigned int cbUncompressedDestBufferSize, unsigned int* nUncompressBytesWritten,
|
||||||
unsigned int nUncompressedVoiceDesiredSampleRate)
|
unsigned int nUncompressedVoiceDesiredSampleRate)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int user::DecompressVoice(void* pCompressed, unsigned int cbCompressed, void* pDestBuffer,
|
int user::DecompressVoice(void* pCompressed, unsigned int cbCompressed, void* pDestBuffer,
|
||||||
unsigned int cbDestBufferSize, unsigned int* nBytesWritten)
|
unsigned int cbDestBufferSize, unsigned int* nBytesWritten)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int user::GetVoiceOptimalSampleRate()
|
unsigned int user::GetVoiceOptimalSampleRate()
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int user::GetAuthSessionTicket(void* pTicket, int cbMaxTicket, unsigned int* pcbTicket)
|
unsigned int user::GetAuthSessionTicket(void* pTicket, int cbMaxTicket, unsigned int* pcbTicket)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int user::BeginAuthSession(const void* pAuthTicket, int cbAuthTicket, steam_id steamID)
|
int user::BeginAuthSession(const void* pAuthTicket, int cbAuthTicket, steam_id steamID)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void user::EndAuthSession(steam_id steamID)
|
void user::EndAuthSession(steam_id steamID)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void user::CancelAuthTicket(unsigned int hAuthTicket)
|
void user::CancelAuthTicket(unsigned int hAuthTicket)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int user::UserHasLicenseForApp(steam_id steamID, unsigned int appID)
|
unsigned int user::UserHasLicenseForApp(steam_id steamID, unsigned int appID)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool user::BIsBehindNAT()
|
bool user::BIsBehindNAT()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void user::AdvertiseGame(steam_id steamIDGameServer, unsigned int unIPServer, unsigned short usPortServer)
|
void user::AdvertiseGame(steam_id steamIDGameServer, unsigned int unIPServer, unsigned short usPortServer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned __int64 user::RequestEncryptedAppTicket(void* pUserData, int cbUserData)
|
unsigned __int64 user::RequestEncryptedAppTicket(void* pUserData, int cbUserData)
|
||||||
{
|
{
|
||||||
// Generate the authentication ticket
|
// Generate the authentication ticket
|
||||||
const auto id = this->GetSteamID();
|
const auto id = this->GetSteamID();
|
||||||
|
|
||||||
auth_ticket = "Open-IW5";
|
auth_ticket = "Open-IW5";
|
||||||
auth_ticket.resize(32);
|
auth_ticket.resize(32);
|
||||||
auth_ticket.append(reinterpret_cast<char*>(pUserData), cbUserData);
|
auth_ticket.append(reinterpret_cast<char*>(pUserData), cbUserData);
|
||||||
auth_ticket.append(reinterpret_cast<const char*>(&id.bits), sizeof(id.bits));
|
auth_ticket.append(reinterpret_cast<const char*>(&id.bits), sizeof(id.bits));
|
||||||
|
|
||||||
// Create the call response
|
// Create the call response
|
||||||
const auto result = callbacks::register_call();
|
const auto result = callbacks::register_call();
|
||||||
auto retvals = static_cast<encrypted_app_ticket_response*>(calloc(1, sizeof(encrypted_app_ticket_response)));
|
auto retvals = static_cast<encrypted_app_ticket_response*>(calloc(1, sizeof(encrypted_app_ticket_response)));
|
||||||
//::Utils::Memory::AllocateArray<EncryptedAppTicketResponse>();
|
//::Utils::Memory::AllocateArray<EncryptedAppTicketResponse>();
|
||||||
retvals->m_e_result = 1;
|
retvals->m_e_result = 1;
|
||||||
|
|
||||||
// Return the call response
|
// Return the call response
|
||||||
callbacks::return_call(retvals, sizeof(encrypted_app_ticket_response),
|
callbacks::return_call(retvals, sizeof(encrypted_app_ticket_response),
|
||||||
encrypted_app_ticket_response::callback_id, result);
|
encrypted_app_ticket_response::callback_id, result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool user::GetEncryptedAppTicket(void* pTicket, int cbMaxTicket, unsigned int* pcbTicket)
|
bool user::GetEncryptedAppTicket(void* pTicket, int cbMaxTicket, unsigned int* pcbTicket)
|
||||||
{
|
{
|
||||||
if (cbMaxTicket < 0 || auth_ticket.empty()) return false;
|
if (cbMaxTicket < 0 || auth_ticket.empty()) return false;
|
||||||
|
|
||||||
const auto size = std::min(size_t(cbMaxTicket), auth_ticket.size());
|
const auto size = std::min(size_t(cbMaxTicket), auth_ticket.size());
|
||||||
std::memcpy(pTicket, auth_ticket.data(), size);
|
std::memcpy(pTicket, auth_ticket.data(), size);
|
||||||
*pcbTicket = size;
|
*pcbTicket = size;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user