From 98ee9360ed34b64ad204edf7273d249eb31a0d49 Mon Sep 17 00:00:00 2001 From: mlemlody Date: Fri, 27 Feb 2026 19:34:08 +0100 Subject: [PATCH 1/2] thanks for the tips <3 --- TextmodeTF2/src/Core/Core.cpp | 14 ++----- TextmodeTF2/src/Core/Core.h | 1 - TextmodeTF2/src/DllMain.cpp | 16 +++++--- TextmodeTF2/src/SDK/SDK.cpp | 77 ++++++++++++++++------------------- 4 files changed, 48 insertions(+), 60 deletions(-) diff --git a/TextmodeTF2/src/Core/Core.cpp b/TextmodeTF2/src/Core/Core.cpp index 554b77d..890980e 100644 --- a/TextmodeTF2/src/Core/Core.cpp +++ b/TextmodeTF2/src/Core/Core.cpp @@ -391,6 +391,9 @@ void CCore::Load() int iVPhysics = m_bVPhysicsLoaded ? 1 : LoadVPhysics(); CHECK(iVPhysics, "Failed to load vphysics") + + if (!m_bFilesystemLoaded || !m_bEngineLoaded || !m_bMatSysLoaded || !m_bClientLoaded || !m_bGameUILoaded || !m_bParticlesLoaded || !m_bMDLCacheLoaded || !m_bVideoServicesLoaded || !m_bVPhysicsLoaded) + Sleep(10); } while (!m_bFilesystemLoaded || !m_bEngineLoaded || !m_bMatSysLoaded || !m_bClientLoaded || !m_bGameUILoaded || !m_bParticlesLoaded || !m_bMDLCacheLoaded || !m_bVideoServicesLoaded || !m_bVPhysicsLoaded); @@ -401,17 +404,6 @@ void CCore::Load() } -void CCore::Loop() -{ - while (true) - { - if (m_bUnload) - break; - - Sleep(3600000); - } -} - void CCore::Unload() { U::Hooks.Unload(); diff --git a/TextmodeTF2/src/Core/Core.h b/TextmodeTF2/src/Core/Core.h index e03d96a..bb7f27f 100644 --- a/TextmodeTF2/src/Core/Core.h +++ b/TextmodeTF2/src/Core/Core.h @@ -8,7 +8,6 @@ class CCore { public: void Load(); - void Loop(); void Unload(); void AppendFailText(const char* sMessage, bool bCritical = false); diff --git a/TextmodeTF2/src/DllMain.cpp b/TextmodeTF2/src/DllMain.cpp index c15831e..f1ee445 100644 --- a/TextmodeTF2/src/DllMain.cpp +++ b/TextmodeTF2/src/DllMain.cpp @@ -6,11 +6,15 @@ DWORD WINAPI MainThread(LPVOID lpParam) { CrashLog::Initialize(lpParam); U::Core.Load(); - U::Core.Loop(); - CrashLog::Unload(); - U::Core.Unload(); - FreeLibraryAndExitThread(static_cast(lpParam), EXIT_SUCCESS); + if (U::Core.m_bUnload) + { + CrashLog::Unload(); + U::Core.Unload(); + FreeLibraryAndExitThread(static_cast(lpParam), EXIT_SUCCESS); + } + + return EXIT_SUCCESS; } @@ -18,9 +22,11 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { if (fdwReason == DLL_PROCESS_ATTACH) { + DisableThreadLibraryCalls(hinstDLL); + if (const auto hMainThread = CreateThread(nullptr, 0, MainThread, hinstDLL, 0, nullptr)) CloseHandle(hMainThread); } return TRUE; -} \ No newline at end of file +} diff --git a/TextmodeTF2/src/SDK/SDK.cpp b/TextmodeTF2/src/SDK/SDK.cpp index 2fc5c7e..28c46ea 100644 --- a/TextmodeTF2/src/SDK/SDK.cpp +++ b/TextmodeTF2/src/SDK/SDK.cpp @@ -1,4 +1,6 @@ #include "SDK.h" +#include +#include void SDK::Output(const char* cFunction, const char* cLog, bool bLogFile, int iMessageBox) { @@ -76,106 +78,95 @@ void SDK::OutputFile(const char* cOutputFileName, const char* cMsg) bool SDK::BlacklistFile(const char* cFileName) { - const static char* blacklist[] = { - ".ani", ".wav", ".mp3", ".vvd", ".vtx", ".vtf", ".vfe", ".cache", - ".jpg", ".png", ".tga", ".dds", ".vmt", // Texture and material files - ".phy", // Physics - ".dem", // Demo and log files - ".vcd", // Scene files - ".ain", // AI node graph - ".lst", // Manifests - ".pcf" // Particle systems - }; - if (!cFileName) return false; - if (!std::strncmp(cFileName, "materials/console/", 18)) - return false; + using namespace std::literals; - if (!std::strncmp(cFileName, "debug/", 6)) - return false; + static const std::unordered_set blacklist{ + ".ani"sv, ".wav"sv, ".mp3"sv, ".vvd"sv, ".vtx"sv, ".vtf"sv, ".vfe"sv, ".cache"sv, + ".jpg"sv, ".png"sv, ".tga"sv, ".dds"sv, ".vmt"sv, + ".phy"sv, ".dem"sv, ".vcd"sv, ".ain"sv, ".lst"sv, ".pcf"sv + }; - if (!std::strncmp(cFileName, "sprites/", 8)) - return true; + const std::string_view fileName{ cFileName }; - std::size_t len = std::strlen(cFileName); - if (len <= 3) + if (fileName.starts_with("materials/console/"sv) || fileName.starts_with("debug/"sv)) return false; - auto ext_p = strrchr(cFileName, '.'); - if (!ext_p) + if (fileName.starts_with("sprites/"sv)) + return true; + + const auto dot = fileName.rfind('.'); + if (dot == std::string_view::npos) return false; + const auto ext = fileName.substr(dot); // NEVER block .bsp files - they are essential for map loading - if (!std::strcmp(ext_p, ".bsp")) + if (ext == ".bsp"sv) return false; // NEVER block .nav files - navengine needs it obviosuly lol - if (!std::strcmp(ext_p, ".nav")) + if (ext == ".nav"sv) return false; // Block all particle effects during map load - if (!std::strcmp(ext_p, ".pcf")) + if (ext == ".pcf"sv) return true; // Block all soundscapes during map load - if (std::strstr(cFileName, "soundscape") && std::strcmp(ext_p, ".txt")) + if (fileName.find("soundscape"sv) != std::string_view::npos && ext != ".txt"sv) return true; // Block detail sprites and props - if (std::strstr(cFileName, "detail") || std::strstr(cFileName, "props_")) + if (fileName.find("detail"sv) != std::string_view::npos || fileName.find("props_"sv) != std::string_view::npos) return true; // Block skybox materials during map load - if (std::strstr(cFileName, "skybox")) + if (fileName.find("skybox"sv) != std::string_view::npos) return true; // Block all ambient sounds - if (std::strstr(cFileName, "ambient")) + if (fileName.find("ambient"sv) != std::string_view::npos) return true; // Block models that aren't players or essential gameplay items - if (!std::strcmp(ext_p, ".mdl")) + if (ext == ".mdl"sv) { - if (std::strstr(cFileName, "player/") || std::strstr(cFileName, "buildables/") || std::strstr(cFileName, "weapons/") || std::strstr(cFileName, "empty.mdl") || std::strstr(cFileName, "error.mdl")) + if (fileName.find("player/"sv) != std::string_view::npos || fileName.find("buildables/"sv) != std::string_view::npos || fileName.find("weapons/"sv) != std::string_view::npos || fileName.find("empty.mdl"sv) != std::string_view::npos || fileName.find("error.mdl"sv) != std::string_view::npos) return false; return true; } - if (!std::strcmp(ext_p, ".vmt")) + if (ext == ".vmt"sv) { // Only allow essential UI materials - if (!std::strstr(cFileName, "hud") && !std::strstr(cFileName, "vgui") && !std::strstr(cFileName, "console")) + if (fileName.find("hud"sv) == std::string_view::npos && fileName.find("vgui"sv) == std::string_view::npos && fileName.find("console"sv) == std::string_view::npos) return true; /* Not loading it causes extreme console spam */ - if (std::strstr(cFileName, "corner")) + if (fileName.find("corner"sv) != std::string_view::npos) return false; /* minor console spam */ - if (std::strstr(cFileName, "hud") || std::strstr(cFileName, "vgui")) + if (fileName.find("hud"sv) != std::string_view::npos || fileName.find("vgui"sv) != std::string_view::npos) return false; return true; } - if (std::strstr(cFileName, "sound.cache") || std::strstr(cFileName, "tf2_sound") || std::strstr(cFileName, "game_sounds")) + if (fileName.find("sound.cache"sv) != std::string_view::npos || fileName.find("tf2_sound"sv) != std::string_view::npos || fileName.find("game_sounds"sv) != std::string_view::npos) return false; - if (!std::strncmp(cFileName, "sound/player/footsteps", 22)) + if (fileName.starts_with("sound/player/footsteps"sv)) return false; - if (!std::strncmp(cFileName, "/decal", 6)) + if (fileName.starts_with("/decal"sv)) return true; - for (int i = 0; i < sizeof(blacklist) / sizeof(blacklist[0]); ++i) - if (!std::strcmp(ext_p, blacklist[i])) - return true; - - return false; + return blacklist.contains(ext); } double SDK::PlatFloatTime() { static auto Plat_FloatTime = U::Memory.GetModuleExport("tier0.dll", "Plat_FloatTime"); return Plat_FloatTime(); -} \ No newline at end of file +} From ba9918bfd48fa016521984b95c9db30f322ad0a3 Mon Sep 17 00:00:00 2001 From: mlemlody Date: Sat, 28 Feb 2026 09:22:13 +0100 Subject: [PATCH 2/2] for now removing all of these so it doesnt crash --- TextmodeTF2/TextmodeTF2.vcxproj | 3 +- TextmodeTF2/src/BytePatches/BytePatches.h | 33 ------------------- TextmodeTF2/src/Core/Core.cpp | 9 ----- .../Hooks/IBaseClientDLL_FrameStageNotify.cpp | 11 ------- TextmodeTF2/src/SDK/Globals.h | 3 +- 5 files changed, 2 insertions(+), 57 deletions(-) delete mode 100644 TextmodeTF2/src/Hooks/IBaseClientDLL_FrameStageNotify.cpp diff --git a/TextmodeTF2/TextmodeTF2.vcxproj b/TextmodeTF2/TextmodeTF2.vcxproj index 838e482..60551da 100644 --- a/TextmodeTF2/TextmodeTF2.vcxproj +++ b/TextmodeTF2/TextmodeTF2.vcxproj @@ -229,7 +229,6 @@ - @@ -295,4 +294,4 @@ - \ No newline at end of file + diff --git a/TextmodeTF2/src/BytePatches/BytePatches.h b/TextmodeTF2/src/BytePatches/BytePatches.h index 93f1e78..da91fa1 100644 --- a/TextmodeTF2/src/BytePatches/BytePatches.h +++ b/TextmodeTF2/src/BytePatches/BytePatches.h @@ -57,45 +57,12 @@ class CBytePatches // We patch the 'jnb' (73) to 'jmp' (EB) to skip the 30fps clamp BytePatch("engine.dll", "F3 0F 10 40 54 0F 2F 05 ?? ?? ?? ?? 73 ??", 0xC, "EB"), - // SCR_UpdateScreen - BytePatch("engine.dll", "40 55 41 54 41 56 41 57 48 8D 6C 24 ? 48 81 EC 88 00 00 00 48 8B 05 ? ? ? ? 45 33 E4 4C 89 65 ? 45 8B FC", 0x0, "31 C0 C3"), - // CEngineVGui::Simulate BytePatch("engine.dll", "41 57 48 81 EC A0 00 00 00 4C 8B F9 48 8B 0D ? ? ? ? 48 8B 01 FF 90 20 01 00 00 49 83 BF B8 00 00 00 00", 0x0, "31 C0 C3"), // CL_DecayLights BytePatch("engine.dll", "48 83 EC 48 0F 29 74 24 30 48 8D 0D ? ? ? ? 0F 29 7C 24 20 E8 ? ? ? ? 0F 28 F8 0F 57 F6 0F 2F FE 0F 86 ? ? ? ?", 0x0, "C3"), - // _Host_RunFrame -> _Host_RunFrame_Render callsite - BytePatch("engine.dll", "45 84 E4 0F 84 ? ? ? ? E8 ? ? ? ? 48 8B 05 ? ? ? ? 4C 8D 25 ? ? ? ? 4C 89 7D ? 48 8D 15", 0x9, "90 90 90 90 90"), - - // _Host_RunFrame_Sound callsite - BytePatch("engine.dll", "83 3D ? ? ? ? 06 F2 0F 11 05 ? ? ? ? 75 09 48 8D 0D ? ? ? ? EB 02 33 C9 E8 ? ? ? ? FF 15 ? ? ? ? F2 0F 10 0D", 0x1C, "90 90 90 90 90"), - - // _Host_RunFrame_Client voice gate callsite - BytePatch("engine.dll", "F3 0F 10 05 ? ? ? ? E8 ? ? ? ? E8 ? ? ? ? 84 C0 0F 84 ? ? ? ? 0F 57 C0 C6 44 24 ? 01", 0xD, "31 C0 90 90 90"), - - // _Host_RunFrame_Input -> ClientDLL_ProcessInput callsite - BytePatch("engine.dll", "FF 15 ? ? ? ? F2 0F 11 05 ? ? ? ? E8 ? ? ? ? FF 15 ? ? ? ? F2 0F 11 05 ? ? ? ? E8 ? ? ? ?", 0xE, "90 90 90 90 90"), - - // _Host_RunFrame non-threaded path -> CL_RunPrediction(PREDICTION_NORMAL) - BytePatch("engine.dll", "48 8B 01 FF 50 18 B9 01 00 00 00 E8 ? ? ? ? E8 ? ? ? ? F3 0F 10 05 ? ? ? ? E8 ? ? ? ? 48 85 F6 74 ? 45 33 C9", 0xB, "90 90 90 90 90"), - - // _Host_RunFrame threaded path -> CL_RunPrediction(PREDICTION_NORMAL) - BytePatch("engine.dll", "B9 01 00 00 00 F3 0F 10 05 ? ? ? ? F3 0F 5E 05 ? ? ? ? F3 0F 11 05 ? ? ? ? E8 ? ? ? ? E8 ? ? ? ? 48 8D 0D ? ? ? ? C6 05", 0x1D, "90 90 90 90 90"), - - // _Host_RunFrame non-threaded path -> CL_ExtraMouseUpdate - BytePatch("engine.dll", "F3 0F 10 05 ? ? ? ? E8 ? ? ? ? 48 85 F6 74 ? 45 33 C9 44 89 7C 24 20 45 33 C0 48 8B D3 48 8B CE FF 96 A8 00 00 00", 0x8, "90 90 90 90 90"), - - // _Host_RunFrame threaded path -> CL_ExtraMouseUpdate - BytePatch("engine.dll", "E8 ? ? ? ? F3 0F 11 05 ? ? ? ? E8 ? ? ? ? F2 0F 10 05 ? ? ? ? 66 0F 5A C0 44 89 35 ? ? ? ? 89 35 ? ? ? ? F3 0F 11 05", 0xD, "90 90 90 90 90"), - - // _Host_RunFrame fallback sleep path - BytePatch("engine.dll", "48 8B 05 ? ? ? ? 8B 48 58 E8 ? ? ? ? 8B 0D ? ? ? ? 85 C9 74 05 E8 ? ? ? ? E8", 0xF, "B9 01 00 00 00 90"), - - // _Host_RunFrame tick loop -> toolframework->Think callsite - BytePatch("engine.dll", "40 38 3D ? ? ? ? 75 08 0F B6 CB E8 ? ? ? ? 48 8B 0D ? ? ? ? 0F B6 D3 48 8B 01 FF 90 D8 00 00 00 F2 0F 10 0D ? ? ? ?", 0x1E, "90 90 90 90 90 90"), - // evil cathook's plan b implementation // Mod_LoadLighting diff --git a/TextmodeTF2/src/Core/Core.cpp b/TextmodeTF2/src/Core/Core.cpp index 890980e..e5c0c49 100644 --- a/TextmodeTF2/src/Core/Core.cpp +++ b/TextmodeTF2/src/Core/Core.cpp @@ -219,15 +219,6 @@ int CCore::LoadClient() if (!U::BytePatches.Initialize("client")) return LOAD_WAIT; - // IBaseClientDLL::FrameStageNotify - if (!G::IBaseClientDLL_FrameStageNotifyAddr) - { - if (auto pClient = U::Memory.FindInterface("client.dll", "VClient017")) - G::IBaseClientDLL_FrameStageNotifyAddr = reinterpret_cast(U::Memory.GetVFunc(pClient, 35)); - } - if (G::IBaseClientDLL_FrameStageNotifyAddr) - U::Hooks.Initialize("IBaseClientDLL_FrameStageNotify"); - // IPanel::PaintTraverse if (!G::IPanel_PaintTraverseAddr) { diff --git a/TextmodeTF2/src/Hooks/IBaseClientDLL_FrameStageNotify.cpp b/TextmodeTF2/src/Hooks/IBaseClientDLL_FrameStageNotify.cpp deleted file mode 100644 index a2dea9b..0000000 --- a/TextmodeTF2/src/Hooks/IBaseClientDLL_FrameStageNotify.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "../Utils/Hooks/Hooks.h" -#include "../SDK/SDK.h" - -// void IBaseClientDLL::FrameStageNotify(ClientFrameStage_t curStage) -MAKE_HOOK(IBaseClientDLL_FrameStageNotify, G::IBaseClientDLL_FrameStageNotifyAddr, void, void* rcx, ClientFrameStage_t curStage) -{ - if (curStage == FRAME_RENDER_START || curStage == FRAME_RENDER_END) - return; - - CALL_ORIGINAL(rcx, curStage); -} diff --git a/TextmodeTF2/src/SDK/Globals.h b/TextmodeTF2/src/SDK/Globals.h index 16ed412..4532fc5 100644 --- a/TextmodeTF2/src/SDK/Globals.h +++ b/TextmodeTF2/src/SDK/Globals.h @@ -37,7 +37,6 @@ namespace G inline uintptr_t SVC_GameEvent_ProcessAddr{}; inline uintptr_t SVC_Sounds_ProcessAddr{}; inline uintptr_t SVC_BSPDecal_ProcessAddr{}; - inline uintptr_t IBaseClientDLL_FrameStageNotifyAddr{}; inline uintptr_t IPanel_PaintTraverseAddr{}; inline uintptr_t IStudioRender_DrawModelAddr{}; inline uintptr_t IStudioRender_DrawModelStaticPropAddr{}; @@ -47,4 +46,4 @@ inline uintptr_t SVC_BSPDecal_ProcessAddr{}; inline uintptr_t IStudioRender_AddShadowAddr{}; inline uintptr_t IStudioRender_DrawModelArrayAddr{}; inline IMDLCache* IMDLCache{}; -}; \ No newline at end of file +};