mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Added ConVar/Command dumper to log.
This commit is contained in:
commit
9a2b086f16
@ -304,6 +304,15 @@ public:
|
|||||||
float m_flMaxValue; //0x007C
|
float m_flMaxValue; //0x007C
|
||||||
}; //Size: 0x0080
|
}; //Size: 0x0080
|
||||||
|
|
||||||
|
class CCVarIteratorInternal // Fully reversed table, just look at the virtual function table and rename the function.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void SetFirst(void) = 0; //0
|
||||||
|
virtual void Next(void) = 0; //1
|
||||||
|
virtual bool IsValid(void) = 0; //2
|
||||||
|
virtual ConCommandBase* Get(void) = 0; //3
|
||||||
|
};
|
||||||
|
|
||||||
class CCVar
|
class CCVar
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -324,6 +333,29 @@ public:
|
|||||||
using OriginalFn = void*(__thiscall*)(CCVar*, const char*);
|
using OriginalFn = void*(__thiscall*)(CCVar*, const char*);
|
||||||
return (*reinterpret_cast<OriginalFn**>(this))[18](this, szCommandName);
|
return (*reinterpret_cast<OriginalFn**>(this))[18](this, szCommandName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CCVarIteratorInternal* FactoryInternalIterator() // @0x140597C10 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||||
|
{
|
||||||
|
using OriginalFn = CCVarIteratorInternal*(__thiscall*)(CCVar*);
|
||||||
|
return (*reinterpret_cast<OriginalFn**>(this))[41](this);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<std::string, ConCommandBase*> DumpToMap()
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
CCVarIteratorInternal* itint = FactoryInternalIterator(); // Allocatd new InternalIterator.
|
||||||
|
|
||||||
|
std::unordered_map<std::string, ConCommandBase*> allConVars;
|
||||||
|
|
||||||
|
for (itint->SetFirst(); itint->IsValid(); itint->Next()) // Loop through all instances.
|
||||||
|
{
|
||||||
|
ConCommandBase* command = itint->Get();
|
||||||
|
const char* commandName = command->m_pszName;
|
||||||
|
allConVars[commandName] = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
return allConVars;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Interface
|
struct Interface
|
||||||
|
@ -104,6 +104,16 @@ void CGameConsole::Draw(const char* title)
|
|||||||
ProcessCommand("exec netchan");
|
ProcessCommand("exec netchan");
|
||||||
}
|
}
|
||||||
ImGui::PopStyleColor(); // Pop color override.
|
ImGui::PopStyleColor(); // Pop color override.
|
||||||
|
if (ImGui::SmallButton("Commands/Convars to Console"))
|
||||||
|
{
|
||||||
|
if (GameGlobals::Cvar)
|
||||||
|
{
|
||||||
|
for (auto map : GameGlobals::Cvar->DumpToMap())
|
||||||
|
{
|
||||||
|
AddLog("%s\n", map.first.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
if (ImGui::Button("Tools"))
|
if (ImGui::Button("Tools"))
|
||||||
@ -125,9 +135,8 @@ void CGameConsole::Draw(const char* title)
|
|||||||
{
|
{
|
||||||
const char* item = Items[i];
|
const char* item = Items[i];
|
||||||
if (!Filter.PassFilter(item))
|
if (!Filter.PassFilter(item))
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
||||||
ImVec4 color;
|
ImVec4 color;
|
||||||
bool has_color = false;
|
bool has_color = false;
|
||||||
@ -176,11 +185,23 @@ void CGameConsole::Draw(const char* title)
|
|||||||
// Filters
|
// Filters
|
||||||
//if (strstr(item, ") -> ")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); has_color = true; }
|
//if (strstr(item, ") -> ")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); has_color = true; }
|
||||||
|
|
||||||
if (has_color) { ImGui::PushStyleColor(ImGuiCol_Text, color); }
|
if (has_color)
|
||||||
ImGui::TextWrapped(item);
|
{
|
||||||
if (has_color) { ImGui::PopStyleColor(); }
|
ImGui::PushStyleColor(ImGuiCol_Text, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TextWrapped(item);
|
||||||
|
|
||||||
|
if (has_color)
|
||||||
|
{
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (copy_to_clipboard)
|
||||||
|
{
|
||||||
|
ImGui::LogFinish();
|
||||||
}
|
}
|
||||||
if (copy_to_clipboard) { ImGui::LogFinish(); }
|
|
||||||
|
|
||||||
if (ScrollToBottom || (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())) { ImGui::SetScrollHereY(1.0f); }
|
if (ScrollToBottom || (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())) { ImGui::SetScrollHereY(1.0f); }
|
||||||
ScrollToBottom = false;
|
ScrollToBottom = false;
|
||||||
|
@ -557,7 +557,6 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return MemoryAddress(latestOccurence);
|
return MemoryAddress(latestOccurence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,72 +29,6 @@ MODULEINFO GetModuleInfo(const char* szModule)
|
|||||||
return modinfo;
|
return modinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// For finding a byte pattern in memory of the game process
|
|
||||||
|
|
||||||
std::uint8_t* PatternScan(const char* module, const char* signature)
|
|
||||||
{
|
|
||||||
static auto PatternToBytes = [](const char* pattern)
|
|
||||||
{
|
|
||||||
char* PatternStart = const_cast<char*>(pattern); // Cast const away and get start of pattern.
|
|
||||||
char* PatternEnd = PatternStart + std::strlen(pattern); // Get end of pattern.
|
|
||||||
|
|
||||||
std::vector<std::int32_t> Bytes = std::vector<std::int32_t>{ }; // Initialize byte vector.
|
|
||||||
|
|
||||||
for (char* CurrentByte = PatternStart; CurrentByte < PatternEnd; ++CurrentByte)
|
|
||||||
{
|
|
||||||
if (*CurrentByte == '?') // Is current char(byte) a wildcard?
|
|
||||||
{
|
|
||||||
++CurrentByte; // Skip 1 character.
|
|
||||||
|
|
||||||
if (*CurrentByte == '?') // Is it a double wildcard pattern?
|
|
||||||
++CurrentByte; // If so skip the next space that will come up so we can reach the next byte.
|
|
||||||
|
|
||||||
Bytes.push_back(-1); // Push the byte back as invalid.
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// https://stackoverflow.com/a/43860875/12541255
|
|
||||||
// Here we convert our string to a unsigned long integer. We pass our string then we use 16 as the base because we want it as hexadecimal.
|
|
||||||
// Afterwards we push the byte into our bytes vector.
|
|
||||||
Bytes.push_back(std::strtoul(CurrentByte, &CurrentByte, 16));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Bytes;
|
|
||||||
};
|
|
||||||
|
|
||||||
const MODULEINFO mInfo = GetModuleInfo(module); // Get module info.
|
|
||||||
const DWORD64 SizeOfModule = (DWORD64)mInfo.SizeOfImage; // Grab the module size.
|
|
||||||
std::uint8_t* ScanBytes = reinterpret_cast<std::uint8_t*>(mInfo.lpBaseOfDll); // Get the base of the module.
|
|
||||||
|
|
||||||
const std::vector<int> PatternBytes = PatternToBytes(signature); // Convert our pattern to a byte array.
|
|
||||||
const std::pair BytesInfo = std::make_pair(PatternBytes.size(), PatternBytes.data()); // Get the size and data of our bytes.
|
|
||||||
|
|
||||||
for (DWORD i = 0ul; i < SizeOfModule - BytesInfo.first; ++i)
|
|
||||||
{
|
|
||||||
bool FoundAddress = true;
|
|
||||||
|
|
||||||
for (DWORD j = 0ul; j < BytesInfo.first; ++j)
|
|
||||||
{
|
|
||||||
// If either the current byte equals to the byte in our pattern or our current byte in the pattern is a wildcard
|
|
||||||
// our if clause will be false.
|
|
||||||
if (ScanBytes[i + j] != BytesInfo.second[j] && BytesInfo.second[j] != -1)
|
|
||||||
{
|
|
||||||
FoundAddress = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FoundAddress)
|
|
||||||
{
|
|
||||||
return &ScanBytes[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
void DbgPrint(LPCSTR sFormat, ...)
|
void DbgPrint(LPCSTR sFormat, ...)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user