diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a88d0ae..a4d41a1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -36,8 +36,6 @@ add_executable(MassBuilderSaveTool WIN32
SaveTool/SaveTool_drawMainMenu.cpp
SaveTool/SaveTool_MainManager.cpp
SaveTool/SaveTool_ProfileManager.cpp
- MassBuilderManager/MassBuilderManager.h
- MassBuilderManager/MassBuilderManager.cpp
ProfileManager/ProfileManager.h
ProfileManager/ProfileManager.cpp
Profile/Profile.h
diff --git a/src/MassBuilderManager/MassBuilderManager.cpp b/src/MassBuilderManager/MassBuilderManager.cpp
deleted file mode 100644
index 2ac969a..0000000
--- a/src/MassBuilderManager/MassBuilderManager.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-// MassBuilderSaveTool
-// Copyright (C) 2021 Guillaume Jacquemin
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#include "MassBuilderManager.h"
-
-#include
-#include
-#include
-
-#include
-#include
-
-using namespace Corrade;
-
-MassBuilderManager::MassBuilderManager() {
- _ready = findSaveDirectory();
-}
-
-auto MassBuilderManager::ready() const -> bool {
- return _ready;
-}
-
-auto MassBuilderManager::lastError() -> std::string const& {
- return _lastError;
-}
-
-auto MassBuilderManager::saveDirectory() -> std::string const& {
- return _saveDirectory;
-}
-
-void MassBuilderManager::checkGameState() {
- WTS_PROCESS_INFOW* process_infos = nullptr;
- unsigned long process_count = 0;
-
- if(WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE, 0, 1, &process_infos, &process_count)) {
- Containers::ScopeGuard guard{process_infos, WTSFreeMemory};
-
- for(unsigned long i = 0; i < process_count; ++i) {
- if(std::wcscmp(process_infos[i].pProcessName, L"MASS_Builder-Win64-Shipping.exe") == 0) {
- _gameState = GameState::Running;
- break;
- }
- else {
- _gameState = GameState::NotRunning;
- }
- }
- }
- else {
- _gameState = GameState::Unknown;
- }
-}
-
-auto MassBuilderManager::gameState() -> GameState {
- return _gameState;
-}
-
-auto MassBuilderManager::findSaveDirectory() -> bool {
- wchar_t* localappdata_path;
- Containers::ScopeGuard guard{localappdata_path, CoTaskMemFree};
- if(SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_NO_APPCONTAINER_REDIRECTION, nullptr, &localappdata_path) != S_OK)
- {
- _lastError = "SHGetKnownFolderPath() failed in MassBuilderManager::findSaveDirectory()";
- return false;
- }
-
- _saveDirectory = Utility::Directory::join(Utility::Directory::fromNativeSeparators(Utility::Unicode::narrow(localappdata_path)), "MASS_Builder");
-
- if(!Utility::Directory::exists(_saveDirectory)) {
- _lastError = _saveDirectory + " wasn't found.";
- return false;
- }
-
- return true;
-}
diff --git a/src/MassBuilderManager/MassBuilderManager.h b/src/MassBuilderManager/MassBuilderManager.h
deleted file mode 100644
index 82a902c..0000000
--- a/src/MassBuilderManager/MassBuilderManager.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#pragma once
-
-// MassBuilderSaveTool
-// Copyright (C) 2021 Guillaume Jacquemin
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#include
-
-#include
-
-using namespace Magnum;
-
-enum class GameState : UnsignedByte {
- Unknown, NotRunning, Running
-};
-
-class MassBuilderManager {
- public:
- MassBuilderManager();
-
- auto ready() const -> bool;
- auto lastError() -> std::string const&;
-
- auto saveDirectory() -> std::string const&;
-
- void checkGameState();
- auto gameState() -> GameState;
-
- private:
- auto findSaveDirectory() -> bool;
-
- bool _ready = false;
-
- std::string _lastError = "";
-
- std::string _saveDirectory = "";
-
- GameState _gameState = GameState::Unknown;
-};
diff --git a/src/SaveTool/SaveTool.cpp b/src/SaveTool/SaveTool.cpp
index ebf3cd1..5f01873 100644
--- a/src/SaveTool/SaveTool.cpp
+++ b/src/SaveTool/SaveTool.cpp
@@ -18,6 +18,8 @@
#include
+#include
+#include
#include
#include
#include
@@ -32,6 +34,8 @@
#include
#include
#include
+#include
+#include
#include "../FontAwesome/IconsFontAwesome5.h"
#include "../FontAwesome/IconsFontAwesome5Brands.h"
@@ -59,11 +63,11 @@ SaveTool::SaveTool(const Arguments& arguments):
Utility::Debug{} << "Clickthrough is available.";
}
else {
- Utility::Debug{} << "Clickthrough is not available (hint couldn't be set).";
+ Utility::Warning{} << "Clickthrough is not available (hint couldn't be set).";
}
}
else {
- Utility::Debug{} << "Clickthrough is not available (SDL2 is too old).";
+ Utility::Warning{} << "Clickthrough is not available (SDL2 is too old).";
}
GL::Renderer::enable(GL::Renderer::Feature::Blending);
@@ -79,7 +83,33 @@ SaveTool::SaveTool(const Arguments& arguments):
if((_initEventId = SDL_RegisterEvents(1)) == UnsignedInt(-1)) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error",
- "SDL_RegisterEvents failed in SaveTool::SaveTool(). Exiting...", nullptr);
+ "SDL_RegisterEvents failed in SaveTool::SaveTool(). Exiting...", window());
+ exit(EXIT_FAILURE);
+ }
+
+ if(!findGameDataDirectory()) {
+ SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error initialising the app", _lastError.c_str(), window());
+ exit(EXIT_FAILURE);
+ }
+
+ _configDir = Utility::Directory::join(_gameDataDir, "Saved/Config/WindowsNoEditor");
+ _saveDir = Utility::Directory::join(_gameDataDir, "Saved/SaveGames");
+ _screenshotsDir = Utility::Directory::join(_gameDataDir, "Saved/Screenshots/WindowsNoEditor");
+
+ if(SDL_InitSubSystem(SDL_INIT_TIMER) != 0) {
+ SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error initialising the app", SDL_GetError(), window());
+ exit(EXIT_FAILURE);
+ }
+
+ checkGameState();
+ _gameCheckTimerId = SDL_AddTimer(2000,
+ [](UnsignedInt interval, void* param)->UnsignedInt{
+ static_cast(param)->checkGameState();
+ return interval;
+ },
+ this);
+ if(_gameCheckTimerId == 0) {
+ SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", SDL_GetError(), window());
exit(EXIT_FAILURE);
}
}
@@ -215,22 +245,6 @@ void SaveTool::initEvent(SDL_Event& event) {
case InitSuccess:
_uiState = UiState::ProfileManager;
ImGui::CloseCurrentPopup();
- SDL_InitSubSystem(SDL_INIT_TIMER);
- _mbManager->checkGameState();
- _gameCheckTimerId = SDL_AddTimer(2000,
- [](UnsignedInt interval, void* param)->UnsignedInt{
- static_cast(param)->checkGameState();
- return interval;
- },
- _mbManager.get());
- if(_gameCheckTimerId == 0) {
- SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", SDL_GetError(), window());
- exit(EXIT_FAILURE);
- }
- break;
- case MbManagerFailure:
- SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error initialising MassBuilderManager", _mbManager->lastError().c_str(), window());
- exit(EXIT_FAILURE);
break;
case ProfileManagerFailure:
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error initialising ProfileManager", _profileManager->lastError().c_str(), window());
@@ -290,14 +304,7 @@ void SaveTool::initialiseManager() {
SDL_zero(event);
event.type = _initEventId;
- _mbManager.emplace();
- if(!_mbManager->ready()) {
- event.user.code = MbManagerFailure;
- SDL_PushEvent(&event);
- return;
- }
-
- _profileManager.emplace(_mbManager->saveDirectory());
+ _profileManager.emplace(_gameDataDir);
if(!_profileManager->ready()) {
event.user.code = ProfileManagerFailure;
SDL_PushEvent(&event);
@@ -308,6 +315,25 @@ void SaveTool::initialiseManager() {
SDL_PushEvent(&event);
}
+auto SaveTool::findGameDataDirectory() -> bool {
+ wchar_t* localappdata_path = nullptr;
+ Containers::ScopeGuard guard{localappdata_path, CoTaskMemFree};
+ if(SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_NO_APPCONTAINER_REDIRECTION, nullptr, &localappdata_path) != S_OK)
+ {
+ _lastError = "SHGetKnownFolderPath() failed in SaveTool::findGameDataDirectory()";
+ return false;
+ }
+
+ _gameDataDir = Utility::Directory::join(Utility::Directory::fromNativeSeparators(Utility::Unicode::narrow(localappdata_path)), "MASS_Builder");
+
+ if(!Utility::Directory::exists(_gameDataDir)) {
+ _lastError = _gameDataDir + " wasn't found. Make sure to play the game at least once.";
+ return false;
+ }
+
+ return true;
+}
+
void SaveTool::initialiseMassManager() {
_currentProfile->refreshValues();
@@ -450,7 +476,7 @@ void SaveTool::drawGameState() {
ImGui::TextUnformatted("Game state:");
ImGui::SameLine();
{
- switch(_mbManager->gameState()) {
+ switch(_gameState) {
case GameState::Unknown:
ImGui::TextColored(ImColor{0xff00a5ff}, ICON_FA_CIRCLE);
drawTooltip("unknown");
@@ -489,3 +515,25 @@ void SaveTool::drawTooltip(const char* text, Float wrap_pos) {
void SaveTool::openUri(const std::string& uri) {
ShellExecuteW(nullptr, nullptr, Utility::Unicode::widen(uri).c_str(), nullptr, nullptr, SW_SHOW);
}
+
+void SaveTool::checkGameState() {
+ WTS_PROCESS_INFOW* process_infos = nullptr;
+ unsigned long process_count = 0;
+
+ if(WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE, 0, 1, &process_infos, &process_count)) {
+ Containers::ScopeGuard guard{process_infos, WTSFreeMemory};
+
+ for(unsigned long i = 0; i < process_count; ++i) {
+ if(std::wcscmp(process_infos[i].pProcessName, L"MASS_Builder-Win64-Shipping.exe") == 0) {
+ _gameState = GameState::Running;
+ break;
+ }
+ else {
+ _gameState = GameState::NotRunning;
+ }
+ }
+ }
+ else {
+ _gameState = GameState::Unknown;
+ }
+}
diff --git a/src/SaveTool/SaveTool.h b/src/SaveTool/SaveTool.h
index b03eea0..2d89d47 100644
--- a/src/SaveTool/SaveTool.h
+++ b/src/SaveTool/SaveTool.h
@@ -31,7 +31,6 @@
#include
-#include "../MassBuilderManager/MassBuilderManager.h"
#include "../ProfileManager/ProfileManager.h"
#include "../MassManager/MassManager.h"
@@ -68,7 +67,6 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
enum InitStatus: Int {
InitSuccess,
- MbManagerFailure,
ProfileManagerFailure
};
void initEvent(SDL_Event& event);
@@ -76,6 +74,7 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
// Initialisation methods
void initialiseGui();
void initialiseManager();
+ auto findGameDataDirectory() -> bool;
void initialiseMassManager();
void initialiseFileWatcher();
@@ -106,7 +105,7 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
template
auto drawUnsafeWidget(Functor func, Args... args) -> bool {
- GameState game_state = _mbManager->gameState();
+ GameState game_state = _gameState; // Copying the value to reduce the risk of a data race.
if(!_unsafeMode && game_state != GameState::NotRunning) {
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.5f);
@@ -125,7 +124,7 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
template
void drawUnsafeText(const char* text, Args... args) { // Alternative to the above, for ImGui::Text*() variants.
- if(!_unsafeMode && _mbManager->gameState() != GameState::NotRunning) {
+ if(!_unsafeMode && _gameState != GameState::NotRunning) {
ImGui::TextDisabled(text, std::forward(args)...);
}
else {
@@ -135,6 +134,8 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
void openUri(const std::string& uri);
+ void checkGameState();
+
Utility::Resource _rs{"assets"};
// GUI-related members
@@ -145,8 +146,7 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
Initialising,
ProfileManager,
MainManager
- };
- UiState _uiState{UiState::Disclaimer};
+ } _uiState{UiState::Disclaimer};
bool _aboutPopup{false};
#ifdef SAVETOOL_DEBUG_BUILD
@@ -158,8 +158,18 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
std::thread _thread;
UnsignedInt _initEventId;
- Containers::Pointer _mbManager;
- SDL_TimerID _gameCheckTimerId;
+ std::string _lastError;
+
+ std::string _gameDataDir;
+ std::string _configDir;
+ std::string _saveDir;
+ std::string _screenshotsDir;
+
+ enum class GameState : UnsignedByte {
+ Unknown, NotRunning, Running
+ } _gameState{GameState::Unknown};
+
+ SDL_TimerID _gameCheckTimerId = 0;
Containers::Pointer _profileManager;
Profile* _currentProfile{nullptr};
diff --git a/src/SaveTool/SaveTool_MainManager.cpp b/src/SaveTool/SaveTool_MainManager.cpp
index e1c4d10..22f1f9b 100644
--- a/src/SaveTool/SaveTool_MainManager.cpp
+++ b/src/SaveTool/SaveTool_MainManager.cpp
@@ -161,9 +161,9 @@ auto SaveTool::drawRenamePopup(Containers::ArrayView name_view) -> bool {
ImGuiInputTextFlags_CallbackCharFilter,
callback, nullptr);
ImGui::SameLine();
- GameState game_state = _mbManager->gameState();
+ GameState game_state = _gameState;
if((!_unsafeMode && game_state != GameState::NotRunning) ||
- !(len >= 6 && len <= 32) ||
+ !(len >= 6 && len <= 32) ||
!(name_view[0] != ' ' && name_view[len - 1] != ' '))
{
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
@@ -176,7 +176,7 @@ auto SaveTool::drawRenamePopup(Containers::ArrayView name_view) -> bool {
}
if((!_unsafeMode && game_state != GameState::NotRunning) ||
- !(len >= 6 && len <= 32) ||
+ !(len >= 6 && len <= 32) ||
!(name_view[0] != ' ' && name_view[len - 1] != ' '))
{
ImGui::PopItemFlag();
@@ -265,7 +265,7 @@ void SaveTool::drawGeneralInfo() {
}
drawTooltip("Story progress directly affects unlocked levels.");
if(ImGui::BeginPopup("StoryProgressMenu")) {
- if(!_unsafeMode && _mbManager->gameState() != GameState::NotRunning) {
+ if(!_unsafeMode && _gameState != GameState::NotRunning) {
ImGui::CloseCurrentPopup();
}
for(const auto& sp : story_progress) {
@@ -441,7 +441,7 @@ void SaveTool::drawMassManager() {
ImGui::EndDragDropSource();
}
- if((!_unsafeMode && _mbManager->gameState() == GameState::NotRunning) && ImGui::BeginDragDropTarget()) {
+ if((!_unsafeMode && _gameState == GameState::NotRunning) && ImGui::BeginDragDropTarget()) {
if(const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("StagedMass")) {
if(payload->DataSize != sizeof(std::string)) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal error",
@@ -595,7 +595,7 @@ auto SaveTool::drawDeleteMassPopup(int mass_index) -> ImGuiID {
return 0;
}
- if(_mbManager->gameState() != GameState::NotRunning) {
+ if(_gameState != GameState::NotRunning) {
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
return 0;
diff --git a/src/SaveTool/SaveTool_drawMainMenu.cpp b/src/SaveTool/SaveTool_drawMainMenu.cpp
index 709396b..94876e0 100644
--- a/src/SaveTool/SaveTool_drawMainMenu.cpp
+++ b/src/SaveTool/SaveTool_drawMainMenu.cpp
@@ -24,18 +24,17 @@
void SaveTool::drawMainMenu() {
if(ImGui::BeginMainMenuBar()) {
if(ImGui::BeginMenu("Save Tool##SaveToolMenu")) {
- if(ImGui::BeginMenu(ICON_FA_FOLDER_OPEN " Open game data directory", _mbManager != nullptr)) {
- if(ImGui::MenuItem(ICON_FA_COG " Configuration", nullptr, false, _mbManager != nullptr)) {
- openUri(Utility::Directory::toNativeSeparators(_mbManager->saveDirectory() + "/Saved/Config/WindowsNoEditor"));
+ if(ImGui::BeginMenu(ICON_FA_FOLDER_OPEN " Open game data directory", Utility::Directory::exists(_gameDataDir))) {
+ if(ImGui::MenuItem(ICON_FA_COG " Configuration", nullptr, false, Utility::Directory::exists(_configDir))) {
+ openUri(Utility::Directory::toNativeSeparators(_configDir));
}
- if(ImGui::MenuItem(ICON_FA_SAVE " Saves", nullptr, false, _profileManager != nullptr)) {
- openUri(Utility::Directory::toNativeSeparators(_profileManager->saveDirectory()));
+ if(ImGui::MenuItem(ICON_FA_SAVE " Saves", nullptr, false, Utility::Directory::exists(_saveDir))) {
+ openUri(Utility::Directory::toNativeSeparators(_saveDir));
}
- static bool _screenshotsAvailable = Utility::Directory::exists(_mbManager->saveDirectory() + "/Saved/Screenshots/WindowsNoEditor");
- if(ImGui::MenuItem(ICON_FA_IMAGE " Screenshots", nullptr, false, _screenshotsAvailable)) {
- openUri(Utility::Directory::toNativeSeparators(_mbManager->saveDirectory() + "/Screenshots/WindowsNoEditor"));
+ if(ImGui::MenuItem(ICON_FA_IMAGE " Screenshots", nullptr, false, Utility::Directory::exists(_screenshotsDir))) {
+ openUri(Utility::Directory::toNativeSeparators(_screenshotsDir));
}
ImGui::EndMenu();
@@ -105,7 +104,7 @@ void SaveTool::drawMainMenu() {
ImGui::EndMenu();
}
- if(_mbManager != nullptr) {
+ if(_gameCheckTimerId != 0) {
if(ImGui::BeginTable("##MainMenuLayout", 2)) {
ImGui::TableSetupColumn("##Dummy", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("##GameState", ImGuiTableColumnFlags_WidthFixed);