Various Preload improvements (down to 600mb per catbot!)
This commit is contained in:
parent
dc2ed5aca9
commit
b80c983ecf
@ -96,3 +96,4 @@ extern IFileSystem *g_IFileSystem;
|
||||
extern IMDLCache *g_IMDLCache;
|
||||
|
||||
void CreateInterfaces();
|
||||
void CreateEarlyInterfaces();
|
||||
|
@ -54,5 +54,6 @@ SharedObject &studiorender();
|
||||
SharedObject &libsdl();
|
||||
#endif
|
||||
|
||||
void LoadEarlyObjects();
|
||||
void LoadAllSharedObjects();
|
||||
} // namespace sharedobj
|
||||
|
@ -10,9 +10,16 @@
|
||||
#include <stack>
|
||||
|
||||
std::stack<void (*)()> &init_stack();
|
||||
std::stack<void (*)()> &init_stack_early();
|
||||
|
||||
class InitRoutine
|
||||
{
|
||||
public:
|
||||
InitRoutine(void (*func)());
|
||||
};
|
||||
|
||||
class InitRoutineEarly
|
||||
{
|
||||
public:
|
||||
InitRoutineEarly(void (*func)());
|
||||
};
|
||||
|
@ -17,3 +17,14 @@ InitRoutine::InitRoutine(void (*func)())
|
||||
{
|
||||
init_stack().push(func);
|
||||
}
|
||||
|
||||
std::stack<void (*)()> &init_stack_early()
|
||||
{
|
||||
static std::stack<void (*)()> stack{};
|
||||
return stack;
|
||||
}
|
||||
|
||||
InitRoutineEarly::InitRoutineEarly(void (*func)())
|
||||
{
|
||||
init_stack_early().push(func);
|
||||
}
|
||||
|
@ -84,6 +84,11 @@ template <typename T> T *BruteforceInterface(std::string name, sharedobj::Shared
|
||||
extern "C" typedef HSteamPipe (*GetHSteamPipe_t)();
|
||||
extern "C" typedef HSteamUser (*GetHSteamUser_t)();
|
||||
|
||||
void CreateEarlyInterfaces()
|
||||
{
|
||||
g_IFileSystem = BruteforceInterface<IFileSystem>("VFileSystem", sharedobj::filesystem_stdio());
|
||||
}
|
||||
|
||||
void CreateInterfaces()
|
||||
{
|
||||
g_ICvar = BruteforceInterface<ICvar>("VEngineCvar", sharedobj::vstdlib());
|
||||
@ -141,8 +146,7 @@ void CreateInterfaces()
|
||||
g_IModelInfo = BruteforceInterface<IVModelInfoClient>("VModelInfoClient", sharedobj::engine());
|
||||
g_IBaseClientState = *(reinterpret_cast<CBaseClientState **>(gSignatures.GetEngineSignature("C7 04 24 ? ? ? ? E8 ? ? ? ? C7 04 24 ? ? ? ? 89 44 24 04 E8 ? ? ? ? A1 ? ? ? ?") + 3));
|
||||
logging::Info("BaseClientState: 0x%08x", g_IBaseClientState);
|
||||
while (!g_IAchievementMgr)
|
||||
g_IAchievementMgr = g_IEngine->GetAchievementMgr();
|
||||
g_IAchievementMgr = g_IEngine->GetAchievementMgr();
|
||||
g_ISteamUserStats = g_ISteamClient->GetISteamUserStats(su, sp, "STEAMUSERSTATS_INTERFACE_VERSION011");
|
||||
IF_GAME(IsTF2())
|
||||
{
|
||||
@ -153,7 +157,6 @@ void CreateInterfaces()
|
||||
g_pGameRules = *reinterpret_cast<CGameRules **>(g_pGameRules_sig + 8);
|
||||
}
|
||||
g_IMaterialSystem = BruteforceInterface<IMaterialSystemFixed>("VMaterialSystem", sharedobj::materialsystem());
|
||||
g_IFileSystem = BruteforceInterface<IFileSystem>("VFileSystem", sharedobj::filesystem_stdio());
|
||||
g_IMDLCache = BruteforceInterface<IMDLCache>("MDLCache", sharedobj::datacache());
|
||||
|
||||
g_IPanel = BruteforceInterface<vgui::IPanel>("VGUI_Panel", sharedobj::vgui2());
|
||||
|
@ -84,19 +84,30 @@ void *SharedObject::CreateInterface(const std::string &interface)
|
||||
return (void *) (fptr(interface.c_str(), nullptr));
|
||||
}
|
||||
|
||||
void LoadEarlyObjects()
|
||||
{
|
||||
try
|
||||
{
|
||||
engine().Load();
|
||||
filesystem_stdio().Load();
|
||||
tier0().Load();
|
||||
materialsystem().Load();
|
||||
}
|
||||
catch (std::exception &ex)
|
||||
{
|
||||
logging::Info("Exception: %s", ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
void LoadAllSharedObjects()
|
||||
{
|
||||
try
|
||||
{
|
||||
steamclient().Load();
|
||||
client().Load();
|
||||
engine().Load();
|
||||
steamapi().Load();
|
||||
vstdlib().Load();
|
||||
tier0().Load();
|
||||
inputsystem().Load();
|
||||
materialsystem().Load();
|
||||
filesystem_stdio().Load();
|
||||
datacache().Load();
|
||||
vgui2().Load();
|
||||
#if ENABLE_VISUALS
|
||||
|
42
src/hack.cpp
42
src/hack.cpp
@ -301,10 +301,12 @@ static bool FSHook_Precache(const char *pFileName, const char *pPathID)
|
||||
|
||||
static CatCommand debug_invalidate("invalidate_mdl_cache", "Invalidates MDL cache", []() { g_IBaseClient->InvalidateMdlCache(); });
|
||||
|
||||
static hooks::VMTHook fs_hook, fs_hook2;
|
||||
static hooks::VMTHook fs_hook{}, fs_hook2{};
|
||||
|
||||
static void ReduceRamUsage()
|
||||
{
|
||||
if (fs_hook.IsHooked(reinterpret_cast<void *>(g_IFileSystem)))
|
||||
return;
|
||||
/* TO DO: Improves load speeds but doesn't reduce memory usage a lot
|
||||
* It seems engine still allocates significant parts without them
|
||||
* being really used
|
||||
@ -329,7 +331,11 @@ static void ReduceRamUsage()
|
||||
* spam related to mdl not being able to play sequence that it
|
||||
* cannot play on error.mdl
|
||||
*/
|
||||
static BytePatch playSequence{ gSignatures.GetClientSignature, "55 89 E5 57 56 53 83 EC ? 8B 75 0C 8B 5D 08 85 F6 74 ? 83 BB", 0x00, { 0xC3 } };
|
||||
if (g_IBaseClient)
|
||||
{
|
||||
static BytePatch playSequence{ gSignatures.GetClientSignature, "55 89 E5 57 56 53 83 EC ? 8B 75 0C 8B 5D 08 85 F6 74 ? 83 BB", 0x00, { 0xC3 } };
|
||||
playSequence.Patch();
|
||||
}
|
||||
#if 0
|
||||
/* Same explanation as above, but spams about certain particles not loaded */
|
||||
static BytePatch particleCreate{ gSignatures.GetClientSignature,
|
||||
@ -348,15 +354,28 @@ static void ReduceRamUsage()
|
||||
particlePrecache.Patch();
|
||||
particleCreating.Patch();
|
||||
#endif
|
||||
playSequence.Patch();
|
||||
}
|
||||
|
||||
static void UnHookFs()
|
||||
{
|
||||
fs_hook.Release();
|
||||
fs_hook2.Release();
|
||||
g_IBaseClient->InvalidateMdlCache();
|
||||
if (g_IBaseClient)
|
||||
g_IBaseClient->InvalidateMdlCache();
|
||||
}
|
||||
#if !ENABLE_VISUALS
|
||||
static InitRoutineEarly nullify_textmode([]() {
|
||||
ReduceRamUsage();
|
||||
static auto addr1 = e8call_direct(gSignatures.GetEngineSignature("E8 ? ? ? ? 8B 93 ? ? ? ? 85 D2 0F 84 ? ? ? ?")) + 0x18;
|
||||
static auto addr2 = sharedobj::materialsystem().Pointer(0x3EC08);
|
||||
|
||||
static BytePatch patch1(addr1, { 0x81, 0xC4, 0x6C, 0x20, 0x00, 0x00, 0x5B, 0x5E, 0x5F, 0x5D, 0xC3 });
|
||||
static BytePatch patch2(addr2, { 0x83, 0xC4, 0x50, 0x5B, 0x5E, 0x5D, 0xC3 });
|
||||
|
||||
patch1.Patch();
|
||||
patch2.Patch();
|
||||
});
|
||||
#endif
|
||||
|
||||
static void InitRandom()
|
||||
{
|
||||
@ -413,15 +432,24 @@ free(logname);*/
|
||||
#endif /* TEXTMODE */
|
||||
logging::Info("Initializing...");
|
||||
InitRandom();
|
||||
sharedobj::LoadAllSharedObjects();
|
||||
CreateInterfaces();
|
||||
CDumper dumper;
|
||||
sharedobj::LoadEarlyObjects();
|
||||
CreateEarlyInterfaces();
|
||||
logging::Info("Clearing Early initializer stack");
|
||||
null_graphics.installChangeCallback([](settings::VariableBase<bool> &, bool after) {
|
||||
if (after)
|
||||
ReduceRamUsage();
|
||||
else
|
||||
UnHookFs();
|
||||
});
|
||||
while (!init_stack_early().empty())
|
||||
{
|
||||
init_stack_early().top()();
|
||||
init_stack_early().pop();
|
||||
}
|
||||
logging::Info("Early Initializer stack done");
|
||||
sharedobj::LoadAllSharedObjects();
|
||||
CreateInterfaces();
|
||||
CDumper dumper;
|
||||
dumper.SaveDump();
|
||||
logging::Info("Is TF2? %d", IsTF2());
|
||||
logging::Info("Is TF2C? %d", IsTF2C());
|
||||
|
@ -35,8 +35,20 @@ static settings::Int equip_secondary{ "achievement.equip-secondary", "0" };
|
||||
static settings::Int equip_melee{ "achievement.equip-melee", "0" };
|
||||
static settings::Int equip_pda2{ "achievement.equip-pda2", "0" };
|
||||
|
||||
bool checkachmngr()
|
||||
{
|
||||
if (!g_IAchievementMgr)
|
||||
{
|
||||
g_IAchievementMgr = g_IEngine->GetAchievementMgr();
|
||||
if (!g_IAchievementMgr)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void Lock()
|
||||
{
|
||||
if (!checkachmngr())
|
||||
return;
|
||||
if (safety)
|
||||
{
|
||||
ConColorMsg({ 255, 0, 0, 255 }, "Switch `cat set achievement.safety` to false before using any achievement commands!\n");
|
||||
@ -53,6 +65,8 @@ void Lock()
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
if (!checkachmngr())
|
||||
return;
|
||||
/*auto Invmng = re::CTFInventoryManager::GTFInventoryManager();
|
||||
auto Inv = re::CTFPlayerInventory::GTFPlayerInventory();
|
||||
auto Item = Inv->GetFirstItemOfItemDef(59);
|
||||
@ -70,6 +84,8 @@ void Unlock()
|
||||
}
|
||||
|
||||
CatCommand dump_achievement("achievement_dump", "Dump achievements to file (development)", []() {
|
||||
if (!checkachmngr())
|
||||
return;
|
||||
std::ofstream out("/tmp/cathook_achievements.txt", std::ios::out);
|
||||
if (out.bad())
|
||||
return;
|
||||
@ -80,6 +96,8 @@ CatCommand dump_achievement("achievement_dump", "Dump achievements to file (deve
|
||||
out.close();
|
||||
});
|
||||
CatCommand unlock_single("achievement_unlock_single", "Unlocks single achievement by ID", [](const CCommand &args) {
|
||||
if (!checkachmngr())
|
||||
return;
|
||||
char *out = nullptr;
|
||||
int id = strtol(args.Arg(1), &out, 10);
|
||||
if (out == args.Arg(1))
|
||||
@ -95,6 +113,8 @@ CatCommand unlock_single("achievement_unlock_single", "Unlocks single achievemen
|
||||
});
|
||||
// For some reason it SEGV's when I try to GetAchievementByID();
|
||||
CatCommand lock_single("achievement_lock_single", "Locks single achievement by INDEX!", [](const CCommand &args) {
|
||||
if (!checkachmngr())
|
||||
return;
|
||||
if (args.ArgC() < 1)
|
||||
{
|
||||
logging::Info("Actually provide an index");
|
||||
@ -143,6 +163,8 @@ std::vector<Autoequip_unlock_list> equip_queue;
|
||||
|
||||
void unlock_achievements_and_accept(std::vector<int> items)
|
||||
{
|
||||
if (!checkachmngr())
|
||||
return;
|
||||
for (auto id : items)
|
||||
{
|
||||
IAchievement *ach = reinterpret_cast<IAchievement *>(g_IAchievementMgr->GetAchievementByID(id));
|
||||
|
Reference in New Issue
Block a user