Skip to content

Commit 800dfa6

Browse files
committed
Debug Interface: Add more pools to pools debug interface
1 parent 9319f24 commit 800dfa6

File tree

2 files changed

+231
-60
lines changed

2 files changed

+231
-60
lines changed

build-count.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
538
1+
540

src/debug/pools.cc

Lines changed: 230 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,225 @@
11
#include <implot.h>
22
#include "base.hh"
3+
#include "common/minhook.hh"
34
#include "imgui.h"
45

6+
#include "common/logger.hh"
7+
58
#include <deque>
69

710
#include <Utils.hh>
811
#include <CPools.hh>
912
#include <type_traits>
1013

14+
static std::map<uint32_t, std::string> s_PoolsNameMap = {
15+
{0x0AB968F6, "streamped req data"},
16+
{0x6E63BFF3, "cpatrolnode"},
17+
{0x85FB462D, "pedprop req data"},
18+
{0x54753C86, "cvehiclestreamrequestgfx"},
19+
{0xB4E04AA4, "cdoorextension"},
20+
{0x1182232C, "cgamescripthandler"},
21+
{0xC2B5F089, "cvehiclestreamrendergfx"},
22+
{0x2D370C34, "streamped render data"},
23+
{0xD29EB05B, "fwcontainerlod"},
24+
{0x539C8EB8, "pedprop render data"},
25+
{0x5E047C3E, "vehicleglasscomponententity"},
26+
{0x652A20AF, "targetting"},
27+
{0x4E2ADF9B, "itemsetbuffer"},
28+
{0x2FEAD7A6, "fraginstnmgta"},
29+
{0x5047B2C4, "cmoveped"},
30+
{0x8DA12117, "peds"},
31+
{0x394AC584, "pedintelligence"},
32+
{0xAC9F5436, "cmovevehicle"},
33+
{0xBF69BB29, "fwanimdirectorcomponentragdoll"},
34+
{0x210E10BE, "fwanimdirectorcomponentfacialrig"},
35+
{0x16A315A2, "fwanimdirectorcomponentsyncedscene"},
36+
{0xBAE33CCF, "cweaponcomponentinfo"},
37+
{0x94E57350, "fwdynamicentitycomponent"},
38+
{0x3CC59946, "fwanimdirectorcomponentexpressions"},
39+
{0x7311A8D7, "fwscriptguid"},
40+
{0xE7509171, "quadtreenodes"},
41+
{0x3A2BC128, "cweapon"},
42+
{0xCA5ED810, "fwanimdirector"},
43+
{0xC79C63D2, "fwanimdirectorcomponentmove"},
44+
{0x36776CCA, "fwanimdirectorcomponentcreature"},
45+
{0x698208CF, "tasksequenceinfo"},
46+
{0x975AC445, "wheels"},
47+
{0x6851786C, "fraginstgta"},
48+
{0xEB9564E1, "phinstgta"},
49+
{0x41663795, "maxloadrequestedinfo"},
50+
{0x2EB2EE6E, "navmeshes"},
51+
};
52+
1153
class PoolsDebugInterface : public DebugInterface
1254
{
13-
inline static CPool<void> sm_FakeCollidersPool;
14-
15-
std::vector<int>
16-
GetXValues ()
55+
constexpr static int GRAPH_WIDTH = 500;
56+
57+
class PoolData
1758
{
18-
std::vector<int> vec;
19-
for (int i = 0; i < 500; i++)
20-
vec.push_back(i);
59+
public:
60+
std::string Name;
2161

22-
return vec;
23-
}
62+
std::function<std::pair<int, int> ()> GetFunction;
63+
std::vector<float> GraphValues;
64+
bool IsCritical = false;
2465

25-
template <typename T>
26-
auto
27-
Dereference (const T &v)
28-
{
29-
if constexpr (std::is_pointer_v<T>)
30-
return Dereference (*v);
31-
else
32-
return v;
33-
}
66+
bool AlwaysDisplay = false;
67+
bool DisplayCritical = true;
68+
bool DisplaySeparate = false;
69+
70+
PoolData (const PoolData &other) = delete;
71+
PoolData (PoolData &&other) = default;
72+
73+
PoolData (std::string name, std::function<std::pair<int, int> ()> func,
74+
bool always = false, bool critical = true,
75+
bool separate = false)
76+
: Name (name), GetFunction (func), AlwaysDisplay (always),
77+
DisplayCritical (critical), DisplaySeparate (separate)
78+
{
79+
}
80+
81+
template <typename T>
82+
PoolData (std::string name, CPool<T> *pool, bool always = false,
83+
bool critical = true, bool separate = false)
84+
: GetFunction ([pool] () -> std::pair<int, int> {
85+
if (!pool)
86+
return {0, 0};
87+
return {pool->GetCount (), pool->m_nMaxElements};
88+
}),
89+
Name (name), AlwaysDisplay (always), DisplayCritical (critical),
90+
DisplaySeparate (separate)
91+
{
92+
}
93+
94+
template <typename T>
95+
PoolData (std::string name, CPool<T> **pool, bool always = false,
96+
bool critical = true, bool separate = false)
97+
: GetFunction ([pool] () -> std::pair<int, int> {
98+
if (!pool || !(*pool))
99+
return {0, 0};
100+
return {(*pool)->GetCount (), (*pool)->m_nMaxElements};
101+
}),
102+
Name (name), AlwaysDisplay (always), DisplayCritical (critical),
103+
DisplaySeparate (separate)
104+
{
105+
}
106+
107+
void
108+
Update ()
109+
{
110+
auto [used, max] = GetFunction ();
111+
112+
if (max == 0)
113+
return;
114+
115+
GraphValues.push_back (used / static_cast<float> (max));
34116

35-
template <typename T>
36-
bool
37-
CanDereference (T &&v)
117+
if (GraphValues.size () >= GRAPH_WIDTH)
118+
GraphValues.erase (GraphValues.begin ());
119+
120+
IsCritical = used > 10 && (GraphValues.back () > 0.5f);
121+
}
122+
123+
bool
124+
ShouldDisplay ()
125+
{
126+
return AlwaysDisplay || (DisplayCritical && IsCritical);
127+
}
128+
};
129+
130+
inline static std::vector<PoolData> sm_Pools;
131+
inline static uint32_t sm_LastPool;
132+
133+
void
134+
UpdatePools ()
38135
{
39-
if constexpr (std::is_pointer_v<T>)
40-
return v && CanDereference (*v);
41-
else
42-
return true;
136+
for (auto &i : sm_Pools)
137+
i.Update ();
43138
}
44139

