Merge branch 'develop' into skip_specops_entities

This commit is contained in:
Louve 2021-07-28 18:32:45 +02:00 committed by GitHub
commit 9de63a3772
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 271 additions and 155 deletions

View File

@ -40,6 +40,7 @@
| `--disable-bitmessage` | Disable use of BitMessage completely. |
| `--disable-base128` | Disable base128 encoding for minidumps. |
| `--no-new-structure` | Do not use new virtual path structure (separating headers and source files). |
| `--iw4x-zones` | Zonebuilder generates iw4x zones that cannot be loaded without IW4x specific patches. |
## Command line arguments

View File

@ -74,6 +74,11 @@ newoption {
description = "Upload minidumps even for Debug builds."
}
newoption {
trigger = "iw4x-zones",
description = "Zonebuilder generates iw4x zones that cannot be loaded without IW4x specific patches."
}
newaction {
trigger = "version",
description = "Returns the version string for the current commit of the source code.",
@ -324,6 +329,9 @@ workspace "iw4x"
if _OPTIONS["force-exception-handler"] then
defines { "FORCE_EXCEPTION_HANDLER" }
end
if _OPTIONS["iw4x-zones"] then
defines { "GENERATE_IW4X_SPECIFIC_ZONES" }
end
-- Pre-compiled header
pchheader "STDInclude.hpp" -- must be exactly same as used in #include directives

View File

@ -252,7 +252,7 @@ namespace Components
Game::TeleportPlayer(&Game::g_entities[clientNum], pos, orientation);
// Logging that will spam the console and screen if people use cinematics
//Logging that will spam the console and screen if people use cinematics
//Logger::Print("Successfully teleported player!\n");
//Toast::Show("cardicon_abduction", "Success", "You have been teleported!", toastDurationShort);
});

View File

