minor changes
improvement `ImGui::BeginGroupPanel` fix typos fix warnings anti-debug bypass changes (implementation is private for now)
This commit is contained in:
parent
ab1a333f3a
commit
eb2fb6fbc3
@ -53,8 +53,8 @@ void PipeTransfer::ReadBytes(void* buffer, size_t size)
|
|||||||
if (size == 0 || !IsPipeOpened()) return;
|
if (size == 0 || !IsPipeOpened()) return;
|
||||||
|
|
||||||
DWORD readCount = 0;
|
DWORD readCount = 0;
|
||||||
auto result = ReadFile(m_Pipe, buffer, size, &readCount, nullptr);
|
auto result = ReadFile(m_Pipe, buffer, static_cast<DWORD>(size), &readCount, nullptr);
|
||||||
if (!result || readCount < size)
|
if (!result || static_cast<size_t>(readCount) < size)
|
||||||
{
|
{
|
||||||
LOG_LAST_ERROR("Failed read from pipe.");
|
LOG_LAST_ERROR("Failed read from pipe.");
|
||||||
CloseHandle(m_Pipe);
|
CloseHandle(m_Pipe);
|
||||||
@ -67,8 +67,8 @@ void PipeTransfer::WriteBytes(void* buffer, size_t size)
|
|||||||
if (size == 0 || !IsPipeOpened()) return;
|
if (size == 0 || !IsPipeOpened()) return;
|
||||||
|
|
||||||
DWORD writenCount = 0;
|
DWORD writenCount = 0;
|
||||||
auto result = WriteFile(m_Pipe, buffer, size, &writenCount, nullptr);
|
auto result = WriteFile(m_Pipe, buffer, static_cast<DWORD>(size), &writenCount, nullptr);
|
||||||
if (!result || writenCount < size)
|
if (!result || static_cast<size_t>(writenCount) < size)
|
||||||
{
|
{
|
||||||
LOG_LAST_ERROR("Failed write to pipe.");
|
LOG_LAST_ERROR("Failed write to pipe.");
|
||||||
CloseHandle(m_Pipe);
|
CloseHandle(m_Pipe);
|
||||||
|
@ -113,7 +113,7 @@ namespace cheat
|
|||||||
void CheatManagerBase::DrawMenuSection(const std::string& sectionName, const std::vector<Feature*>& features) const
|
void CheatManagerBase::DrawMenuSection(const std::string& sectionName, const std::vector<Feature*>& features) const
|
||||||
{
|
{
|
||||||
if (!sectionName.empty())
|
if (!sectionName.empty())
|
||||||
BeginGroupPanel(sectionName.c_str(), ImVec2(-1, 0));
|
ImGui::BeginGroupPanel(sectionName.c_str());
|
||||||
|
|
||||||
for (auto& feature : features)
|
for (auto& feature : features)
|
||||||
{
|
{
|
||||||
@ -123,7 +123,7 @@ namespace cheat
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!sectionName.empty())
|
if (!sectionName.empty())
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheatManagerBase::DrawProfileGlobalActivities()
|
void CheatManagerBase::DrawProfileGlobalActivities()
|
||||||
@ -350,7 +350,7 @@ namespace cheat
|
|||||||
if (!moduleShowAny)
|
if (!moduleShowAny)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
BeginGroupPanel(moduleName.c_str(), ImVec2(-1, 0));
|
ImGui::BeginGroupPanel(moduleName.c_str());
|
||||||
|
|
||||||
for (auto& [sectionName, features] : sections)
|
for (auto& [sectionName, features] : sections)
|
||||||
{
|
{
|
||||||
@ -365,7 +365,7 @@ namespace cheat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
@ -31,7 +31,7 @@ namespace cheat::feature
|
|||||||
NF(f_HotkeyExit, "Hotkeys", "General::FastExit", Hotkey(VK_F12))
|
NF(f_HotkeyExit, "Hotkeys", "General::FastExit", Hotkey(VK_F12))
|
||||||
|
|
||||||
{
|
{
|
||||||
renderer::SetGlobalFontSize(f_FontSize);
|
renderer::SetGlobalFontSize(static_cast<float>(f_FontSize));
|
||||||
f_HotkeyExit.value().PressedEvent += MY_METHOD_HANDLER(Settings::OnExitKeyPressed);
|
f_HotkeyExit.value().PressedEvent += MY_METHOD_HANDLER(Settings::OnExitKeyPressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ namespace cheat::feature
|
|||||||
void Settings::DrawMain()
|
void Settings::DrawMain()
|
||||||
{
|
{
|
||||||
|
|
||||||
BeginGroupPanel("General", ImVec2(-1, 0));
|
ImGui::BeginGroupPanel("General");
|
||||||
{
|
{
|
||||||
ConfigWidget(f_MenuKey, false,
|
ConfigWidget(f_MenuKey, false,
|
||||||
"Key to toggle main menu visibility. Cannot be empty.\n"\
|
"Key to toggle main menu visibility. Cannot be empty.\n"\
|
||||||
@ -53,12 +53,12 @@ namespace cheat::feature
|
|||||||
if (ConfigWidget(f_FontSize, 1, 8, 64, "Font size for cheat interface."))
|
if (ConfigWidget(f_FontSize, 1, 8, 64, "Font size for cheat interface."))
|
||||||
{
|
{
|
||||||
f_FontSize = std::clamp(f_FontSize.value(), 8, 64);
|
f_FontSize = std::clamp(f_FontSize.value(), 8, 64);
|
||||||
renderer::SetGlobalFontSize(f_FontSize);
|
renderer::SetGlobalFontSize(static_cast<float>(f_FontSize));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
|
|
||||||
BeginGroupPanel("Logging", ImVec2(-1, 0));
|
ImGui::BeginGroupPanel("Logging");
|
||||||
{
|
{
|
||||||
bool consoleChanged = ConfigWidget(f_ConsoleLogging,
|
bool consoleChanged = ConfigWidget(f_ConsoleLogging,
|
||||||
"Enable console for logging information (changes will take effect after relaunch)");
|
"Enable console for logging information (changes will take effect after relaunch)");
|
||||||
@ -75,37 +75,37 @@ namespace cheat::feature
|
|||||||
Logger::SetLevel(Logger::Level::None, Logger::LoggerType::FileLogger);
|
Logger::SetLevel(Logger::Level::None, Logger::LoggerType::FileLogger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
|
|
||||||
BeginGroupPanel("Status Window", ImVec2(-1, 0));
|
ImGui::BeginGroupPanel("Status Window");
|
||||||
{
|
{
|
||||||
ConfigWidget(f_StatusShow);
|
ConfigWidget(f_StatusShow);
|
||||||
ConfigWidget(f_StatusMove, "Allow moving of 'Status' window.");
|
ConfigWidget(f_StatusMove, "Allow moving of 'Status' window.");
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
|
|
||||||
BeginGroupPanel("Info Window", ImVec2(-1, 0));
|
ImGui::BeginGroupPanel("Info Window");
|
||||||
{
|
{
|
||||||
ConfigWidget(f_InfoShow);
|
ConfigWidget(f_InfoShow);
|
||||||
ConfigWidget(f_InfoMove, "Allow moving of 'Info' window.");
|
ConfigWidget(f_InfoMove, "Allow moving of 'Info' window.");
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
|
|
||||||
BeginGroupPanel("FPS indicator", ImVec2(-1, 0));
|
ImGui::BeginGroupPanel("FPS indicator");
|
||||||
{
|
{
|
||||||
ConfigWidget(f_FpsShow);
|
ConfigWidget(f_FpsShow);
|
||||||
ConfigWidget(f_FpsMove, "Allow moving of 'FPS Indicator' window.");
|
ConfigWidget(f_FpsMove, "Allow moving of 'FPS Indicator' window.");
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
|
|
||||||
BeginGroupPanel("Show Notifications", ImVec2(-1, 0));
|
ImGui::BeginGroupPanel("Show Notifications");
|
||||||
{
|
{
|
||||||
ConfigWidget(f_NotificationsShow, "Notifications on the bottom-right corner of the window will be displayed.");
|
ConfigWidget(f_NotificationsShow, "Notifications on the bottom-right corner of the window will be displayed.");
|
||||||
ConfigWidget(f_NotificationsDelay, 1,1,10000, "Delay in milliseconds between notifications.");
|
ConfigWidget(f_NotificationsDelay, 1,1,10000, "Delay in milliseconds between notifications.");
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
|
|
||||||
BeginGroupPanel("Fast Exit", ImVec2(-1, 0));
|
ImGui::BeginGroupPanel("Fast Exit");
|
||||||
{
|
{
|
||||||
ConfigWidget("Enabled",
|
ConfigWidget("Enabled",
|
||||||
f_FastExitEnable,
|
f_FastExitEnable,
|
||||||
@ -120,7 +120,7 @@ namespace cheat::feature
|
|||||||
if (!f_FastExitEnable)
|
if (!f_FastExitEnable)
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings& Settings::GetInstance()
|
Settings& Settings::GetInstance()
|
||||||
|
@ -2,23 +2,48 @@
|
|||||||
|
|
||||||
#include "FieldEntry.h"
|
#include "FieldEntry.h"
|
||||||
#include "FieldSerialize.h"
|
#include "FieldSerialize.h"
|
||||||
|
#include <cheat-base/events/event.hpp>
|
||||||
|
#include <cheat-base/events/handlers/methodeventhandler.hpp>
|
||||||
|
|
||||||
namespace config::internal
|
namespace config::internal
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class FieldBase
|
class FieldBase
|
||||||
{
|
{
|
||||||
|
using _FieldBaseT = FieldBase<T>;
|
||||||
public:
|
public:
|
||||||
using _ValueType = T;
|
using _ValueType = T;
|
||||||
|
|
||||||
explicit FieldBase() : p_Container(nullptr) {}
|
explicit FieldBase() : p_Container(nullptr), FieldChangedEvent(m_FieldChangedEvent) {}
|
||||||
|
|
||||||
explicit FieldBase(FieldSerialize<T>* serializeFieldPtr) : p_Container(serializeFieldPtr) { }
|
explicit FieldBase(FieldSerialize<T>* serializeFieldPtr) : p_Container(serializeFieldPtr), FieldChangedEvent(m_FieldChangedEvent)
|
||||||
|
{
|
||||||
|
p_Container->ChangedEvent += MY_METHOD_HANDLER(_FieldBaseT::OnFieldChanged);
|
||||||
|
}
|
||||||
|
|
||||||
explicit FieldBase(const std::shared_ptr<FieldSerialize<T>>& serializeField) : p_Container(serializeField) { }
|
explicit FieldBase(const std::shared_ptr<FieldSerialize<T>>& serializeField) : p_Container(serializeField), FieldChangedEvent(m_FieldChangedEvent)
|
||||||
|
{
|
||||||
|
p_Container->ChangedEvent += MY_METHOD_HANDLER(_FieldBaseT::OnFieldChanged);
|
||||||
|
}
|
||||||
|
|
||||||
explicit FieldBase(const std::string friendlyName, const std::string name, const std::string section, T defaultValue, bool multiProfile = false)
|
explicit FieldBase(const std::string friendlyName, const std::string name, const std::string section, T defaultValue, bool multiProfile = false)
|
||||||
: p_Container(std::make_shared<FieldSerialize<T>>(friendlyName, name, section, defaultValue, multiProfile)) { }
|
: p_Container(std::make_shared<FieldSerialize<T>>(friendlyName, name, section, defaultValue, multiProfile)), FieldChangedEvent(m_FieldChangedEvent)
|
||||||
|
{
|
||||||
|
p_Container->ChangedEvent += MY_METHOD_HANDLER(_FieldBaseT::OnFieldChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit FieldBase(const FieldBase<T>& field) :
|
||||||
|
p_Container(field.p_Container),
|
||||||
|
m_FieldChangedEvent(), FieldChangedEvent(m_FieldChangedEvent)
|
||||||
|
{
|
||||||
|
p_Container->ChangedEvent += MY_METHOD_HANDLER(FieldBase<T>::OnFieldChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
~FieldBase()
|
||||||
|
{
|
||||||
|
if (p_Container.get() != nullptr)
|
||||||
|
p_Container->ChangedEvent -= MY_METHOD_HANDLER(FieldBase<T>::OnFieldChanged);
|
||||||
|
}
|
||||||
|
|
||||||
std::string name() const
|
std::string name() const
|
||||||
{
|
{
|
||||||
@ -89,17 +114,39 @@ namespace config::internal
|
|||||||
|
|
||||||
FieldBase<T>& operator=(std::shared_ptr<FieldSerialize<T>>& other)
|
FieldBase<T>& operator=(std::shared_ptr<FieldSerialize<T>>& other)
|
||||||
{
|
{
|
||||||
|
p_Container->ChangedEvent -= MY_METHOD_HANDLER(FieldBase<T>::OnFieldChanged);
|
||||||
|
|
||||||
p_Container = other;
|
p_Container = other;
|
||||||
|
p_Container->ChangedEvent += MY_METHOD_HANDLER(FieldBase<T>::OnFieldChanged);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
FieldBase<T>& operator=(FieldSerialize<T>* other)
|
FieldBase<T>& operator=(FieldSerialize<T>* other)
|
||||||
{
|
{
|
||||||
|
p_Container->ChangedEvent -= MY_METHOD_HANDLER(FieldBase<T>::OnFieldChanged);
|
||||||
|
|
||||||
p_Container = std::make_shared<FieldSerialize<T>>(other);
|
p_Container = std::make_shared<FieldSerialize<T>>(other);
|
||||||
|
p_Container->ChangedEvent += MY_METHOD_HANDLER(FieldBase<T>::OnFieldChanged);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FieldBase<T>& operator=(const FieldBase<T>& other)
|
||||||
|
{
|
||||||
|
p_Container = other.p_Container;
|
||||||
|
p_Container->ChangedEvent += MY_METHOD_HANDLER(FieldBase<T>::OnFieldChanged);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
IEvent<T&>& FieldChangedEvent;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
TEvent<T&> m_FieldChangedEvent;
|
||||||
|
|
||||||
std::shared_ptr<FieldSerialize<T>> p_Container;
|
std::shared_ptr<FieldSerialize<T>> p_Container;
|
||||||
|
void OnFieldChanged(FieldEntry* entry)
|
||||||
|
{
|
||||||
|
m_FieldChangedEvent(value());
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -47,8 +47,8 @@ std::optional<ImageLoader::ImageData> ImageLoader::GetImage(const std::string& i
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
imageData.size.x = width;
|
imageData.size.x = static_cast<float>(width);
|
||||||
imageData.size.y = height;
|
imageData.size.y = static_cast<float>(height);
|
||||||
s_Textures[imageName] = imageData;
|
s_Textures[imageName] = imageData;
|
||||||
return imageData;
|
return imageData;
|
||||||
}
|
}
|
@ -214,256 +214,7 @@ bool ConfigWidget(config::Field<config::Toggle<Hotkey>>& field, const char* desc
|
|||||||
|
|
||||||
#undef ShowDesc
|
#undef ShowDesc
|
||||||
|
|
||||||
// https://github.com/ocornut/imgui/issues/1496#issuecomment-655048353
|
|
||||||
|
|
||||||
struct GroupPanelInfo
|
|
||||||
{
|
|
||||||
ImRect labelRect;
|
|
||||||
ImRect selectRect;
|
|
||||||
};
|
|
||||||
static ImVector<GroupPanelInfo> s_GroupPanelLabelStack;
|
|
||||||
|
|
||||||
bool GroupPanelIsOpen(ImGuiID id)
|
|
||||||
{
|
|
||||||
ImGuiContext& g = *GImGui;
|
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
|
||||||
ImGuiStorage* storage = window->DC.StateStorage;
|
|
||||||
|
|
||||||
return storage->GetInt(id, 1) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GroupPanelSetOpen(ImGuiID id, bool open)
|
|
||||||
{
|
|
||||||
ImGuiContext& g = *GImGui;
|
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
|
||||||
ImGuiStorage* storage = window->DC.StateStorage;
|
|
||||||
|
|
||||||
storage->SetInt(id, open ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BeginGroupPanel(const char* name, const ImVec2& size, bool node, SelectData* selectData)
|
|
||||||
{
|
|
||||||
ImGuiContext& g = *GImGui;
|
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
|
||||||
|
|
||||||
ImGui::PushID(name);
|
|
||||||
ImGui::BeginGroup();
|
|
||||||
auto cursorPos = ImGui::GetCursorScreenPos();
|
|
||||||
|
|
||||||
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
|
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
|
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
|
||||||
|
|
||||||
auto frameHeight = ImGui::GetFrameHeight();
|
|
||||||
ImGui::BeginGroup();
|
|
||||||
|
|
||||||
ImVec2 effectiveSize = size;
|
|
||||||
if (size.x < 0.0f)
|
|
||||||
effectiveSize.x = ImGui::GetContentRegionAvail().x;
|
|
||||||
else
|
|
||||||
effectiveSize.x = size.x;
|
|
||||||
ImGui::Dummy(ImVec2(effectiveSize.x, 0.0f));
|
|
||||||
|
|
||||||
ImVec2 startPos = window->DC.CursorPos;
|
|
||||||
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
|
|
||||||
ImGui::SameLine(0.0f, 0.0f);
|
|
||||||
ImGui::BeginGroup();
|
|
||||||
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
|
|
||||||
ImGui::SameLine(0.0f, 0.0f);
|
|
||||||
ImGui::TextUnformatted(name);
|
|
||||||
|
|
||||||
auto labelMin = ImGui::GetItemRectMin();
|
|
||||||
auto labelMax = ImGui::GetItemRectMax();
|
|
||||||
ImGui::SameLine(0.0f, 0.0f);
|
|
||||||
|
|
||||||
ImVec2 selectMin = {};
|
|
||||||
ImVec2 selectMax = {};
|
|
||||||
if (selectData != nullptr)
|
|
||||||
{
|
|
||||||
bool useText = true;
|
|
||||||
const char* selectAll = "Select all";
|
|
||||||
auto textSize = ImGui::CalcTextSize(selectAll);
|
|
||||||
auto spaceSize = ImVec2(effectiveSize.x - textSize.x - 35.0f - labelMax.x + startPos.x, 0.0f);
|
|
||||||
if (spaceSize.x <= 0)
|
|
||||||
{
|
|
||||||
spaceSize = ImVec2(effectiveSize.x - 35.0f - labelMax.x + startPos.x, 0.0f);
|
|
||||||
useText = false;
|
|
||||||
}
|
|
||||||
ImGui::Dummy(spaceSize);
|
|
||||||
ImGui::SameLine(0.0f, 0.0f);
|
|
||||||
|
|
||||||
selectData->changed = ImGui::Checkbox(useText ? selectAll : "", &selectData->toggle);
|
|
||||||
|
|
||||||
selectMin = ImGui::GetItemRectMin();
|
|
||||||
selectMax = ImGui::GetItemRectMax();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::SameLine(0.0f, 0.0f);
|
|
||||||
ImGui::Dummy(ImVec2(0.0, frameHeight + itemSpacing.y));
|
|
||||||
|
|
||||||
if (node)
|
|
||||||
{
|
|
||||||
labelMin.x = startPos.x;
|
|
||||||
|
|
||||||
const ImVec2 text_size = ImGui::CalcTextSize(name);
|
|
||||||
const ImGuiID id = window->GetID(name);
|
|
||||||
|
|
||||||
bool isOpen = GroupPanelIsOpen(id);
|
|
||||||
|
|
||||||
bool hovered;
|
|
||||||
bool toggled = ImGui::ButtonBehavior({ labelMin, labelMax }, id, &hovered, nullptr, ImGuiButtonFlags_PressedOnClick);
|
|
||||||
if (toggled)
|
|
||||||
{
|
|
||||||
isOpen = !isOpen;
|
|
||||||
GroupPanelSetOpen(id, isOpen);
|
|
||||||
}
|
|
||||||
|
|
||||||
const ImU32 text_col = ImGui::GetColorU32(ImGuiCol_Text);
|
|
||||||
ImGui::RenderArrow(window->DrawList, { cursorPos.x, cursorPos.y + text_size.y * 0.15f }, text_col,
|
|
||||||
isOpen ? ImGuiDir_Down : ImGuiDir_Right, 0.7f);
|
|
||||||
|
|
||||||
if (!isOpen)
|
|
||||||
{
|
|
||||||
ImGui::PopStyleVar(2);
|
|
||||||
ImGui::EndGroup();
|
|
||||||
ImGui::EndGroup();
|
|
||||||
ImGui::EndGroup();
|
|
||||||
ImGui::PopID();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
|
||||||
|
|
||||||
//ImGui::GetWindowDrawList()->AddRect(labelMin, labelMax, IM_COL32(255, 0, 255, 255));
|
|
||||||
|
|
||||||
ImGui::PopStyleVar(2);
|
|
||||||
|
|
||||||
#if IMGUI_VERSION_NUM >= 17301
|
|
||||||
ImGui::GetCurrentWindow()->ContentRegionRect.Max.x -= frameHeight * 0.5f;
|
|
||||||
ImGui::GetCurrentWindow()->WorkRect.Max.x -= frameHeight * 0.5f;
|
|
||||||
ImGui::GetCurrentWindow()->InnerRect.Max.x -= frameHeight * 0.5f;
|
|
||||||
#else
|
|
||||||
ImGui::GetCurrentWindow()->ContentsRegionRect.Max.x -= frameHeight * 0.5f;
|
|
||||||
#endif
|
|
||||||
ImGui::GetCurrentWindow()->Size.x -= frameHeight;
|
|
||||||
|
|
||||||
auto itemWidth = ImGui::CalcItemWidth();
|
|
||||||
ImGui::PushItemWidth(ImMax(0.0f, itemWidth - frameHeight));
|
|
||||||
|
|
||||||
s_GroupPanelLabelStack.push_back({ ImRect(labelMin, labelMax) , ImRect(selectMin, selectMax)});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EndGroupPanel()
|
|
||||||
{
|
|
||||||
ImGui::PopItemWidth();
|
|
||||||
|
|
||||||
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
|
|
||||||
|
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
|
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
|
||||||
|
|
||||||
auto frameHeight = ImGui::GetFrameHeight();
|
|
||||||
|
|
||||||
ImGui::EndGroup();
|
|
||||||
|
|
||||||
//ImGui::GetWindowDrawList()->AddRectFilled(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(0, 255, 0, 64), 4.0f);
|
|
||||||
|
|
||||||
ImGui::EndGroup();
|
|
||||||
|
|
||||||
ImGui::SameLine(0.0f, 0.0f);
|
|
||||||
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
|
|
||||||
ImGui::Dummy(ImVec2(0.0, frameHeight - frameHeight * 0.5f - itemSpacing.y));
|
|
||||||
|
|
||||||
ImGui::EndGroup();
|
|
||||||
|
|
||||||
auto itemMin = ImGui::GetItemRectMin();
|
|
||||||
auto itemMax = ImGui::GetItemRectMax();
|
|
||||||
//ImGui::GetWindowDrawList()->AddRectFilled(itemMin, itemMax, IM_COL32(255, 0, 0, 64), 4.0f);
|
|
||||||
|
|
||||||
auto& info = s_GroupPanelLabelStack.back();
|
|
||||||
s_GroupPanelLabelStack.pop_back();
|
|
||||||
|
|
||||||
ImVec2 halfFrame = ImVec2(frameHeight * 0.25f, frameHeight) * 0.5f;
|
|
||||||
ImRect frameRect = ImRect(itemMin + halfFrame, itemMax - ImVec2(halfFrame.x, 0.0f));
|
|
||||||
|
|
||||||
auto& labelRect = info.labelRect;
|
|
||||||
labelRect.Min.x -= itemSpacing.x;
|
|
||||||
labelRect.Max.x += itemSpacing.x;
|
|
||||||
|
|
||||||
bool hasSelect = info.selectRect.Min.x != 0;
|
|
||||||
|
|
||||||
if (!hasSelect)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 3; ++i)
|
|
||||||
{
|
|
||||||
switch (i)
|
|
||||||
{
|
|
||||||
// left half-plane
|
|
||||||
case 0: ImGui::PushClipRect(ImVec2(-FLT_MAX, -FLT_MAX), ImVec2(labelRect.Min.x, FLT_MAX), true); break;
|
|
||||||
// right half-plane
|
|
||||||
case 1: ImGui::PushClipRect(ImVec2(labelRect.Max.x, -FLT_MAX), ImVec2(FLT_MAX, FLT_MAX), true); break;
|
|
||||||
// bottom
|
|
||||||
case 2: ImGui::PushClipRect(ImVec2(labelRect.Min.x, labelRect.Max.y), ImVec2(labelRect.Max.x, FLT_MAX), true); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::GetWindowDrawList()->AddRect(
|
|
||||||
frameRect.Min, frameRect.Max,
|
|
||||||
ImColor(ImGui::GetStyleColorVec4(ImGuiCol_Border)),
|
|
||||||
halfFrame.x);
|
|
||||||
|
|
||||||
ImGui::PopClipRect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto& selectRect = info.selectRect;
|
|
||||||
selectRect.Min.x -= itemSpacing.x;
|
|
||||||
selectRect.Max.x += itemSpacing.x;
|
|
||||||
for (int i = 0; i < 5; ++i)
|
|
||||||
{
|
|
||||||
switch (i)
|
|
||||||
{
|
|
||||||
// left half-plane
|
|
||||||
case 0: ImGui::PushClipRect(ImVec2(-FLT_MAX, -FLT_MAX), ImVec2(labelRect.Min.x, FLT_MAX), true); break;
|
|
||||||
// label - select
|
|
||||||
case 1: ImGui::PushClipRect(ImVec2(labelRect.Max.x, -FLT_MAX), ImVec2(selectRect.Min.x, FLT_MAX), true); break;
|
|
||||||
// bottom label
|
|
||||||
case 2: ImGui::PushClipRect(ImVec2(labelRect.Min.x, labelRect.Max.y), ImVec2(labelRect.Max.x, FLT_MAX), true); break;
|
|
||||||
// bottom select
|
|
||||||
case 3: ImGui::PushClipRect(ImVec2(selectRect.Min.x, selectRect.Max.y), ImVec2(selectRect.Max.x, FLT_MAX), true); break;
|
|
||||||
// right hand-plane
|
|
||||||
case 4: ImGui::PushClipRect(ImVec2(selectRect.Max.x, -FLT_MAX), ImVec2(FLT_MAX, FLT_MAX), true); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::GetWindowDrawList()->AddRect(
|
|
||||||
frameRect.Min, frameRect.Max,
|
|
||||||
ImColor(ImGui::GetStyleColorVec4(ImGuiCol_Border)),
|
|
||||||
halfFrame.x);
|
|
||||||
|
|
||||||
ImGui::PopClipRect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ImGui::PopStyleVar(2);
|
|
||||||
|
|
||||||
#if IMGUI_VERSION_NUM >= 17301
|
|
||||||
ImGui::GetCurrentWindow()->ContentRegionRect.Max.x += frameHeight * 0.5f;
|
|
||||||
ImGui::GetCurrentWindow()->WorkRect.Max.x += frameHeight * 0.5f;
|
|
||||||
ImGui::GetCurrentWindow()->InnerRect.Max.x += frameHeight * 0.5f;
|
|
||||||
#else
|
|
||||||
ImGui::GetCurrentWindow()->ContentsRegionRect.Max.x += frameHeight * 0.5f;
|
|
||||||
#endif
|
|
||||||
ImGui::GetCurrentWindow()->Size.x += frameHeight;
|
|
||||||
|
|
||||||
ImGui::Dummy(ImVec2(0.0f, 0.0f));
|
|
||||||
|
|
||||||
ImGui::EndGroup();
|
|
||||||
ImGui::PopID();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddUnderLine(ImColor col_)
|
void AddUnderLine(ImColor col_)
|
||||||
{
|
{
|
||||||
@ -663,8 +414,8 @@ float ImGui::CalcContrastRatio(const ImU32& backgroundColor, const ImU32& foreGr
|
|||||||
float lumFG = 0.2126 * colFG.x + 0.7152 * colFG.y + 0.0722 * colFG.z;
|
float lumFG = 0.2126 * colFG.x + 0.7152 * colFG.y + 0.0722 * colFG.z;
|
||||||
return (ImMax(lumBG, lumFG) + 0.05) / (ImMin(lumBG, lumFG) + 0.05);*/
|
return (ImMax(lumBG, lumFG) + 0.05) / (ImMin(lumBG, lumFG) + 0.05);*/
|
||||||
|
|
||||||
float sa0 = ((backgroundColor >> IM_COL32_A_SHIFT) & 0xFF);
|
float sa0 = static_cast<float>((backgroundColor >> IM_COL32_A_SHIFT) & 0xFF);
|
||||||
float sa1 = ((foreGroundColor >> IM_COL32_A_SHIFT) & 0xFF);
|
float sa1 = static_cast<float>((foreGroundColor >> IM_COL32_A_SHIFT) & 0xFF);
|
||||||
static float sr = 0.2126f / 255.0f;
|
static float sr = 0.2126f / 255.0f;
|
||||||
static float sg = 0.7152f / 255.0f;
|
static float sg = 0.7152f / 255.0f;
|
||||||
static float sb = 0.0722f / 255.0f;
|
static float sb = 0.0722f / 255.0f;
|
||||||
@ -738,3 +489,264 @@ bool ImGui::DrawRenamePopup(std::string& out)
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace ImGui
|
||||||
|
{
|
||||||
|
struct GroupPanelHeaderBounds
|
||||||
|
{
|
||||||
|
ImRect left;
|
||||||
|
ImRect right;
|
||||||
|
bool collapsed;
|
||||||
|
};
|
||||||
|
|
||||||
|
static ImVector<GroupPanelHeaderBounds> _groupPanelStack;
|
||||||
|
|
||||||
|
static bool GroupPanelIsOpen(ImGuiID id)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
|
ImGuiStorage* storage = window->DC.StateStorage;
|
||||||
|
|
||||||
|
return storage->GetInt(id, 1) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GroupPanelSetOpen(ImGuiID id, bool open)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
|
ImGuiStorage* storage = window->DC.StateStorage;
|
||||||
|
|
||||||
|
storage->SetInt(id, open ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modified version of: https://github.com/ocornut/imgui/issues/1496#issuecomment-655048353
|
||||||
|
|
||||||
|
bool BeginGroupPanel(const char* label, bool node, const ImVec2& size)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
|
|
||||||
|
const ImGuiID id = window->GetID(label);
|
||||||
|
ImGui::PushID(id);
|
||||||
|
|
||||||
|
auto groupPanelPos = window->DC.CursorPos;
|
||||||
|
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
|
||||||
|
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
||||||
|
|
||||||
|
ImGui::BeginGroup(); // Outer group
|
||||||
|
|
||||||
|
ImVec2 effectiveSize = size;
|
||||||
|
if (size.x < 0.0f)
|
||||||
|
effectiveSize.x = ImGui::GetContentRegionAvail().x;
|
||||||
|
else
|
||||||
|
effectiveSize.x = size.x;
|
||||||
|
|
||||||
|
ImGui::Dummy(ImVec2(effectiveSize.x, 0.0f)); // Adjusting group x size
|
||||||
|
|
||||||
|
auto frameHeight = ImGui::GetFrameHeight();
|
||||||
|
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f)); ImGui::SameLine(0.0f, 0.0f); // Inner group spacing
|
||||||
|
ImGui::BeginGroup(); // Inner group
|
||||||
|
|
||||||
|
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f)); ImGui::SameLine(0.0f, 0.0f); // Name text spacing
|
||||||
|
ImGui::TextUnformatted(label);
|
||||||
|
|
||||||
|
ImRect leftRect = { ImGui::GetItemRectMin(), ImGui::GetItemRectMax() };
|
||||||
|
ImVec2 rightMax = ImVec2(groupPanelPos.x + effectiveSize.x - frameHeight, leftRect.Max.y);
|
||||||
|
ImRect rightRect = { { rightMax.x, leftRect.Min.x }, rightMax };
|
||||||
|
ImGui::SameLine(0.0f, 0.0f);
|
||||||
|
|
||||||
|
ImGui::Dummy(ImVec2(0.0, frameHeight + itemSpacing.y));
|
||||||
|
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
leftRect.Min.x = groupPanelPos.x;
|
||||||
|
|
||||||
|
const ImVec2 text_size = ImGui::CalcTextSize(label);
|
||||||
|
bool isOpen = GroupPanelIsOpen(id);
|
||||||
|
|
||||||
|
bool hovered;
|
||||||
|
bool toggled = ImGui::ButtonBehavior(leftRect, id, &hovered, nullptr, ImGuiButtonFlags_PressedOnClick);
|
||||||
|
if (toggled)
|
||||||
|
{
|
||||||
|
isOpen = !isOpen;
|
||||||
|
GroupPanelSetOpen(id, isOpen);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ImU32 text_col = ImGui::GetColorU32(ImGuiCol_Text);
|
||||||
|
ImGui::RenderArrow(window->DrawList, { groupPanelPos.x, groupPanelPos.y + text_size.y * 0.15f }, text_col,
|
||||||
|
isOpen ? ImGuiDir_Down : ImGuiDir_Right, 0.7f);
|
||||||
|
|
||||||
|
if (!isOpen)
|
||||||
|
{
|
||||||
|
ImGui::PopStyleVar(2);
|
||||||
|
ImGui::EndGroup();
|
||||||
|
ImGui::EndGroup();
|
||||||
|
ImGui::PopID();
|
||||||
|
|
||||||
|
_groupPanelStack.push_back({ leftRect, rightRect, true });
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::PopStyleVar(2);
|
||||||
|
|
||||||
|
ImGui::GetCurrentWindow()->ContentRegionRect.Max.x -= frameHeight * 0.5f;
|
||||||
|
ImGui::GetCurrentWindow()->WorkRect.Max.x -= frameHeight * 0.5f;
|
||||||
|
ImGui::GetCurrentWindow()->InnerRect.Max.x -= frameHeight * 0.5f;
|
||||||
|
ImGui::GetCurrentWindow()->Size.x -= frameHeight;
|
||||||
|
|
||||||
|
auto itemWidth = ImGui::CalcItemWidth();
|
||||||
|
ImGui::PushItemWidth(ImMax(0.0f, itemWidth - frameHeight));
|
||||||
|
|
||||||
|
_groupPanelStack.push_back({ leftRect, rightRect, false });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EndGroupPanel()
|
||||||
|
{
|
||||||
|
IM_ASSERT(_groupPanelStack.Size > 0); // Mismatched BeginGroupPanel()/EndGroupPanel() calls
|
||||||
|
auto& info = _groupPanelStack.back();
|
||||||
|
_groupPanelStack.pop_back();
|
||||||
|
|
||||||
|
if (info.collapsed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
|
||||||
|
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
||||||
|
|
||||||
|
ImGui::EndGroup(); // Inner group
|
||||||
|
|
||||||
|
auto frameHeight = ImGui::GetFrameHeight();
|
||||||
|
ImGui::SameLine(0.0f, 0.0f);
|
||||||
|
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
|
||||||
|
ImGui::Dummy(ImVec2(0.0, frameHeight - frameHeight * 0.5f - itemSpacing.y));
|
||||||
|
|
||||||
|
ImGui::EndGroup(); // Outer group
|
||||||
|
|
||||||
|
// Outer group rect
|
||||||
|
auto itemMin = ImGui::GetItemRectMin();
|
||||||
|
auto itemMax = ImGui::GetItemRectMax();
|
||||||
|
|
||||||
|
ImVec2 halfFrame = ImVec2(frameHeight * 0.25f, frameHeight) * 0.5f;
|
||||||
|
ImRect frameRect = ImRect(itemMin + halfFrame, itemMax - ImVec2(halfFrame.x, 0.0f));
|
||||||
|
|
||||||
|
auto& leftRect = info.left;
|
||||||
|
leftRect.Min.x -= itemSpacing.x;
|
||||||
|
leftRect.Max.x += itemSpacing.x;
|
||||||
|
|
||||||
|
bool hasRightPart = info.right.Min.x != info.right.Max.x;
|
||||||
|
auto& rightRect = info.right;
|
||||||
|
|
||||||
|
if (hasRightPart)
|
||||||
|
{
|
||||||
|
rightRect.Min.x -= itemSpacing.x;
|
||||||
|
rightRect.Max.x += itemSpacing.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drawing rectangle
|
||||||
|
for (int i = 0; i < (hasRightPart ? 5 : 3); ++i)
|
||||||
|
{
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
// left half-plane
|
||||||
|
case 0: ImGui::PushClipRect(ImVec2(-FLT_MAX, -FLT_MAX), ImVec2(leftRect.Min.x, FLT_MAX), true); break;
|
||||||
|
// right half-plane
|
||||||
|
case 1: ImGui::PushClipRect(ImVec2(leftRect.Max.x, -FLT_MAX), ImVec2(hasRightPart ? rightRect.Min.x : FLT_MAX, FLT_MAX), true); break;
|
||||||
|
// bottom
|
||||||
|
case 2: ImGui::PushClipRect(ImVec2(leftRect.Min.x, leftRect.Max.y), ImVec2(leftRect.Max.x, FLT_MAX), true); break;
|
||||||
|
// bottom select
|
||||||
|
case 3: ImGui::PushClipRect(ImVec2(rightRect.Min.x, rightRect.Max.y), ImVec2(rightRect.Max.x, FLT_MAX), true); break;
|
||||||
|
// right hand-plane
|
||||||
|
case 4: ImGui::PushClipRect(ImVec2(rightRect.Max.x, -FLT_MAX), ImVec2(FLT_MAX, FLT_MAX), true); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::GetWindowDrawList()->AddRect(
|
||||||
|
frameRect.Min, frameRect.Max,
|
||||||
|
ImColor(ImGui::GetStyleColorVec4(ImGuiCol_Border)),
|
||||||
|
halfFrame.x);
|
||||||
|
|
||||||
|
ImGui::PopClipRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ImGui::PopStyleVar(2);
|
||||||
|
|
||||||
|
// Restore content region
|
||||||
|
ImGui::GetCurrentWindow()->ContentRegionRect.Max.x += frameHeight * 0.5f;
|
||||||
|
ImGui::GetCurrentWindow()->WorkRect.Max.x += frameHeight * 0.5f;
|
||||||
|
ImGui::GetCurrentWindow()->InnerRect.Max.x += frameHeight * 0.5f;
|
||||||
|
ImGui::GetCurrentWindow()->Size.x += frameHeight;
|
||||||
|
|
||||||
|
// Add vertical spacing
|
||||||
|
ImGui::Dummy(ImVec2(0.0f, 0.0f));
|
||||||
|
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NextGroupPanelHeaderItem(const ImVec2& size, bool rightAlign)
|
||||||
|
{
|
||||||
|
IM_ASSERT(size.x > 0.0f); // Size should be specified
|
||||||
|
IM_ASSERT(_groupPanelStack.Size > 0); // Mismatched BeginGroupPanel()/EndGroupPanel() calls
|
||||||
|
auto& info = _groupPanelStack.back();
|
||||||
|
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
|
|
||||||
|
if (rightAlign)
|
||||||
|
{
|
||||||
|
if (info.right.Min.x != info.right.Max.x)
|
||||||
|
info.right.Min.x -= g.Style.ItemSpacing.x;
|
||||||
|
|
||||||
|
info.right.Min.x -= size.x;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
info.left.Max.x += g.Style.ItemSpacing.x;
|
||||||
|
|
||||||
|
window->DC.CursorPos.x = rightAlign ? info.right.Min.x : info.left.Max.x;
|
||||||
|
window->DC.CursorPos.y = info.left.Min.y - (size.y - ImGui::GetFrameHeight() + g.Style.FramePadding.y) / 2;
|
||||||
|
|
||||||
|
if (!rightAlign)
|
||||||
|
info.left.Max.x += size.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BeginSelectableGroupPanel(const char* label, bool& value, bool& changed, bool node, const ImVec2& size, const char* selectLabel)
|
||||||
|
{
|
||||||
|
bool opened = BeginGroupPanel(label, node, size);
|
||||||
|
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
|
||||||
|
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
const ImGuiStyle& style = g.Style;
|
||||||
|
|
||||||
|
const ImVec2 label_size = CalcTextSize(selectLabel, NULL, true);
|
||||||
|
const float square_sz = GetFrameHeight();
|
||||||
|
const ImVec2 checkbox_size = ImVec2(square_sz + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), label_size.y + style.FramePadding.y * 2.0f);
|
||||||
|
|
||||||
|
NextGroupPanelHeaderItem(checkbox_size, true);
|
||||||
|
changed = Checkbox(selectLabel, &value);
|
||||||
|
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
return opened;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EndSelectableGroupPanel()
|
||||||
|
{
|
||||||
|
EndGroupPanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImVec2 CalcButtonSize(const char* label)
|
||||||
|
{
|
||||||
|
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||||
|
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
const ImGuiStyle& style = g.Style;
|
||||||
|
ImVec2 size = CalcItemSize({}, label_size.x + style.FramePadding.x * 2.0f, label_size.y + style.FramePadding.y * 2.0f);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -81,16 +81,6 @@ void DrawTextWithOutline(ImDrawList* drawList, ImFont* font, float fontSize, con
|
|||||||
void DrawTextWithOutline(ImDrawList* drawList, const ImVec2& screenPos, const char* text, const ImColor& textColor,
|
void DrawTextWithOutline(ImDrawList* drawList, const ImVec2& screenPos, const char* text, const ImColor& textColor,
|
||||||
float outlineThickness = 0.0f, OutlineSide sides = OutlineSide::All, const ImColor& outlineColor = ImColor(0.0f, 0.0f, 0.0f));
|
float outlineThickness = 0.0f, OutlineSide sides = OutlineSide::All, const ImColor& outlineColor = ImColor(0.0f, 0.0f, 0.0f));
|
||||||
|
|
||||||
|
|
||||||
struct SelectData
|
|
||||||
{
|
|
||||||
bool toggle;
|
|
||||||
bool changed;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool BeginGroupPanel(const char* name, const ImVec2& size = ImVec2(-1, 0), bool node = false, SelectData* selectData = nullptr);
|
|
||||||
void EndGroupPanel();
|
|
||||||
|
|
||||||
namespace ImGui
|
namespace ImGui
|
||||||
{
|
{
|
||||||
bool HotkeyWidget(const char* label, Hotkey& hotkey, const ImVec2& size = ImVec2(0, 0));
|
bool HotkeyWidget(const char* label, Hotkey& hotkey, const ImVec2& size = ImVec2(0, 0));
|
||||||
@ -102,6 +92,16 @@ namespace ImGui
|
|||||||
void OpenRenamePopup(const std::string& initName);
|
void OpenRenamePopup(const std::string& initName);
|
||||||
bool IsRenamePopupOpened();
|
bool IsRenamePopupOpened();
|
||||||
bool DrawRenamePopup(std::string& out);
|
bool DrawRenamePopup(std::string& out);
|
||||||
|
|
||||||
|
bool BeginGroupPanel(const char* label, bool node = false, const ImVec2& size = ImVec2(-1.0f, 0.0f));
|
||||||
|
void EndGroupPanel();
|
||||||
|
|
||||||
|
bool BeginSelectableGroupPanel(const char* label, bool& value, bool& changed, bool node = false, const ImVec2& size = ImVec2(-1.0f, 0.0f), const char* selectLabel = "Select");
|
||||||
|
void EndSelectableGroupPanel();
|
||||||
|
|
||||||
|
void NextGroupPanelHeaderItem(const ImVec2& size, bool rightAlign = false);
|
||||||
|
|
||||||
|
ImVec2 CalcButtonSize(const char* label);
|
||||||
}
|
}
|
||||||
|
|
||||||
float CalcWidth(const std::string_view& view);
|
float CalcWidth(const std::string_view& view);
|
||||||
@ -116,18 +116,29 @@ float GetMaxEnumWidth()
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool ComboEnum(const char* label, T* currentValue)
|
bool ComboEnum(const char* label, T* currentValue, std::vector<T>* whitelist = nullptr)
|
||||||
{
|
{
|
||||||
auto name = magic_enum::enum_name(*currentValue);
|
auto name = magic_enum::enum_name(*currentValue);
|
||||||
auto& current = *currentValue;
|
auto& current = *currentValue;
|
||||||
bool result = false;
|
bool result = false;
|
||||||
static auto width = GetMaxEnumWidth<T>();
|
static auto width = GetMaxEnumWidth<T>();
|
||||||
|
|
||||||
|
std::unordered_set<T> whiteSet;
|
||||||
|
if (whitelist != nullptr)
|
||||||
|
{
|
||||||
|
for (auto& value : *whitelist)
|
||||||
|
{
|
||||||
|
whiteSet.insert(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
ImGui::SetNextItemWidth(width);
|
ImGui::SetNextItemWidth(width);
|
||||||
if (ImGui::BeginCombo(label, name.data()))
|
if (ImGui::BeginCombo(label, name.data()))
|
||||||
{
|
{
|
||||||
for (auto& entry : magic_enum::enum_entries<T>())
|
for (auto& entry : magic_enum::enum_entries<T>())
|
||||||
{
|
{
|
||||||
|
if (whitelist != nullptr && whiteSet.count(entry.first) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
bool is_selected = (name == entry.second);
|
bool is_selected = (name == entry.second);
|
||||||
if (ImGui::Selectable(entry.second.data(), is_selected))
|
if (ImGui::Selectable(entry.second.data(), is_selected))
|
||||||
{
|
{
|
||||||
|
@ -122,7 +122,7 @@ namespace renderer
|
|||||||
for (int i = 0; i < _fontsCount; i++)
|
for (int i = 0; i < _fontsCount; i++)
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
auto newFont = io.Fonts->AddFontFromMemoryTTF(_customFontData.data, _customFontData.size, (i + 1) * _fontSizeStep);
|
auto newFont = io.Fonts->AddFontFromMemoryTTF(_customFontData.data, _customFontData.size, static_cast<float>((i + 1) * _fontSizeStep));
|
||||||
if (newFont == nullptr)
|
if (newFont == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -185,8 +185,8 @@ namespace renderer
|
|||||||
POINT mPos;
|
POINT mPos;
|
||||||
GetCursorPos(&mPos);
|
GetCursorPos(&mPos);
|
||||||
ScreenToClient(hWnd, &mPos);
|
ScreenToClient(hWnd, &mPos);
|
||||||
ImGui::GetIO().MousePos.x = mPos.x;
|
ImGui::GetIO().MousePos.x = static_cast<float>(mPos.x);
|
||||||
ImGui::GetIO().MousePos.y = mPos.y;
|
ImGui::GetIO().MousePos.y = static_cast<float>(mPos.y);
|
||||||
|
|
||||||
ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam);
|
ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam);
|
||||||
|
|
||||||
@ -210,7 +210,7 @@ namespace renderer
|
|||||||
key = GET_XBUTTON_WPARAM(wParam);
|
key = GET_XBUTTON_WPARAM(wParam);
|
||||||
break;
|
break;
|
||||||
case WM_KEYUP:
|
case WM_KEYUP:
|
||||||
key = wParam;
|
key = static_cast<short>(wParam);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
keyUpEvent = false;
|
keyUpEvent = false;
|
||||||
|
@ -222,7 +222,7 @@ namespace util
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<BYTE> base64_decode(std::string const& encoded_string) {
|
std::vector<BYTE> base64_decode(std::string const& encoded_string) {
|
||||||
int in_len = encoded_string.size();
|
size_t in_len = encoded_string.size();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
int in_ = 0;
|
int in_ = 0;
|
||||||
@ -233,7 +233,7 @@ namespace util
|
|||||||
char_array_4[i++] = encoded_string[in_]; in_++;
|
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||||
if (i == 4) {
|
if (i == 4) {
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
char_array_4[i] = base64_chars.find(char_array_4[i]);
|
char_array_4[i] = static_cast<BYTE>(base64_chars.find(char_array_4[i])); // base64_chars len < 255
|
||||||
|
|
||||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||||
@ -250,7 +250,7 @@ namespace util
|
|||||||
char_array_4[j] = 0;
|
char_array_4[j] = 0;
|
||||||
|
|
||||||
for (j = 0; j < 4; j++)
|
for (j = 0; j < 4; j++)
|
||||||
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
char_array_4[j] = static_cast<BYTE>(base64_chars.find(char_array_4[j]));
|
||||||
|
|
||||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||||
@ -261,4 +261,13 @@ namespace util
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t GetTimezoneBias()
|
||||||
|
{
|
||||||
|
_TIME_ZONE_INFORMATION timezoneInfo{};
|
||||||
|
if (GetTimeZoneInformation(&timezoneInfo) == TIME_ZONE_ID_INVALID)
|
||||||
|
LOG_LAST_ERROR("Failed to get timezone.");
|
||||||
|
|
||||||
|
return static_cast<int64_t>(timezoneInfo.Bias) * 60;
|
||||||
|
}
|
||||||
}
|
}
|
@ -42,6 +42,8 @@ namespace util
|
|||||||
std::string base64_encode(BYTE const* buf, unsigned int bufLen);
|
std::string base64_encode(BYTE const* buf, unsigned int bufLen);
|
||||||
std::vector<BYTE> base64_decode(std::string const&);
|
std::vector<BYTE> base64_decode(std::string const&);
|
||||||
|
|
||||||
|
int64_t GetTimezoneBias();
|
||||||
|
|
||||||
|
|
||||||
template<typename ... Args>
|
template<typename ... Args>
|
||||||
std::string string_format(const std::string& format, Args ... args)
|
std::string string_format(const std::string& format, Args ... args)
|
||||||
|
2
cheat-base/vendor/imgui
vendored
2
cheat-base/vendor/imgui
vendored
@ -1 +1 @@
|
|||||||
Subproject commit af916cdf1aa41243b493c217c8d4256c04aa8921
|
Subproject commit 47fb633e73f69e1ba57cef16cd077ddc4d97f0ee
|
@ -15,6 +15,10 @@
|
|||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="src\user\cheat\debugger.h">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WS|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="src\user\cheat\misc\sniffer\MessageManager.h">
|
<ClInclude Include="src\user\cheat\misc\sniffer\MessageManager.h">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WS|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WS|x64'">true</ExcludedFromBuild>
|
||||||
@ -118,6 +122,10 @@
|
|||||||
<Font Include="res\Ruda-ExtraBold.ttf" />
|
<Font Include="res\Ruda-ExtraBold.ttf" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="src\user\cheat\debugger.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WS|x64'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="src\user\cheat\misc\sniffer\MessageManager.cpp">
|
<ClCompile Include="src\user\cheat\misc\sniffer\MessageManager.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WS|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WS|x64'">true</ExcludedFromBuild>
|
||||||
@ -877,7 +885,7 @@
|
|||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>_AMD64_;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;_WINDOWS;_USRDLL;_DEBUG;CHEATLIBRARY_EXPORTS;_PACKET_SNIFFER;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_AMD64_;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;_WINDOWS;_USRDLL;_DEBUG;CHEATLIBRARY_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
<PrecompiledHeaderFile>pch-il2cpp.h</PrecompiledHeaderFile>
|
<PrecompiledHeaderFile>pch-il2cpp.h</PrecompiledHeaderFile>
|
||||||
|
@ -216,6 +216,9 @@
|
|||||||
<ClInclude Include="src\user\cheat\misc\sniffer\MessageManager.h">
|
<ClInclude Include="src\user\cheat\misc\sniffer\MessageManager.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\user\cheat\debugger.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Font Include="res\Ruda-Bold.ttf" />
|
<Font Include="res\Ruda-Bold.ttf" />
|
||||||
@ -390,6 +393,9 @@
|
|||||||
<ClCompile Include="src\user\cheat\misc\sniffer\MessageManager.cpp">
|
<ClCompile Include="src\user\cheat\misc\sniffer\MessageManager.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\user\cheat\debugger.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="res\res.rc">
|
<ResourceCompile Include="res\res.rc">
|
||||||
|
@ -27,7 +27,7 @@ protected:
|
|||||||
std::map<std::string, std::vector<OffsetSignature>> m_MethodInfoPattern;
|
std::map<std::string, std::vector<OffsetSignature>> m_MethodInfoPattern;
|
||||||
std::map<std::string, std::vector<OffsetSignature>> m_TypeInfoPattern;
|
std::map<std::string, std::vector<OffsetSignature>> m_TypeInfoPattern;
|
||||||
|
|
||||||
// Maybe in some feature I do search method/type info by translated name, but not now, not now
|
// Maybe in future I do search method/type info by translated name, but not now, not now
|
||||||
// std::map<std::string, std::string> m_TranslationMap;
|
// std::map<std::string, std::string> m_TranslationMap;
|
||||||
|
|
||||||
std::map<std::string, uintptr_t> m_ApiMethodsCache;
|
std::map<std::string, uintptr_t> m_ApiMethodsCache;
|
||||||
|
12
cheat-library/src/user/cheat/debugger.cpp
Normal file
12
cheat-library/src/user/cheat/debugger.cpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include <pch-il2cpp.h>
|
||||||
|
|
||||||
|
void DebuggerBypassPre()
|
||||||
|
{
|
||||||
|
LOG_INFO("You have no implementation for anti-debugger bypass.\n\tSo if you try to attach VS debugger to process - game will crash.");
|
||||||
|
// Sry, implementation is private for now
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebuggerBypassPost()
|
||||||
|
{
|
||||||
|
// Sry, implementation is privite for now
|
||||||
|
}
|
4
cheat-library/src/user/cheat/debugger.h
Normal file
4
cheat-library/src/user/cheat/debugger.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void DebuggerBypassPre(); // Phase before loading game library
|
||||||
|
void DebuggerBypassPost(); // Phase after loading game library
|
@ -61,53 +61,54 @@ namespace cheat::feature
|
|||||||
|
|
||||||
void ESP::DrawMain()
|
void ESP::DrawMain()
|
||||||
{
|
{
|
||||||
if (BeginGroupPanel("General", ImVec2(-1, 0), true))
|
if (ImGui::BeginGroupPanel("General", true))
|
||||||
{
|
{
|
||||||
ConfigWidget("ESP Enabled", f_Enabled, "Show filtered object through obstacles.");
|
ConfigWidget("ESP Enabled", f_Enabled, "Show filtered object through obstacles.");
|
||||||
ConfigWidget("Range (m)", f_Range, 1.0f, 1.0f, 200.0f);
|
ConfigWidget("Range (m)", f_Range, 1.0f, 1.0f, 200.0f);
|
||||||
|
|
||||||
ConfigWidget(f_DrawBoxMode, "Select the mode of box drawing.");
|
ConfigWidget(f_DrawBoxMode, "Select the mode of box drawing.");
|
||||||
ConfigWidget(f_DrawTracerMode, "Select the mode of tracer drawing.");
|
ConfigWidget(f_DrawTracerMode, "Select the mode of tracer drawing.");
|
||||||
|
|
||||||
ConfigWidget(f_Fill);
|
ConfigWidget(f_Fill);
|
||||||
ConfigWidget(f_FillTransparency, 0.01f, 0.0f, 1.0f, "Transparency of filled part.");
|
ConfigWidget(f_FillTransparency, 0.01f, 0.0f, 1.0f, "Transparency of filled part.");
|
||||||
|
|
||||||
if (f_DrawTracerMode.value() == DrawTracerMode::OffscreenArrows &&
|
if (f_DrawTracerMode.value() == DrawTracerMode::OffscreenArrows)
|
||||||
BeginGroupPanel("Arrow tracer options", ImVec2(-1, 0), true))
|
{
|
||||||
{
|
if (ImGui::BeginGroupPanel("Arrow tracer options", true))
|
||||||
ConfigWidget(f_TracerSize, 0.005f, 0.1f, 10.0f, "Size of tracer.");
|
{
|
||||||
ConfigWidget(f_ArrowRadius, 0.5f, 50.0f, 300.0f, "Radius of arrow.");
|
ConfigWidget(f_TracerSize, 0.005f, 0.1f, 10.0f, "Size of tracer.");
|
||||||
ConfigWidget(f_OutlineThickness, 0.005f, 0.0f, 10.0f, "Outline thickness of arrow.");
|
ConfigWidget(f_ArrowRadius, 0.5f, 50.0f, 300.0f, "Radius of arrow.");
|
||||||
|
ConfigWidget(f_OutlineThickness, 0.005f, 0.0f, 10.0f, "Outline thickness of arrow.");
|
||||||
EndGroupPanel();
|
}
|
||||||
}
|
ImGui::EndGroupPanel();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ConfigWidget(f_DrawName, "Draw name of object.");
|
ConfigWidget(f_DrawName, "Draw name of object.");
|
||||||
ConfigWidget(f_DrawDistance, "Draw distance of object.");
|
ConfigWidget(f_DrawDistance, "Draw distance of object.");
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ConfigWidget(f_FontSize, 0.05f, 1.0f, 100.0f, "Font size of name or distance.");
|
ConfigWidget(f_FontSize, 1, 1, 100, "Font size of name or distance.");
|
||||||
ConfigWidget("## Font outline enabled", f_FontOutline); ImGui::SameLine();
|
ConfigWidget("## Font outline enabled", f_FontOutline); ImGui::SameLine();
|
||||||
ConfigWidget("Font outline", f_FontOutlineSize, 0.001f, 0.0f, 10.0f);
|
ConfigWidget("Font outline", f_FontOutlineSize, 0.001f, 0.0f, 10.0f);
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
if (BeginGroupPanel("Global colors", ImVec2(-1, 0), true))
|
if (ImGui::BeginGroupPanel("Global colors", true))
|
||||||
{
|
{
|
||||||
if (ConfigWidget(f_GlobalFontColor, "Color of line, name, or distance text font."))
|
if (ConfigWidget(f_GlobalFontColor, "Color of line, name, or distance text font."))
|
||||||
m_FontContrastColor = ImGui::CalcContrastColor(f_GlobalFontColor);
|
m_FontContrastColor = ImGui::CalcContrastColor(f_GlobalFontColor);
|
||||||
|
|
||||||
ConfigWidget(f_GlobalBoxColor, "Color of box font.");
|
ConfigWidget(f_GlobalBoxColor, "Color of box font.");
|
||||||
ConfigWidget(f_GlobalLineColor, "Color of line font.");
|
ConfigWidget(f_GlobalLineColor, "Color of line font.");
|
||||||
ConfigWidget(f_GlobalRectColor, "Color of rectangle font.");
|
ConfigWidget(f_GlobalRectColor, "Color of rectangle font.");
|
||||||
EndGroupPanel();
|
|
||||||
}
|
}
|
||||||
|
ImGui::EndGroupPanel();
|
||||||
|
|
||||||
ConfigWidget(f_MinSize, 0.05f, 0.1f, 200.0f, "Minimum entity size as measured in-world.\n" \
|
ConfigWidget(f_MinSize, 0.05f, 0.1f, 200.0f, "Minimum entity size as measured in-world.\n" \
|
||||||
"Some entities have either extremely small or no bounds at all.\n" \
|
"Some entities have either extremely small or no bounds at all.\n" \
|
||||||
"This parameter helps filter out entities that don't meet this condition.");
|
"This parameter helps filter out entities that don't meet this condition.");
|
||||||
|
|
||||||
EndGroupPanel();
|
|
||||||
}
|
}
|
||||||
|
ImGui::EndGroupPanel();
|
||||||
|
|
||||||
ImGui::Text("How to use item filters:\n\tLMB - Toggle visibility\n\tRMB - Open color picker");
|
ImGui::Text("How to use item filters:\n\tLMB - Toggle visibility\n\tRMB - Open color picker");
|
||||||
ImGui::InputText("Search Filters", &m_Search);
|
ImGui::InputText("Search Filters", &m_Search);
|
||||||
@ -174,13 +175,10 @@ namespace cheat::feature
|
|||||||
if (validFilters.empty())
|
if (validFilters.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SelectData selData
|
bool checked = std::all_of(validFilters.begin(), validFilters.end(), [](const FilterInfo* filter) { return filter->first.value().m_Enabled; });
|
||||||
{
|
bool changed = false;
|
||||||
std::all_of(validFilters.begin(), validFilters.end(), [](const FilterInfo* filter) { return filter->first.value().m_Enabled; }),
|
|
||||||
false
|
|
||||||
};
|
|
||||||
|
|
||||||
if (BeginGroupPanel(section.c_str(), ImVec2(-1, 0), true, &selData))
|
if (ImGui::BeginSelectableGroupPanel(section.c_str(), checked, changed, true))
|
||||||
{
|
{
|
||||||
for (auto& info : validFilters)
|
for (auto& info : validFilters)
|
||||||
{
|
{
|
||||||
@ -207,14 +205,14 @@ namespace cheat::feature
|
|||||||
|
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
|
||||||
}
|
}
|
||||||
|
ImGui::EndSelectableGroupPanel();
|
||||||
|
|
||||||
if (selData.changed)
|
if (changed)
|
||||||
{
|
{
|
||||||
for (auto& info : validFilters)
|
for (auto& info : validFilters)
|
||||||
{
|
{
|
||||||
info->first.value().m_Enabled = selData.toggle;
|
info->first.value().m_Enabled = checked;
|
||||||
info->first.FireChanged();
|
info->first.FireChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,18 +26,20 @@ namespace cheat::feature::esp::render
|
|||||||
|
|
||||||
s_Camera = nullptr;
|
s_Camera = nullptr;
|
||||||
|
|
||||||
|
auto loadingManager = GET_SINGLETON(LoadingManager);
|
||||||
|
if (loadingManager == nullptr || !app::LoadingManager_IsLoaded(loadingManager, nullptr))
|
||||||
|
return;
|
||||||
|
|
||||||
|
SAFE_BEGIN();
|
||||||
auto camera = app::Camera_get_main(nullptr, nullptr);
|
auto camera = app::Camera_get_main(nullptr, nullptr);
|
||||||
if (camera == nullptr)
|
if (camera == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!app::Behaviour_get_isActiveAndEnabled(reinterpret_cast<app::Behaviour*>(camera), nullptr))
|
if (!app::Behaviour_get_isActiveAndEnabled(reinterpret_cast<app::Behaviour*>(camera), nullptr))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto loadingManager = GET_SINGLETON(LoadingManager);
|
|
||||||
if (loadingManager == nullptr || !app::LoadingManager_IsLoaded(loadingManager, nullptr))
|
|
||||||
return;
|
|
||||||
|
|
||||||
s_Camera = camera;
|
s_Camera = camera;
|
||||||
|
SAFE_EEND();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UpdateResolutionScale()
|
static void UpdateResolutionScale()
|
||||||
@ -65,11 +67,11 @@ namespace cheat::feature::esp::render
|
|||||||
if (screenHeight == pixelHeight && screenWidth == pixelWidth)
|
if (screenHeight == pixelHeight && screenWidth == pixelWidth)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
s_ScreenResolution.x = screenWidth;
|
s_ScreenResolution.x = static_cast<float>(screenWidth);
|
||||||
s_ScreenResolution.y = screenHeight;
|
s_ScreenResolution.y = static_cast<float>(screenHeight);
|
||||||
|
|
||||||
s_ResolutionScale.x = static_cast<float>(screenWidth) / static_cast<float>(pixelWidth);
|
s_ResolutionScale.x = s_ScreenResolution.x / static_cast<float>(pixelWidth);
|
||||||
s_ResolutionScale.y = static_cast<float>(screenHeight) / static_cast<float>(pixelHeight);
|
s_ResolutionScale.y = s_ScreenResolution.y / static_cast<float>(pixelHeight);
|
||||||
SAFE_EEND();
|
SAFE_EEND();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,7 +393,7 @@ namespace cheat::feature::esp::render
|
|||||||
draw->AddLine(s_AvatarPosition, *screenPos, color);
|
draw->AddLine(s_AvatarPosition, *screenPos, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PI 3.14159265358979323846
|
#define PI 3.14159265358979323846f
|
||||||
|
|
||||||
static void DrawOffscreenArrows(game::Entity* entity, const ImColor& color)
|
static void DrawOffscreenArrows(game::Entity* entity, const ImColor& color)
|
||||||
{
|
{
|
||||||
@ -438,10 +440,10 @@ namespace cheat::feature::esp::render
|
|||||||
entity_pos.x < 0 ? abs(entity_pos.x) : (entity_pos.x > screen_rect.Max.x ? entity_pos.x - screen_rect.Max.x : 0.0f),
|
entity_pos.x < 0 ? abs(entity_pos.x) : (entity_pos.x > screen_rect.Max.x ? entity_pos.x - screen_rect.Max.x : 0.0f),
|
||||||
entity_pos.y < 0 ? abs(entity_pos.y) : (entity_pos.y > screen_rect.Max.y ? entity_pos.y - screen_rect.Max.y : 0.0f),
|
entity_pos.y < 0 ? abs(entity_pos.y) : (entity_pos.y > screen_rect.Max.y ? entity_pos.y - screen_rect.Max.y : 0.0f),
|
||||||
};
|
};
|
||||||
auto distance = std::pow(screen_outer_diff.x, 2) + std::pow(screen_outer_diff.y, 2);
|
float distance = static_cast<float>(std::pow(screen_outer_diff.x, 2) + std::pow(screen_outer_diff.y, 2));
|
||||||
alpha = entity_pos.z < 0 ? 1.0f : (distance / nearThreshold);
|
alpha = entity_pos.z < 0 ? 1.0f : (distance / nearThreshold);
|
||||||
}
|
}
|
||||||
auto arrowColor = color;
|
auto arrowColor = color; // Copy
|
||||||
arrowColor.Value.w = std::min(alpha, 1.0f);
|
arrowColor.Value.w = std::min(alpha, 1.0f);
|
||||||
|
|
||||||
// Draw the arrow
|
// Draw the arrow
|
||||||
@ -477,19 +479,19 @@ namespace cheat::feature::esp::render
|
|||||||
// Might need to be aware of performance hit but there shouldn't be any.
|
// Might need to be aware of performance hit but there shouldn't be any.
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImFont* font = g.Font;
|
ImFont* font = g.Font;
|
||||||
auto textSize = font->CalcTextSizeA(esp.f_FontSize, FLT_MAX, FLT_MAX, text.c_str());
|
auto textSize = font->CalcTextSizeA(static_cast<float>(esp.f_FontSize), FLT_MAX, FLT_MAX, text.c_str());
|
||||||
namePosition.x -= (textSize.x / 2.0f);
|
namePosition.x -= (textSize.x / 2.0f);
|
||||||
namePosition.y -= esp.f_FontSize;
|
namePosition.y -= esp.f_FontSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
auto draw = ImGui::GetBackgroundDrawList();
|
auto draw = ImGui::GetBackgroundDrawList();
|
||||||
auto font = renderer::GetFontBySize(esp.f_FontSize);
|
auto font = renderer::GetFontBySize(static_cast<float>(esp.f_FontSize));
|
||||||
// Outline
|
// Outline
|
||||||
if (esp.f_FontOutline)
|
if (esp.f_FontOutline)
|
||||||
DrawTextWithOutline(draw, font, esp.f_FontSize, namePosition, text.c_str(), color, esp.f_FontOutlineSize, OutlineSide::All, contrastColor);
|
DrawTextWithOutline(draw, font, static_cast<float>(esp.f_FontSize), namePosition, text.c_str(), color, esp.f_FontOutlineSize, OutlineSide::All, contrastColor);
|
||||||
else
|
else
|
||||||
draw->AddText(font, esp.f_FontSize, namePosition, color, text.c_str());
|
draw->AddText(font, static_cast<float>(esp.f_FontSize), namePosition, color, text.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DrawEntity(const std::string& name, game::Entity* entity, const ImColor& color, const ImColor& contrastColor)
|
bool DrawEntity(const std::string& name, game::Entity* entity, const ImColor& color, const ImColor& contrastColor)
|
||||||
|
@ -112,7 +112,7 @@ namespace cheat::feature
|
|||||||
|
|
||||||
void InteractiveMap::DrawMenu()
|
void InteractiveMap::DrawMenu()
|
||||||
{
|
{
|
||||||
BeginGroupPanel("General");
|
ImGui::BeginGroupPanel("General");
|
||||||
{
|
{
|
||||||
ConfigWidget("Enabled", f_Enabled);
|
ConfigWidget("Enabled", f_Enabled);
|
||||||
ConfigWidget(f_SeparatedWindows, "Config and filters will be in separate windows.");
|
ConfigWidget(f_SeparatedWindows, "Config and filters will be in separate windows.");
|
||||||
@ -121,25 +121,25 @@ namespace cheat::feature
|
|||||||
UpdateUserDataField(f_CompletedPointsJson, f_STCompletedPoints.value(), true);
|
UpdateUserDataField(f_CompletedPointsJson, f_STCompletedPoints.value(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
|
|
||||||
BeginGroupPanel("Icon view");
|
ImGui::BeginGroupPanel("Icon view");
|
||||||
{
|
{
|
||||||
ConfigWidget(f_IconSize, 0.01f, 4.0f, 100.0f);
|
ConfigWidget(f_IconSize, 0.01f, 4.0f, 100.0f);
|
||||||
ConfigWidget(f_MinimapIconSize, 0.01f, 4.0f, 100.0f);
|
ConfigWidget(f_MinimapIconSize, 0.01f, 4.0f, 100.0f);
|
||||||
ConfigWidget(f_DynamicSize, "Icons will be sized dynamically depend to zoom size.\nMinimap icons don't affected.");
|
ConfigWidget(f_DynamicSize, "Icons will be sized dynamically depend to zoom size.\nMinimap icons don't affected.");
|
||||||
ConfigWidget(f_ShowHDIcons, "Toggle icons to HD format.");
|
ConfigWidget(f_ShowHDIcons, "Toggle icons to HD format.");
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
|
|
||||||
BeginGroupPanel("Completed icon view");
|
ImGui::BeginGroupPanel("Completed icon view");
|
||||||
{
|
{
|
||||||
ConfigWidget(f_ShowCompleted, "Show completed points.");
|
ConfigWidget(f_ShowCompleted, "Show completed points.");
|
||||||
ConfigWidget(f_CompletePointTransparency, 0.01f, 0.0f, 1.0f, "Completed points transparency.");
|
ConfigWidget(f_CompletePointTransparency, 0.01f, 0.0f, 1.0f, "Completed points transparency.");
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
|
|
||||||
BeginGroupPanel("Item adjusting");
|
ImGui::BeginGroupPanel("Item adjusting");
|
||||||
{
|
{
|
||||||
ConfigWidget(f_AutoFixItemPositions, "Do fix positions to nearest to point.\n"
|
ConfigWidget(f_AutoFixItemPositions, "Do fix positions to nearest to point.\n"
|
||||||
"Only items with green line support this function.");
|
"Only items with green line support this function.");
|
||||||
@ -157,9 +157,9 @@ namespace cheat::feature
|
|||||||
ConfigWidget(f_CheckObjectsDelay, 10, 100, 100000, "Adjusting items is power consumption operation.\n"
|
ConfigWidget(f_CheckObjectsDelay, 10, 100, 100000, "Adjusting items is power consumption operation.\n"
|
||||||
"So rescanning will happen with specified delay.");
|
"So rescanning will happen with specified delay.");
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
|
|
||||||
BeginGroupPanel("Gather detecting");
|
ImGui::BeginGroupPanel("Gather detecting");
|
||||||
{
|
{
|
||||||
ConfigWidget(f_AutoDetectGatheredItems, "Enables detecting gathered items.\n"
|
ConfigWidget(f_AutoDetectGatheredItems, "Enables detecting gathered items.\n"
|
||||||
"It works only items what will be gathered after enabling this function.\n"
|
"It works only items what will be gathered after enabling this function.\n"
|
||||||
@ -168,16 +168,16 @@ namespace cheat::feature
|
|||||||
ConfigWidget(f_GatheredItemsDetectRange, 0.1f, 5.0f, 30.0f,
|
ConfigWidget(f_GatheredItemsDetectRange, 0.1f, 5.0f, 30.0f,
|
||||||
"When entity was gathered finding nearest point in this range.");
|
"When entity was gathered finding nearest point in this range.");
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
|
|
||||||
BeginGroupPanel("Manual completing");
|
ImGui::BeginGroupPanel("Manual completing");
|
||||||
{
|
{
|
||||||
ConfigWidget(f_CompleteNearestPoint, true, "When pressed, complete the nearest to avatar point.");
|
ConfigWidget(f_CompleteNearestPoint, true, "When pressed, complete the nearest to avatar point.");
|
||||||
ConfigWidget(f_RevertLatestCompletion, true, "When pressed, revert latest complete operation.");
|
ConfigWidget(f_RevertLatestCompletion, true, "When pressed, revert latest complete operation.");
|
||||||
ConfigWidget(f_CompleteOnlyViewed, "Complete performed only to visible points.");
|
ConfigWidget(f_CompleteOnlyViewed, "Complete performed only to visible points.");
|
||||||
ConfigWidget(f_PointFindRange, 0.5f, 0.0f, 200.0f, "Complete performs within specified range. If 0 - unlimited.");
|
ConfigWidget(f_PointFindRange, 0.5f, 0.0f, 200.0f, "Complete performs within specified range. If 0 - unlimited.");
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractiveMap::DrawFilters(const bool searchFixed)
|
void InteractiveMap::DrawFilters(const bool searchFixed)
|
||||||
@ -223,13 +223,10 @@ namespace cheat::feature
|
|||||||
if (validLabels.empty())
|
if (validLabels.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SelectData selData
|
bool checked = std::all_of(validLabels.begin(), validLabels.end(), [](const LabelData* label) { return label->enabled; });
|
||||||
{
|
bool changed = false;
|
||||||
std::all_of(validLabels.begin(), validLabels.end(), [](const LabelData* label) { return label->enabled; }),
|
|
||||||
false
|
|
||||||
};
|
|
||||||
|
|
||||||
if (BeginGroupPanel(categoryName.c_str(), ImVec2(-1, 0), true, &selData))
|
if (ImGui::BeginSelectableGroupPanel(categoryName.c_str(), checked, changed, true))
|
||||||
{
|
{
|
||||||
if (ImGui::BeginTable("MarkFilters", 2))
|
if (ImGui::BeginTable("MarkFilters", 2))
|
||||||
{
|
{
|
||||||
@ -242,15 +239,14 @@ namespace cheat::feature
|
|||||||
}
|
}
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
EndGroupPanel();
|
|
||||||
}
|
}
|
||||||
|
ImGui::EndSelectableGroupPanel();
|
||||||
|
|
||||||
if (selData.changed)
|
if (changed)
|
||||||
{
|
{
|
||||||
for (const auto& label : validLabels)
|
for (const auto& label : validLabels)
|
||||||
{
|
{
|
||||||
label->enabled = selData.toggle;
|
label->enabled = checked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,7 +438,7 @@ namespace cheat::feature
|
|||||||
ImGui::TableHeadersRow();
|
ImGui::TableHeadersRow();
|
||||||
|
|
||||||
ImGuiListClipper clipper;
|
ImGuiListClipper clipper;
|
||||||
clipper.Begin(entities.size());
|
clipper.Begin(static_cast<int>(entities.size()));
|
||||||
while (clipper.Step())
|
while (clipper.Step())
|
||||||
for (int row_n = clipper.DisplayStart; row_n < clipper.DisplayEnd; row_n++)
|
for (int row_n = clipper.DisplayStart; row_n < clipper.DisplayEnd; row_n++)
|
||||||
{
|
{
|
||||||
@ -1037,6 +1037,7 @@ namespace cheat::feature
|
|||||||
}
|
}
|
||||||
catch (nlohmann::detail::parse_error& parseError)
|
catch (nlohmann::detail::parse_error& parseError)
|
||||||
{
|
{
|
||||||
|
UNREFERENCED_PARAMETER(parseError);
|
||||||
LOG_ERROR("Failed to parse json");
|
LOG_ERROR("Failed to parse json");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,14 +57,14 @@ namespace cheat::feature
|
|||||||
|
|
||||||
for (auto& fields : multiLineSections)
|
for (auto& fields : multiLineSections)
|
||||||
{
|
{
|
||||||
if (BeginGroupPanel((*fields)[0]->section().c_str(), ImVec2(-1, 0), true))
|
if (ImGui::BeginGroupPanel((*fields)[0]->section().c_str(), true))
|
||||||
{
|
{
|
||||||
for (auto& field : *fields)
|
for (auto& field : *fields)
|
||||||
{
|
{
|
||||||
ConfigWidget(*field, nullptr, true);
|
ConfigWidget(*field, nullptr, true);
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
|
||||||
}
|
}
|
||||||
|
ImGui::EndGroupPanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
|
@ -39,6 +39,8 @@ namespace sniffer
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageManager::ProcessMessage()
|
void MessageManager::ProcessMessage()
|
||||||
|
@ -21,7 +21,7 @@ namespace sniffer
|
|||||||
|
|
||||||
uint32_t PacketInfo::id() const
|
uint32_t PacketInfo::id() const
|
||||||
{
|
{
|
||||||
return m_Data.packetID;
|
return m_Data.messageID;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t PacketInfo::size() const
|
size_t PacketInfo::size() const
|
||||||
|
@ -26,7 +26,7 @@ namespace sniffer
|
|||||||
|
|
||||||
bool PacketParser::Parse(PacketData& data)
|
bool PacketParser::Parse(PacketData& data)
|
||||||
{
|
{
|
||||||
auto name = m_ProtoManager.GetName(data.packetID);
|
auto name = m_ProtoManager.GetName(data.messageID);
|
||||||
if (!name)
|
if (!name)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ namespace sniffer
|
|||||||
if (!head)
|
if (!head)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto message = m_ProtoManager.GetJson(data.packetID, data.messageRawData);
|
auto message = m_ProtoManager.GetJson(data.messageID, data.messageRawData);
|
||||||
if (!message)
|
if (!message)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ namespace sniffer
|
|||||||
|
|
||||||
bool PacketParser::IsUnionPacket(const PacketData& data)
|
bool PacketParser::IsUnionPacket(const PacketData& data)
|
||||||
{
|
{
|
||||||
return m_UnionPacketIds.count(data.packetID) > 0;
|
return m_UnionPacketIds.count(data.messageID) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PacketData> PacketParser::ParseUnionPacket(const PacketData& data)
|
std::vector<PacketData> PacketParser::ParseUnionPacket(const PacketData& data)
|
||||||
@ -54,7 +54,7 @@ namespace sniffer
|
|||||||
if (!IsUnionPacket(data))
|
if (!IsUnionPacket(data))
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
auto parseFunction = m_UnionPacketIds[data.packetID];
|
auto parseFunction = m_UnionPacketIds[data.messageID];
|
||||||
return (this->*parseFunction)(data);
|
return (this->*parseFunction)(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,10 +64,10 @@ namespace sniffer
|
|||||||
nestedPacketData.headRawData = parent.headRawData;
|
nestedPacketData.headRawData = parent.headRawData;
|
||||||
nestedPacketData.headJson = parent.headJson;
|
nestedPacketData.headJson = parent.headJson;
|
||||||
nestedPacketData.messageRawData = util::base64_decode(bodyEncoded);
|
nestedPacketData.messageRawData = util::base64_decode(bodyEncoded);
|
||||||
nestedPacketData.packetID = packetID;
|
nestedPacketData.messageID = packetID;
|
||||||
nestedPacketData.valid = true;
|
nestedPacketData.valid = true;
|
||||||
nestedPacketData.ioType = parent.ioType;
|
nestedPacketData.ioType = parent.ioType;
|
||||||
nestedPacketData.parentID = parent.sequenceID();
|
nestedPacketData.parentPacketID = parent.sequenceID();
|
||||||
|
|
||||||
if (packetID != 0)
|
if (packetID != 0)
|
||||||
Parse(nestedPacketData);
|
Parse(nestedPacketData);
|
||||||
|
@ -129,7 +129,7 @@ namespace cheat::feature
|
|||||||
auto dataSize = modifyData->modifiedData.size();
|
auto dataSize = modifyData->modifiedData.size();
|
||||||
packet->data = new byte[dataSize]();
|
packet->data = new byte[dataSize]();
|
||||||
memcpy_s(packet->data, dataSize, modifyData->modifiedData.data(), dataSize);
|
memcpy_s(packet->data, dataSize, modifyData->modifiedData.data(), dataSize);
|
||||||
packet->dataLen = dataSize;
|
packet->dataLen = static_cast<uint32_t>(dataSize);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PacketModifyType::Unchanged:
|
case PacketModifyType::Unchanged:
|
||||||
@ -224,7 +224,7 @@ namespace cheat::feature
|
|||||||
}
|
}
|
||||||
|
|
||||||
packetData.valid = true;
|
packetData.valid = true;
|
||||||
packetData.packetID = messageId;
|
packetData.messageID = messageId;
|
||||||
|
|
||||||
packetData.headRawData = std::vector<byte>((size_t)headSize, 0);
|
packetData.headRawData = std::vector<byte>((size_t)headSize, 0);
|
||||||
memcpy_s(packetData.headRawData.data(), headSize, data + 10, headSize);
|
memcpy_s(packetData.headRawData.data(), headSize, data + 10, headSize);
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
namespace sniffer
|
namespace sniffer
|
||||||
{
|
{
|
||||||
|
|
||||||
static class ErrorCollector : public google::protobuf::compiler::MultiFileErrorCollector
|
class ErrorCollector : public google::protobuf::compiler::MultiFileErrorCollector
|
||||||
{
|
{
|
||||||
// Inherited via MultiFileErrorCollector
|
// Inherited via MultiFileErrorCollector
|
||||||
virtual void AddError(const std::string& filename, int line, int column, const std::string& message) override
|
virtual void AddError(const std::string& filename, int line, int column, const std::string& message) override
|
||||||
|
@ -437,6 +437,7 @@ namespace sniffer
|
|||||||
}
|
}
|
||||||
catch (const std::regex_error& e)
|
catch (const std::regex_error& e)
|
||||||
{
|
{
|
||||||
|
UNREFERENCED_PARAMETER(e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -465,7 +466,7 @@ namespace sniffer
|
|||||||
|
|
||||||
bool removed = false;
|
bool removed = false;
|
||||||
auto name = fmt::format("Group {}", magic_enum::enum_name(m_Rule));
|
auto name = fmt::format("Group {}", magic_enum::enum_name(m_Rule));
|
||||||
BeginGroupPanel(name.c_str(), ImVec2(-1, 0));
|
ImGui::BeginGroupPanel(name.c_str());
|
||||||
{
|
{
|
||||||
ComboEnum("Rule", &m_Rule);
|
ComboEnum("Rule", &m_Rule);
|
||||||
|
|
||||||
@ -498,7 +499,7 @@ namespace sniffer
|
|||||||
m_Filters.push_back(new Filter());
|
m_Filters.push_back(new Filter());
|
||||||
|
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
|
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@ void PacketData::Write(PipeTransfer* transfer)
|
|||||||
transfer->Write(ioType);
|
transfer->Write(ioType);
|
||||||
transfer->Write(dataType);
|
transfer->Write(dataType);
|
||||||
transfer->Write(valid);
|
transfer->Write(valid);
|
||||||
transfer->Write(parentID);
|
transfer->Write(parentPacketID);
|
||||||
transfer->Write(packetID);
|
transfer->Write(messageID);
|
||||||
transfer->Write(headRawData);
|
transfer->Write(headRawData);
|
||||||
transfer->Write(messageRawData);
|
transfer->Write(messageRawData);
|
||||||
|
|
||||||
@ -26,8 +26,8 @@ void PacketData::Read(PipeTransfer* transfer)
|
|||||||
transfer->Read(ioType);
|
transfer->Read(ioType);
|
||||||
transfer->Read(dataType);
|
transfer->Read(dataType);
|
||||||
transfer->Read(valid);
|
transfer->Read(valid);
|
||||||
transfer->Read(parentID);
|
transfer->Read(parentPacketID);
|
||||||
transfer->Read(packetID);
|
transfer->Read(messageID);
|
||||||
transfer->Read(headRawData);
|
transfer->Read(headRawData);
|
||||||
transfer->Read(messageRawData);
|
transfer->Read(messageRawData);
|
||||||
|
|
||||||
|
@ -26,9 +26,9 @@ public:
|
|||||||
|
|
||||||
bool valid;
|
bool valid;
|
||||||
|
|
||||||
uint64_t parentID;
|
uint64_t parentPacketID;
|
||||||
|
|
||||||
int16_t packetID;
|
int16_t messageID;
|
||||||
std::vector<byte> headRawData;
|
std::vector<byte> headRawData;
|
||||||
std::vector<byte> messageRawData;
|
std::vector<byte> messageRawData;
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ namespace cheat::feature
|
|||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::TableSetColumnIndex(0);
|
ImGui::TableSetColumnIndex(0);
|
||||||
|
|
||||||
BeginGroupPanel("Auto-Pickup", ImVec2(-1, 0));
|
ImGui::BeginGroupPanel("Auto-Pickup");
|
||||||
{
|
{
|
||||||
ConfigWidget("Enabled", f_AutoPickup, "Automatically picks up dropped items.\n" \
|
ConfigWidget("Enabled", f_AutoPickup, "Automatically picks up dropped items.\n" \
|
||||||
"Note: Using this with custom range and low delay times is extremely risky.\n" \
|
"Note: Using this with custom range and low delay times is extremely risky.\n" \
|
||||||
@ -56,9 +56,9 @@ namespace cheat::feature
|
|||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::TextColored(ImColor(255, 165, 0, 255), "Read the note!");
|
ImGui::TextColored(ImColor(255, 165, 0, 255), "Read the note!");
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
|
|
||||||
BeginGroupPanel("Custom Pickup Range", ImVec2(-1, 0));
|
ImGui::BeginGroupPanel("Custom Pickup Range");
|
||||||
{
|
{
|
||||||
ConfigWidget("Enabled", f_UseCustomRange, "Enable custom pickup range.\n" \
|
ConfigWidget("Enabled", f_UseCustomRange, "Enable custom pickup range.\n" \
|
||||||
"High values are not recommended, as it is easily detected by the server.\n\n" \
|
"High values are not recommended, as it is easily detected by the server.\n\n" \
|
||||||
@ -68,18 +68,18 @@ namespace cheat::feature
|
|||||||
ImGui::SetNextItemWidth(100.0f);
|
ImGui::SetNextItemWidth(100.0f);
|
||||||
ConfigWidget("Range (m)", f_CustomRange, 0.1f, 0.5f, 40.0f, "Modifies pickup/open range to this value (in meters).");
|
ConfigWidget("Range (m)", f_CustomRange, 0.1f, 0.5f, 40.0f, "Modifies pickup/open range to this value (in meters).");
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
|
|
||||||
BeginGroupPanel("Looting Speed", ImVec2(-1, 0));
|
ImGui::BeginGroupPanel("Looting Speed");
|
||||||
{
|
{
|
||||||
ImGui::SetNextItemWidth(100.0f);
|
ImGui::SetNextItemWidth(100.0f);
|
||||||
ConfigWidget("Delay Time (ms)", f_DelayTime, 1, 0, 1000, "Delay (in ms) between loot/open actions.\n" \
|
ConfigWidget("Delay Time (ms)", f_DelayTime, 1, 0, 1000, "Delay (in ms) between loot/open actions.\n" \
|
||||||
"Values under 200ms are unsafe.\nNot used if no auto-functions are on.");
|
"Values under 200ms are unsafe.\nNot used if no auto-functions are on.");
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
|
|
||||||
ImGui::TableSetColumnIndex(1);
|
ImGui::TableSetColumnIndex(1);
|
||||||
BeginGroupPanel("Auto-Treasure", ImVec2(-1, 0));
|
ImGui::BeginGroupPanel("Auto-Treasure");
|
||||||
{
|
{
|
||||||
ConfigWidget("Enabled", f_AutoTreasure, "Automatically opens chests and other treasures.\n" \
|
ConfigWidget("Enabled", f_AutoTreasure, "Automatically opens chests and other treasures.\n" \
|
||||||
"Note: Using this with custom range and low delay times is extremely risky.\n" \
|
"Note: Using this with custom range and low delay times is extremely risky.\n" \
|
||||||
@ -95,7 +95,7 @@ namespace cheat::feature
|
|||||||
ConfigWidget("Others", f_Others, "Book Pages, Spincrystals, etc.");
|
ConfigWidget("Others", f_Others, "Book Pages, Spincrystals, etc.");
|
||||||
ImGui::Unindent();
|
ImGui::Unindent();
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ namespace cheat::feature
|
|||||||
|
|
||||||
auto& attackCount = s_AttackCountMap[position];
|
auto& attackCount = s_AttackCountMap[position];
|
||||||
attackCount++;
|
attackCount++;
|
||||||
if (attackCount > m_AttackPerTree)
|
if (attackCount > static_cast<uint32_t>(m_AttackPerTree))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,23 +40,23 @@ namespace cheat::feature
|
|||||||
"Mobs within the specified radius will move\nto a specified distance in front of the player.");
|
"Mobs within the specified radius will move\nto a specified distance in front of the player.");
|
||||||
|
|
||||||
bool filtersChanged = false;
|
bool filtersChanged = false;
|
||||||
BeginGroupPanel("Monsters", ImVec2(-1, 0));
|
ImGui::BeginGroupPanel("Monsters");
|
||||||
{
|
{
|
||||||
filtersChanged |= ConfigWidget(f_IncludeMonsters, "Include monsters in vacuum.");
|
filtersChanged |= ConfigWidget(f_IncludeMonsters, "Include monsters in vacuum.");
|
||||||
filtersChanged |= ConfigWidget(f_MonsterCommon, "Common enemies."); ImGui::SameLine();
|
filtersChanged |= ConfigWidget(f_MonsterCommon, "Common enemies."); ImGui::SameLine();
|
||||||
filtersChanged |= ConfigWidget(f_MonsterElites, "Elite enemies."); ImGui::SameLine();
|
filtersChanged |= ConfigWidget(f_MonsterElites, "Elite enemies."); ImGui::SameLine();
|
||||||
filtersChanged |= ConfigWidget(f_MonsterBosses, "World and Trounce boss enemies.");
|
filtersChanged |= ConfigWidget(f_MonsterBosses, "World and Trounce boss enemies.");
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
|
|
||||||
BeginGroupPanel("Animals", ImVec2(-1, 0));
|
ImGui::BeginGroupPanel("Animals");
|
||||||
{
|
{
|
||||||
filtersChanged |= ConfigWidget(f_IncludeAnimals, "Include animals in vacuum.");
|
filtersChanged |= ConfigWidget(f_IncludeAnimals, "Include animals in vacuum.");
|
||||||
filtersChanged |= ConfigWidget(f_AnimalDrop, "Animals you need to kill before collecting."); ImGui::SameLine();
|
filtersChanged |= ConfigWidget(f_AnimalDrop, "Animals you need to kill before collecting."); ImGui::SameLine();
|
||||||
filtersChanged |= ConfigWidget(f_AnimalPickUp, "Animals you can immediately collect."); ImGui::SameLine();
|
filtersChanged |= ConfigWidget(f_AnimalPickUp, "Animals you can immediately collect."); ImGui::SameLine();
|
||||||
filtersChanged |= ConfigWidget(f_AnimalNPC, "Animals without mechanics.");
|
filtersChanged |= ConfigWidget(f_AnimalNPC, "Animals without mechanics.");
|
||||||
}
|
}
|
||||||
EndGroupPanel();
|
ImGui::EndGroupPanel();
|
||||||
|
|
||||||
if (filtersChanged)
|
if (filtersChanged)
|
||||||
UpdateFilters();
|
UpdateFilters();
|
||||||
|
@ -6,23 +6,16 @@
|
|||||||
#include <cheat/cheat.h>
|
#include <cheat/cheat.h>
|
||||||
#include <cheat-base/cheat/misc/Settings.h>
|
#include <cheat-base/cheat/misc/Settings.h>
|
||||||
|
|
||||||
|
#include <tlhelp32.h>
|
||||||
#include <cheat/ILPatternScanner.h>
|
#include <cheat/ILPatternScanner.h>
|
||||||
#include <resource.h>
|
#include <resource.h>
|
||||||
|
|
||||||
bool StubTerminateProcess();
|
#ifdef _DEBUG
|
||||||
|
#include <cheat/debugger.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
void Run(HMODULE* phModule)
|
void Run(HMODULE* phModule)
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
|
||||||
Sleep(10000);
|
|
||||||
#else
|
|
||||||
while (GetModuleHandle("UserAssembly.dll") == nullptr)
|
|
||||||
{
|
|
||||||
Sleep(2000);
|
|
||||||
}
|
|
||||||
Sleep(15000);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ResourceLoader::SetModuleHandle(*phModule);
|
ResourceLoader::SetModuleHandle(*phModule);
|
||||||
|
|
||||||
// Init config
|
// Init config
|
||||||
@ -43,43 +36,26 @@ void Run(HMODULE* phModule)
|
|||||||
il2cppi_new_console();
|
il2cppi_new_console();
|
||||||
}
|
}
|
||||||
|
|
||||||
init_il2cpp();
|
#ifdef _DEBUG
|
||||||
|
DebuggerBypassPre();
|
||||||
|
|
||||||
if (StubTerminateProcess())
|
LOG_DEBUG("Waiting 10sec for loading game library.");
|
||||||
LOG_INFO("TerminateProcess stubbed successfully.");
|
Sleep(10000);
|
||||||
else
|
|
||||||
LOG_ERROR("Stub TerminateProcess failed.");
|
DebuggerBypassPost();
|
||||||
|
#else
|
||||||
|
while (GetModuleHandle("UserAssembly.dll") == nullptr)
|
||||||
|
{
|
||||||
|
LOG_DEBUG("UserAssembly.dll isn't initialized, waiting for 2 sec.");
|
||||||
|
Sleep(2000);
|
||||||
|
}
|
||||||
|
LOG_DEBUG("Waiting 15sec for game initialize.");
|
||||||
|
Sleep(15000);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
init_il2cpp();
|
||||||
|
|
||||||
cheat::Init();
|
cheat::Init();
|
||||||
|
|
||||||
LOG_DEBUG("Config path is at %s", configPath.c_str());
|
LOG_DEBUG("Config path is at %s", configPath.c_str());
|
||||||
LOG_DEBUG("UserAssembly.dll is at 0x%p", il2cppi_get_base_address());
|
|
||||||
LOG_DEBUG("UnityPlayer.dll is at 0x%p", il2cppi_get_unity_address());
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL WINAPI TerminateProcess_Hook(HANDLE hProcessUINT, UINT uExitCode)
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StubTerminateProcess()
|
|
||||||
{
|
|
||||||
HMODULE hKernelBase = GetModuleHandle("kernelbase.dll");
|
|
||||||
if (hKernelBase == NULL)
|
|
||||||
{
|
|
||||||
LOG_LAST_ERROR("Failed to get the kernelbase.dll handle.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FARPROC pTerminateProcess = GetProcAddress(hKernelBase, "TerminateProcess");
|
|
||||||
if (pTerminateProcess == nullptr)
|
|
||||||
{
|
|
||||||
LOG_LAST_ERROR("Getting KernelBase::NtTerminateProcess failed.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
using TerminateProcess_Type = BOOL(*)(HANDLE, UINT);
|
|
||||||
|
|
||||||
HookManager::install((TerminateProcess_Type)pTerminateProcess, TerminateProcess_Hook);
|
|
||||||
LOG_DEBUG("Terminate process hooked. Origin at 0x%p", HookManager::getOrigin(TerminateProcess_Hook));
|
|
||||||
return true;
|
|
||||||
}
|
}
|
@ -14,7 +14,7 @@ const std::string ChinaGenshinProcName = "YuanShen.exe";
|
|||||||
|
|
||||||
static CSimpleIni ini;
|
static CSimpleIni ini;
|
||||||
|
|
||||||
HANDLE OpenGenshinProcess();
|
bool OpenGenshinProcess(HANDLE* phProcess, HANDLE* phThread);
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
@ -31,8 +31,8 @@ int main(int argc, char* argv[])
|
|||||||
ini.SetUnicode();
|
ini.SetUnicode();
|
||||||
ini.LoadFile("cfg.ini");
|
ini.LoadFile("cfg.ini");
|
||||||
|
|
||||||
HANDLE hProcess = OpenGenshinProcess();
|
HANDLE hProcess, hThread;
|
||||||
if (hProcess == NULL)
|
if (!OpenGenshinProcess(&hProcess, &hThread))
|
||||||
{
|
{
|
||||||
std::cout << "Failed to open GenshinImpact process." << std::endl;
|
std::cout << "Failed to open GenshinImpact process." << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
@ -60,10 +60,13 @@ int main(int argc, char* argv[])
|
|||||||
InjectDLL(hProcess, currentDllPath.string());
|
InjectDLL(hProcess, currentDllPath.string());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Sleep(2000);
|
||||||
|
ResumeThread(hThread);
|
||||||
|
|
||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE OpenGenshinProcess()
|
bool OpenGenshinProcess(HANDLE *phProcess, HANDLE* phThread)
|
||||||
{
|
{
|
||||||
STARTUPINFOA startInfo{};
|
STARTUPINFOA startInfo{};
|
||||||
PROCESS_INFORMATION processInformation{};
|
PROCESS_INFORMATION processInformation{};
|
||||||
@ -74,7 +77,7 @@ HANDLE OpenGenshinProcess()
|
|||||||
LPSTR lpstr = commandline == nullptr ? nullptr : const_cast<LPSTR>(commandline);
|
LPSTR lpstr = commandline == nullptr ? nullptr : const_cast<LPSTR>(commandline);
|
||||||
|
|
||||||
if (!filePath)
|
if (!filePath)
|
||||||
return NULL;
|
return false;
|
||||||
|
|
||||||
BOOL result = CreateProcessA(filePath->c_str(),
|
BOOL result = CreateProcessA(filePath->c_str(),
|
||||||
lpstr, 0, 0, FALSE, CREATE_SUSPENDED, nullptr, nullptr, &startInfo, &processInformation);
|
lpstr, 0, 0, FALSE, CREATE_SUSPENDED, nullptr, nullptr, &startInfo, &processInformation);
|
||||||
@ -82,12 +85,12 @@ HANDLE OpenGenshinProcess()
|
|||||||
{
|
{
|
||||||
LOG_LAST_ERROR("Failed to create game process.");
|
LOG_LAST_ERROR("Failed to create game process.");
|
||||||
LOG_ERROR("If you have problem with GenshinImpact.exe path. You can change it manually in cfg.ini.");
|
LOG_ERROR("If you have problem with GenshinImpact.exe path. You can change it manually in cfg.ini.");
|
||||||
return NULL;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ini.SaveFile("cfg.ini");
|
ini.SaveFile("cfg.ini");
|
||||||
|
|
||||||
ResumeThread(processInformation.hThread);
|
*phThread = processInformation.hThread;
|
||||||
|
*phProcess = processInformation.hProcess;
|
||||||
return processInformation.hProcess;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user