45-
template <auto &Pool>
46140
void
47-
DrawPool (const char *name)
141+
DrawMasterGraph ()
48142
{
49-
if (!CanDereference(Pool))
143+
if (!ImGui::CollapsingHeader ("Master Graph"))
144+
return;
145+
146+
ImPlot::SetNextPlotLimits (0, 520, 0, 1.2f, ImGuiCond_Always);
147+
if (!ImPlot::BeginPlot ("Master Graph"))
50148
return;
51-
52-
int PoolUsage = Dereference(Pool).GetCount ();
53-
int PoolSize = Dereference(Pool).m_nMaxElements;
54149

55-
static std::vector<int> x_Values = GetXValues ();
56-
static std::vector<int> y_Values;
150+
static float One = 1.0f;
151+
152+
ImPlot::SetNextLineStyle (ImVec4 (1.0, 0.0, 0.0, 1.0), 5.0f);
153+
ImPlot::PlotHLines ("Max", &One, 1);
57154

58-
y_Values.push_back (Dereference(Pool).GetCount ());
155+
ImPlot::SetNextLineStyle (IMPLOT_AUTO_COL);
59156

60-
if (y_Values.size () > 500)
157+
static std::vector<float> x_Values = GetXValues ();
158+
for (auto &i : sm_Pools)
61159
{
62-
y_Values.erase (y_Values.begin ());
160+
if (i.ShouldDisplay ())
161+
{
162+
ImPlot::SetNextLineStyle (IMPLOT_AUTO_COL, 2.0f);
163+
ImPlot::PlotLine (i.Name.c_str (), x_Values.data (),
164+
i.GraphValues.data (),
165+
i.GraphValues.size ());
166+
}
63167
}
64168

65-
if (!ImGui::CollapsingHeader (name))
169+
ImPlot::EndPlot ();
170+
}
171+
172+
void
173+
DrawPoolGraph (PoolData &data)
174+
{
175+
if (!ImGui::CollapsingHeader (data.Name.c_str ()))
66176
return;
67177

68-
ImPlot::SetNextPlotLimits (0, 520, 0, PoolSize + 10, ImGuiCond_Always);
69-
if (ImPlot::BeginPlot (name))
70-
{
71-
ImPlot::SetNextLineStyle (ImVec4 (1.0, 0.0, 0.0, 1.0));
72-
ImPlot::PlotHLines ("Max", &PoolSize, 1);
178+
ImPlot::SetNextPlotLimits (0, 520, 0, 1.0f, ImGuiCond_Always);
73179

74-
ImPlot::SetNextLineStyle (IMPLOT_AUTO_COL, 5.0);
75-
ImPlot::PlotLine ("Usage", x_Values.data (), y_Values.data (),
76-
y_Values.size ());
180+
if (!ImPlot::BeginPlot (data.Name.c_str ()))
181+
return;
77182

78-
ImPlot::SetNextLineStyle ();
79-
ImPlot::EndPlot ();
80-
}
183+
static float One = 1.0f;
184+
static std::vector<float> x_Values = GetXValues ();
81185

82-
ImGui::ProgressBar (PoolUsage / static_cast<float> (PoolSize));
186+
ImPlot::SetNextLineStyle (ImVec4 (1.0, 0.0, 0.0, 1.0));
187+
ImPlot::PlotHLines ("Max", &One, 1);
188+
189+
ImPlot::SetNextLineStyle (IMPLOT_AUTO_COL, 5.0f);
190+
191+
ImPlot::PlotLine ("Usage", x_Values.data (), data.GraphValues.data (),
192+
data.GraphValues.size ());
193+
194+
ImPlot::SetNextLineStyle ();
195+
196+
ImPlot::EndPlot ();
83197
}
84198