@ -341,9 +341,6 @@ namespace Components
// original code
mov eax, dword ptr[esp + 0xa0];
jmp collide;
collide:
push 0x00478376;
retn;
@ -374,11 +371,6 @@ namespace Components
// dont eject if g_playerEjection is set to 0
je donteject;
// original code
cmp dword ptr[ebx + 19ch], edi;
jle eject;
eject:
push 0x005d8152;
retn;
@ -388,12 +380,12 @@ namespace Components
}
}
template <typename T> std::function < T > ImportFunction(const std::string& dll, const std::string& function)
template <typename T> std::function <T> ImportFunction(const std::string& dll, const std::string& function)
{
auto dllHandle = GetModuleHandleA(&dll[0]);
auto procAddr = GetProcAddress(dllHandle, &function[0]);
return std::function < T >(reinterpret_cast<T*>(procAddr));
return std::function <T>(reinterpret_cast<T*>(procAddr));
}
bool QuickPatch::IsDynClassnameStub(char* a1)
@ -418,7 +410,7 @@ namespace Components
// Passthrough to the game's own IsDynClassname
return Utils::Hook::Call<bool(char*)>(0x444810)(a1);
}
QuickPatch::QuickPatch()
{
QuickPatch::FrameTime = 0;
@ -430,36 +422,10 @@ namespace Components
// quit_hard
Command::Add("quit_hard", [](Command::Params*)
{
typedef enum _HARDERROR_RESPONSE_OPTION {
OptionAbortRetryIgnore,
OptionOk,
OptionOkCancel,
OptionRetryCancel,
OptionYesNo,
OptionYesNoCancel,
OptionShutdownSystem
} HARDERROR_RESPONSE_OPTION, *PHARDERROR_RESPONSE_OPTION;
typedef enum _HARDERROR_RESPONSE {
ResponseReturnToCaller,
ResponseNotHandled,
ResponseAbort,
ResponseCancel,
ResponseIgnore,
ResponseNo,
ResponseOk,
ResponseRetry,
ResponseYes
} HARDERROR_RESPONSE, *PHARDERROR_RESPONSE;
BOOLEAN hasPerms;
HARDERROR_RESPONSE response;
auto result = ImportFunction<NTSTATUS __stdcall(ULONG, BOOLEAN, BOOLEAN, PBOOLEAN)>("ntdll.dll", "RtlAdjustPrivilege")
(19, true, false, &hasPerms);
result = ImportFunction<NTSTATUS __stdcall(NTSTATUS, ULONG, LPCSTR, PVOID, HARDERROR_RESPONSE_OPTION, PHARDERROR_RESPONSE)>("ntdll.dll", "NtRaiseHardError")
(0xC000007B /*0x0000000A*/, 0, nullptr, nullptr, OptionShutdownSystem, &response);
int data = false;
const Utils::Library ntdll("ntdll.dll");
ntdll.InvokePascal<void>("RtlAdjustPrivilege", 19, true, false, &data);
ntdll.InvokePascal<void>("NtRaiseHardError", 0xC000007B, 0, nullptr, nullptr, 6, &data);
});
// Filtering any mapents that is intended for Spec:Ops gamemode (CODO) and prevent them from spawning

View File

@ -25,9 +25,14 @@ namespace Components
}
else
{
if (!RCon::Password.empty() && *reinterpret_cast<int*>(0xB2C540) >= 5) // Get our state
auto addr = reinterpret_cast<Game::netadr_t*>(0xA5EA44);
if (!RCon::Password.empty())
{
Network::Address target(reinterpret_cast<Game::netadr_t*>(0xA5EA44));
Network::Address target(addr);
if (!target.isValid() || target.getIP().full == 0)
{
target = Party::Target();
}
if (target.isValid())
{
@ -71,6 +76,7 @@ namespace Components
Dvar::OnInit([]()
{
Dvar::Register<const char*>("rcon_password", "", Game::dvar_flag::DVAR_FLAG_NONE, "The password for rcon");
Dvar::Register<bool>("log_rcon_requests", false, Game::dvar_flag::DVAR_FLAG_NONE, "Print remote commands in the output log");
});
Network::Handle("rcon", [](Network::Address address, const std::string& _data)
@ -107,9 +113,12 @@ namespace Components
static std::string outputBuffer;
outputBuffer.clear();
#ifdef DEBUG
Logger::Print("Executing RCon request from %s: %s\n", address.getCString(), command.data());
#ifndef DEBUG
if (Dvar::Var("log_rcon_requests").get<bool>())
#endif
{
Logger::Print("Executing RCon request from %s: %s\n", address.getCString(), command.data());
}
Logger::PipeOutput([](const std::string& output)
{

View File

@ -378,7 +378,7 @@ namespace Components
Game::XFileHeader header =
{
#ifdef DEBUG
#ifndef GENERATE_IW4X_SPECIFIC_ZONES
XFILE_MAGIC_UNSIGNED,
#else
XFILE_HEADER_IW4X | (static_cast<unsigned __int64>(XFILE_VERSION_IW4X) << 32),
@ -394,7 +394,7 @@ namespace Components
std::string zoneBuffer = this->buffer.toBuffer();
#ifndef DEBUG
#ifdef GENERATE_IW4X_SPECIFIC_ZONES
// Insert a random byte, this will destroy the whole alignment and result in a crash, if not handled
zoneBuffer.insert(zoneBuffer.begin(), static_cast<char>(Utils::Cryptography::Rand::GenerateInt()));
@ -844,7 +844,7 @@ namespace Components
Command::Add("quit", [](Command::Params*)
{
ZoneBuilder::Quit();
Game::Com_Quitf_t();
});
Command::Add("error", [](Command::Params*)
@ -921,12 +921,6 @@ namespace Components
return 0;
}
void ZoneBuilder::Quit()
{
//TerminateProcess(GetCurrentProcess(), 0);
ExitProcess(0);
}
void ZoneBuilder::HandleError(int level, const char* format, ...)
{
char buffer[256] = { 0 };
@ -1088,9 +1082,6 @@ namespace Components
// set new entry point
Utils::Hook(0x4513DA, ZoneBuilder::EntryPoint, HOOK_JUMP).install()->quick();
// set quit handler
Utils::Hook(0x4D4000, ZoneBuilder::Quit, HOOK_JUMP).install()->quick();
// handle com_error calls
Utils::Hook(0x4B22D0, ZoneBuilder::HandleError, HOOK_JUMP).install()->quick();

View File

@ -138,7 +138,6 @@ namespace Components
static std::string FindMaterialByTechnique(const std::string& name);
static int __stdcall EntryPoint(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*nShowCmd*/);
static void Quit();
static void HandleError(int level, const char* format, ...);
static void SoftErrorAssetOverflow();

View File

@ -8,6 +8,58 @@ namespace Components
int Zones::FxEffectIndex;
char* Zones::FxEffectStrings[64];
static std::unordered_map<std::string, std::string> shellshock_replace_list = {
{ "66","bg_shock_screenType" },
{ "67","bg_shock_screenBlurBlendTime"},
{ "68","bg_shock_screenBlurBlendFadeTime"},
{ "69","bg_shock_screenFlashWhiteFadeTime"},
{ "70","bg_shock_screenFlashShotFadeTime"},
{ "71","bg_shock_viewKickPeriod"},
{ "72","bg_shock_viewKickRadius"},
{ "73","bg_shock_viewKickFadeTime"},
{ "78","bg_shock_sound"},
{ "74","bg_shock_soundLoop"},
{ "75","bg_shock_soundLoopSilent"},
{ "76","bg_shock_soundEnd"},
{ "77","bg_shock_soundEndAbort"},
{ "79","bg_shock_soundFadeInTime"},
{ "80","bg_shock_soundFadeOutTime"},
{ "81","bg_shock_soundLoopFadeTime"},
{ "82","bg_shock_soundLoopEndDelay"},
{ "83","bg_shock_soundRoomType"},
{ "84","bg_shock_soundDryLevel"},
{ "85","bg_shock_soundWetLevel"},
{ "86","bg_shock_soundModEndDelay"},
// guessed, not sure
{ "87","bg_shock_lookControl"},
{ "88","bg_shock_lookControl_maxpitchspeed"},
{ "89","bg_shock_lookControl_maxyawspeed"},
{ "90","bg_shock_lookControl_mousesensitivityscale"},
{ "91","bg_shock_lookControl_fadeTime"},
{ "92","bg_shock_movement"}
};
static std::unordered_map<std::string, std::string> vision_replace_list = {
{ "511","r_glow" },
{ "516","r_glowRadius0" },
{ "512","r_glowBloomCutoff" },
{ "513","r_glowBloomDesaturation" },
{ "514","r_glowBloomIntensity0" },
{ "520","r_filmEnable" },
{ "522","r_filmContrast" },
{ "521","r_filmBrightness" },
{ "523","r_filmDesaturation" },
{ "524","r_filmDesaturationDark" },
{ "525","r_filmInvert" },
{ "526","r_filmLightTint" },
{ "527","r_filmMediumTint" },
{ "528","r_filmDarkTint" },
{ "529","r_primaryLightUseTweaks" },
{ "530","r_primaryLightTweakDiffuseStrength" },
{ "531","r_primaryLightTweakSpecularStrength" },
};
Game::XAssetType currentAssetType = Game::XAssetType::ASSET_TYPE_INVALID;
Game::XAssetType previousAssetType = Game::XAssetType::ASSET_TYPE_INVALID;
@ -223,30 +275,20 @@ namespace Components
int size = 3112;
if (Zones::ZoneVersion >= 318)
{
if (Zones::ZoneVersion >= 461)
size = 4124;
else if (Zones::ZoneVersion >= 460)
size = 4120;
else if (Zones::ZoneVersion >= 365)
size = 3124;
else if (Zones::ZoneVersion >= 359)
size = 3120;
else if (Zones::ZoneVersion >= 332)
size = 3068;
else if (Zones::ZoneVersion >= 318)
size = 3156;
if (Zones::ZoneVersion >= 332)
{
size = 3068; // We didn't adapt that, but who the fuck cares!
if (Zones::ZoneVersion >= 359)
{
size = 3120;
if (Zones::ZoneVersion >= 365)
{
size = 3124;
if (Zones::ZoneVersion >= 460)
{
size = 4120;
}
}
}
}
}
int offsetShift = (Zones::ZoneVersion >= 461) ? 4 : 0;
// and do the stuff
Game::Load_Stream(true, varWeaponCompleteDef, size);
@ -270,7 +312,7 @@ namespace Components
if (Zones::ZoneVersion >= 359)
{
auto count = (Zones::Version() == 460) ? 52 : 56;
auto count = (Zones::Version() >= 460) ? 52 : 56;
for (int offset = 20; offset <= count; offset += 4)
{
*Game::varXModelPtr = reinterpret_cast<Game::XModel**>(varWeaponCompleteDef + offset);
@ -299,7 +341,7 @@ namespace Components
if (Zones::ZoneVersion >= 359)
{
auto stringCount = (Zones::Version() == 460) ? 62 : 52;
auto stringCount = (Zones::Version() >= 460) ? 62 : 52;
auto arraySize = stringCount * 4;
// 236
@ -395,8 +437,8 @@ namespace Components
// 980
if (Zones::ZoneVersion >= 359)
{
auto offset = (Zones::Version() == 460) ? 1476 : 916;
auto count = (Zones::Version() == 460) ? 57 : 52;
auto offset = (Zones::Version() >= 460) ? 1476 : 916;
auto count = (Zones::Version() >= 461) ? 58 : (Zones::Version() >= 460) ? 57 : 52;
// 53 soundalias name references; up to and including 1124
for (int i = 0; i < count; ++i, offset += 4)
@ -809,7 +851,7 @@ namespace Components
void* vec2 = Game::DB_AllocStreamPos(3);
*reinterpret_cast<void**>(varWeaponCompleteDef + 3204) = vec2;
Game::Load_Stream(true, vec2, 8 * *reinterpret_cast<short*>(varWeaponCompleteDef + 3776));
Game::Load_Stream(true, vec2, 8 * *reinterpret_cast<short*>(varWeaponCompleteDef + 3776 + offsetShift));
}
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3200);
@ -820,7 +862,7 @@ namespace Components
void* vec2 = Game::DB_AllocStreamPos(3);
*reinterpret_cast<void**>(varWeaponCompleteDef + 3208) = vec2;
Game::Load_Stream(true, vec2, 8 * *reinterpret_cast<short*>(varWeaponCompleteDef + 3778));
Game::Load_Stream(true, vec2, 8 * *reinterpret_cast<short*>(varWeaponCompleteDef + 3778 + offsetShift));
}
}
else if (Zones::ZoneVersion >= 359)
@ -868,22 +910,22 @@ namespace Components
if (Zones::Version() >= 460)
{
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3288);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3288 + offsetShift);
Game::Load_XString(false);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3292);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3292 + offsetShift);
Game::Load_XString(false);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3324);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3324 + offsetShift);
Game::Load_XString(false);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3328);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3328 + offsetShift);
Game::Load_XString(false);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3484);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3484 + offsetShift);
Game::Load_XString(false);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3488);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3488 + offsetShift);
Game::Load_XString(false);
}
else if (Zones::ZoneVersion >= 359)
@ -929,37 +971,37 @@ namespace Components
if (Zones::Version() >= 460)
{
*Game::varTracerDefPtr = reinterpret_cast<Game::TracerDef * *>(varWeaponCompleteDef + 3492);
*Game::varTracerDefPtr = reinterpret_cast<Game::TracerDef * *>(varWeaponCompleteDef + 3492 + offsetShift);
Game::Load_TracerDefPtr(false);
*Game::varTracerDefPtr = reinterpret_cast<Game::TracerDef * *>(varWeaponCompleteDef + 3496);
*Game::varTracerDefPtr = reinterpret_cast<Game::TracerDef * *>(varWeaponCompleteDef + 3496 + offsetShift);
Game::Load_TracerDefPtr(false);
*Game::varTracerDefPtr = reinterpret_cast<Game::TracerDef * *>(varWeaponCompleteDef + 3500);
*Game::varTracerDefPtr = reinterpret_cast<Game::TracerDef * *>(varWeaponCompleteDef + 3500 + offsetShift);
Game::Load_TracerDefPtr(false);
*Game::varsnd_alias_list_name = reinterpret_cast<Game::snd_alias_list_t * *>(varWeaponCompleteDef + 3528);
*Game::varsnd_alias_list_name = reinterpret_cast<Game::snd_alias_list_t * *>(varWeaponCompleteDef + 3528 + offsetShift);
Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name); // 2848
*Game::varFxEffectDefHandle = reinterpret_cast<Game::FxEffectDef * *>(varWeaponCompleteDef + 3532);
*Game::varFxEffectDefHandle = reinterpret_cast<Game::FxEffectDef * *>(varWeaponCompleteDef + 3532 + offsetShift);
Game::Load_FxEffectDefHandle(false);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3536);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3536 + offsetShift);
Game::Load_XString(false);
*Game::varsnd_alias_list_name = reinterpret_cast<Game::snd_alias_list_t * *>(varWeaponCompleteDef + 3552);
*Game::varsnd_alias_list_name = reinterpret_cast<Game::snd_alias_list_t * *>(varWeaponCompleteDef + 3552 + offsetShift);
Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name);
*Game::varsnd_alias_list_name = reinterpret_cast<Game::snd_alias_list_t * *>(varWeaponCompleteDef + 3556);
*Game::varsnd_alias_list_name = reinterpret_cast<Game::snd_alias_list_t * *>(varWeaponCompleteDef + 3556 + offsetShift);
Game::Load_snd_alias_list_nameArray(false, 4);
*Game::varsnd_alias_list_name = reinterpret_cast<Game::snd_alias_list_t * *>(varWeaponCompleteDef + 3572);
*Game::varsnd_alias_list_name = reinterpret_cast<Game::snd_alias_list_t * *>(varWeaponCompleteDef + 3572 + offsetShift);
Game::Load_snd_alias_list_nameArray(false, 4);
*Game::varsnd_alias_list_name = reinterpret_cast<Game::snd_alias_list_t * *>(varWeaponCompleteDef + 3588);
*Game::varsnd_alias_list_name = reinterpret_cast<Game::snd_alias_list_t * *>(varWeaponCompleteDef + 3588 + offsetShift);
Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name);
*Game::varsnd_alias_list_name = reinterpret_cast<Game::snd_alias_list_t * *>(varWeaponCompleteDef + 3592);
*Game::varsnd_alias_list_name = reinterpret_cast<Game::snd_alias_list_t * *>(varWeaponCompleteDef + 3592 + offsetShift);
Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name);
}
else if (Zones::ZoneVersion >= 359)
@ -1023,7 +1065,7 @@ namespace Components
if (Zones::Version() >= 460)
{
for (int i = 0, offset = 3660; i < 6; ++i, offset += 4)
for (int i = 0, offset = 3660 + offsetShift; i < 6; ++i, offset += 4)
{
*Game::varsnd_alias_list_name = reinterpret_cast<Game::snd_alias_list_t * *>(varWeaponCompleteDef + offset);
Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name);
@ -1058,25 +1100,25 @@ namespace Components
if (Zones::Version() >= 460)
{
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3712);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3712 + offsetShift);
Game::Load_XString(false);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3728);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3728 + offsetShift);
Game::Load_XString(false);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3732);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3732 + offsetShift);
Game::Load_XString(false);
*Game::varMaterialHandle = reinterpret_cast<Game::Material * *>(varWeaponCompleteDef + 3740);
*Game::varMaterialHandle = reinterpret_cast<Game::Material * *>(varWeaponCompleteDef + 3740 + offsetShift);
Game::Load_MaterialHandle(false);
*Game::varMaterialHandle = reinterpret_cast<Game::Material * *>(varWeaponCompleteDef + 3744);
*Game::varMaterialHandle = reinterpret_cast<Game::Material * *>(varWeaponCompleteDef + 3744 + offsetShift);
Game::Load_MaterialHandle(false);
*Game::varMaterialHandle = reinterpret_cast<Game::Material * *>(varWeaponCompleteDef + 3748);
*Game::varMaterialHandle = reinterpret_cast<Game::Material * *>(varWeaponCompleteDef + 3748 + offsetShift);
Game::Load_MaterialHandle(false);
*Game::varMaterialHandle = reinterpret_cast<Game::Material * *>(varWeaponCompleteDef + 3752);
*Game::varMaterialHandle = reinterpret_cast<Game::Material * *>(varWeaponCompleteDef + 3752 + offsetShift);
Game::Load_MaterialHandle(false);
}
else if (Zones::ZoneVersion >= 359)
@ -1127,35 +1169,35 @@ namespace Components
if (Zones::Version() >= 460)
{
if (*reinterpret_cast<DWORD*>(varWeaponCompleteDef + 3780) == -1)
if (*reinterpret_cast<DWORD*>(varWeaponCompleteDef + 3780 + offsetShift) == -1)
{
void* vec2 = Game::DB_AllocStreamPos(3);
*reinterpret_cast<void**>(varWeaponCompleteDef + 3780) = vec2;
*reinterpret_cast<void**>(varWeaponCompleteDef + 3780 + offsetShift) = vec2;
Game::Load_Stream(true, vec2, 8 * *reinterpret_cast<short*>(varWeaponCompleteDef + 3776));
Game::Load_Stream(true, vec2, 8 * *reinterpret_cast<short*>(varWeaponCompleteDef + 3776 + offsetShift));
}
if (*reinterpret_cast<DWORD*>(varWeaponCompleteDef + 3784) == -1)
if (*reinterpret_cast<DWORD*>(varWeaponCompleteDef + 3784 + offsetShift) == -1)
{
void* vec2 = Game::DB_AllocStreamPos(3);
*reinterpret_cast<void**>(varWeaponCompleteDef + 3784) = vec2;
*reinterpret_cast<void**>(varWeaponCompleteDef + 3784 + offsetShift) = vec2;
Game::Load_Stream(true, vec2, 8 * *reinterpret_cast<short*>(varWeaponCompleteDef + 3778));
Game::Load_Stream(true, vec2, 8 * *reinterpret_cast<short*>(varWeaponCompleteDef + 3778 + offsetShift));
}
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3876);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3876 + offsetShift);
Game::Load_XString(false);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3880);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3880 + offsetShift);
Game::Load_XString(false);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3884);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3884 + offsetShift);
Game::Load_XString(false);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3996);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 3996 + offsetShift);
Game::Load_XString(false);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 4012);
*Game::varXString = reinterpret_cast<char**>(varWeaponCompleteDef + 4012 + offsetShift);
Game::Load_XString(false);
}
else if (Zones::ZoneVersion >= 359)
@ -3445,7 +3487,30 @@ namespace Components
Game::DB_PopStreamPos();
}
char* Zones::ParseVision_Stub(const char** data_p)
{
auto token = Game::Com_Parse(data_p);
if (vision_replace_list.find(token) != vision_replace_list.end())
{
return vision_replace_list[token].data();
}
return token;
}
char* Zones::ParseShellShock_Stub(const char** data_p)
{
auto token = Game::Com_Parse(data_p);
if (shellshock_replace_list.find(token) != shellshock_replace_list.end())
{
return shellshock_replace_list[token].data();
}
return token;
}
Zones::Zones()
{
Zones::ZoneVersion = 0;
@ -3591,6 +3656,9 @@ namespace Components
Utils::Hook(0x4B8FF5, Zones::Loadsunflare_t, HOOK_CALL).install()->quick();
Utils::Hook(0x418998, Zones::GameMapSpPatchStub, HOOK_JUMP).install()->quick();
Utils::Hook(0x427A1B, Zones::LoadPathDataTail, HOOK_JUMP).install()->quick();
Utils::Hook(0x4B4EA1, Zones::ParseShellShock_Stub, HOOK_CALL).install()->quick();
Utils::Hook(0x4B4F0C, Zones::ParseShellShock_Stub, HOOK_CALL).install()->quick();
Utils::Hook(0x4F4D3B, [] ()
{
@ -3614,6 +3682,10 @@ namespace Components
Utils::Hook(0x4597DD, Zones::LoadStatement, HOOK_CALL).install()->quick();
Utils::Hook(0x471A39, Zones::LoadWindowImage, HOOK_JUMP).install()->quick();
// Fix newer vision file
Utils::Hook(0x59A849, ParseVision_Stub, HOOK_CALL).install()->quick();
Utils::Hook(0x59A8AD, ParseVision_Stub, HOOK_CALL).install()->quick();
#ifdef DEBUG
// Easy dirty disk debugging
Utils::Hook::Set<WORD>(0x4CF7F0, 0xC3CC);

View File

@ -3,6 +3,7 @@
#define VERSION_ALPHA2 316
#define VERSION_ALPHA3 318//319
#define VERSION_ALPHA3_DEC 319
#define VERSION_LATEST_CODO 461
namespace Components
{
@ -101,5 +102,7 @@ namespace Components
static void LoadTracerDef(bool atStreamStart, Game::TracerDef* tracer, int size);
static void LoadTracerDefFxEffect();
static void FixImageCategory(Game::GfxImage* image);
static char* ParseShellShock_Stub(const char** data_p);
static char* ParseVision_Stub(const char** data_p);
};
}

View File

@ -65,6 +65,7 @@ namespace Game
Com_Parse_t Com_Parse = Com_Parse_t(0x474D60);
Com_MatchToken_t Com_MatchToken = Com_MatchToken_t(0x447130);
Com_SetSlowMotion_t Com_SetSlowMotion = Com_SetSlowMotion_t(0x446E20);
Com_Quitf_t Com_Quit_f = Com_Quitf_t(0x4D4000);
Con_DrawMiniConsole_t Con_DrawMiniConsole = Con_DrawMiniConsole_t(0x464F30);
Con_DrawSolidConsole_t Con_DrawSolidConsole = Con_DrawSolidConsole_t(0x5A5040);

View File

@ -130,6 +130,9 @@ namespace Game
typedef void(__cdecl * Com_SetSlowMotion_t)(float start, float end, int duration);
extern Com_SetSlowMotion_t Com_SetSlowMotion;
typedef void(__cdecl * Com_Quitf_t)();
extern Com_Quitf_t Com_Quit_f;
typedef char* (__cdecl * Con_DrawMiniConsole_t)(int localClientNum, int xPos, int yPos, float alpha);
extern Con_DrawMiniConsole_t Con_DrawMiniConsole;

View File

@ -149,6 +149,7 @@ template <size_t S> class Sizer { };
#pragma comment(lib, "Advapi32.lib")
#pragma comment(lib, "rpcrt4.lib")
#pragma comment(lib, "dbghelp.lib")
#pragma comment(lib, "ntdll.lib")
// Enable additional literals
using namespace std::literals;

View File

@ -384,25 +384,25 @@ namespace Steam
Proxy::LaunchWatchGuard();
Proxy::Overlay = ::Utils::Library(GAMEOVERLAY_LIB, false);
if (!Proxy::Overlay.valid()) return false;
if (!Proxy::Overlay.IsValid()) return false;
}
Proxy::Client = ::Utils::Library(STEAMCLIENT_LIB, false);
if (!Proxy::Client.valid()) return false;
if (!Proxy::Client.IsValid()) return false;
Proxy::SteamClient = Proxy::Client.get<ISteamClient008*(const char*, int*)>("CreateInterface")("SteamClient008", nullptr);
Proxy::SteamClient = Proxy::Client.Get<ISteamClient008*(const char*, int*)>("CreateInterface")("SteamClient008", nullptr);
if(!Proxy::SteamClient) return false;
Proxy::SteamBGetCallback = Proxy::Client.get<Proxy::SteamBGetCallbackFn>("Steam_BGetCallback");
Proxy::SteamBGetCallback = Proxy::Client.Get<Proxy::SteamBGetCallbackFn>("Steam_BGetCallback");
if (!Proxy::SteamBGetCallback) return false;
Proxy::SteamFreeLastCallback = Proxy::Client.get<Proxy::SteamFreeLastCallbackFn>("Steam_FreeLastCallback");
Proxy::SteamFreeLastCallback = Proxy::Client.Get<Proxy::SteamFreeLastCallbackFn>("Steam_FreeLastCallback");
if (!Proxy::SteamFreeLastCallback) return false;
Proxy::SteamGetAPICallResult = Proxy::Client.get<Proxy::SteamGetAPICallResultFn>("Steam_GetAPICallResult");
Proxy::SteamGetAPICallResult = Proxy::Client.Get<Proxy::SteamGetAPICallResultFn>("Steam_GetAPICallResult");
if (!Proxy::SteamGetAPICallResult) return false;
Proxy::SteamClient = Proxy::Client.get<ISteamClient008*(const char*, int*)>("CreateInterface")("SteamClient008", nullptr);
Proxy::SteamClient = Proxy::Client.Get<ISteamClient008*(const char*, int*)>("CreateInterface")("SteamClient008", nullptr);
if (!Proxy::SteamClient) return false;
Proxy::SteamPipe = Proxy::SteamClient->CreateSteamPipe();
@ -411,7 +411,7 @@ namespace Steam
Proxy::SteamUser = Proxy::SteamClient->ConnectToGlobalUser(Proxy::SteamPipe);
if (!Proxy::SteamUser) return false;
Proxy::ClientEngine = Proxy::Client.get<IClientEngine*(const char*, int*)>("CreateInterface")("CLIENTENGINE_INTERFACE_VERSION005", nullptr);
Proxy::ClientEngine = Proxy::Client.Get<IClientEngine*(const char*, int*)>("CreateInterface")("CLIENTENGINE_INTERFACE_VERSION005", nullptr);
if (!Proxy::ClientEngine) return false;
Proxy::ClientUser = Proxy::ClientEngine->GetIClientUser(Proxy::SteamUser, Proxy::SteamPipe);
@ -526,17 +526,17 @@ namespace Steam
void Proxy::SetOverlayNotificationPosition(uint32_t eNotificationPosition)
{
if (Proxy::Overlay.valid())
if (Proxy::Overlay.IsValid())
{
Proxy::Overlay.get<void(uint32_t)>("SetNotificationPosition")(eNotificationPosition);
Proxy::Overlay.Get<void(uint32_t)>("SetNotificationPosition")(eNotificationPosition);
}
}
bool Proxy::IsOverlayEnabled()
{
if (Proxy::Overlay.valid())
if (Proxy::Overlay.IsValid())
{
return Proxy::Overlay.get<bool()>("IsOverlayEnabled")();
return Proxy::Overlay.Get<bool()>("IsOverlayEnabled")();
}
return false;
@ -544,9 +544,9 @@ namespace Steam
bool Proxy::BOverlayNeedsPresent()
{
if (Proxy::Overlay.valid())
if (Proxy::Overlay.IsValid())
{
return Proxy::Overlay.get<bool()>("BOverlayNeedsPresent")();
return Proxy::Overlay.Get<bool()>("BOverlayNeedsPresent")();
}
return false;

View File

@ -2,34 +2,63 @@
namespace Utils
{
Library Library::Load(const std::string& name)
{
return Library(LoadLibraryA(name.data()));
}
Library Library::Load(const std::filesystem::path& path)
{
return Library::Load(path.generic_string());
}
Library Library::GetByAddress(void* address)
{
HMODULE handle = nullptr;
GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, static_cast<LPCSTR>(address), &handle);
return Library(handle);
}
Library::Library(const std::string& buffer, bool _freeOnDestroy) : _module(nullptr), freeOnDestroy(_freeOnDestroy)
{
this->_module = LoadLibraryExA(buffer.data(), nullptr, 0);
}
Library::Library(const std::string& buffer)
{
this->_module = GetModuleHandleA(buffer.data());
this->freeOnDestroy = true;
}
Library::Library(const HMODULE handle)
{
this->_module = handle;
this->freeOnDestroy = true;
}
Library::~Library()
{
if (this->freeOnDestroy)
{
this->free();
this->Free();
}
}
bool Library::valid()
bool Library::IsValid() const
{
return (this->getModule() != nullptr);
return this->_module != nullptr;
}
HMODULE Library::getModule()
HMODULE Library::GetModule()
{
return this->_module;
}
void Library::free()
void Library::Free()
{
if (this->valid())
if (this->IsValid())
{
FreeLibrary(this->getModule());
FreeLibrary(this->_module);
}
this->_module = nullptr;

View File

@ -5,25 +5,58 @@ namespace Utils
class Library
{
public:
static Library Load(const std::string& name);
static Library Load(const std::filesystem::path& path);
static Library GetByAddress(void* address);
Library() : _module(nullptr), freeOnDestroy(false) {};
Library(const std::string& buffer, bool freeOnDestroy = true);
Library(const std::string& buffer, bool freeOnDestroy);
explicit Library(const std::string& name);
explicit Library(HMODULE handle);
~Library();
bool valid();
HMODULE getModule();
bool IsValid() const;
HMODULE GetModule();
template <typename T>
std::function<T> get(const std::string& process)
T GetProc(const std::string& process) const
{
if (!this->valid())
{
throw std::runtime_error("Library not loaded!");
}
return reinterpret_cast<T*>(GetProcAddress(this->getModule(), process.data()));
if (!this->IsValid()) T{};
return reinterpret_cast<T>(GetProcAddress(this->_module, process.data()));
}
void free();
template <typename T>
std::function<T> Get(const std::string& process) const
{
if (!this->IsValid()) return std::function<T>();
return static_cast<T*>(this->GetProc<void*>(process));
}
template <typename T, typename... Args>
T Invoke(const std::string& process, Args ... args) const
{
auto method = this->Get<T(__cdecl)(Args ...)>(process);
if (method) return method(args...);
return T();
}
template <typename T, typename... Args>
T InvokePascal(const std::string& process, Args ... args) const
{
auto method = this->Get<T(__stdcall)(Args ...)>(process);
if (method) return method(args...);
return T();
}
template <typename T, typename... Args>
T InvokeThis(const std::string& process, void* this_ptr, Args ... args) const
{
auto method = this->Get<T(__thiscall)(void*, Args ...)>(this_ptr, process);
if (method) return method(args...);
return T();
}
void Free();
private:
HMODULE _module;