Skip to content

Commit

Permalink
Manually implement CUIPanel::FindChildInLayoutFile() method
Browse files Browse the repository at this point in the history
  • Loading branch information
danielkrupinski committed May 31, 2024
1 parent ebfec8c commit 179a85c
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 17 deletions.
7 changes: 6 additions & 1 deletion Source/CS2/Classes/Panorama.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,12 +265,17 @@ struct CUIPanel {

using setParent = void (*)(CUIPanel* thisptr, CUIPanel* parent);
using setVisible = void (*)(CUIPanel* thisptr, bool visible);
using findChildInLayoutFile = CUIPanel* (*)(CUIPanel* thisptr, const char* childId);
using getAttributeString = const char* (*)(CUIPanel* thisptr, CPanoramaSymbol attributeName, const char* defaultValue);
using setAttributeString = void (*)(CUIPanel* thisptr, CPanoramaSymbol attributeName, const char* value);

using childrenVector = CUtlVector<CUIPanel*>;
using classesVector = CUtlVector<CPanoramaSymbol>;
using m_pchID = CUtlString;
using PanelFlags = std::uint8_t;
};

enum EPanelFlag {
k_EPanelFlag_HasOwnLayoutFile = 0x40
};

struct ImageProperties {
Expand Down
6 changes: 4 additions & 2 deletions Source/GameClasses/Implementation/PanoramaUiPanelImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ struct PanoramaUiPanelImpl {
explicit PanoramaUiPanelImpl(const PanoramaUiPanelPatterns& panoramaUiPanelPatterns) noexcept
: setParent{panoramaUiPanelPatterns.setParent()}
, setVisible{panoramaUiPanelPatterns.setVisible()}
, findChildInLayoutFile{panoramaUiPanelPatterns.findChildInLayoutFile()}
, getAttributeString{panoramaUiPanelPatterns.getAttributeString()}
, setAttributeString{panoramaUiPanelPatterns.setAttributeString()}
, childPanels{panoramaUiPanelPatterns.childPanelsVectorOffset()}
, classes{panoramaUiPanelPatterns.classesVectorOffset()}
, panelStyle{panoramaUiPanelPatterns.panelStyleOffset()}
, parentWindowOffset{panoramaUiPanelPatterns.parentWindowOffset()}
, offsetToPanelId{panoramaUiPanelPatterns.offsetToPanelId()}
, offsetToPanelFlags{panoramaUiPanelPatterns.offsetToPanelFlags()}
{
}

Expand All @@ -26,12 +27,13 @@ struct PanoramaUiPanelImpl {

Offset<cs2::CUIPanel::setParent> setParent;
Offset<cs2::CUIPanel::setVisible> setVisible;
Offset<cs2::CUIPanel::findChildInLayoutFile> findChildInLayoutFile;
Offset<cs2::CUIPanel::getAttributeString> getAttributeString;
Offset<cs2::CUIPanel::setAttributeString> setAttributeString;

ChildPanelsVectorOffset childPanels;
PanelClassesVectorOffset classes;
PanelStyleOffset panelStyle;
ParentWindowOffset parentWindowOffset;
OffsetToPanelId offsetToPanelId;
OffsetToPanelFlags offsetToPanelFlags;
};
2 changes: 2 additions & 0 deletions Source/GameClasses/OffsetTypes/PanoramaUiPanelOffset.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ using ChildPanelsVectorOffset = PanoramaUiPanelOffset<cs2::CUIPanel::childrenVec
using PanelClassesVectorOffset = PanoramaUiPanelOffset<cs2::CUIPanel::classesVector, std::int32_t>;
using PanelStyleOffset = PanoramaUiPanelOffset<cs2::CPanelStyle, std::int8_t>;
using ParentWindowOffset = PanoramaUiPanelOffset<cs2::CTopLevelWindow*, std::int8_t>;
using OffsetToPanelId = PanoramaUiPanelOffset<cs2::CUIPanel::m_pchID, std::int8_t>;
using OffsetToPanelFlags = PanoramaUiPanelOffset<cs2::CUIPanel::PanelFlags, std::int32_t>;
31 changes: 28 additions & 3 deletions Source/GameClasses/PanoramaUiPanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ struct PanoramaUiPanel {

[[nodiscard]] PanoramaUiPanel findChildInLayoutFile(const char* childId) const noexcept
{
if (const auto fn = impl().findChildInLayoutFile.of(thisptr->vmt).get())
return PanoramaUiPanel{ (*fn)(thisptr, childId) };
return PanoramaUiPanel{ nullptr };
if (!impl().offsetToPanelFlags || !impl().offsetToPanelId)
return PanoramaUiPanel{nullptr};
return PanoramaUiPanel{findChildInLayoutFileInternal(thisptr, childId)};
}

[[nodiscard]] const char* getAttributeString(cs2::CPanoramaSymbol attributeName, const char* defaultValue) const noexcept
Expand Down Expand Up @@ -86,6 +86,31 @@ struct PanoramaUiPanel {
}

private:
[[nodiscard]] cs2::CUIPanel* findChildInLayoutFileInternal(cs2::CUIPanel* parentPanel, const char* idToFind) const noexcept
{
const auto children = impl().childPanels.of(parentPanel).get();
if (!children)
return nullptr;

for (int i = 0; i < children->size; ++i) {
const auto panel = children->memory[i];
const auto panelId = impl().offsetToPanelId.of(panel).get()->m_pString;
if (panelId && std::strcmp(panelId, idToFind) == 0)
return panel;
}

for (int i = 0; i < children->size; ++i) {
const auto panel = children->memory[i];
const auto panelFlags = *impl().offsetToPanelFlags.of(panel).get();
if ((panelFlags & cs2::k_EPanelFlag_HasOwnLayoutFile) == 0) {
if (const auto found = findChildInLayoutFileInternal(panel, idToFind))
return found;
}
}

return nullptr;
}

[[nodiscard]] static const PanoramaUiPanelImpl& impl() noexcept
{
return PanoramaUiPanelImpl::instance();
Expand Down
16 changes: 10 additions & 6 deletions Source/MemoryPatterns/Linux/PanoramaUiPanelPatternsLinux.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ struct PanoramaUiPanelPatterns {
return patternFinders.clientPatternFinder("F6 48 8B 78 ? 48 8B 07 FF 90 ? ? ? ? E9 ? ? ? ? ? 8D"_pat).add(10).template as<std::int32_t*>();
}

[[nodiscard]] std::int32_t* findChildInLayoutFile() const noexcept
{
return patternFinders.clientPatternFinder("49 89 84 24 ? ? ? ? 48 8B 07 FF 90 ? ? ? ? 49 8B 7C 24 ? 48 8D 35 ? ? ? ? 48 8B 07 FF 90 ? ? ? ? 48 85 C0 0F 84 ? ? ? ? 48 89 C7 48 8B 00 FF 50 50 49 89 C6 48 8D 05 ? ? ? ? 0F B7 18"_pat).add(34).template as<std::int32_t*>();
}

[[nodiscard]] std::int32_t* getAttributeString() const noexcept
{
return patternFinders.clientPatternFinder("FF 90 ? ? ? ? 41 80 BC 24 ? ? ? ? ? 48 89 C2"_pat).add(2).template as<std::int32_t*>();
Expand Down Expand Up @@ -53,5 +48,14 @@ struct PanoramaUiPanelPatterns {
{
return patternFinders.panoramaPatternFinder("4D 89 ? 24 ? 4D 85 ? 0F 84 ? ? ? ? 4C"_pat).add(4).template readOffset<ParentWindowOffset>();
}
};

[[nodiscard]] OffsetToPanelId offsetToPanelId() const noexcept
{
return patternFinders.panoramaPatternFinder("00 48 83 7B ? 00 74 ? 48 8D 7B ? 5B 41 5C 41"_pat).add(4).template readOffset<OffsetToPanelId>();
}

[[nodiscard]] OffsetToPanelFlags offsetToPanelFlags() const noexcept
{
return patternFinders.panoramaPatternFinder("D8 41 F6 85 ? ? ? ?"_pat).add(4).template readOffset<OffsetToPanelFlags>();
}
};
15 changes: 10 additions & 5 deletions Source/MemoryPatterns/Windows/PanoramaUiPanelPatternsWindows.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ struct PanoramaUiPanelPatterns {
return patternFinders.clientPatternFinder("01 FF 90 ? ? ? ? 45 33 C0 33 D2 ? 8B ? E8"_pat).add(3).template as<std::int32_t*>();
}

[[nodiscard]] std::int32_t* findChildInLayoutFile() const noexcept
{
return patternFinders.clientPatternFinder("48 8B 48 ? 48 8D 15 ? ? ? ? 4C 89 74 24 ? 48 8B 01 FF 90 ? ? ? ? 48 85"_pat).add(21).template as<std::int32_t*>();
}

[[nodiscard]] std::int32_t* getAttributeString() const noexcept
{
return patternFinders.clientPatternFinder("12 48 8B 01 FF 90 ? ? ? ? 48 8B D0 48 85 C0"_pat).add(6).template as<std::int32_t*>();
Expand Down Expand Up @@ -53,4 +48,14 @@ struct PanoramaUiPanelPatterns {
{
return patternFinders.panoramaPatternFinder("48 89 ? ? 48 85 ? 75 ? 48 85"_pat).add(3).template readOffset<ParentWindowOffset>();
}

[[nodiscard]] OffsetToPanelId offsetToPanelId() const noexcept
{
return patternFinders.panoramaPatternFinder("? 48 8B 6C 24 ? 74 ? FF 15 ? ? ? ? 48 8D"_pat).template readOffset<OffsetToPanelId>();
}

[[nodiscard]] OffsetToPanelFlags offsetToPanelFlags() const noexcept
{
return patternFinders.panoramaPatternFinder("06 48 8B 0C 07 F6 81 ? ? ? ?"_pat).add(7).template readOffset<OffsetToPanelFlags>();
}
};

0 comments on commit 179a85c

Please sign in to comment.