85199
void
86-
ProcessPhInstPool ()
200+
DrawPools ()
201+
{
202+
UpdatePools ();
203+
DrawMasterGraph ();
204+
for (auto &i : sm_Pools)
205+
{
206+
if (i.DisplaySeparate)
207+
DrawPoolGraph (i);
208+
}
209+
}
210+
211+
std::vector<float>
212+
GetXValues ()
213+
{
214+
std::vector<float> vec;
215+
for (int i = 0; i < 500; i++)
216+
vec.push_back (i);
217+
218+
return vec;
219+
}
220+
221+
static std::pair<int, int>
222+
GetCollidersUsage ()
87223
{
88224
static char **phInstance = GetRelativeReference<char *> (
89225
"? 8B 0D ? ? ? ? ? 83 64 ? ? 00 ? 0F B7 D1 ? 33 C9 E8", 3, 7);
@@ -97,22 +233,46 @@ class PoolsDebugInterface : public DebugInterface
97233
}();
98234

99235
if (!*phInstance)
100-
return;
236+
return {0, 0};
101237

102-
sm_FakeCollidersPool.m_nCount = injector::ReadMemory<uint32_t> (
103-
*phInstance + usedCollidersOffset);
104-
sm_FakeCollidersPool.m_nMaxElements
105-
= injector::ReadMemory<uint32_t> (*phInstance + maxCollidersOffset);
238+
return {
239+
injector::ReadMemory<uint32_t> (*phInstance + usedCollidersOffset),
240+
injector::ReadMemory<uint32_t> (*phInstance + maxCollidersOffset)};
106241
}
107242

108243
void
109244
Draw () override
110245
{
111-
ProcessPhInstPool ();
246+
DrawPools ();
247+
}
112248

113-
DrawPool<sm_FakeCollidersPool> ("Colliders");
114-
DrawPool<CPools::g_pVehicleStreamRequestGfxPool> ("Vehicle Stream Request GFX");
115-
DrawPool<CPools::g_pVehicleStructPool> ("Vehicle Struct");
249+
template <auto &fwConfigManager__GetSizeOfPool>
250+
static uint32_t
251+
GetNextPoolName (void *p1, uint32_t hash, uint32_t p3)
252+
{
253+
sm_LastPool = hash;
254+
return fwConfigManager__GetSizeOfPool (p1, hash, p3);
255+
}
256+
257+
template <auto &CPool__Allocate>
258+
static void
259+
RegisterPool (CPool<void> *pool)
260+
{
261+
if (sm_Pools.size () == 0)
262+
{
263+
sm_Pools.emplace_back ("colliders", GetCollidersUsage, true,
264+
true, true);
265+
266+
sm_Pools.emplace_back ("vehicle struct",
267+
CPools::g_pVehicleStructPool, true, true,
268+
true);
269+
}
270+
271+
if (pool->m_nMaxElements > 10 && s_PoolsNameMap.count (sm_LastPool))
272+
sm_Pools.emplace_back (s_PoolsNameMap[sm_LastPool], pool, true,
273+
true, true);
274+
275+
return CPool__Allocate (pool);
116276
}
117277

118278
public:
@@ -123,4 +283,15 @@ class PoolsDebugInterface : public DebugInterface
123283
return "Pools";
124284
}
125285

286+
PoolsDebugInterface ()
287+
{
288+
REGISTER_MH_HOOK_BRANCH ("ba 67 ee cc f8 ? b8 10 00 00 00 e8 ? ? ? ?",
289+
11, GetNextPoolName, uint32_t, void *,
290+
uint32_t, uint32_t);
291+
292+
REGISTER_MH_HOOK ("? 53 ? 83 ec 20 ? 83 39 00 ? 8b d9 75 ? 8b 41 14 0f "
293+
"af 41 10 ? 63 c8 ",
294+
0, RegisterPool, void, CPool<void> *);
295+
}
296+
126297
} inline g_PoolsDebugInterface;

0 commit comments

Comments
 (0)