[VisionFile] Move zone patch here
This commit is contained in:
parent
b52142bbb1
commit
034abfe235
@ -175,20 +175,20 @@ namespace Components
|
||||
}
|
||||
}
|
||||
|
||||
BOOL QuickPatch::IsDynClassnameStub(char* a1)
|
||||
BOOL QuickPatch::IsDynClassnameStub(const char* classname)
|
||||
{
|
||||
auto version = Zones::GetEntitiesZoneVersion();
|
||||
const auto version = Zones::Version();
|
||||
|
||||
if (version >= VERSION_LATEST_CODO)
|
||||
{
|
||||
for (auto i = 0; i < Game::spawnVars->numSpawnVars; i++)
|
||||
{
|
||||
char** kvPair = Game::spawnVars->spawnVars[i];
|
||||
auto key = kvPair[0];
|
||||
auto val = kvPair[1];
|
||||
const auto* key = kvPair[0];
|
||||
const auto* val = kvPair[1];
|
||||
|
||||
bool isSpecOps = strncmp(key, "script_specialops", 17) == 0;
|
||||
bool isSpecOpsOnly = val[0] == '1' && val[1] == '\0';
|
||||
auto isSpecOps = std::strncmp(key, "script_specialops", 17) == 0;
|
||||
auto isSpecOpsOnly = (val[0] == '1') && (val[1] == '\0');
|
||||
|
||||
if (isSpecOps && isSpecOpsOnly)
|
||||
{
|
||||
@ -199,8 +199,7 @@ namespace Components
|
||||
}
|
||||
}
|
||||
|
||||
// Passthrough to the game's own IsDynClassname
|
||||
return Utils::Hook::Call<BOOL(char*)>(0x444810)(a1);
|
||||
return Utils::Hook::Call<BOOL(const char*)>(0x444810)(classname); // IsDynClassname
|
||||
}
|
||||
|
||||
void QuickPatch::CL_KeyEvent_OnEscape()
|
||||
|
@ -23,7 +23,7 @@ namespace Components
|
||||
static void ClientEventsFireWeaponStub();
|
||||
static void ClientEventsFireWeaponMeleeStub();
|
||||
|
||||
static BOOL IsDynClassnameStub(char* a1);
|
||||
static BOOL IsDynClassnameStub(const char* classname);
|
||||
|
||||
static void CL_KeyEvent_OnEscape();
|
||||
static void CL_KeyEvent_ConsoleEscape_Stub();
|
||||
|
@ -2,76 +2,104 @@
|
||||
|
||||
namespace Components
|
||||
{
|
||||
const char* VisionFile::DvarExceptions[] =
|
||||
std::vector<std::string> VisionFile::DvarExceptions =
|
||||
{
|
||||
"r_pretess",
|
||||
};
|
||||
|
||||
void VisionFile::ApplyExemptDvar(const std::string& dvarName, const char* buffer, const std::string& fileName)
|
||||
std::unordered_map<std::string, std::string> VisionFile::VisionReplacements
|
||||
{
|
||||
for (std::size_t i = 0; i < ARRAYSIZE(DvarExceptions); ++i)
|
||||
{
|
||||
if (dvarName == DvarExceptions[i])
|
||||
{
|
||||
const auto* dvar = Game::Dvar_FindVar(dvarName.data());
|
||||
const auto* parsedValue = Game::Com_ParseOnLine(&buffer);
|
||||
{"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"},
|
||||
};
|
||||
|
||||
assert(dvar != nullptr);
|
||||
bool VisionFile::ApplyExemptDvar(const char* dvarName, const char** buffer, const char* filename)
|
||||
{
|
||||
for (auto& exceptions : DvarExceptions)
|
||||
{
|
||||
if (!_stricmp(dvarName, exceptions.data()))
|
||||
{
|
||||
const auto* dvar = Game::Dvar_FindVar(dvarName);
|
||||
const auto* parsedValue = Game::Com_ParseOnLine(buffer);
|
||||
|
||||
assert(dvar);
|
||||
assert(parsedValue);
|
||||
|
||||
Game::Dvar_SetFromStringFromSource(dvar, parsedValue, Game::DvarSetSource::DVAR_SOURCE_INTERNAL);
|
||||
Logger::Print("Overriding '{}' from '{}'\n", dvarName, fileName);
|
||||
Logger::Print("Overriding '{}' from '{}'\n", dvar->name, filename);
|
||||
|
||||
// Successfully found and tried to apply the string value to the dvar
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Game::Com_PrintWarning(Game::conChannel_t::CON_CHANNEL_SYSTEM,
|
||||
"WARNING: unknown dvar \'%s\' in file \'%s\'\n", dvarName.data(), fileName.data());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Gets the dvar name and value and attemps to apply it to the vision settings
|
||||
void VisionFile::ApplyValueToSettings(const std::string& key, const char* buffer,
|
||||
const std::string& fileName, Game::visionSetVars_t* settings)
|
||||
bool VisionFile::LoadVisionSettingsFromBuffer(const char* buffer, const char* filename, Game::visionSetVars_t* settings)
|
||||
{
|
||||
for (std::size_t i = 0; i < 21; ++i)
|
||||
assert(settings);
|
||||
|
||||
bool wasRead[21]{};
|
||||
Game::Com_BeginParseSession(filename);
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Must be case insensitive comparison
|
||||
if (key == Utils::String::ToLower(Game::visionDefFields[i].name))
|
||||
auto* token = Game::Com_Parse(&buffer);
|
||||
|
||||
if (!*token)
|
||||
{
|
||||
auto* const dvarValue = Game::Com_ParseOnLine(&buffer);
|
||||
|
||||
if (!Game::ApplyTokenToField(i, dvarValue, settings))
|
||||
{
|
||||
Game::Com_PrintWarning(Game::conChannel_t::CON_CHANNEL_SYSTEM,
|
||||
"WARNING: malformed dvar \'%s\' in file \'%s\'\n", dvarValue, fileName.data());
|
||||
|
||||
// Failed to apply the value. Check that sscanf can actually parse the value
|
||||
return;
|
||||
}
|
||||
|
||||
// Successfully found and applied the value to the settings
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Dvar not found in visionDefFields, let's try to see if it's a 'patched' dvar
|
||||
ApplyExemptDvar(key, buffer, fileName);
|
||||
}
|
||||
auto found = false;
|
||||
auto fieldNum = 0;
|
||||
|
||||
bool VisionFile::LoadVisionSettingsFromBuffer(const char* buffer, const char* fileName, Game::visionSetVars_t* settings)
|
||||
{
|
||||
assert(settings != nullptr);
|
||||
assert(fileName != nullptr);
|
||||
const auto it = VisionReplacements.find(token);
|
||||
for (fieldNum = 0; fieldNum < 21; ++fieldNum)
|
||||
{
|
||||
if (!wasRead[fieldNum] && !_stricmp((it == VisionReplacements.end()) ? token : it->second.data(), Game::visionDefFields[fieldNum].name))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Game::Com_BeginParseSession(fileName);
|
||||
if (!found)
|
||||
{
|
||||
if (!ApplyExemptDvar(token, &buffer, filename))
|
||||
{
|
||||
Logger::Warning(Game::CON_CHANNEL_SYSTEM, "WARNING: unknown dvar '{}' in file '{}'\n", token, filename);
|
||||
Game::Com_SkipRestOfLine(&buffer);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Will split the buffer into tokens using the following delimiters: space, newlines (more?)
|
||||
for (auto i = Game::Com_Parse(&buffer); *i != '\0'; i = Game::Com_Parse(&buffer))
|
||||
{
|
||||
// Converting 'key' to lower case as it will be needed later
|
||||
ApplyValueToSettings(Utils::String::ToLower(i), buffer, fileName, settings);
|
||||
Game::Com_SkipRestOfLine(&buffer);
|
||||
token = Game::Com_ParseOnLine(&buffer);
|
||||
if (ApplyTokenToField(fieldNum, token, settings))
|
||||
{
|
||||
wasRead[fieldNum] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::Warning(Game::CON_CHANNEL_SYSTEM, "WARNING: malformed dvar '{}' in file '{}'\n", token, filename);
|
||||
Game::Com_SkipRestOfLine(&buffer);
|
||||
}
|
||||
}
|
||||
|
||||
Game::Com_EndParseSession();
|
||||
@ -80,15 +108,21 @@ namespace Components
|
||||
|
||||
__declspec(naked) bool VisionFile::LoadVisionSettingsFromBuffer_Stub()
|
||||
{
|
||||
// No need for push/pop ad guards, I have checked :)
|
||||
__asm
|
||||
{
|
||||
push [esp + 0x8] // settings
|
||||
push eax
|
||||
pushad
|
||||
|
||||
push [esp + 0x24 + 0x8] // settings
|
||||
push ebx // filename
|
||||
push [esp + 0xC] // buffer
|
||||
call VisionFile::LoadVisionSettingsFromBuffer
|
||||
push [esp + 0x24 + 0xC] // buffer
|
||||
call LoadVisionSettingsFromBuffer
|
||||
add esp, 0xC
|
||||
|
||||
mov [esp + 0x20], eax
|
||||
popad
|
||||
pop eax
|
||||
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
@ -8,12 +8,12 @@ namespace Components
|
||||
VisionFile();
|
||||
|
||||
private:
|
||||
static const char* DvarExceptions[];
|
||||
static std::vector<std::string> DvarExceptions;
|
||||
static std::unordered_map<std::string, std::string> VisionReplacements;
|
||||
|
||||
static void ApplyExemptDvar(const std::string& dvarName, const char* buffer, const std::string& fileName);
|
||||
static void ApplyValueToSettings(const std::string& dvarName, const char* buffer, const std::string& fileName, Game::visionSetVars_t* settings);
|
||||
static bool ApplyExemptDvar(const char* dvarName, const char** buffer, const char* filename);
|
||||
|
||||
static bool LoadVisionSettingsFromBuffer(const char* buffer, const char* fileName, Game::visionSetVars_t* settings);
|
||||
static bool LoadVisionSettingsFromBuffer(const char* buffer, const char* filename, Game::visionSetVars_t* settings);
|
||||
static bool LoadVisionSettingsFromBuffer_Stub();
|
||||
};
|
||||
}
|
||||
|
@ -4,12 +4,12 @@
|
||||
namespace Components
|
||||
{
|
||||
int Zones::ZoneVersion;
|
||||
int Zones::EntitiesVersion;
|
||||
|
||||
int Zones::FxEffectIndex;
|
||||
char* Zones::FxEffectStrings[64];
|
||||
|
||||
static std::unordered_map<std::string, std::string> shellshock_replace_list = {
|
||||
static std::unordered_map<std::string, std::string> shellshock_replace_list =
|
||||
{
|
||||
{ "66","bg_shock_screenType" },
|
||||
{ "67","bg_shock_screenBlurBlendTime"},
|
||||
{ "68","bg_shock_screenBlurBlendFadeTime"},
|
||||
@ -41,26 +41,6 @@ namespace Components
|
||||
{ "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;
|
||||
|
||||
@ -2559,8 +2539,6 @@ namespace Components
|
||||
|
||||
int Zones::LoadMapEnts(bool atStreamStart, Game::MapEnts* buffer, int size)
|
||||
{
|
||||
EntitiesVersion = Zones::Version();
|
||||
|
||||
if (Zones::Version() >= 446)
|
||||
{
|
||||
size /= 44;
|
||||
@ -3487,18 +3465,6 @@ 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)
|
||||
{
|
||||
@ -3507,10 +3473,10 @@ namespace Components
|
||||
{
|
||||
return shellshock_replace_list[token].data();
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
|
||||
Zones::Zones()
|
||||
{
|
||||
Zones::ZoneVersion = 0;
|
||||
@ -3682,10 +3648,6 @@ 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);
|
||||
|
@ -21,14 +21,11 @@ namespace Components
|
||||
|
||||
static void SetVersion(int version);
|
||||
|
||||
static int Version() { return Zones::ZoneVersion; };
|
||||
|
||||
static int GetEntitiesZoneVersion() { return Zones::EntitiesVersion; };
|
||||
static int Version() { return Zones::ZoneVersion; }
|
||||
|
||||
private:
|
||||
|
||||
static int ZoneVersion;
|
||||
static int EntitiesVersion;
|
||||
|
||||
static int FxEffectIndex;
|
||||
static char* FxEffectStrings[64];
|
||||
@ -105,6 +102,5 @@ namespace Components
|
||||
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);
|
||||
};
|
||||
}
|
||||
|
@ -995,7 +995,6 @@ namespace Game
|
||||
MaterialShaderArgument *args;
|
||||
};
|
||||
|
||||
/* 9045 */
|
||||
struct visionSetVars_t
|
||||
{
|
||||
bool glowEnable;
|
||||
|
@ -43,6 +43,14 @@ namespace Utils
|
||||
return text;
|
||||
}
|
||||
|
||||
bool Compare(const std::string& lhs, const std::string& rhs)
|
||||
{
|
||||
return std::ranges::equal(lhs, rhs, [](const unsigned char a, const unsigned char b)
|
||||
{
|
||||
return std::tolower(a) == std::tolower(b);
|
||||
});
|
||||
}
|
||||
|
||||
std::string DumpHex(const std::string& data, const std::string& separator)
|
||||
{
|
||||
std::string result;
|
||||
@ -106,18 +114,18 @@ namespace Utils
|
||||
return std::equal(needle.rbegin(), needle.rend(), haystack.rbegin());
|
||||
}
|
||||
|
||||
int IsSpace(int c)
|
||||
bool IsNumber(const std::string& str)
|
||||
{
|
||||
if (c < -1) return 0;
|
||||
return _isspace_l(c, nullptr);
|
||||
return !str.empty() && std::find_if(str.begin(),
|
||||
str.end(), [](unsigned char input) { return !std::isdigit(input); }) == str.end();
|
||||
}
|
||||
|
||||
// Trim from start
|
||||
std::string& LTrim(std::string& str)
|
||||
{
|
||||
str.erase(str.begin(), std::find_if(str.begin(), str.end(), [](int val)
|
||||
str.erase(str.begin(), std::find_if(str.begin(), str.end(), [](const unsigned char input)
|
||||
{
|
||||
return !IsSpace(val);
|
||||
return !std::isspace(input);
|
||||
}));
|
||||
|
||||
return str;
|
||||
@ -126,9 +134,9 @@ namespace Utils
|
||||
// Trim from end
|
||||
std::string& RTrim(std::string& str)
|
||||
{
|
||||
str.erase(std::find_if(str.rbegin(), str.rend(), [](int val)
|
||||
str.erase(std::find_if(str.rbegin(), str.rend(), [](const unsigned char input)
|
||||
{
|
||||
return !IsSpace(val);
|
||||
return !std::isspace(input);
|
||||
}).base(), str.end());
|
||||
|
||||
return str;
|
||||
|
@ -4,7 +4,7 @@ namespace Utils
|
||||
{
|
||||
namespace String
|
||||
{
|
||||
template <size_t Buffers, size_t MinBufferSize>
|
||||
template <std::size_t Buffers, std::size_t MinBufferSize>
|
||||
class VAProvider
|
||||
{
|
||||
public:
|
||||
@ -25,7 +25,7 @@ namespace Utils
|
||||
|
||||
while (true)
|
||||
{
|
||||
const auto res = _vsnprintf_s(entry->buffer, entry->size, _TRUNCATE, format, ap);
|
||||
const auto res = vsnprintf_s(entry->buffer, entry->size, _TRUNCATE, format, ap);
|
||||
if (res > 0) break; // Success
|
||||
if (res == 0) return ""; // Error
|
||||
|
||||
@ -47,15 +47,15 @@ namespace Utils
|
||||
|
||||
~Entry()
|
||||
{
|
||||
if (this->buffer) Utils::Memory::GetAllocator()->free(this->buffer);
|
||||
if (this->buffer) Memory::GetAllocator()->free(this->buffer);
|
||||
this->size = 0;
|
||||
this->buffer = nullptr;
|
||||
}
|
||||
|
||||
void allocate()
|
||||
{
|
||||
if (this->buffer) Utils::Memory::GetAllocator()->free(this->buffer);
|
||||
this->buffer = Utils::Memory::GetAllocator()->allocateArray<char>(this->size + 1);
|
||||
if (this->buffer) Memory::GetAllocator()->free(this->buffer);
|
||||
this->buffer = Memory::GetAllocator()->allocateArray<char>(this->size + 1);
|
||||
}
|
||||
|
||||
void doubleSize()
|
||||
@ -74,13 +74,14 @@ namespace Utils
|
||||
|
||||
const char *VA(const char *fmt, ...);
|
||||
|
||||
int IsSpace(int c);
|
||||
std::string ToLower(std::string text);
|
||||
std::string ToUpper(std::string text);
|
||||
bool Compare(const std::string& lhs, const std::string& rhs);
|
||||
std::vector<std::string> Split(const std::string& str, char delim);
|
||||
void Replace(std::string& string, const std::string& find, const std::string& replace);
|
||||
bool StartsWith(const std::string& haystack, const std::string& needle);
|
||||
bool EndsWith(const std::string& haystack, const std::string& needle);
|
||||
bool IsNumber(const std::string& str);
|
||||
|
||||
std::string& LTrim(std::string& str);
|
||||
std::string& RTrim(std::string& str);
|
||||
@ -94,7 +95,7 @@ namespace Utils
|
||||
|
||||
std::string DumpHex(const std::string& data, const std::string& separator = " ");
|
||||
|
||||
std::string XOR(const std::string str, char value);
|
||||
std::string XOR(std::string str, char value);
|
||||
|
||||
std::string EncodeBase64(const char* input, const unsigned long inputSize);
|
||||
std::string EncodeBase64(const std::string& input);
|
||||
|
Loading…
Reference in New Issue
Block a user