Seregon/ShadPKG

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

C++/47.3 KB/No license
gui/views/StructEditorView.cpp
ShadPKG / gui / views / StructEditorView.cpp
1#include "gui/include/views/StructEditorView.h"
2#include "gui/include/StyleManager.h"
3#include "imgui.h"
4#include <sstream>
5 
6namespace ShadPKG::GUI {
7 
8StructEditorView::StructEditorView() { newStructName_.resize(256); }
9 
10void StructEditorView::Draw(GUIContext &ctx) {
11 ImGui::Begin("Struct Editor", nullptr, ImGuiWindowFlags_None);
12 
13 auto decompCtx = &ShadPKG::Decompiler::DecompilerContext::Get();
14 auto typeManager = decompCtx->GetTypeManager();
15 
16 // 1. Struct List
17 ImGui::BeginChild("StructList", ImVec2(200, 0), true);
18 ImGui::Text("Defined Structs");
19 ImGui::Separator();
20 
21 // Create New Struct
22 if (ImGui::Button("New Struct")) {
23 // Find unique name
24 int i = 1;
25 while (typeManager->getType("Struct" + std::to_string(i)))
26 i++;
27 typeManager->createStruct("Struct" + std::to_string(i));
28 }
29 
30 ImGui::Separator();
31 
32 
33 
34 // Placeholder iteration (requires TypeManager update)
35 auto allTypes = typeManager->getAllTypes(); // NEED TO IMPLEMENT
36 int idx = 0;
37 for (const auto &[name, type] : allTypes) {
38 if (type->getKind() == ShadPKG::Decompiler::Analysis::Type::Kind::Struct) {
39 bool selected = (selectedStructIndex_ == idx);
40 if (ImGui::Selectable(name.c_str(), selected)) {
41 selectedStructIndex_ = idx;
42 newStructName_ = name;
43 newStructName_.resize(256, '\0');
44 }
45 idx++;
46 }
47 }
48 
49 ImGui::EndChild();
50 
51 ImGui::SameLine();
52 
53 // 2. Struct Details Editor
54 ImGui::BeginChild("StructDetails", ImVec2(0, 0), true);
55 
56 if (selectedStructIndex_ != -1) {
57 // Find selected struct by index is inefficient but works for now
58 // Requires stable ordering or index mapping.
59 
60 std::shared_ptr<ShadPKG::Decompiler::Analysis::StructType> currentStruct =
61 nullptr;
62 std::string currentName;
63 
64 int i = 0;
65 for (const auto &[name, type] : allTypes) {
66 if (type->getKind() ==
67 ShadPKG::Decompiler::Analysis::Type::Kind::Struct) {
68 if (i == selectedStructIndex_) {
69 currentStruct = std::dynamic_pointer_cast<
70 ShadPKG::Decompiler::Analysis::StructType>(type);
71 currentName = name;
72 break;
73 }
74 i++;
75 }
76 }
77 
78 if (currentStruct) {
79 ImGui::Text("Editing: %s", currentName.c_str());
80 
81 // Rename
82 if (ImGui::InputText("Name", &newStructName_[0], 256,
83 ImGuiInputTextFlags_EnterReturnsTrue)) {
84 std::string newName = newStructName_.c_str();
85 if (newName != currentName && !newName.empty()) {
86 typeManager->renameType(currentName, newName); // NEED TO IMPLEMENT
87 }
88 }
89 
90 ImGui::Separator();
91 ImGui::Text("Members");
92 
93 // Members Table
94 if (ImGui::BeginTable("MembersTable", 4,
95 ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg |
96 ImGuiTableFlags_Resizable)) {
97 ImGui::TableSetupColumn("Offset", ImGuiTableColumnFlags_WidthFixed,
98 60.0f);
99 ImGui::TableSetupColumn("Type");
100 ImGui::TableSetupColumn("Name");
101 ImGui::TableSetupColumn("Action", ImGuiTableColumnFlags_WidthFixed,
102 50.0f);
103 ImGui::TableHeadersRow();
104 
105 auto members = currentStruct->getMembers(); // Copy
106 bool changed = false;
107 
108 for (int mIdx = 0; mIdx < members.size(); ++mIdx) {
109 auto &member = members[mIdx];
110 
111 ImGui::PushID(mIdx);
112 ImGui::TableNextRow();
113 
114 // Offset
115 ImGui::TableSetColumnIndex(0);
116 ImGui::Text("0x%X", member.offset); // Read-only for now, or editable?
117 
118 // Type
119 ImGui::TableSetColumnIndex(1);
120 if (ImGui::Button(member.type->toString().c_str())) {
121 ImGui::OpenPopup("TypeSelector");
122 }
123 if (ImGui::BeginPopup("TypeSelector")) {
124 // List primitives
125 if (ImGui::Selectable("int32")) {
126 member.type = typeManager->getType("int32");
127 changed = true;
128 }
129 if (ImGui::Selectable("float")) {
130 member.type = typeManager->getType("float");
131 changed = true;
132 }
133 // ... iterate all types
134 ImGui::EndPopup();
135 }
136 
137 // Name
138 ImGui::TableSetColumnIndex(2);
139 char nameBuf[64];
140 strncpy(nameBuf, member.name.c_str(), 63);
141 if (ImGui::InputText("##name", nameBuf, 64)) {
142 member.name = nameBuf;
143 changed = true;
144 }
145 
146 // Action
147 ImGui::TableSetColumnIndex(3);
148 if (ImGui::Button("X")) {
149 // Delete member
150 // Need update logic
151 }
152 
153 ImGui::PopID();
154 }
155 
156 // Add new Member Row
157 ImGui::TableNextRow();
158 ImGui::TableSetColumnIndex(0);
159 ImGui::Text("+");
160 ImGui::TableSetColumnIndex(3);
161 if (ImGui::Button("Add")) {
162 currentStruct->addMember("field_" + std::to_string(members.size()),
163 typeManager->getType("int32"),
164 currentStruct->getSize());
165 }
166 
167 ImGui::EndTable();
168 
169 if (changed) {
170 // Update struct definition
171 // currentStruct->setMembers(members); // NEED TO IMPLEMENT setter or
172 // direct ref access
173 }
174 }
175 }
176 } else {
177 ImGui::Text("Select a struct to edit.");
178 }
179 
180 ImGui::EndChild();
181 
182 ImGui::End();
183}
184 
185} // namespace ShadPKG::GUI
186