From acb3222903c03186a1b2a9e6a0080555fcd97c4e Mon Sep 17 00:00:00 2001 From: ALittlePatate Date: Sat, 1 Oct 2022 23:53:04 +0200 Subject: [PATCH] add: objects inspector just like UnityExplorer, gosh that was a pain --- DevourClient/DevourClient.vcxproj | 2 + DevourClient/Features/Menu.cpp | 111 ++++++++++++++++++++++- DevourClient/Features/Misc/Misc.cpp | 10 +-- DevourClient/Utils/Dumper/Dumper.cpp | 116 +++++++++++++++++++------ DevourClient/Utils/Dumper/Dumper.hpp | 12 ++- DevourClient/Utils/Players/Players.cpp | 2 +- 6 files changed, 213 insertions(+), 40 deletions(-) diff --git a/DevourClient/DevourClient.vcxproj b/DevourClient/DevourClient.vcxproj index df95cd8..2e9feb0 100644 --- a/DevourClient/DevourClient.vcxproj +++ b/DevourClient/DevourClient.vcxproj @@ -310,6 +310,7 @@ + @@ -356,6 +357,7 @@ + diff --git a/DevourClient/Features/Menu.cpp b/DevourClient/Features/Menu.cpp index a99412f..bd3358f 100644 --- a/DevourClient/Features/Menu.cpp +++ b/DevourClient/Features/Menu.cpp @@ -174,6 +174,107 @@ void DrawMapSpecificTab() { } } +bool inspector = false; +void DrawInspector() { + ImGui::SetNextWindowSize(ImVec2(600.000f, 600.000f), ImGuiCond_Once); + if (!ImGui::Begin("Inspector", &inspector, 2)) { + ImGui::End(); + return; + } + + static std::vector components; + static std::vector classes; + static std::vector methods; + static std::string current_comp = ""; + + ImGui::Text("Components"); + if (ImGui::Button("Update##comp")) { + components = Dumper::DumpComponentsString(); + } + + ImGui::SetNextItemWidth(150.000f); + static int component_current_idx = 0; // Here we store our selection data as an index. + static ImGuiTextFilter c_filter; + c_filter.Draw("Search##compfilter"); + if (ImGui::BeginListBox("##Components", ImVec2(-FLT_MIN, 5 * ImGui::GetTextLineHeightWithSpacing()))) + { + for (size_t n = 0; n < components.size(); n++) + { + if (!c_filter.PassFilter(components[n].c_str())) { + continue; + } + const bool comp_is_selected = (component_current_idx == (int)n); + if (ImGui::Selectable(components[n].c_str(), comp_is_selected)) + component_current_idx = (int)n; + + // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) + if (comp_is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndListBox(); + } + + ImGui::Spacing(); + ImGui::Text("Classes"); + if (ImGui::Button("Update##class")) { + classes = Dumper::DumpClassesString(components[component_current_idx]); + current_comp = components[component_current_idx]; + } + + ImGui::SetNextItemWidth(150.000f); + static int class_current_idx = 0; // Here we store our selection data as an index. + static ImGuiTextFilter cl_filter; + cl_filter.Draw("Search##classfilter"); + if (ImGui::BeginListBox("##Class", ImVec2(-FLT_MIN, 5 * ImGui::GetTextLineHeightWithSpacing()))) + { + for (size_t n = 0; n < classes.size(); n++) + { + if (!cl_filter.PassFilter(classes[n].c_str())) { + continue; + } + const bool class_is_selected = (class_current_idx == (int)n); + if (ImGui::Selectable(classes[n].c_str(), class_is_selected)) { + class_current_idx = (int)n; + } + + // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) + if (class_is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndListBox(); + } + + ImGui::Spacing(); + ImGui::Text("Methods"); + if (ImGui::Button("Update##Methods")) { + methods = Dumper::DumpMethodsString(current_comp, classes[class_current_idx]); + } + + ImGui::SetNextItemWidth(150.000f); + static int method_current_idx = 0; // Here we store our selection data as an index. + static ImGuiTextFilter me_filter; + me_filter.Draw("Search##methodfilter"); + if (ImGui::BeginListBox("##Methods", ImVec2(-FLT_MIN, -1))) + { + for (size_t n = 0; n < methods.size(); n++) + { + if (!me_filter.PassFilter(methods[n].c_str())) { + continue; + } + const bool meth_is_selected = (method_current_idx == (int)n); + if (ImGui::Selectable(methods[n].c_str(), meth_is_selected)) + method_current_idx = (int)n; + + // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) + if (meth_is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndListBox(); + } + + ImGui::End(); +} + void DrawMiscTab() { ImGui::Checkbox("Chat spam", &settings::chat_spam); ImGui::InputText("Message", &settings::message); @@ -220,10 +321,12 @@ void DrawMiscTab() { #if _DEBUG ImGui::Spacing(); - static std::string component = "NolanBehaviour"; - ImGui::InputText("##component", &component); - if (ImGui::Button("FindObjectsOfType")) { - Dump(component); + if (ImGui::Button("Inspector")) { + inspector = !inspector; + } + + if (inspector) { + DrawInspector(); } #endif diff --git a/DevourClient/Features/Misc/Misc.cpp b/DevourClient/Features/Misc/Misc.cpp index a6f8d5d..b7040f2 100644 --- a/DevourClient/Features/Misc/Misc.cpp +++ b/DevourClient/Features/Misc/Misc.cpp @@ -5,13 +5,5 @@ void Misc::SetRank(int rank) { } void Misc::WalkInlobby(bool walk) { - Unity::CComponent* UltimateCharacterLocomotionHandler = Players::LocalPlayer->GetComponent("UltimateCharacterLocomotionHandler"); - - if (UltimateCharacterLocomotionHandler == NULL) - { - Players::LocalPlayer->AddComponent(IL2CPP::Class::GetSystemType("UltimateCharacterLocomotionHandler")); - Players::LocalPlayer->GetComponent("UltimateCharacterLocomotionHandler")->SetMemberValue("enabled", false); - } - - Players::LocalPlayer->GetComponent("UltimateCharacterLocomotionHandler")->SetMemberValue("enabled", walk); + Players::LocalPlayer->GetComponent("UltimateCharacterLocomotionHandler")->GetGameObject()->SetActive(walk); } \ No newline at end of file diff --git a/DevourClient/Utils/Dumper/Dumper.cpp b/DevourClient/Utils/Dumper/Dumper.cpp index a095a1d..6cfafa1 100644 --- a/DevourClient/Utils/Dumper/Dumper.cpp +++ b/DevourClient/Utils/Dumper/Dumper.cpp @@ -1,35 +1,101 @@ #include "Dumper.hpp" #include "../Output/Output.hpp" -void Dump(std::string component) { - print("\n\n\n"); - print("Dumping %s\n\n", component.c_str()); - auto list = Unity::Object::FindObjectsOfType(component.c_str()); +std::vector Dumper::DumpMethods(std::string component, std::string classname) { + std::vector methods_to_return; + Unity::CGameObject* component_obj = Unity::GameObject::Find(component.c_str()); + if (!component_obj) { + return methods_to_return; + } + + size_t pos = classname.find("::"); + classname.erase(0, pos+2); + + Unity::CComponent* ccc = component_obj->GetComponent(classname.c_str()); + if (!ccc) { + return methods_to_return; + } + + ccc->FetchMethods(&methods_to_return); + + return methods_to_return; +} + +std::vector Dumper::DumpMethodsString(std::string component, std::string classname) { + std::vector methods_to_return; + std::vector methods = Dumper::DumpMethods(component, classname); + + for (Unity::il2cppMethodInfo* method : methods) { + if (!method) { + return methods_to_return; + } + + methods_to_return.push_back(method->m_pName); + } + + return methods_to_return; +} + + +std::vector Dumper::DumpClasses(std::string component) { + std::vector classes_to_return; + + Unity::CGameObject* component_obj = Unity::GameObject::Find(component.c_str()); + if (!component_obj) { + return classes_to_return; + } + + auto components = component_obj->GetComponents(UNITY_COMPONENT_CLASS); + for (int n = 0; n < components->m_uMaxLength; n++) + { + if (!components->operator[](n)) + continue; + + classes_to_return.push_back(components->operator[](n)); + } + + return classes_to_return; +} + +std::vector Dumper::DumpClassesString(std::string component) { + std::vector classes_to_return; + + std::vector classes = Dumper::DumpClasses(component); + for (Unity::CComponent* class_obj : classes) + { + if (!class_obj) + continue; + + classes_to_return.push_back(std::string(class_obj->m_Object.m_pClass->m_pNamespace) + "::" + std::string(class_obj->m_Object.m_pClass->m_pName)); + } + return classes_to_return; +} + +std::vector Dumper::DumpComponents() { + std::vector compenents_to_return; + + auto list = Unity::Object::FindObjectsOfType(UNITY_COMPONENT_CLASS); for (int i = 0; i < list->m_uMaxLength + 1; i++) { if (!list->operator[](i)) continue; - Unity::CGameObject* object = list->operator[](i)->GetMemberValue("gameObject"); - - print("%s\n", object->GetName()->ToString().c_str()); //SurvivalPlayer(Clone) - - auto components = object->GetComponents(UNITY_COMPONENT_CLASS); - for (int n = 0; n < components->m_uMaxLength; n++) - { - if (!components->operator[](n)) - continue; - - print("| -> %s::%s\n", components->operator[](n)->m_Object.m_pClass->m_pNamespace, components->operator[](n)->m_Object.m_pClass->m_pName); - - } - Unity::CComponent* BoltEntity = object->GetComponent("BoltEntity"); - if (BoltEntity) - { - print("|-------- owner:%d \n", BoltEntity->CallMethod("get_IsOwner")); //local player check? - if (BoltEntity->CallMethod("get_IsOwner")) - { - } - } + compenents_to_return.push_back(list->operator[](i)); } + return compenents_to_return; +} + +std::vector Dumper::DumpComponentsString() { + std::vector compenents_to_return; + + std::vector components = Dumper::DumpComponents(); + for (Unity::CComponent* component : components) + { + if (!component) + continue; + + Unity::CGameObject* object = component->GetMemberValue("gameObject"); + compenents_to_return.push_back(object->GetName()->ToString()); + } + return compenents_to_return; } \ No newline at end of file diff --git a/DevourClient/Utils/Dumper/Dumper.hpp b/DevourClient/Utils/Dumper/Dumper.hpp index 1b5c957..d0180d8 100644 --- a/DevourClient/Utils/Dumper/Dumper.hpp +++ b/DevourClient/Utils/Dumper/Dumper.hpp @@ -1,4 +1,14 @@ #pragma once #include "../Dependencies/IL2CPP_Resolver/il2cpp_resolver.hpp" -void Dump(std::string component); \ No newline at end of file + +namespace Dumper { + std::vector DumpComponents(); + std::vector DumpComponentsString(); + + std::vector DumpClasses(std::string component); + std::vector DumpClassesString(std::string component); + + std::vector DumpMethods(std::string component, std::string classname); + std::vector DumpMethodsString(std::string component, std::string classname); +} \ No newline at end of file diff --git a/DevourClient/Utils/Players/Players.cpp b/DevourClient/Utils/Players/Players.cpp index 63382c5..acd0f92 100644 --- a/DevourClient/Utils/Players/Players.cpp +++ b/DevourClient/Utils/Players/Players.cpp @@ -40,7 +40,7 @@ void Players::GetPlayersThread() { } } - Sleep(500); + Sleep(5000); //FIXME //waiting 5 sec here to avoid crash cuz we're trying to get players when stuff load } } \ No newline at end of file