Seregon/ShadPKG

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

C++/47.3 KB/No license
gui/include/GUIContext.h
ShadPKG / gui / include / GUIContext.h
1// SPDX-FileCopyrightText: Copyright 2025 shadPKG
2// SPDX-License-Identifier: GPL-2.0-or-later
3 
4#pragma once
5 
6#include <atomic>
7#include <cstring>
8#include <functional>
9#include <mutex>
10#include <string>
11#include <thread>
12#include <vector>
13 
14class PKG;
15 
16// ╔═══════════════════════════════════════════════════════════════════════════╗
17// ║ GUIContext: Bridge between ImGui frontend and PKG extraction backend ║
18// ║ ║
19// ║ This module manages async operations to prevent GUI freezing during ║
20// ║ long-running PKG extractions. Uses Producer-Consumer pattern. ║
21// ╚═══════════════════════════════════════════════════════════════════════════╝
22 
23namespace ShadPKG::GUI {
24 
25// ┌─────────────────────────────────────────────────────────────────────────┐
26// │ ExtractionJob: Encapsulates all parameters for a PKG extraction │
27// └─────────────────────────────────────────────────────────────────────────┘
28struct ExtractionJob {
29 std::string pkgPath; // Source PKG file path
30 std::string outPath; // Output directory
31 std::string rifPath; // Optional RIF file path
32 bool useRif = false; // Enable RIF decryption
33 bool createSubfolder = true; // Create TitleID subfolder
34};
35 
36// ┌─────────────────────────────────────────────────────────────────────────┐
37// │ WorkerState: Thread-safe state shared between GUI and worker thread │
38// │ │
39// │ GUI Thread reads: isBusy, progress, currentOperation, completed │
40// │ Worker Thread writes: all fields except stopRequested │
41// │ GUI Thread writes: stopRequested (to cancel) │
42// └─────────────────────────────────────────────────────────────────────────┘
43struct WorkerState {
44 std::atomic<bool> isBusy{false};
45 std::atomic<float> progress{0.0f}; // 0.0 to 1.0
46 std::atomic<bool> stopRequested{false};
47 std::atomic<bool> completed{false};
48 std::atomic<bool> success{false};
49 
50 // Protected by stateMutex
51 std::mutex stateMutex;
52 char currentOperation[256] = "Idle";
53 std::string lastError;
54 std::string extractedPath;
55 
56 void SetOperation(const std::string &op) {
57 std::lock_guard<std::mutex> lock(stateMutex);
58 strncpy(currentOperation, op.c_str(), sizeof(currentOperation) - 1);
59 currentOperation[sizeof(currentOperation) - 1] = '\0';
60 }
61 
62 std::string GetOperation() const {
63 std::lock_guard<std::mutex> lock(const_cast<std::mutex &>(stateMutex));
64 return std::string(currentOperation);
65 }
66 
67 void SetError(const std::string &err) {
68 std::lock_guard<std::mutex> lock(stateMutex);
69 lastError = err;
70 }
71 
72 std::string GetError() const {
73 std::lock_guard<std::mutex> lock(const_cast<std::mutex &>(stateMutex));
74 return lastError;
75 }
76 
77 void Reset() {
78 isBusy = false;
79 progress = 0.0f;
80 stopRequested = false;
81 completed = false;
82 success = false;
83 SetOperation("Idle");
84 SetError("");
85 extractedPath.clear();
86 }
87};
88 
89// ┌─────────────────────────────────────────────────────────────────────────┐
90// │ GUIContext: Main application context managing views and state │
91// └─────────────────────────────────────────────────────────────────────────┘
92class GUIContext {
93public:
94 enum class View {
95 Extractor,
96 Inspector,
97 RIF,
98 Settings,
99 Decompiler,
100 StructEditor
101 };
102 
103 GUIContext() = default;
104 ~GUIContext();
105 
106 // View management
107 void SetCurrentView(View view) { currentView_ = view; }
108 View GetCurrentView() const { return currentView_; }
109 
110 // Extraction control
111 void StartExtraction(const ExtractionJob &job);
112 void CancelExtraction();
113 bool IsExtracting() const { return workerState_.isBusy; }
114 float GetProgress() const { return workerState_.progress; }
115 std::string GetCurrentOperation() const {
116 return workerState_.GetOperation();
117 }
118 bool IsCompleted() const { return workerState_.completed; }
119 bool WasSuccessful() const { return workerState_.success; }
120 std::string GetLastError() const { return workerState_.GetError(); }
121 
122 WorkerState &GetWorkerState() { return workerState_; }
123 
124 // Loaded PKG info (for Inspector)
125 std::string loadedPkgPath;
126 bool pkgLoaded = false;
127 std::shared_ptr<PKG>
128 currentPkg; // Shared PKG instance for Decompiler/Inspector
129 
130 // Update Checker
131 struct UpdateStatus {
132 bool hasUpdate = false;
133 std::string latestVersion;
134 std::string releaseUrl;
135 bool checked = false;
136 };
137 
138 void CheckForUpdates();
139 const UpdateStatus &GetUpdateStatus() const { return updateStatus_; }
140 
141 // Contributors
142 struct Contributor {
143 std::string name;
144 std::string url;
145 };
146 void FetchContributors();
147 const std::vector<Contributor> &GetContributors() const {
148 return contributors;
149 }
150 
151private:
152 View currentView_ = View::Extractor;
153 WorkerState workerState_;
154 std::thread workerThread_;
155 UpdateStatus updateStatus_;
156 std::vector<Contributor> contributors;
157 
158 void WorkerFunction(ExtractionJob job);
159};
160 
161} // namespace ShadPKG::GUI
162