Seregon/ShadPKG

A tool for deriving PKG packet encryption keys for ps4 written in c++

C++/47.3 KB/No license
gui/ConsoleLog.cpp
ShadPKG / gui / ConsoleLog.cpp
1// SPDX-FileCopyrightText: Copyright 2025 shadPKG
2// SPDX-License-Identifier: GPL-2.0-or-later
3 
4#include "include/ConsoleLog.h"
5#include "include/StyleManager.h"
6#include <assert.h>
7 
8namespace ShadPKG::GUI {
9 
10// ╔═══════════════════════════════════════════════════════════════════════════╗
11// ║ ConsoleLog::Draw - Render the collapsible console panel ║
12// ╚═══════════════════════════════════════════════════════════════════════════╝
13void ConsoleLog::Draw(float height) {
14 auto &logSink = GuiLogSink::Instance();
15 
16 // Custom header drawing to ensure stability
17 const float headerHeight = 30.0f;
18 ImVec2 p = ImGui::GetCursorScreenPos();
19 ImVec2 contentAvail = ImGui::GetContentRegionAvail();
20 float windowWidth = ImGui::GetWindowWidth();
21
22 // Background
23 ImGui::GetWindowDrawList()->AddRectFilled(
24 p, ImVec2(p.x + windowWidth, p.y + headerHeight),
25 ImGui::GetColorU32(Colors::NavBarBg));
26 
27 // Toggle button (invisible, covers the left part)
28 ImGui::SetCursorScreenPos(p);
29 if (ImGui::InvisibleButton("##console_toggle", ImVec2(150, headerHeight))) {
30 expanded_ = !expanded_;
31 }
32
33 // Icon and Title
34 ImGui::SetCursorScreenPos(ImVec2(p.x + 8, p.y + 6)); // Align text
35 const char *headerIcon = expanded_ ? ICON_FA_FOLDER_OPEN : ICON_FA_FOLDER;
36 ImGui::Text("%s Console", headerIcon);
37 
38 // If expanded, draw content
39 if (expanded_) {
40 const ImGuiStyle &style = ImGui::GetStyle();
41 const float buttonSpacing = style.ItemSpacing.x;
42 auto buttonWidth = [&style](const char *label) {
43 const ImVec2 size = ImGui::CalcTextSize(label);
44 return size.x + style.FramePadding.x * 2.0f;
45 };
46 const float toolbarWidth =
47 buttonWidth("I") + buttonWidth("W") + buttonWidth("E") +
48 buttonWidth(ICON_FA_DOWNLOAD) + buttonWidth(ICON_FA_FILE " Copy") + buttonWidth("Clear") +
49 buttonSpacing * 5.0f;
50
51 // Position toolbar on the right
52 float cursorX = windowWidth - toolbarWidth - 8.0f; // Right align with padding
53 ImGui::SetCursorScreenPos(ImVec2(p.x + cursorX, p.y + 4)); // Vertical align
54 
55 ImGui::PushID("console_toolbar");
56 ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4, 2));
57 
58 ImGui::PushStyleColor(ImGuiCol_Button,
59 showInfo_ ? Colors::Success : Colors::FrameBg);
60 if (ImGui::SmallButton("I")) {
61 showInfo_ = !showInfo_;
62 }
63 ImGui::PopStyleColor();
64 if (ImGui::IsItemHovered())
65 ImGui::SetTooltip("Toggle Info messages");
66 
67 ImGui::SameLine();
68 
69 ImGui::PushStyleColor(ImGuiCol_Button,
70 showWarnings_ ? Colors::Warning : Colors::FrameBg);
71 if (ImGui::SmallButton("W")) {
72 showWarnings_ = !showWarnings_;
73 }
74 ImGui::PopStyleColor();
75 if (ImGui::IsItemHovered())
76 ImGui::SetTooltip("Toggle Warning messages");
77 
78 ImGui::SameLine();
79 
80 ImGui::PushStyleColor(ImGuiCol_Button,
81 showErrors_ ? Colors::Error : Colors::FrameBg);
82 if (ImGui::SmallButton("E")) {
83 showErrors_ = !showErrors_;
84 }
85 ImGui::PopStyleColor();
86 if (ImGui::IsItemHovered())
87 ImGui::SetTooltip("Toggle Error messages");
88 
89 ImGui::SameLine();
90 
91 // Auto-scroll toggle
92 bool autoScroll = logSink.IsAutoScroll();
93 ImGui::PushStyleColor(ImGuiCol_Button,
94 autoScroll ? Colors::Primary : Colors::FrameBg);
95 if (ImGui::SmallButton(ICON_FA_DOWNLOAD)) {
96 logSink.SetAutoScroll(!autoScroll);
97 }
98 ImGui::PopStyleColor();
99 if (ImGui::IsItemHovered())
100 ImGui::SetTooltip("Auto-scroll");
101 
102 ImGui::SameLine();
103 
104 // Copy button
105 if (ImGui::SmallButton(ICON_FA_FILE " Copy")) {
106 std::string clipboardText;
107 auto logs = logSink.GetLogs();
108 for (const auto &entry : logs) {
109 // Apply current filters to clipboard copy too
110 if (entry.level == LogLevel::Info && !showInfo_) continue;
111 if (entry.level == LogLevel::Warning && !showWarnings_) continue;
112 if (entry.level == LogLevel::Error && !showErrors_) continue;
113 
114 clipboardText += "[" + entry.timestamp + "] ";
115 switch (entry.level) {
116 case LogLevel::Info: clipboardText += "[INFO] "; break;
117 case LogLevel::Warning: clipboardText += "[WARN] "; break;
118 case LogLevel::Error: clipboardText += "[ERROR] "; break;
119 }
120 clipboardText += entry.message + "\n";
121 }
122 ImGui::SetClipboardText(clipboardText.c_str());
123 }
124 if (ImGui::IsItemHovered())
125 ImGui::SetTooltip("Copy visible logs to clipboard");
126 
127 ImGui::SameLine();
128 
129 // Clear button
130 if (ImGui::SmallButton("Clear")) {
131 logSink.Clear();
132 }
133 
134 ImGui::PopStyleVar();
135 ImGui::PopID();
136 
137 // Move cursor below header
138 ImGui::SetCursorScreenPos(ImVec2(p.x, p.y + headerHeight));
139 
140 // Log content
141 ImGui::BeginChild("##log_content", ImVec2(0, height), true,
142 ImGuiWindowFlags_HorizontalScrollbar);
143 
144 auto logs = logSink.GetLogs();
145 
146 for (const auto &entry : logs) {
147 // Filter by level
148 if (entry.level == LogLevel::Info && !showInfo_)
149 continue;
150 if (entry.level == LogLevel::Warning && !showWarnings_)
151 continue;
152 if (entry.level == LogLevel::Error && !showErrors_)
153 continue;
154 
155 // Timestamp
156 ImGui::TextColored(Colors::TextDim, "[%s]", entry.timestamp.c_str());
157 ImGui::SameLine();
158 
159 // Level indicator
160 switch (entry.level) {
161 case LogLevel::Info:
162 ImGui::TextColored(Colors::Success, "[INFO]");
163 break;
164 case LogLevel::Warning:
165 ImGui::TextColored(Colors::Warning, "[WARN]");
166 break;
167 case LogLevel::Error:
168 ImGui::TextColored(Colors::Error, "[ERROR]");
169 break;
170 }
171 ImGui::SameLine();
172 
173 // Message
174 ImGui::TextUnformatted(entry.message.c_str());
175 }
176 
177 // Auto-scroll to bottom
178 if (logSink.IsAutoScroll() &&
179 ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) {
180 ImGui::SetScrollHereY(1.0f);
181 }
182 
183 ImGui::EndChild();
184 }
185}
186 
187} // namespace ShadPKG::GUI
188