A tool for deriving PKG packet encryption keys for ps4 written in c++
| 1 | // SPDX-FileCopyrightText: Copyright 2025 shadPKG |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | |
| 4 | #pragma once |
| 5 | |
| 6 | #include "../GUIContext.h" |
| 7 | #include "core/file_format/pkg.h" |
| 8 | #include <memory> |
| 9 | #include <string> |
| 10 | #include <vector> |
| 11 | |
| 12 | // ╔═══════════════════════════════════════════════════════════════════════════╗ |
| 13 | // ║ InspectorView: PKG metadata and filesystem browser ║ |
| 14 | // ║ ║ |
| 15 | // ║ Split Layout: ║ |
| 16 | // ║ ┌─────────────────────────────┬─────────────────────────────────────────┐ |
| 17 | // ║ ║ │ METADATA (SFO) │ FILE SYSTEM (PFS) │ ║ ║ │ |
| 18 | // ┌───────────┬────────────┐ │ [ 🔍 Search Filter... ] │ ║ ║ │ |
| 19 | // │ Key │ Value │ │ │ ║ ║ │ |
| 20 | // │───────────│────────────│ │ Name | Size | Type │ ║ ║ │ |
| 21 | // │ TITLE_ID │ CUSA12345 │ │ ├── 📁 assets │ - │ DIR │ ║ ║ │ |
| 22 | // │ APP_VER │ 01.05 │ │ │ └── 📁 textures │ - │ DIR │ ║ ║ │ |
| 23 | // │ PUB_TOOL │ 4.50 │ │ │ ├── hero.tex│ 4MB │ FILE │ ║ ║ │ |
| 24 | // │ TOTAL_SIZE│ 45 GB │ │ │ └── map.tex │ 12MB │ FILE │ ║ ║ │ |
| 25 | // └───────────┴────────────┘ │ ├── data.bin │ 1GB │ FILE │ ║ ║ │ |
| 26 | // │ ├── 🖼️ icon0.png │ 50KB │ FILE │ ║ ║ │ │ └── 📄 param.sfo │ |
| 27 | // 2KB │ FILE │ ║ ║ |
| 28 | // └─────────────────────────────┴─────────────────────────────────────────┘ ║ |
| 29 | // ╚═══════════════════════════════════════════════════════════════════════════╝ |
| 30 | |
| 31 | namespace ShadPKG::GUI { |
| 32 | |
| 33 | class InspectorView { |
| 34 | public: |
| 35 | InspectorView() = default; |
| 36 | ~InspectorView() = default; |
| 37 | |
| 38 | void Draw(GUIContext &ctx); |
| 39 | void LoadPkg(GUIContext &ctx, const std::string &path); |
| 40 | void Clear(); |
| 41 | |
| 42 | bool IsPkgLoaded() const { return pkgLoaded_; } |
| 43 | |
| 44 | private: |
| 45 | // ═══════════════════════════════════════════════════════════════════════ |
| 46 | // SFO Entry for display |
| 47 | // ═══════════════════════════════════════════════════════════════════════ |
| 48 | struct SfoEntry { |
| 49 | std::string key; |
| 50 | std::string value; |
| 51 | std::string type; // "String", "Integer", "Binary" |
| 52 | }; |
| 53 | |
| 54 | // ═══════════════════════════════════════════════════════════════════════ |
| 55 | // File tree node for PFS display |
| 56 | // ═══════════════════════════════════════════════════════════════════════ |
| 57 | struct FileNode { |
| 58 | std::string name; |
| 59 | std::string fullPath; |
| 60 | uint64_t size = 0; |
| 61 | bool isDirectory = false; |
| 62 | std::vector<std::unique_ptr<FileNode>> children; |
| 63 | bool expanded = false; |
| 64 | int fileIndex = -1; // Index in fsTable for extraction |
| 65 | }; |
| 66 | |
| 67 | // PKG data |
| 68 | char pkgPathBuf_[512] = ""; |
| 69 | bool pkgLoaded_ = false; |
| 70 | std::string titleId_; |
| 71 | std::string contentId_; |
| 72 | uint64_t pkgSize_ = 0; |
| 73 | |
| 74 | // SFO entries |
| 75 | std::vector<SfoEntry> sfoEntries_; |
| 76 | |
| 77 | // File tree |
| 78 | std::unique_ptr<FileNode> fileTreeRoot_; |
| 79 | bool fileTreeLoaded_ = false; |
| 80 | char searchFilter_[128] = ""; |
| 81 | |
| 82 | // Split position |
| 83 | float splitRatio_ = 0.35f; |
| 84 | |
| 85 | // UI drawing |
| 86 | void DrawLoadSection(GUIContext &ctx); |
| 87 | void DrawMetadataPanel(); |
| 88 | void DrawFilesystemPanel(); |
| 89 | void DrawFileNode(FileNode *node, int depth = 0); |
| 90 | |
| 91 | // Data loading |
| 92 | void LoadSfoData(const PKG &pkg); |
| 93 | void LoadFileTree(const PKG &pkg); |
| 94 | void BuildFileTree(const std::vector<PKG::EntryInfo> &entries); |
| 95 | |
| 96 | // Extraction |
| 97 | void ExtractNode(const FileNode *node); |
| 98 | std::string PickFolder(); |
| 99 | |
| 100 | // Helpers |
| 101 | static std::string FormatSize(uint64_t bytes); |
| 102 | static const char *GetFileIcon(const std::string &name, bool isDir); |
| 103 | bool MatchesFilterText(const std::string &text) const; |
| 104 | bool NodeMatchesFilter(const FileNode *node) const; |
| 105 | }; |
| 106 | |
| 107 | } // namespace ShadPKG::GUI |
| 108 |