smol thingy's

This commit is contained in:
Skull Merlin 2022-02-21 21:39:44 +02:00
parent 9fad4ec948
commit 0d8ca4ef7a
14 changed files with 387 additions and 22 deletions

View File

@ -42,7 +42,7 @@ namespace auth
std::string get_protected_data()
{
std::string input = "X-Labs-S1x-Auth";
std::string input = "X-Labs-H1Mod-Auth";
DATA_BLOB data_in{}, data_out{};
data_in.pbData = reinterpret_cast<uint8_t*>(input.data());

View File

@ -0,0 +1 @@
#include <std_include.hpp>

View File

@ -0,0 +1 @@
#include <std_include.hpp>

View File

@ -243,10 +243,10 @@ namespace network
utils::hook::call(0x140480E62, &net_compare_address); // H1MP64(1.4)
// increase cl_maxpackets
dvars::override::register_int("cl_maxpackets", 1000, 1, 1000, game::DVAR_FLAG_SAVED);
dvars::override::register_int("cl_maxpackets", 1000, 1, 1000, game::DVAR_FLAG_SAVED, true);
// increase snaps
dvars::override::register_int("sv_remote_client_snapshot_msec", 33, 33, 100, game::DVAR_FLAG_NONE);
dvars::override::register_int("sv_remote_client_snapshot_msec", 33, 33, 100, game::DVAR_FLAG_NONE, true);
// ignore impure client
utils::hook::jump(0x140481B58, reinterpret_cast<void*>(0x140481BEE)); // H1MP64(1.4)
@ -256,10 +256,10 @@ namespace network
utils::hook::set<uint8_t>(0x14051345A, 0); // H1MP64(1.4)
// don't read checksum
utils::hook::jump(0x140513389, 0x14051339F);
utils::hook::jump(0x140513389, 0x14051339F); // H1MP64(1.4)
// don't try to reconnect client
utils::hook::call(0x140480DFF, reconnect_migratated_client);
utils::hook::call(0x140480DFF, reconnect_migratated_client); // H1MP64(1.4)
utils::hook::nop(0x140480DDB, 4); // H1MP64(1.4) this crashes when reconnecting for some reason
// allow server owner to modify net_port before the socket bind

View File

@ -0,0 +1,78 @@
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "game/game.hpp"
#include "game/dvars.hpp"
#include <utils/hook.hpp>
#include <utils/string.hpp>
#include <component/scheduler.hpp>
namespace patches
{
namespace
{
utils::hook::detour gscr_set_save_dvar_hook;
utils::hook::detour dvar_register_float_hook;
void gscr_set_save_dvar_stub()
{
const auto string = utils::string::to_lower(utils::hook::invoke<const char*>(SELECT_VALUE(0x140375210, 0x140443150), 0));
if (string == "cg_fov" || string == "cg_fovscale")
{
return;
}
gscr_set_save_dvar_hook.invoke<void>();
}
game::dvar_t* cg_fov = nullptr;
game::dvar_t* cg_fovScale = nullptr;
game::dvar_t* dvar_register_float_stub(int hash, const char* dvarName, float value, float min, float max, unsigned int flags)
{
static const auto cg_fov_hash = game::generateHashValue("cg_fov");
static const auto cg_fov_scale_hash = game::generateHashValue("cg_fovscale");
if (hash == cg_fov_hash)
{
return cg_fov;
}
if (hash == cg_fov_scale_hash)
{
return cg_fovScale;
}
return dvar_register_float_hook.invoke<game::dvar_t*>(hash, dvarName, value, min, max, flags);
}
}
class component final : public component_interface
{
public:
void post_unpack() override
{
// Unlock fps in main menu
utils::hook::set<BYTE>(SELECT_VALUE(0x14018D47B, 0x14025B86B), 0xEB); // H1(1.4)
// Fix mouse lag
utils::hook::nop(SELECT_VALUE(0x1403E3C05, 0x1404DB1AF), 6);
scheduler::loop([]()
{
SetThreadExecutionState(ES_DISPLAY_REQUIRED);
}, scheduler::pipeline::main);
// Prevent game from overriding cg_fov and cg_fovscale values
gscr_set_save_dvar_hook.create(SELECT_VALUE(0x1402AE020, 0x14036B600), &gscr_set_save_dvar_stub);
// Make cg_fov and cg_fovscale saved dvars
cg_fov = dvars::register_float("cg_fov", 65.f, 40.f, 200.f, game::DvarFlags::DVAR_FLAG_SAVED, true);
cg_fovScale = dvars::register_float("cg_fovScale", 1.f, 0.1f, 2.f, game::DvarFlags::DVAR_FLAG_SAVED, true);
dvar_register_float_hook.create(game::Dvar_RegisterFloat.get(), dvar_register_float_stub);
}
};
}
REGISTER_COMPONENT(patches::component)

View File

@ -0,0 +1,53 @@
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "game/game.hpp"
#include <utils/hook.hpp>
#include <utils/string.hpp>
namespace slowmotion
{
namespace
{
void scr_cmd_set_slow_motion()
{
if (game::Scr_GetNumParam() < 1)
{
return;
}
int duration = 1000;
float end = 1.0f;
const float start = game::Scr_GetFloat(0);
if (game::Scr_GetNumParam() >= 2)
{
end = game::Scr_GetFloat(1u);
}
if (game::Scr_GetNumParam() >= 3)
{
duration = static_cast<int>(game::Scr_GetFloat(2u) * 1000.0f);
}
game::SV_SetConfigstring(10, utils::string::va("%i %i %g %g", *game::mp::gameTime, duration, start, end));
game::Com_SetSlowMotion(start, end, duration);
}
}
class component final : public component_interface
{
public:
void post_unpack() override
{
if (!game::environment::is_dedi())
{
return;
}
utils::hook::jump(0x140365480, scr_cmd_set_slow_motion); // H1(1.4)
}
};
}
REGISTER_COMPONENT(slowmotion::component)

View File

@ -0,0 +1,100 @@
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "system_check.hpp"
#include "game/game.hpp"
#include <utils/io.hpp>
#include <utils/cryptography.hpp>
namespace system_check
{
namespace
{
std::string read_zone(const std::string& name)
{
std::string data{};
if (utils::io::read_file(name, &data))
{
return data;
}
if (utils::io::read_file("zone/" + name, &data))
{
return data;
}
return {};
}
std::string hash_zone(const std::string& name)
{
const auto data = read_zone(name);
return utils::cryptography::sha256::compute(data, true);
}
bool verify_hashes(const std::unordered_map<std::string, std::string>& zone_hashes)
{
for (const auto& zone_hash : zone_hashes)
{
const auto hash = hash_zone(zone_hash.first);
if (hash != zone_hash.second)
{
return false;
}
}
return true;
}
bool is_system_valid()
{
static std::unordered_map<std::string, std::string> mp_zone_hashes =
{
{"patch_common_mp.ff", "3F44B0CFB0B8E0FBD9687C2942204AB7F11E66E6E15C73B8B4A5EB5920115A31"},
};
static std::unordered_map<std::string, std::string> sp_zone_hashes =
{
// Steam doesn't necessarily deliver this file :(
{"patch_common.ff", "BB0617DD94AF2F511571E7184BBEDE76E64D97E5D0DAFDB457F00717F035EBF0"},
};
return verify_hashes(mp_zone_hashes) && (game::environment::is_dedi() || verify_hashes(sp_zone_hashes));
}
void verify_binary_version()
{
const auto value = *reinterpret_cast<DWORD*>(0x140001337);
if (value != 0xFFB8006D && value != 0xFFB80080)
{
throw std::runtime_error("Unsupported Call of Duty: Modern Warfare Remastered version(1.4)");
}
}
}
bool is_valid()
{
static auto valid = is_system_valid();
return valid;
}
class component final : public component_interface
{
public:
void post_load() override
{
verify_binary_version();
if (!is_valid())
{
MessageBoxA(nullptr, "Your game files are outdated or unsupported.\n"
"Please get the latest officially supported Call of Duty: Modern Warfare Remastered 1.4 files, or you will get random crashes and issues.",
"Invalid game files!", MB_ICONINFORMATION);
}
}
};
}
REGISTER_COMPONENT(system_check::component)

View File

@ -0,0 +1,6 @@
#pragma once
namespace system_check
{
bool is_valid();
}

View File

@ -0,0 +1,60 @@
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "scheduler.hpp"
#include "game/game.hpp"
#include <utils/thread.hpp>
namespace thread_names
{
namespace
{
void set_thread_names()
{
static std::unordered_map<int, std::string> thread_names =
{
{game::THREAD_CONTEXT_MAIN, "Main"},
{game::THREAD_CONTEXT_BACKEND, "Backend"}, // Renderer
{game::THREAD_CONTEXT_WORKER0, "Worker0"},
{game::THREAD_CONTEXT_WORKER1, "Worker1"},
{game::THREAD_CONTEXT_WORKER2, "Worker2"},
{game::THREAD_CONTEXT_WORKER3, "Worker3"},
{game::THREAD_CONTEXT_WORKER4, "Worker4"},
{game::THREAD_CONTEXT_WORKER5, "Worker5"},
{game::THREAD_CONTEXT_WORKER6, "Worker6"},
{game::THREAD_CONTEXT_WORKER7, "Worker7"},
{game::THREAD_CONTEXT_SERVER, "Server"},
{game::THREAD_CONTEXT_CINEMATIC, "Cinematic"},
{game::THREAD_CONTEXT_DATABASE, "Database"},
{game::THREAD_CONTEXT_STREAM, "Stream"},
{game::THREAD_CONTEXT_SNDSTREAMPACKETCALLBACK, "Snd stream packet callback"},
{game::THREAD_CONTEXT_STATS_WRITE, "Stats write"},
};
for (const auto& thread_name : thread_names)
{
const auto id = game::threadIds[thread_name.first];
if (id)
{
utils::thread::set_name(id, thread_name.second);
}
}
}
}
class component final : public component_interface
{
public:
void post_unpack() override
{
set_thread_names();
scheduler::once(set_thread_names, scheduler::pipeline::main);
scheduler::once(set_thread_names, scheduler::pipeline::renderer);
scheduler::once(set_thread_names, scheduler::pipeline::server);
}
};
}
REGISTER_COMPONENT(thread_names::component)

View File

@ -0,0 +1,55 @@
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "game/game.hpp"
#include <utils/hook.hpp>
namespace videos
{
namespace
{
utils::hook::detour playvid_hook;
std::unordered_map<std::string, std::string> video_replaces;
void playvid(const char* name, const int a2, const int a3)
{
const auto vid = video_replaces.find(name);
if (vid != video_replaces.end())
{
char path[256];
game::Sys_BuildAbsPath(path, sizeof(path), game::SF_VIDEO, vid->second.data(), ".bik");
if (game::Sys_FileExists(path))
{
name = vid->second.data();
}
}
return playvid_hook.invoke<void>(name, a2, a3);
}
}
class component final : public component_interface
{
public:
void post_unpack() override
{
playvid_hook.create(SELECT_VALUE(0x1404A9D00, 0x1405B0AF0), &playvid); // H1(1.4)
if (game::environment::is_mp())
{
video_replaces["menus_bg_comp2"] = "menus_bg_h1mod";
video_replaces["mp_menus_bg_options"] = "menus_bg_h1mod_blur";
}
else if (game::environment::is_sp())
{
video_replaces["sp_menus_bg_main_menu"] = "menus_bg_h1mod_sp";
video_replaces["sp_menus_bg_campaign"] = "menus_bg_h1mod_sp";
video_replaces["sp_menus_bg_options"] = "menus_bg_h1mod_sp";
}
}
};
}
REGISTER_COMPONENT(videos::component)

View File

@ -21,6 +21,8 @@ namespace dvars
game::dvar_t* r_fullbright;
game::dvar_t* r_chams;
game::dvar_t* cg_legacyCrashHandling;
std::string dvar_get_vector_domain(const int components, const game::dvar_limits& domain)
{
if (domain.vector.min == -FLT_MAX)
@ -196,6 +198,7 @@ namespace dvars
"cg_fovExtraCam",
"cg_fovMin",
"cg_fovScale",
"cg_legacyCrashHandling",
"cl_maxpackets",
"cl_maxPing",
"com_introPlayed",

View File

@ -21,6 +21,8 @@ namespace dvars
extern game::dvar_t* r_fullbright;
extern game::dvar_t* r_chams;
extern game::dvar_t* cg_legacyCrashHandling;
extern std::vector<std::string> dvar_list;
std::string dvar_get_vector_domain(const int components, const game::dvar_limits& domain);

View File

@ -17,10 +17,14 @@ namespace game
WEAK symbol<CodPlayMode()> Com_GetCurrentCoDPlayMode{ 0, 0x1405039A0 }; // H1(1.4)
WEAK symbol<void(float, float, int)> Com_SetSlowMotion{ 0, 0x1400DB790 }; // H1(1.4)
WEAK symbol<void(unsigned int weapon, bool isAlternate, char* output, unsigned int maxStringLen)> BG_GetWeaponNameComplete{ 0, 0x140165580 };
WEAK symbol<void()> Com_Quit_f{ 0x140352BE0, 0x1400DA830 }; // H1(1.4)
WEAK symbol<const char* (int, int, int)> Key_KeynumToString{ 0x140187CC0, 0x14024FE10 }; // H1(1.4)
WEAK symbol<void(const char* text_in)> Cmd_TokenizeString{ 0x140344110, 0x1404046F0 }; // H1(1.4)
WEAK symbol<void(const char* dvar, const char* buffer)> Dvar_SetCommand{ 0x1403C72B0, 0x1404FD0A0 }; // H1(1.4)
@ -46,7 +50,9 @@ namespace game
WEAK symbol<dvar_t* (int dvarName, const char* a2, float x, float y, float z, float w, float min, float max, unsigned int flags)> Dvar_RegisterVec4{ 0x1403C5220, 0x1404FAF40 }; // H1(1.4)
WEAK symbol<dvar_t* (const char* dvarName, const char** valueList, int defaultIndex, unsigned int flags)> Dvar_RegisterEnum{ 0x1403C4AC0, 0x1404C0EC0 }; // H1(1.4)
WEAK symbol<float(int index)> Scr_GetFloat{ 0x140374D20, 0x140442D10 }; // H1(1.4)
WEAK symbol<int()> Scr_GetNumParam{ 0x140374F30, 0x140442E70 }; // H1(1.4)
WEAK symbol<long long(const char* qpath, char** buffer)> FS_ReadFile{ 0x1403B9020, 0x1404EE720 }; // H1(1.4)
@ -171,6 +177,8 @@ namespace game
WEAK symbol<const char* (scr_string_t stringValue)> SL_ConvertToString{ 0x14036D420, 0x1405BFBB0 };
WEAK symbol<scr_string_t(const char* str, unsigned int user)> SL_GetString{ 0x14036D9A0, 0x1405C0170 };
WEAK symbol<void(int index, const char* string)> SV_SetConfigstring{ 0, 0x140486720 }; // H1(1.4)
WEAK symbol<bool()> SV_Loaded{ 0x140442F60, 0x1404864A0 }; // H1(1.4)
WEAK symbol<bool(const char* map)> SV_MapExists{ 0, 0x14047ED60 }; // H1(1.4)
@ -192,9 +200,16 @@ namespace game
WEAK symbol<void(int arg, char* buffer, int bufferLength)> SV_Cmd_ArgvBuffer{ 0x1402EEFD0, 0x1403B05C0 };
// Variables
WEAK symbol<CmdArgs> sv_cmd_args{ 0, 0x14946BA20 }; // mwr maybe
WEAK symbol<void(char* path, int pathSize, Sys_Folder folder, const char* filename, const char* ext)>
Sys_BuildAbsPath{ 0x1403CFF90, 0x140507010 }; // H1(1.4)
WEAK symbol<bool(const char* path)> Sys_FileExists{ 0x1403E0CE0, 0x1405115E0 }; // H1(1.4)
// Variables
WEAK symbol<CmdArgs> sv_cmd_args{ 0, 0x14946BA20 }; // H1(1.4)
WEAK symbol<const char*> command_whitelist{ 0x141079A60, 0x14120C6D0 }; // H1(1.4)
WEAK symbol<const char*> g_assetNames{ 0, 0x140BEF280 };
WEAK symbol<int> g_poolSize{ 0, 0x140FEADF0 }; // H1(1.4)
@ -214,14 +229,17 @@ namespace game
WEAK symbol<function_stack_t> scr_function_stack{ 0,0x14BAA93C0 };
WEAK symbol<void*> DB_XAssetPool{ 0x140DE8C80, 0x140FEB5D0 }; // H1(1.4)
WEAK symbol<DWORD> threadIds{0x14B19B880, 0x149810E00 }; // H1(1.4)
namespace mp
{
WEAK symbol<gentity_s> g_entities{ 0, 0x14621E530 }; // H1(1.4)
WEAK symbol<client_t> svs_clients{ 0, 0x14B204A10 }; // H1(1.4)
WEAK symbol<int> gameTime{ 0, 0x14621BDBC }; // H1(1.4)
}
namespace sp
{
WEAK symbol<gentity_s> g_entities{ 0x14550DD90 , 0 };
WEAK symbol<gentity_s> g_entities{ 0x14550DD90 , 0 }; // H1(1.4)
}
}

View File

@ -110,16 +110,6 @@ void remove_crash_file()
utils::io::remove_file("__h1Exe");
}
void verify_mwr_version()
{
const auto value = *reinterpret_cast<DWORD*>(0x140001337);
//sp && mp
if (value != 0xFFB8006D && value != 0xFFB80080)
{
throw std::runtime_error("Unsupported Call of Duty: Modern Warfare Remastered version"s);
}
}
void enable_dpi_awareness()
{
const utils::nt::library user32{"user32.dll"};
@ -203,8 +193,6 @@ int main()
if (!component_loader::post_load()) return 0;
verify_mwr_version();
premature_shutdown = false;
}
catch (std::exception& e)