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 554b77d..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)
{
@@ -391,6 +382,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 +395,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/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
+};
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
+}