mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2024-12-28 06:43:01 +05:00
Allow SVF to register model names, not just IDs
This commit is contained in:
parent
ccf61157fb
commit
4169c9e867
15 changed files with 263 additions and 23 deletions
|
@ -5,6 +5,7 @@
|
|||
#include "Utils/HookEach.hpp"
|
||||
#include "StoredCar.h"
|
||||
#include "SVF.h"
|
||||
#include "ParseUtils.hpp"
|
||||
|
||||
#include "Utils/DelimStringReader.h"
|
||||
|
||||
|
@ -136,9 +137,11 @@ namespace ExtraCompSpecularity
|
|||
GetPrivateProfileSectionW(L"ExtraCompSpecularityExceptions", reader.GetBuffer(), reader.GetSize(), pPath);
|
||||
while (const wchar_t* str = reader.GetString())
|
||||
{
|
||||
int32_t toList = wcstol(str, nullptr, 0);
|
||||
if ( toList > 0 )
|
||||
SVF::RegisterFeature(toList, SVF::Feature::_INTERNAL_NO_SPECULARITY_ON_EXTRAS);
|
||||
auto modelID = ParseUtils::TryParseInt(str);
|
||||
if (modelID)
|
||||
SVF::RegisterFeature(*modelID, SVF::Feature::_INTERNAL_NO_SPECULARITY_ON_EXTRAS);
|
||||
else
|
||||
SVF::RegisterFeature(ParseUtils::ParseString(str), SVF::Feature::_INTERNAL_NO_SPECULARITY_ON_EXTRAS);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
37
SilentPatch/ParseUtils.cpp
Normal file
37
SilentPatch/ParseUtils.cpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
#include "ParseUtils.hpp"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define NOMINMAX
|
||||
#include <Windows.h>
|
||||
|
||||
static std::string WcharToUTF8(std::wstring_view str)
|
||||
{
|
||||
std::string result;
|
||||
|
||||
const int count = WideCharToMultiByte(CP_UTF8, 0, str.data(), str.size(), nullptr, 0, nullptr, nullptr);
|
||||
if (count != 0)
|
||||
{
|
||||
result.resize(count);
|
||||
WideCharToMultiByte(CP_UTF8, 0, str.data(), str.size(), result.data(), count, nullptr, nullptr);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::optional<int32_t> ParseUtils::TryParseInt(const wchar_t* str)
|
||||
{
|
||||
std::optional<int32_t> result;
|
||||
|
||||
wchar_t* end;
|
||||
const int32_t val = wcstol(str, &end, 0);
|
||||
if (*end == '\0')
|
||||
{
|
||||
result.emplace(val);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string ParseUtils::ParseString(const wchar_t* str)
|
||||
{
|
||||
return WcharToUTF8(str);
|
||||
}
|
11
SilentPatch/ParseUtils.hpp
Normal file
11
SilentPatch/ParseUtils.hpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace ParseUtils
|
||||
{
|
||||
std::optional<int32_t> TryParseInt(const wchar_t* str);
|
||||
std::string ParseString(const wchar_t* str);
|
||||
};
|
|
@ -84,6 +84,26 @@ namespace SVF
|
|||
#endif
|
||||
};
|
||||
|
||||
static std::multimap<std::string, std::tuple<Feature, int32_t> > specialVehFeaturesByName;
|
||||
static void* (*GetModelInfoCB)(const char* name, int* outIndex);
|
||||
static bool bModelNamesReady = false;
|
||||
|
||||
void _resolveFeatureNamesInternal()
|
||||
{
|
||||
if (bModelNamesReady && GetModelInfoCB != nullptr && !specialVehFeaturesByName.empty())
|
||||
{
|
||||
for (const auto& feature : specialVehFeaturesByName)
|
||||
{
|
||||
int32_t index;
|
||||
if (GetModelInfoCB(feature.first.c_str(), &index) != nullptr)
|
||||
{
|
||||
specialVehFeatures.emplace(index, feature.second);
|
||||
}
|
||||
}
|
||||
specialVehFeaturesByName.clear();
|
||||
}
|
||||
}
|
||||
|
||||
int32_t RegisterFeature( int32_t modelID, Feature feature )
|
||||
{
|
||||
if ( feature == Feature::NO_FEATURE ) return -1;
|
||||
|
@ -93,6 +113,15 @@ namespace SVF
|
|||
return cookie;
|
||||
}
|
||||
|
||||
int32_t RegisterFeature( std::string modelName, Feature feature )
|
||||
{
|
||||
if ( feature == Feature::NO_FEATURE ) return -1;
|
||||
|
||||
const int32_t cookie = _getCookie();
|
||||
specialVehFeaturesByName.emplace( std::move(modelName), std::make_tuple(feature, cookie) );
|
||||
return cookie;
|
||||
}
|
||||
|
||||
void DeleteFeature( int32_t cookie )
|
||||
{
|
||||
for ( auto it = specialVehFeatures.begin(); it != specialVehFeatures.end(); ++it )
|
||||
|
@ -103,6 +132,15 @@ namespace SVF
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto it = specialVehFeaturesByName.begin(); it != specialVehFeaturesByName.end(); ++it )
|
||||
{
|
||||
if ( std::get<int32_t>(it->second) == cookie )
|
||||
{
|
||||
specialVehFeaturesByName.erase( it );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DisableStockVehiclesForFeature( Feature feature )
|
||||
|
@ -119,10 +157,23 @@ namespace SVF
|
|||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto it = specialVehFeaturesByName.begin(); it != specialVehFeaturesByName.end(); )
|
||||
{
|
||||
if ( std::get<Feature>(it->second) == feature && std::get<int32_t>(it->second) <= highestStockCookie )
|
||||
{
|
||||
it = specialVehFeaturesByName.erase( it );
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ModelHasFeature( int32_t modelID, Feature feature )
|
||||
{
|
||||
_resolveFeatureNamesInternal();
|
||||
auto results = specialVehFeatures.equal_range( modelID );
|
||||
return std::find_if( results.first, results.second, [feature] ( const auto& e ) {
|
||||
return std::get<Feature>(e.second) == feature;
|
||||
|
@ -131,6 +182,7 @@ namespace SVF
|
|||
|
||||
std::function<bool(Feature)> ForAllModelFeatures( int32_t modelID, std::function<bool(Feature)> pred )
|
||||
{
|
||||
_resolveFeatureNamesInternal();
|
||||
auto results = specialVehFeatures.equal_range( modelID );
|
||||
for ( auto it = results.first; it != results.second; ++it )
|
||||
{
|
||||
|
@ -141,6 +193,16 @@ namespace SVF
|
|||
}
|
||||
return std::move(pred);
|
||||
}
|
||||
|
||||
void RegisterGetModelInfoCB(void*(*func)(const char*, int*))
|
||||
{
|
||||
GetModelInfoCB = func;
|
||||
}
|
||||
|
||||
void MarkModelNamesReady()
|
||||
{
|
||||
bModelNamesReady = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns "feature cookie" on success, -1 on failure
|
||||
|
@ -152,6 +214,12 @@ __declspec(dllexport) int32_t RegisterSpecialVehicleFeature( int32_t modelID, co
|
|||
return SVF::RegisterFeature( modelID, SVF::GetFeatureFromName(featureName) );
|
||||
}
|
||||
|
||||
__declspec(dllexport) int32_t RegisterSpecialVehicleFeatureByName( const char* modelName, const char* featureName )
|
||||
{
|
||||
if ( featureName == nullptr || modelName == nullptr ) return -1;
|
||||
return SVF::RegisterFeature( modelName, SVF::GetFeatureFromName(featureName) );
|
||||
}
|
||||
|
||||
__declspec(dllexport) void DeleteSpecialVehicleFeature( int32_t cookie )
|
||||
{
|
||||
if ( cookie == -1 ) return;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
namespace SVF
|
||||
{
|
||||
|
@ -49,8 +50,12 @@ namespace SVF
|
|||
};
|
||||
|
||||
int32_t RegisterFeature( int32_t modelID, Feature feature );
|
||||
int32_t RegisterFeature( std::string modelName, Feature feature );
|
||||
void DeleteFeature( int32_t cookie );
|
||||
void DisableStockVehiclesForFeature( Feature feature );
|
||||
bool ModelHasFeature( int32_t modelID, Feature feature );
|
||||
std::function<bool(Feature)> ForAllModelFeatures( int32_t modelID, std::function<bool(Feature)> pred );
|
||||
|
||||
void RegisterGetModelInfoCB(void*(*func)(const char*, int*));
|
||||
void MarkModelNamesReady();
|
||||
};
|
|
@ -839,6 +839,17 @@ namespace SitInBoat
|
|||
}
|
||||
|
||||
|
||||
namespace SVFReadyHook
|
||||
{
|
||||
static void (*orgInitialiseObjectData)(const char*);
|
||||
static void InitialiseObjectData_ReadySVF(const char* path)
|
||||
{
|
||||
orgInitialiseObjectData(path);
|
||||
SVF::MarkModelNamesReady();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InjectDelayedPatches_III_Common( bool bHasDebugMenu, const wchar_t* wcModulePath )
|
||||
{
|
||||
using namespace Memory;
|
||||
|
@ -995,6 +1006,21 @@ void InjectDelayedPatches_III_Common( bool bHasDebugMenu, const wchar_t* wcModul
|
|||
}
|
||||
TXN_CATCH();
|
||||
|
||||
|
||||
// Register CBaseModelInfo::GetModelInfo for SVF so we can resolve model names
|
||||
try
|
||||
{
|
||||
using namespace SVFReadyHook;
|
||||
|
||||
auto initialiseObjectData = get_pattern("E8 ? ? ? ? B3 01 59 8D 6D 04");
|
||||
auto getModelInfo = (void*(*)(const char*, int*))get_pattern("31 FF 8D 84 20 00 00 00 00 8B 04 BD", -7);
|
||||
|
||||
InterceptCall(initialiseObjectData, orgInitialiseObjectData, InitialiseObjectData_ReadySVF);
|
||||
SVF::RegisterGetModelInfoCB(getModelInfo);
|
||||
}
|
||||
TXN_CATCH();
|
||||
|
||||
|
||||
FLAUtils::Init(moduleList);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,11 @@
|
|||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Shipping|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\SilentPatch\ParseUtils.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Shipping|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\SilentPatch\RWGTA.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Shipping|Win32'">NotUsing</PrecompiledHeader>
|
||||
|
@ -66,6 +71,7 @@
|
|||
<ClInclude Include="..\SilentPatch\debugmenu_public.h" />
|
||||
<ClInclude Include="..\SilentPatch\Desktop.h" />
|
||||
<ClInclude Include="..\SilentPatch\Maths.h" />
|
||||
<ClInclude Include="..\SilentPatch\ParseUtils.hpp" />
|
||||
<ClInclude Include="..\SilentPatch\StdAfx.h" />
|
||||
<ClInclude Include="..\SilentPatch\StoredCar.h" />
|
||||
<ClInclude Include="..\SilentPatch\SVF.h" />
|
||||
|
|
|
@ -57,6 +57,9 @@
|
|||
<ClCompile Include="..\SilentPatch\TheFLAUtils.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\SilentPatch\ParseUtils.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\SilentPatch\Timer.h">
|
||||
|
@ -104,6 +107,9 @@
|
|||
<ClInclude Include="..\SilentPatch\TheFLAUtils.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\SilentPatch\ParseUtils.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\SilentPatch\SilentPatch.rc">
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "Utils/HookEach.hpp"
|
||||
|
||||
#include "Desktop.h"
|
||||
#include "SVF.h"
|
||||
|
||||
#include "debugmenu_public.h"
|
||||
#include "resource.h"
|
||||
|
@ -2659,6 +2660,16 @@ static bool IgnoresWeaponPedsForPCFix()
|
|||
}
|
||||
|
||||
|
||||
namespace SVFReadyHook
|
||||
{
|
||||
static void (*orgMatchAllModelStrings)();
|
||||
static void MatchAllModelStrings_ReadySVF()
|
||||
{
|
||||
orgMatchAllModelStrings();
|
||||
SVF::MarkModelNamesReady();
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
// ============= QPC spoof for verifying high timer issues =============
|
||||
|
@ -3894,6 +3905,16 @@ BOOL InjectDelayedPatches_10()
|
|||
}
|
||||
}
|
||||
|
||||
// Register CBaseModelInfo::GetModelInfo for SVF so we can resolve model names
|
||||
{
|
||||
using namespace SVFReadyHook;
|
||||
|
||||
auto func = (void*(*)(const char*, int*))0x4C5940;
|
||||
|
||||
InterceptCall(0x5B922F, orgMatchAllModelStrings, MatchAllModelStrings_ReadySVF);
|
||||
SVF::RegisterGetModelInfoCB(func);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
if ( const int QPCDays = GetPrivateProfileIntW(L"Debug", L"AddDaysToQPC", 0, wcModulePath); QPCDays != 0 )
|
||||
{
|
||||
|
|
|
@ -207,6 +207,11 @@ copy /y "$(TargetPath)" "H:\Rockstar Games\Grand Theft Auto San Andreas\SilentPa
|
|||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Shipping|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\SilentPatch\ParseUtils.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Shipping|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\SilentPatch\SVF.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Shipping|Win32'">NotUsing</PrecompiledHeader>
|
||||
|
@ -246,6 +251,7 @@ copy /y "$(TargetPath)" "H:\Rockstar Games\Grand Theft Auto San Andreas\SilentPa
|
|||
<ClInclude Include="..\SilentPatch\debugmenu_public.h" />
|
||||
<ClInclude Include="..\SilentPatch\Desktop.h" />
|
||||
<ClInclude Include="..\SilentPatch\Maths.h" />
|
||||
<ClInclude Include="..\SilentPatch\ParseUtils.hpp" />
|
||||
<ClInclude Include="..\SilentPatch\resource1.h" />
|
||||
<ClInclude Include="..\SilentPatch\RWUtils.hpp" />
|
||||
<ClInclude Include="..\SilentPatch\SVF.h" />
|
||||
|
|
|
@ -81,6 +81,9 @@
|
|||
<ClCompile Include="..\SilentPatch\Desktop.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\SilentPatch\ParseUtils.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="StdAfxSA.h">
|
||||
|
@ -164,6 +167,9 @@
|
|||
<ClInclude Include="..\SilentPatch\RWUtils.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\SilentPatch\ParseUtils.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\SilentPatch\SilentPatch.rc">
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "PedSA.h"
|
||||
#include "Utils/DelimStringReader.h"
|
||||
#include "PlayerInfoSA.h"
|
||||
#include "ParseUtils.hpp"
|
||||
|
||||
#include "SVF.h"
|
||||
|
||||
|
@ -27,26 +28,29 @@ bool ReadDoubleRearWheels(const wchar_t* pPath)
|
|||
GetPrivateProfileSectionW( L"DoubleRearWheels", reader.GetBuffer(), reader.GetSize(), pPath );
|
||||
while ( const wchar_t* str = reader.GetString() )
|
||||
{
|
||||
wchar_t textLine[64];
|
||||
wchar_t* context = nullptr;
|
||||
wchar_t* token;
|
||||
wchar_t textLine[128];
|
||||
wcscpy_s(textLine, str);
|
||||
|
||||
wcscpy_s( textLine, str );
|
||||
token = wcstok_s( textLine, L"=", &context );
|
||||
wchar_t* context = nullptr;
|
||||
wchar_t* model = wcstok_s(textLine, L"=", &context);
|
||||
if (model == nullptr) continue;
|
||||
|
||||
int32_t toList = wcstol( token, nullptr, 0 );
|
||||
if ( toList <= 0 ) continue;
|
||||
wchar_t* val = wcstok_s(nullptr, L"=", &context);
|
||||
if (val == nullptr) continue;
|
||||
|
||||
wchar_t* begin = wcstok_s( nullptr, L"=", &context );
|
||||
if ( begin == nullptr ) continue;
|
||||
auto value = ParseUtils::TryParseInt(val);
|
||||
if (!value) continue;
|
||||
|
||||
wchar_t* end = nullptr;
|
||||
bool value = wcstoul( begin, &end, 0 ) != 0;
|
||||
if ( begin != end )
|
||||
auto modelID = ParseUtils::TryParseInt(model);
|
||||
if (modelID)
|
||||
{
|
||||
SVF::RegisterFeature( toList, value ? SVF::Feature::_INTERNAL_FORCE_DOUBLE_RWHEELS_ON : SVF::Feature::_INTERNAL_FORCE_DOUBLE_RWHEELS_OFF );
|
||||
listedAny = true;
|
||||
SVF::RegisterFeature(*modelID, *value ? SVF::Feature::_INTERNAL_FORCE_DOUBLE_RWHEELS_ON : SVF::Feature::_INTERNAL_FORCE_DOUBLE_RWHEELS_OFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
SVF::RegisterFeature(ParseUtils::ParseString(model), *value ? SVF::Feature::_INTERNAL_FORCE_DOUBLE_RWHEELS_ON : SVF::Feature::_INTERNAL_FORCE_DOUBLE_RWHEELS_OFF);
|
||||
}
|
||||
listedAny = true;
|
||||
}
|
||||
return listedAny;
|
||||
}
|
||||
|
@ -202,9 +206,11 @@ void ReadRotorFixExceptions(const wchar_t* pPath)
|
|||
GetPrivateProfileSectionW( L"RotorFixExceptions", reader.GetBuffer(), reader.GetSize(), pPath );
|
||||
while ( const wchar_t* str = reader.GetString() )
|
||||
{
|
||||
int32_t toList = wcstol( str, nullptr, 0 );
|
||||
if ( toList > 0 )
|
||||
SVF::RegisterFeature( toList, SVF::Feature::_INTERNAL_NO_ROTOR_FADE );
|
||||
auto ID = ParseUtils::TryParseInt(str);
|
||||
if (ID)
|
||||
SVF::RegisterFeature(*ID, SVF::Feature::_INTERNAL_NO_ROTOR_FADE);
|
||||
else
|
||||
SVF::RegisterFeature(ParseUtils::ParseString(str), SVF::Feature::_INTERNAL_NO_ROTOR_FADE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -216,9 +222,11 @@ void ReadLightbeamFixExceptions(const wchar_t* pPath)
|
|||
GetPrivateProfileSectionW( L"LightbeamFixExceptions", reader.GetBuffer(), reader.GetSize(), pPath );
|
||||
while ( const wchar_t* str = reader.GetString() )
|
||||
{
|
||||
int32_t toList = wcstol( str, nullptr, 0 );
|
||||
if ( toList > 0 )
|
||||
SVF::RegisterFeature( toList, SVF::Feature::_INTERNAL_NO_LIGHTBEAM_BFC_FIX );
|
||||
auto ID = ParseUtils::TryParseInt(str);
|
||||
if (ID)
|
||||
SVF::RegisterFeature(*ID, SVF::Feature::_INTERNAL_NO_LIGHTBEAM_BFC_FIX);
|
||||
else
|
||||
SVF::RegisterFeature(ParseUtils::ParseString(str), SVF::Feature::_INTERNAL_NO_LIGHTBEAM_BFC_FIX);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -771,6 +771,17 @@ namespace CarPartsBackfaceCulling
|
|||
}
|
||||
|
||||
|
||||
namespace SVFReadyHook
|
||||
{
|
||||
static void (*orgInitialiseObjectData)(const char*);
|
||||
static void InitialiseObjectData_ReadySVF(const char* path)
|
||||
{
|
||||
orgInitialiseObjectData(path);
|
||||
SVF::MarkModelNamesReady();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModulePath )
|
||||
{
|
||||
using namespace Memory;
|
||||
|
@ -926,6 +937,20 @@ void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModule
|
|||
TXN_CATCH();
|
||||
}
|
||||
|
||||
// Register CBaseModelInfo::GetModelInfo for SVF so we can resolve model names
|
||||
try
|
||||
{
|
||||
using namespace SVFReadyHook;
|
||||
|
||||
auto initialiseObjectData = get_pattern("E8 ? ? ? ? 59 E8 ? ? ? ? E8 ? ? ? ? 31 DB");
|
||||
auto getModelInfo = (void*(*)(const char*, int*))get_pattern("57 31 FF 55 8B 6C 24 14", -6);
|
||||
|
||||
InterceptCall(initialiseObjectData, orgInitialiseObjectData, InitialiseObjectData_ReadySVF);
|
||||
SVF::RegisterGetModelInfoCB(getModelInfo);
|
||||
}
|
||||
TXN_CATCH();
|
||||
|
||||
|
||||
FLAUtils::Init(moduleList);
|
||||
}
|
||||
|
||||
|
|
|
@ -170,6 +170,7 @@
|
|||
<ClInclude Include="..\SilentPatch\debugmenu_public.h" />
|
||||
<ClInclude Include="..\SilentPatch\Desktop.h" />
|
||||
<ClInclude Include="..\SilentPatch\Maths.h" />
|
||||
<ClInclude Include="..\SilentPatch\ParseUtils.hpp" />
|
||||
<ClInclude Include="..\SilentPatch\RWUtils.hpp" />
|
||||
<ClInclude Include="..\SilentPatch\StdAfx.h" />
|
||||
<ClInclude Include="..\SilentPatch\StoredCar.h" />
|
||||
|
@ -198,6 +199,11 @@
|
|||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Shipping|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\SilentPatch\ParseUtils.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Shipping|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\SilentPatch\RWGTA.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Shipping|Win32'">NotUsing</PrecompiledHeader>
|
||||
|
|
|
@ -66,6 +66,9 @@
|
|||
<ClInclude Include="..\SilentPatch\RWUtils.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\SilentPatch\ParseUtils.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\SilentPatch\Timer.cpp">
|
||||
|
@ -107,6 +110,9 @@
|
|||
<ClCompile Include="..\SilentPatch\TheFLAUtils.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\SilentPatch\ParseUtils.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\SilentPatch\SilentPatch.rc">
|
||||
|
|
Loading…
Reference in a new issue