diff --git a/r5dev/bsplib/bsplib.cpp b/r5dev/bsplib/bsplib.cpp index bf8bbc3a..56c703b5 100644 --- a/r5dev/bsplib/bsplib.cpp +++ b/r5dev/bsplib/bsplib.cpp @@ -1,17 +1,25 @@ #include "core/stdafx.h" #include "tier1/cvar.h" +#include "datacache/mdlcache.h" #include "common/pseudodefs.h" -#include "bsplib/bsplib.h" +#include "materialsystem/cmaterialglue.h" #include "engine/host_state.h" #include "engine/modelloader.h" +#include "bsplib/bsplib.h" + +struct CStaticPropMaterialGlue +{ + void* m_pVTable0; + void* m_pVTable1; +}; //----------------------------------------------------------------------------- // Purpose: calculates the view frustum culling data per static prop //----------------------------------------------------------------------------- -__int64 __fastcall HCalcPropStaticFrustumCulling(__int64 a1, __int64 a2, unsigned int a3, unsigned int a4, __int64 a5, __int64 a6, __int64 a7) +__int64 __fastcall BuildPropStaticFrustumCullMap(__int64 a1, __int64 a2, unsigned int a3, unsigned int a4, __int64 a5, __int64 a6, __int64 a7) { if (staticProp_defaultBuildFrustum->GetBool()) - return CalcPropStaticFrustumCulling(a1, a2, a3, a4, a5, a6, a7); + return v_BuildPropStaticFrustumCullMap(a1, a2, a3, a4, a5, a6, a7); float v9; // xmm6_4 char v10; // r13 @@ -89,22 +97,6 @@ __int64 __fastcall HCalcPropStaticFrustumCulling(__int64 a1, __int64 a2, unsigne __int64 v84; // [rsp+298h] [rbp+190h] __int64 v85; // [rsp+2A8h] [rbp+1A0h] - static auto g_MdlCache = CMemory(0x14D40B328).RCast(); - static auto dword_1696A9D20 = *CMemory(0x1696A9D20).RCast(); - static auto sub_1404365A0 = CMemory(0x1404365A0).RCast(); - static auto qword_141744EA8 = *CMemory(0x141744EA8).RCast(); - static auto sub_140270130 = CMemory(0x140270130).RCast<__m128(*)(__m128*)>(); - static auto off_141731448 = CMemory(0x141731448).RCast(); - static auto sub_14028F170 = CMemory(0x14028F170).RCast(); - static auto qword_141744EA0 = *CMemory(0x141744EA0).RCast(); - static auto dword_141744EBC = *CMemory(0x141744EBC).RCast(); - static auto qword_141744E88 = *CMemory(0x141744E88).RCast(); - static auto dword_141744EE8 = *CMemory(0x141744EE8).RCast(); - static auto off_141744E70 = CMemory(0x141744E70).RCast(); - static auto sub_1401E7900 = CMemory(0x1401E7900).RCast<__int64(*)(void*, unsigned __int16, __int64)>(); - static auto sub_140257F20 = CMemory(0x140257F20).RCast<__int64(*)(void*, __int64, __m128i*, __int8*)>(); - static auto sub_1401E7080 = CMemory(0x1401E7080).RCast<__int64(*)(void*, unsigned __int16 a2)>(); - v9 = 1.0; v10 = a4; *(_QWORD*)(a1 + 20) = *(_QWORD*)a5; @@ -115,10 +107,10 @@ __int64 __fastcall HCalcPropStaticFrustumCulling(__int64 a1, __int64 a2, unsigne *(float*)(a1 + 12) = 1.0 / (float)(*(float*)&v11 * *(float*)&v11); v13 = *(unsigned __int16*)(a7 + 320); *(_WORD*)a1 = v13; - v14 = sub_1401E7900(g_MdlCache, v13, 0i64); + v14 = (__int64)CMDLCache::FindMDL(g_MDLCache, v13, 0i64); v84 = v14; - if ((*(_BYTE*)(v14 + 156) & 0x10) == 0 && dword_1696A9D20 < 100) - ++dword_1696A9D20; + if ((*(_BYTE*)(v14 + 156) & 0x10) == 0 && *dword_1696A9D20 < 100) + ++*dword_1696A9D20; v15 = *(_BYTE*)(a5 + 30); if (v15 > 2u && (unsigned __int8)(v15 - 6) > 2u) { @@ -157,12 +149,12 @@ __int64 __fastcall HCalcPropStaticFrustumCulling(__int64 a1, __int64 a2, unsigne v21 = *(_WORD*)(a5 + 34); *(_WORD*)(a1 + 2) = v21; sub_1404365A0(v77, (const __m128i*)a5, (unsigned int*)(a5 + 12), v11); - v22 = qword_141744EA8; + v22 = *qword_141744EA8; v23 = v77[0]; v24 = v77[1]; v25 = v77[2]; v26 = (unsigned __int64)(unsigned int)v12 << 6; - *(__m128*)(v26 + qword_141744EA8) = v77[0]; + *(__m128*)(v26 + *qword_141744EA8) = v77[0]; *(__m128*)(v26 + v22 + 16) = v24; *(__m128*)(v26 + v22 + 32) = v25; auto m1 = _mm_set_ps(0.003922, 0.003922, 0.003922, 0.003922); @@ -170,43 +162,43 @@ __int64 __fastcall HCalcPropStaticFrustumCulling(__int64 a1, __int64 a2, unsigne __m128i m3 = { 0 }; v74 = _mm_mul_ps(_mm_cvtepi32_ps(_mm_unpacklo_epi16(_mm_unpacklo_epi8(_mm_cvtsi32_si128(*(_DWORD*)(a5 + 52)), m2), m3)), m1); v27 = sub_140270130(&v74); - *(__m128*)(v26 + qword_141744EA8 + 48) = v27; + *(__m128*)(v26 + *qword_141744EA8 + 48) = v27; sub_140257F20(&off_141731448, a7, &v71, &v71.m128i_i8[12]); sub_14028F170((__int64)&v74, (__int64)&v74.m128_i64[1] + 4, v77, &v71, (const __m128i*) & v71.m128i_i8[12]); v72 = v71.m128i_i8[12]; // may be wrong - v28 = qword_141744EA0; + v28 = *qword_141744EA0; v29 = 3 * v12; v75 = (__int64)&v74.m128_i64[1] + 4; // may be wrong. v30 = v75; - *(__m128*)(qword_141744EA0 + 8 * v29) = v74; + *(__m128*)(*qword_141744EA0 + 8 * v29) = v74; *(_QWORD*)(v28 + 8 * v29 + 16) = v30; if ((v10 & 1) != 0) { - v31 = dword_141744EBC; + v31 = *dword_141744EBC; v32 = v71; *(_DWORD*)a2 = *(_DWORD*)(a6 + 48); *(_DWORD*)(a2 + 4) = *(_DWORD*)(a6 + 52); *(_QWORD*)(a2 + 8) = 0i64; v33 = 3i64 * (unsigned int)(v31 + v12); v34 = (unsigned __int64)(unsigned int)(v31 + v12) << 6; - v35 = qword_141744EA0; - *(__m128i*)(qword_141744EA0 + 8 * v33) = v32; + v35 = *qword_141744EA0; + *(__m128i*)(*qword_141744EA0 + 8 * v33) = v32; *(_QWORD*)(v35 + 8 * v33 + 16) = v72; - v36 = qword_141744EA8; + v36 = *qword_141744EA8; v37 = (unsigned __int64)(unsigned int)(v12 + 2 * v31) << 6; - *(__m128*)(v34 + qword_141744EA8) = v23; + *(__m128*)(v34 + *qword_141744EA8) = v23; *(__m128*)(v34 + v36 + 16) = v24; *(__m128*)(v34 + v36 + 32) = v25; - *(__m128*)(v34 + qword_141744EA8 + 48) = v27; - v38 = qword_141744EA8; - *(__m128*)(v37 + qword_141744EA8) = v23; + *(__m128*)(v34 + *qword_141744EA8 + 48) = v27; + v38 = *qword_141744EA8; + *(__m128*)(v37 + *qword_141744EA8) = v23; *(__m128*)(v37 + v38 + 16) = v24; *(__m128*)(v37 + v38 + 32) = v25; - *(__m128*)(v37 + qword_141744EA8 + 48) = v27; + *(__m128*)(v37 + *qword_141744EA8 + 48) = v27; v39 = (unsigned __int64)(unsigned int)(v31 + v12 + 2 * v31) << 6; - *(__m128*)(v39 + qword_141744EA8 + 48) = v27; - v40 = qword_141744EA8; - *(__m128*)(v39 + qword_141744EA8) = *(__m128*)a6; //*(_OWORD*)(v39 + qword_141744EA8) = *(_OWORD*)a6; + *(__m128*)(v39 + *qword_141744EA8 + 48) = v27; + v40 = *qword_141744EA8; + *(__m128*)(v39 + *qword_141744EA8) = *(__m128*)a6; //*(_OWORD*)(v39 + qword_141744EA8) = *(_OWORD*)a6; *(__m128*)(v39 + v40 + 16) = *(__m128*)(a6 + 16); //*(_OWORD*)(v39 + v40 + 16) = *(_OWORD*)(a6 + 16); *(__m128*)(v39 + v40 + 32) = *(__m128*)(a6 + 32); //*(__m128*)(v40 + v41 + 32) = *(__m128*)(a6 + 32); } @@ -252,17 +244,17 @@ __int64 __fastcall HCalcPropStaticFrustumCulling(__int64 a1, __int64 a2, unsigne v48 = (unsigned int)(_mm_cvtsi128_si32(v47) - 1065351168) >> 12; } *(_WORD*)(a1 + 6) = v48; - v49 = *(float*)(qword_141744EA0 + 24 * ((unsigned __int64)*(unsigned int*)(a1 + 8) >> 1) + 8) - *(float*)(qword_141744EA0 + 24 * ((unsigned __int64)*(unsigned int*)(a1 + 8) >> 1) + 20); - v50 = *(float*)(qword_141744EA0 + 24 * ((unsigned __int64)*(unsigned int*)(a1 + 8) >> 1) + 4) - *(float*)(qword_141744EA0 + 24 * ((unsigned __int64)*(unsigned int*)(a1 + 8) >> 1) + 16); - v51 = *(float*)(qword_141744EA0 + 24 * ((unsigned __int64)*(unsigned int*)(a1 + 8) >> 1)) - *(float*)(qword_141744EA0 + 24 * ((unsigned __int64)*(unsigned int*)(a1 + 8) >> 1) + 12); + v49 = *(float*)(*qword_141744EA0 + 24 * ((unsigned __int64)*(unsigned int*)(a1 + 8) >> 1) + 8) - *(float*)(*qword_141744EA0 + 24 * ((unsigned __int64)*(unsigned int*)(a1 + 8) >> 1) + 20); + v50 = *(float*)(*qword_141744EA0 + 24 * ((unsigned __int64)*(unsigned int*)(a1 + 8) >> 1) + 4) - *(float*)(*qword_141744EA0 + 24 * ((unsigned __int64)*(unsigned int*)(a1 + 8) >> 1) + 16); + v51 = *(float*)(*qword_141744EA0 + 24 * ((unsigned __int64)*(unsigned int*)(a1 + 8) >> 1)) - *(float*)(*qword_141744EA0 + 24 * ((unsigned __int64)*(unsigned int*)(a1 + 8) >> 1) + 12); v52 = (float)((float)(v50 * v50) + (float)(v51 * v51)) + (float)(v49 * v49); if (v44 >= 227023.363449684) v9 = g_pCVar->FindVar("staticProp_no_fade_scalar")->GetFloat(); v53 = 0; - *(float*)(qword_141744E88 + 8i64 * a3) = v9 * (float)(1.0 / (float)(v52 * g_pCVar->FindVar("staticProp_gather_size_weight")->GetFloat())); - *(_BYTE*)(qword_141744E88 + 8i64 * a3 + 4) &= 0xFEu; - *(_BYTE*)(qword_141744E88 + 8i64 * a3 + 4) |= v44 >= 227023.363449684; - v55 = sub_1401E7080(g_MdlCache, *(unsigned __int16*)(a7 + 320)); // Gets some object containing pointer to 2 CMaterialGlue vtables. + *(float*)(*qword_141744E88 + 8i64 * a3) = v9 * (float)(1.0 / (float)(v52 * g_pCVar->FindVar("staticProp_gather_size_weight")->GetFloat())); + *(_BYTE*)(*qword_141744E88 + 8i64 * a3 + 4) &= 0xFEu; + *(_BYTE*)(*qword_141744E88 + 8i64 * a3 + 4) |= v44 >= 227023.363449684; + v55 = (__int64)CMDLCache::GetStudioMaterialGlue(g_MDLCache, *(unsigned __int16*)(a7 + 320)); // Gets some object containing pointer to 2 CMaterialGlue vtables. v56 = *(unsigned __int16*)(a5 + 0x20); v76 = *(__int64*)v55; v57 = v84 + *(int*)(v84 + 232) + 2i64 * v56 * *(_DWORD*)(v84 + 224); @@ -295,31 +287,35 @@ __int64 __fastcall HCalcPropStaticFrustumCulling(__int64 a1, __int64 a2, unsigne do { v68 = *(void**)(v66 + 8i64 * *(__int16*)(v57 + 2i64 * *(int*)(v67 + *(int*)(v65 + 80) + v65))); - if (!(*(unsigned __int8(__fastcall**)(void*))(*(_QWORD*)v68 + 688i64))(v68)) + + if (v68 > (void*)0x160000000 && v68 < (void*)0x180000000) // ??? HACK ??? CHANGE ASAP ??? { - if (!(*(unsigned __int8(__fastcall**)(void*))(*(_QWORD*)v68 + 256i64))(v68) && (*(unsigned __int8(__fastcall**)(void*))(*(_QWORD*)v68 + 248i64))(v68)) + if (!(*(unsigned __int8(__fastcall**)(void*))(*(_QWORD*)v68 + 688i64))(v68)) { - v69 = 0i64; - if (dword_141744EE8) + if (!(*(unsigned __int8(__fastcall**)(void*))(*(_QWORD*)v68 + 256i64))(v68) && (*(unsigned __int8(__fastcall**)(void*))(*(_QWORD*)v68 + 248i64))(v68)) { - while (*(&off_141744E70 + v69 + 16) != v68) + v69 = 0i64; + if (*dword_141744EE8) { - v69 = (unsigned int)(v69 + 1); - if ((unsigned int)v69 >= dword_141744EE8) - goto LABEL_42; + while (*(&off_141744E70 + v69 + 16) != v68) + { + v69 = (unsigned int)(v69 + 1); + if ((unsigned int)v69 >= *dword_141744EE8) + goto LABEL_42; + } + } + else + { + LABEL_42: + *(&off_141744E70 + (unsigned int)*dword_141744EE8++ + 16) = v68; } } - else - { - LABEL_42: - *(&off_141744E70 + (unsigned int)dword_141744EE8++ + 16) = v68; - } + if ((*(unsigned __int8(__fastcall**)(void*))(*(_QWORD*)v68 + 168i64))(v68) && (*(unsigned int(__fastcall**)(void*, __int64))(*(_QWORD*)v68 + 144i64))(v68, 1i64)) + *(_BYTE*)(a1 + 5) |= 0x80u; + if (!(*(unsigned __int8(__fastcall**)(void*))(*(_QWORD*)v68 + 384i64))(v68) && (*(unsigned int(__fastcall**)(void*, __int64))(*(_QWORD*)v68 + 144i64))(v68, 21844i64)) + v53 |= 2u; + v53 |= (*(unsigned __int8(__fastcall**)(void*))(*(_QWORD*)v68 + 384i64))(v68) != 0; } - if ((*(unsigned __int8(__fastcall**)(void*))(*(_QWORD*)v68 + 168i64))(v68) && (*(unsigned int(__fastcall**)(void*, __int64))(*(_QWORD*)v68 + 144i64))(v68, 1i64)) - *(_BYTE*)(a1 + 5) |= 0x80u; - if (!(*(unsigned __int8(__fastcall**)(void*))(*(_QWORD*)v68 + 384i64))(v68) && (*(unsigned int(__fastcall**)(void*, __int64))(*(_QWORD*)v68 + 144i64))(v68, 21844i64)) - v53 |= 2u; - v53 |= (*(unsigned __int8(__fastcall**)(void*))(*(_QWORD*)v68 + 384i64))(v68) != 0; } v57 = v85; ++v64; @@ -350,10 +346,10 @@ __int64 __fastcall HCalcPropStaticFrustumCulling(__int64 a1, __int64 a2, unsigne void BspLib_Attach() { - DetourAttach((LPVOID*)&CalcPropStaticFrustumCulling, &HCalcPropStaticFrustumCulling); + DetourAttach((LPVOID*)&v_BuildPropStaticFrustumCullMap, &BuildPropStaticFrustumCullMap); } void BspLib_Detach() { - DetourDetach((LPVOID*)&CalcPropStaticFrustumCulling, &HCalcPropStaticFrustumCulling); + DetourDetach((LPVOID*)&v_BuildPropStaticFrustumCullMap, &BuildPropStaticFrustumCullMap); } diff --git a/r5dev/bsplib/bsplib.h b/r5dev/bsplib/bsplib.h index 8a056060..27eb44c7 100644 --- a/r5dev/bsplib/bsplib.h +++ b/r5dev/bsplib/bsplib.h @@ -1,50 +1,76 @@ #pragma once -namespace -{ - //static auto g_CModelLoader = CMemory(0x14173B210).RCast(); - //static auto dword_1696A9D20 = CMemory(0x14D40B328).RCast(); - //static auto dword_141744EE8 = CMemory(0x141744EE8).RCast(); - //static auto dword_141744EBC = CMemory(0x141744EBC).RCast(); +inline CMemory p_BuildPropStaticFrustumCullMap; +inline auto v_BuildPropStaticFrustumCullMap = p_BuildPropStaticFrustumCullMap.RCast<__int64(*)(__int64 a1, __int64 a2, unsigned int a3, unsigned int a4, __int64 a5, __int64 a6, __int64 a7)>(); - //static auto qword_14D40B328 = CMemory(0x14D40B328).RCast(); - //static auto qword_141744EA8 = CMemory(0x141744EA8).RCast(); - //static auto qword_141744EA0 = CMemory(0x141744EA0).RCast(); - //static auto qword_141744E88 = CMemory(0x141744E88).RCast(); +inline void** (*sub_1404365A0)(__m128*, const __m128i*, unsigned int*, double); +inline __m128 (*sub_140270130)(__m128*); +inline const __m128i* (*sub_14028F170)(__int64, __int64, __m128*, const __m128i*, const __m128i*); +inline int64_t(*sub_140257F20)(void*, __int64, __m128i*, __int8*); - //static auto off_141744E70 = CMemory(0x141744E70).RCast(); - //static auto off_141731448 = CMemory(0x141744EA8).RCast(); +inline uint32_t* dword_1696A9D20; +inline int32_t* dword_141744EBC; +inline int32_t* dword_141744EE8; - //__m128 xmmword_1415BD270 = _mm_castsi128_ps(_mm_set_epi32(0x3B808081, 0x3B808081, 0x3B808081, 0x3B808081)); // xmmword_1415BD270 +inline int64_t* qword_141744EA8; +inline int64_t* qword_141744EA0; +inline uint64_t* qword_141744E88; - //static auto sub_1404365A0 = CMemory(0x1404365A0).RCast(); // Prototype is most likely incorrect: 'local variable allocation has failed, the output may be wrong!' - //static auto sub_140270130 = CMemory(0x140270130).RCast<__m128 (*)(__m128*)>(); - //static auto sub_14028F170 = CMemory(0x14028F170).RCast(); -} +inline void* off_141744E70; +inline void* off_141731448; -inline CMemory p_CalcPropStaticFrustumCulling; -inline auto CalcPropStaticFrustumCulling = p_CalcPropStaticFrustumCulling.RCast<__int64(*)(__int64 a1, __int64 a2, unsigned int a3, unsigned int a4, __int64 a5, __int64 a6, __int64 a7)>(); - -__int64 __fastcall HCalcPropStaticFrustumCulling(__int64 a1, __int64 a2, unsigned int a3, unsigned int a4, __int64 a5, __int64 a6, __int64 a7); +__int64 __fastcall BuildPropStaticFrustumCullMap(__int64 a1, __int64 a2, unsigned int a3, unsigned int a4, __int64 a5, __int64 a6, __int64 a7); void BspLib_Attach(); void BspLib_Detach(); - /////////////////////////////////////////////////////////////////////////////// class HBspLib : public IDetour { virtual void GetAdr(void) const { - std::cout << "| FUN: CalcPropStaticFrustumCulling : 0x" << std::hex << std::uppercase << p_CalcPropStaticFrustumCulling.GetPtr() << std::setw(nPad) << " |" << std::endl; + std::cout << "| FUN: BuildPropStaticFrustumCullMap : 0x" << std::hex << std::uppercase << p_BuildPropStaticFrustumCullMap.GetPtr() << std::setw(nPad) << " |" << std::endl; + std::cout << "| FUN: sub_1404365A0 : 0x" << std::hex << std::uppercase << sub_1404365A0 << std::setw(0) << " |" << std::endl; + std::cout << "| FUN: sub_140270130 : 0x" << std::hex << std::uppercase << sub_140270130 << std::setw(0) << " |" << std::endl; + std::cout << "| FUN: sub_14028F170 : 0x" << std::hex << std::uppercase << sub_14028F170 << std::setw(0) << " |" << std::endl; + std::cout << "| FUN: sub_140257F20 : 0x" << std::hex << std::uppercase << sub_140257F20 << std::setw(0) << " |" << std::endl; + std::cout << "| VAR: dword_1696A9D20 : 0x" << std::hex << std::uppercase << dword_1696A9D20 << std::setw(0) << " |" << std::endl; + std::cout << "| VAR: dword_141744EBC : 0x" << std::hex << std::uppercase << dword_141744EBC << std::setw(0) << " |" << std::endl; + std::cout << "| VAR: dword_141744EE8 : 0x" << std::hex << std::uppercase << dword_141744EE8 << std::setw(0) << " |" << std::endl; + std::cout << "| VAR: qword_141744EA8 : 0x" << std::hex << std::uppercase << qword_141744EA8 << std::setw(0) << " |" << std::endl; + std::cout << "| VAR: qword_141744EA0 : 0x" << std::hex << std::uppercase << qword_141744EA0 << std::setw(0) << " |" << std::endl; + std::cout << "| VAR: qword_141744E88 : 0x" << std::hex << std::uppercase << qword_141744E88 << std::setw(0) << " |" << std::endl; + std::cout << "| VAR: off_141744E70 : 0x" << std::hex << std::uppercase << off_141744E70 << std::setw(0) << " |" << std::endl; + std::cout << "| VAR: off_141731448 : 0x" << std::hex << std::uppercase << off_141731448 << std::setw(0) << " |" << std::endl; std::cout << "+----------------------------------------------------------------+" << std::endl; } virtual void GetFun(void) const { - p_CalcPropStaticFrustumCulling = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x8B\xC4\x44\x89\x40\x18\x48\x89\x50\x10\x55"), "xxxxxxxxxxxx"); /*48 8B C4 44 89 40 18 48 89 50 10 55*/ - CalcPropStaticFrustumCulling = p_CalcPropStaticFrustumCulling.RCast<__int64(*)(__int64, __int64, unsigned int, unsigned int, __int64, __int64, __int64)>(); + p_BuildPropStaticFrustumCullMap = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x8B\xC4\x44\x89\x40\x18\x48\x89\x50\x10\x55"), "xxxxxxxxxxxx"); /*48 8B C4 44 89 40 18 48 89 50 10 55*/ + v_BuildPropStaticFrustumCullMap = p_BuildPropStaticFrustumCullMap.RCast<__int64(*)(__int64, __int64, unsigned int, unsigned int, __int64, __int64, __int64)>(); + + sub_1404365A0 = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x8B\xC4\x48\x83\xEC\x78\xF3\x41\x0F\x10\x48\x00"), "xxxxxxxxxxxx?").RCast(); + sub_140270130 = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x83\xEC\x28\x66\x0F\x6F\x15\x00\x00\x00\x00"), "xxxxxxxx????").RCast<__m128(*)(__m128*)>(); + sub_14028F170 = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x83\xEC\x58\xF3\x41\x0F\x7E\x11"), "xxxxxxxxx").RCast(); + sub_140257F20 = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x57\x48\x83\xEC\x20\x49\x8B\xD9\x49\x8B\xF8\x48\x85\xD2"), "xxxx?xxxxxxxxxxxxxx").RCast<__int64(*)(void*, __int64, __m128i*, __int8*)>(); + } + virtual void GetVar(void) const + { + dword_1696A9D20 = p_BuildPropStaticFrustumCullMap.FindPattern("89 0D").ResolveRelativeAddressSelf(0x2, 0x6).RCast(); + dword_141744EBC = p_BuildPropStaticFrustumCullMap.Offset(0x200).FindPattern("44 8B").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); + dword_141744EE8 = p_BuildPropStaticFrustumCullMap.Offset(0x550).FindPattern("8B 15").ResolveRelativeAddressSelf(0x2, 0x6).RCast(); + + qword_141744EA8 = p_BuildPropStaticFrustumCullMap.Offset(0x150).FindPattern("48 8B").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); + qword_141744EA0 = p_BuildPropStaticFrustumCullMap.Offset(0x220).FindPattern("48 8B").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); + qword_141744E88 = p_BuildPropStaticFrustumCullMap.Offset(0x4E0).FindPattern("48 8B").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); + + off_141744E70 = p_BuildPropStaticFrustumCullMap.Offset(0x550).FindPattern("4C 8D").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); +#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) + off_141731448 = p_CalcPropStaticFrustumCulling.Offset(0x1F0).FindPattern("48 ?? ?? ?? ?? ?? 01").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); +#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) + off_141731448 = p_BuildPropStaticFrustumCullMap.Offset(0x200).FindPattern("48 ?? ?? ?? ?? ?? 01").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); +#endif } - virtual void GetVar(void) const { } virtual void GetCon(void) const { } virtual void Attach(void) const { } virtual void Detach(void) const { } diff --git a/r5dev/common/opcodes.cpp b/r5dev/common/opcodes.cpp index 1171ba06..f73cff57 100644 --- a/r5dev/common/opcodes.cpp +++ b/r5dev/common/opcodes.cpp @@ -354,42 +354,3 @@ void RuntimePtc_Init() /* .TEXT */ Server_S2C_CONNECT_1.Offset(0x7).Patch({ 0xEB }); // JZ --> JMP | Prevent entitlement check to kick player from server on S2C_CONNECT Packet if it does not match the servers one. #endif // !CLIENT_DLL } - -void RuntimePtc_Toggle() /* .TEXT */ -{ -#ifdef GAMEDLL_S3 - static bool g_nop = true; - - if (g_nop) - { - //------------------------------------------------------------------------- - // CALL --> NOP | Allow some maps to be loaded by nopping out a call in LoadProp function - dst007.Offset(0x5E8).Patch({ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - //------------------------------------------------------------------------- - // CALL --> NOP | Disable the viewmodel rendered to avoid a crash from a certain entity in desertlands_mu1 - //dst008.Offset(0x67).Patch({ 0x90, 0x90, 0x90, 0x90, 0x90 }); - - printf("\n"); - printf("+--------------------------------------------------------+\n"); - printf("|>>>>>>>>>>>>>>| TEXT OPCODES OVERWRITTEN |<<<<<<<<<<<<<<|\n"); - printf("+--------------------------------------------------------+\n"); - printf("\n"); - } - else - { - //------------------------------------------------------------------------- - // NOP --> CALL | Recover function DST007 - dst007.Offset(0x5E8).Patch({ 0x48, 0x8B, 0x03, 0xFF, 0x90, 0xB0, 0x02, 0x00, 0x00, 0x84, 0xC0 }); - //------------------------------------------------------------------------- - // NOP --> CALL | Recover function DST008 - //dst008.Offset(0x67).Patch({ 0xE8, 0x54, 0xD8, 0xFF, 0xFF }); - - printf("\n"); - printf("+--------------------------------------------------------+\n"); - printf("|>>>>>>>>>>>>>>>| TEXT OPCODES RECOVERED |<<<<<<<<<<<<<<<|\n"); - printf("+--------------------------------------------------------+\n"); - printf("\n"); - } - g_nop = !g_nop; -#endif // GAMEDLL_S3 -} diff --git a/r5dev/common/opcodes.h b/r5dev/common/opcodes.h index 8c7086eb..e1c1cceb 100644 --- a/r5dev/common/opcodes.h +++ b/r5dev/common/opcodes.h @@ -8,7 +8,6 @@ inline const char* g_szGameDll = "r5apex.exe"; #endif // DEDICATED void RuntimePtc_Init(); -void RuntimePtc_Toggle(); #ifdef GAMEDLL_S3 /* -------------- OTHER ------------------------------------------------------------------------------------------------------------------------------------------------- */ inline CMemory dst007; diff --git a/r5dev/datacache/mdlcache.cpp b/r5dev/datacache/mdlcache.cpp index 6fcd6cae..78a0194f 100644 --- a/r5dev/datacache/mdlcache.cpp +++ b/r5dev/datacache/mdlcache.cpp @@ -127,13 +127,20 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, vo bool v16; // zf studiohdr_t* v17; // rdi studiohdr_t** v18; // rax - bool bOldModel {}; + bool bOldModel {}; + bool bInvalidHandle{}; CThreadFastMutex::WaitForLock((CThreadFastMutex*)a3 + 0x80); EnterCriticalSection(reinterpret_cast(&*m_MDLMutex)); void* modelCache = cache->m_pModelCacheSection; v8 = (const char*)(*(_QWORD*)((int64)modelCache + 24 * static_cast(handle) + 8)); LeaveCriticalSection(reinterpret_cast(&*m_MDLMutex)); + if (IsBadReadPtrV2((void*)v8)) + { + bInvalidHandle = true; + goto LABEL_ERROR; + } + v9 = -1i64; do ++v9; @@ -163,15 +170,17 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, vo LABEL_ERROR: if (std::find(g_vBadMDLHandles.begin(), g_vBadMDLHandles.end(), handle) == g_vBadMDLHandles.end()) { - if (!bOldModel) + if (bInvalidHandle) + Error(eDLL_T::ENGINE, "Model with handle \"hu\" not found; replacing with \"%s\".\n", handle, ERROR_MODEL); + else if (bOldModel) + Error(eDLL_T::ENGINE, "Attempted to load old model \"%s\"; replace with rmdl.\n", v8); + else { if (g_pMDLFallback->m_hErrorMDL) Error(eDLL_T::ENGINE, "Model \"%s\" not found; replacing with \"%s\".\n", v8, ERROR_MODEL); else Error(eDLL_T::ENGINE, "Model \"%s\" not found and \"%s\" couldn't be loaded.\n", v8, ERROR_MODEL); } - else - Error(eDLL_T::ENGINE, "Attempted to load old model \"%s\"; replace with rmdl.\n", v8); g_vBadMDLHandles.push_back(handle); } @@ -265,6 +274,24 @@ CStudioHWDataRef* CMDLCache::GetStudioHardwareRef(CMDLCache* cache, MDLHandle_t return reinterpret_cast(result); } +//----------------------------------------------------------------------------- +// Purpose: gets the studio material glue from cache pool by handle +// Input : *this - +// handle - +// Output : a pointer to the CMaterialGlue object +//----------------------------------------------------------------------------- +void* CMDLCache::GetStudioMaterialGlue(CMDLCache* cache, MDLHandle_t handle) +{ + __int64 v2; // rbx + __int64 v3; // rbx + + v2 = handle; + EnterCriticalSection(reinterpret_cast(&*m_MDLMutex)); + v3 = *(_QWORD*)(m_MDLDict.Deref().GetPtr() + 24 * v2 + 16); + LeaveCriticalSection(reinterpret_cast(&*m_MDLMutex)); + return (char*)v3 + 40; +} + void MDLCache_Attach() { DetourAttach((LPVOID*)&v_CMDLCache__FindMDL, &CMDLCache::FindMDL); diff --git a/r5dev/datacache/mdlcache.h b/r5dev/datacache/mdlcache.h index 23895126..9b1169f6 100644 --- a/r5dev/datacache/mdlcache.h +++ b/r5dev/datacache/mdlcache.h @@ -45,6 +45,7 @@ public: static studiohdr_t* FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, void* a3, void* a4); static studiohdr_t* GetStudioHDR(CMDLCache* cache, MDLHandle_t handle); static CStudioHWDataRef* GetStudioHardwareRef(CMDLCache* cache, MDLHandle_t handle); + static void* GetStudioMaterialGlue(CMDLCache* cache, MDLHandle_t handle); CMDLCache* m_pVTable; void* m_pStrCmp; // string compare func; diff --git a/r5dev/materialsystem/cmaterialglue.h b/r5dev/materialsystem/cmaterialglue.h index 71f473ac..9ad3fce0 100644 --- a/r5dev/materialsystem/cmaterialglue.h +++ b/r5dev/materialsystem/cmaterialglue.h @@ -45,6 +45,8 @@ public: static_assert(sizeof(CMaterialGlue) == 0x130); #pragma pack(pop) +inline void* g_pMaterialGlueVTable = nullptr;; + /* ==== CMATERIALGLUE ================================================================================================================================================== */ inline CMemory p_GetMaterialAtCrossHair; inline auto GetMaterialAtCrossHair = p_GetMaterialAtCrossHair.RCast(); @@ -57,6 +59,7 @@ class HCMaterialGlue : public IDetour virtual void GetAdr(void) const { std::cout << "| FUN: CMaterialGlue::GetMaterialAtCrossHair: 0x" << std::hex << std::uppercase << p_GetMaterialAtCrossHair.GetPtr() << std::setw(nPad) << " |" << std::endl; + std::cout << "| CON: g_pMaterialGlueVTable : 0x" << std::hex << std::uppercase << g_pMaterialGlueVTable << std::setw(0) << " |" << std::endl; std::cout << "+----------------------------------------------------------------+" << std::endl; } virtual void GetFun(void) const @@ -65,7 +68,11 @@ class HCMaterialGlue : public IDetour GetMaterialAtCrossHair = p_GetMaterialAtCrossHair.RCast(); /*48 8B C4 48 83 EC 58 48 83 3D ? ? ? ? ?*/ } virtual void GetVar(void) const { } - virtual void GetCon(void) const { } + virtual void GetCon(void) const + { + g_pMaterialGlueVTable = g_mGameDll.FindPatternSIMD(reinterpret_cast("\xB9\x00\x00\x00\x00\x48\x8D\x05\x00\x00\x00\x00\x48\x8D\x15\x00\x00\x00\x00"), "x????xxx????xxx????") + .FindPatternSelf("48 8D ?? ?? ?? ?? 01").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); /*B9 ? ? ? ? 48 8D 05 ? ? ? ? 48 8D 15 ? ? ? ?*/ + } virtual void Attach(void) const { } virtual void Detach(void) const { } }; diff --git a/r5dev/tier1/IConVar.cpp b/r5dev/tier1/IConVar.cpp index 68966f3a..2303fa19 100644 --- a/r5dev/tier1/IConVar.cpp +++ b/r5dev/tier1/IConVar.cpp @@ -47,7 +47,7 @@ void ConVar::Init(void) const { //------------------------------------------------------------------------- // ENGINE | - staticProp_defaultBuildFrustum = new ConVar("staticProp_defaultBuildFrustum", "0", FCVAR_DEVELOPMENTONLY, "Use the old solution for building static prop frustum culling map.", false, 0.f, false, 0.f, nullptr, nullptr);; + staticProp_defaultBuildFrustum = new ConVar("staticProp_defaultBuildFrustum", "0", FCVAR_DEVELOPMENTONLY, "Use the old solution for building static prop frustum culling.", false, 0.f, false, 0.f, nullptr, nullptr);; cm_debug_cmdquery = new ConVar("cm_debug_cmdquery" , "0", FCVAR_DEVELOPMENTONLY, "Prints the flags of each ConVar/ConCommand query to the console ( !slower! ).", false, 0.f, false, 0.f, nullptr, nullptr); cm_unset_all_cmdquery = new ConVar("cm_unset_all_cmdquery" , "0", FCVAR_DEVELOPMENTONLY | FCVAR_REPLICATED, "Returns false on every ConVar/ConCommand query ( !warning! ).", false, 0.f, false, 0.f, nullptr, nullptr); diff --git a/r5dev/windows/console.cpp b/r5dev/windows/console.cpp index b6b86cde..89ad2ba1 100644 --- a/r5dev/windows/console.cpp +++ b/r5dev/windows/console.cpp @@ -130,7 +130,6 @@ DWORD __stdcall ProcessConsoleWorker(LPVOID) //-- Debug toggles if (sCommand == "pattern test") { PrintHAddress(); continue; } - if (sCommand == "opcodes test") { RuntimePtc_Toggle(); continue; } // Execute the command in the r5 SQVM Cbuf_AddText(Cbuf_GetCurrentPlayer(), sCommand.c_str(), cmd_source_t::kCommandSrcCode);