From 3d671742e3a83e505aae56a133cde6827836272c Mon Sep 17 00:00:00 2001 From: merika <126014478+szaaamerik@users.noreply.github.com> Date: Wed, 18 Sep 2024 15:20:40 +0200 Subject: [PATCH] feat(saving): add save dialog - changed ui naming a bit --- forza_saveswapper/CMakeLists.txt | 2 + forza_saveswapper/application/Application.hpp | 24 ++--- forza_saveswapper/application/Window.cpp | 45 +++++---- forza_saveswapper/application/Window.hpp | 94 +++++++++---------- .../fileUtilities/FileDialogs.cpp | 49 ++++++++++ .../fileUtilities/FileDialogs.hpp | 3 + .../fileUtilities/TFileSaveResult.hpp | 19 ++++ forza_saveswapper/swapper/CBinaryStream.hpp | 5 +- 8 files changed, 160 insertions(+), 81 deletions(-) create mode 100644 forza_saveswapper/fileUtilities/TFileSaveResult.hpp diff --git a/forza_saveswapper/CMakeLists.txt b/forza_saveswapper/CMakeLists.txt index 1f52755..dd1a2d5 100644 --- a/forza_saveswapper/CMakeLists.txt +++ b/forza_saveswapper/CMakeLists.txt @@ -67,6 +67,8 @@ add_executable(forza_saveswapper encryption/keys/Fh4Keys.cpp encryption/keys/Fh4Keys.hpp encryption/keys/Fh5Keys.hpp + fileUtilities/TFileSaveResult.hpp + fileUtilities/TFileSaveResult.hpp ) target_link_libraries(forza_saveswapper PRIVATE diff --git a/forza_saveswapper/application/Application.hpp b/forza_saveswapper/application/Application.hpp index 72c03a1..b22601d 100644 --- a/forza_saveswapper/application/Application.hpp +++ b/forza_saveswapper/application/Application.hpp @@ -10,22 +10,22 @@ namespace forza_saveswapper { -class Window; + class Window; -class Application { -public: - explicit Application(const std::string& windowName); - ~Application(); + class Application { + public: + explicit Application(const std::string& windowName); + ~Application(); - void Run() const; + void Run() const; -private: - void Loop() const; + private: + void Loop() const; -private: - std::string m_WindowName; - std::unique_ptr m_Window; -}; + private: + std::string m_WindowName; + std::unique_ptr m_Window; + }; } // forza_saveswapper diff --git a/forza_saveswapper/application/Window.cpp b/forza_saveswapper/application/Window.cpp index 7a6225b..1a6b64b 100644 --- a/forza_saveswapper/application/Window.cpp +++ b/forza_saveswapper/application/Window.cpp @@ -3,23 +3,22 @@ // #include "Window.hpp" + #include "../fileUtilities/FileDialogs.hpp" -#include "../swapper./CBinaryStream.hpp" #include "../encryption/streams/CFh3Stream.hpp" +#include "../swapper/CBinaryStream.hpp" +#include "../swapper/CCompileTimeHash.hpp" +#include "../swapper/CRuntimeHash.hpp" -#include -#include #include #include #include #include +#include +#include #include #include -#include - -#include "../swapper/CCompileTimeHash.hpp" -#include "../swapper/CRuntimeHash.hpp" extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler( HWND window, @@ -115,10 +114,12 @@ namespace forza_saveswapper { m_Application(application), m_Name (std::move(name)), m_IsRunning(true) { - m_FileOpenReuslt.SelectedFileName = "No save file picked!"; + m_OpenSaveFilename = "No save file picked!"; } bool Window::Initialize() { + constexpr auto className = "class001"; + m_WindowClass.cbSize = sizeof(WNDCLASSEX); m_WindowClass.style = CS_CLASSDC; m_WindowClass.lpfnWndProc = WindowProcess; @@ -129,13 +130,13 @@ namespace forza_saveswapper { m_WindowClass.hCursor = nullptr; m_WindowClass.hbrBackground = nullptr; m_WindowClass.lpszMenuName = nullptr; - m_WindowClass.lpszClassName = "class001"; + m_WindowClass.lpszClassName = className; m_WindowClass.hIconSm = nullptr; RegisterClassEx(&m_WindowClass); m_Window = CreateWindowEx( 0, - "class001", + className, m_Name.c_str(), WS_POPUP, 100, @@ -258,19 +259,23 @@ namespace forza_saveswapper { } void Window::OpenSave() { - m_FileOpenReuslt = FileDialogs::OpenFile(); - if (!m_FileOpenReuslt.Succeeded) { + const auto openResult = FileDialogs::OpenFile(); + if (!openResult.Succeeded) { MessageBoxA(nullptr, "The save file opening failed!", "Error", MB_ICONERROR); + return; } + + m_OpenSavePath = openResult.Path; + m_OpenSaveFilename = openResult.SelectedFileName; } void Window::SwapSave(const uint64_t newXuid) const { - if (!m_FileOpenReuslt.Succeeded) { + if (m_OpenSavePath.empty()) { MessageBoxA(nullptr, "The file open must succeed first!", "Error", MB_ICONERROR); return; } - const std::filesystem::path inputPath(m_FileOpenReuslt.Path); + const std::filesystem::path inputPath(m_OpenSavePath); if (!exists(inputPath)) { MessageBoxA(nullptr, "The input save doesn't exist anymore!", "Error", MB_ICONERROR); return; @@ -323,15 +328,15 @@ namespace forza_saveswapper { const auto es = std::make_unique(*output2, input_size, std::array{ }, s_Contexts[0]); es->WriteData(*output); - std::ofstream file(m_FileOpenReuslt.SelectedFileName, std::ios::binary); + const auto fileSaveRes = FileDialogs::SaveFile(); + std::ofstream file(fileSaveRes.Path, std::ios::binary); if (!file) { MessageBoxA(nullptr, "Failed to open output file!", "Error", MB_ICONERROR); return; } std::string contents = output2->str(); - file.write(contents.c_str(), contents.size()); - + file.write(contents.c_str(), static_cast(contents.size())); if (file.fail()) { MessageBoxA(nullptr, "Failed to write to output file!", "Error", MB_ICONERROR); return; @@ -403,13 +408,13 @@ namespace forza_saveswapper { const auto buttonWidth = ImVec2(ImGui::GetContentRegionAvail().x, 0); ImGui::Text("Open save: "); - if (ImGui::Button(m_FileOpenReuslt.SelectedFileName.c_str(), buttonWidth)) { + if (ImGui::Button(m_OpenSaveFilename.c_str(), buttonWidth)) { OpenSave(); } static uint64_t xuid = 0; - ImGui::Text("Enter XUID"); + ImGui::Text("Enter XUID (In hex)"); ImGui::InputScalar("##xuid", ImGuiDataType_U64, &xuid, nullptr, nullptr, "%016llX"); ImGui::SameLine(); if (ImGui::Button("Grab XUID", ImVec2(ImGui::GetContentRegionAvail().x, 0))) { @@ -423,7 +428,7 @@ namespace forza_saveswapper { ); } - if (ImGui::Button("Swap!", buttonWidth)) { + if (ImGui::Button("Export", buttonWidth)) { SwapSave(xuid); } ImGui::End(); diff --git a/forza_saveswapper/application/Window.hpp b/forza_saveswapper/application/Window.hpp index 55a43a4..e88ea8d 100644 --- a/forza_saveswapper/application/Window.hpp +++ b/forza_saveswapper/application/Window.hpp @@ -6,74 +6,74 @@ #define GUI_HPP #include "Application.hpp" -#include "../fileUtilities/TFileOpenResult.hpp" #include #include namespace forza_saveswapper { -class Window -{ -public: - static constexpr int WIDTH = 320; - static constexpr int HEIGHT = 170; + class Window + { + public: + static constexpr int WIDTH = 320; + static constexpr int HEIGHT = 170; - explicit Window(Application& application, std::string name); + explicit Window(Application& application, std::string name); - bool Initialize(); - void Cleanup(); + bool Initialize(); + void Cleanup(); - void BeginRender() noexcept; - void EndRender() const noexcept; - void Render() noexcept; - void ResetDevice() const noexcept; + void BeginRender() noexcept; + void EndRender() const noexcept; + void Render() noexcept; + void ResetDevice() const noexcept; - [[nodiscard]] IDXGISwapChain* GetSwapchain() const { - return m_SwapChain; - } + [[nodiscard]] IDXGISwapChain* GetSwapchain() const { + return m_SwapChain; + } - [[nodiscard]] POINTS GetPosition() const { - return m_Position; - } + [[nodiscard]] POINTS GetPosition() const { + return m_Position; + } - void SetPosition(const POINTS newValue) { - m_Position = newValue; - } + void SetPosition(const POINTS newValue) { + m_Position = newValue; + } - [[nodiscard]] HWND GetWindow() const { - return m_Window; - } + [[nodiscard]] HWND GetWindow() const { + return m_Window; + } - [[nodiscard]] bool GetIsRunning() const { - return m_IsRunning; - } + [[nodiscard]] bool GetIsRunning() const { + return m_IsRunning; + } -private: - void CreateDevice() noexcept; - void DestroyDevice() const noexcept; - void CreateImGui() const noexcept; + private: + void CreateDevice() noexcept; + void DestroyDevice() const noexcept; + void CreateImGui() const noexcept; - static void DestroyImGui() noexcept; + static void DestroyImGui() noexcept; - void OpenSave(); - void SwapSave(uint64_t newXuid) const; + void OpenSave(); + void SwapSave(uint64_t newXuid) const; -private: - HWND m_Window; - WNDCLASSEX m_WindowClass{}; - POINTS m_Position{}; + private: + HWND m_Window; + WNDCLASSEX m_WindowClass{}; + POINTS m_Position{}; - ID3D11Device* m_Device; - ID3D11DeviceContext* m_DeviceContext; - IDXGISwapChain* m_SwapChain; + ID3D11Device* m_Device; + ID3D11DeviceContext* m_DeviceContext; + IDXGISwapChain* m_SwapChain; - Application& m_Application; - std::string m_Name; - bool m_IsRunning; + Application& m_Application; + std::string m_Name; + bool m_IsRunning; - TFileOpenResult m_FileOpenReuslt; -}; + std::string m_OpenSavePath; + std::string m_OpenSaveFilename; + }; } // forza_saveswapper diff --git a/forza_saveswapper/fileUtilities/FileDialogs.cpp b/forza_saveswapper/fileUtilities/FileDialogs.cpp index feda7c7..5beedfb 100644 --- a/forza_saveswapper/fileUtilities/FileDialogs.cpp +++ b/forza_saveswapper/fileUtilities/FileDialogs.cpp @@ -63,4 +63,53 @@ namespace forza_saveswapper { return result; } + TFileSaveResult FileDialogs::SaveFile() { + TFileSaveResult result{}; + HRESULT f_SysHr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); + if (FAILED(f_SysHr)) { + return result; + } + + IFileSaveDialog* f_FileSystem; + f_SysHr = CoCreateInstance(CLSID_FileSaveDialog, nullptr, CLSCTX_ALL, IID_IFileSaveDialog, reinterpret_cast(&f_FileSystem)); + if (FAILED(f_SysHr)) { + CoUninitialize(); + return result; + } + + f_SysHr = f_FileSystem->Show(nullptr); + if (FAILED(f_SysHr)) { + f_FileSystem->Release(); + CoUninitialize(); + return result; + } + + IShellItem* f_Files; + f_SysHr = f_FileSystem->GetResult(&f_Files); + if (FAILED(f_SysHr)) { + f_FileSystem->Release(); + CoUninitialize(); + return result; + } + + PWSTR f_Path; + f_SysHr = f_Files->GetDisplayName(SIGDN_FILESYSPATH, &f_Path); + if (FAILED(f_SysHr)) { + f_Files->Release(); + f_FileSystem->Release(); + CoUninitialize(); + return result; + } + + std::wstring wPath(f_Path); + const std::string path(wPath.begin(), wPath.end()); + result.Path = path; + + CoTaskMemFree(f_Path); + f_Files->Release(); + f_FileSystem->Release(); + CoUninitialize(); + result.Succeeded = true; + return result; + } } // forza_saveswapper \ No newline at end of file diff --git a/forza_saveswapper/fileUtilities/FileDialogs.hpp b/forza_saveswapper/fileUtilities/FileDialogs.hpp index f107565..898befe 100644 --- a/forza_saveswapper/fileUtilities/FileDialogs.hpp +++ b/forza_saveswapper/fileUtilities/FileDialogs.hpp @@ -4,11 +4,14 @@ #ifndef FILEDIALOGS_HPP #define FILEDIALOGS_HPP + #include "TFileOpenResult.hpp" +#include "TFileSaveResult.hpp" namespace forza_saveswapper::FileDialogs { TFileOpenResult OpenFile(); + TFileSaveResult SaveFile(); } // forza_saveswapper diff --git a/forza_saveswapper/fileUtilities/TFileSaveResult.hpp b/forza_saveswapper/fileUtilities/TFileSaveResult.hpp new file mode 100644 index 0000000..2b2802f --- /dev/null +++ b/forza_saveswapper/fileUtilities/TFileSaveResult.hpp @@ -0,0 +1,19 @@ +// +// Created by merika on 9/18/2024. +// + +#ifndef TFILESAVERESULT_HPP +#define TFILESAVERESULT_HPP + +#include + +namespace forza_saveswapper { + + struct TFileSaveResult { + bool Succeeded = false; + std::string Path; + }; + +} // forza_saveswapper + +#endif //TFILESAVERESULT_HPP diff --git a/forza_saveswapper/swapper/CBinaryStream.hpp b/forza_saveswapper/swapper/CBinaryStream.hpp index b2191af..18eb39d 100644 --- a/forza_saveswapper/swapper/CBinaryStream.hpp +++ b/forza_saveswapper/swapper/CBinaryStream.hpp @@ -8,8 +8,9 @@ namespace forza_saveswapper { class CBinaryStream { public: - explicit CBinaryStream(const std::shared_ptr& stream) - : m_Stream(stream) {} + explicit CBinaryStream(const std::shared_ptr& stream) : m_Stream(stream) { + + } template T Read() {