Changeset View
Changeset View
Standalone View
Standalone View
source/ps/SavedGame.cpp
/* Copyright (C) 2021 Wildfire Games. | /* Copyright (C) 2022 Wildfire Games. | ||||||||||||||||
* This file is part of 0 A.D. | * This file is part of 0 A.D. | ||||||||||||||||
* | * | ||||||||||||||||
* 0 A.D. is free software: you can redistribute it and/or modify | * 0 A.D. is free software: you can redistribute it and/or modify | ||||||||||||||||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | ||||||||||||||||
* the Free Software Foundation, either version 2 of the License, or | * the Free Software Foundation, either version 2 of the License, or | ||||||||||||||||
* (at your option) any later version. | * (at your option) any later version. | ||||||||||||||||
* | * | ||||||||||||||||
* 0 A.D. is distributed in the hope that it will be useful, | * 0 A.D. is distributed in the hope that it will be useful, | ||||||||||||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||||||||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||||||||||||
* GNU General Public License for more details. | * GNU General Public License for more details. | ||||||||||||||||
* | * | ||||||||||||||||
* You should have received a copy of the GNU General Public License | * You should have received a copy of the GNU General Public License | ||||||||||||||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. | * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. | ||||||||||||||||
*/ | */ | ||||||||||||||||
#include "precompiled.h" | #include "precompiled.h" | ||||||||||||||||
#include "SavedGame.h" | #include "SavedGame.h" | ||||||||||||||||
#include "graphics/GameView.h" | #include "graphics/GameView.h" | ||||||||||||||||
#include "gui/GUIManager.h" | |||||||||||||||||
#include "i18n/L10n.h" | #include "i18n/L10n.h" | ||||||||||||||||
#include "lib/allocators/shared_ptr.h" | #include "lib/allocators/shared_ptr.h" | ||||||||||||||||
#include "lib/file/archive/archive_zip.h" | #include "lib/file/archive/archive_zip.h" | ||||||||||||||||
#include "lib/file/io/io.h" | #include "lib/file/io/io.h" | ||||||||||||||||
#include "lib/utf8.h" | #include "lib/utf8.h" | ||||||||||||||||
#include "maths/Vector3D.h" | #include "maths/Vector3D.h" | ||||||||||||||||
#include "ps/CLogger.h" | #include "ps/CLogger.h" | ||||||||||||||||
#include "ps/Filesystem.h" | #include "ps/Filesystem.h" | ||||||||||||||||
#include "ps/Game.h" | #include "ps/Game.h" | ||||||||||||||||
#include "ps/Mod.h" | #include "ps/Mod.h" | ||||||||||||||||
#include "ps/Pyrogenesis.h" | #include "ps/Pyrogenesis.h" | ||||||||||||||||
#include "scriptinterface/Object.h" | #include "scriptinterface/Object.h" | ||||||||||||||||
#include "scriptinterface/JSON.h" | #include "scriptinterface/JSON.h" | ||||||||||||||||
#include "scriptinterface/StructuredClone.h" | #include "scriptinterface/StructuredClone.h" | ||||||||||||||||
#include "simulation2/Simulation2.h" | #include "simulation2/Simulation2.h" | ||||||||||||||||
#include "simulation2/system/TurnManager.h" | |||||||||||||||||
// TODO: we ought to check version numbers when loading files | // TODO: we ought to check version numbers when loading files | ||||||||||||||||
Status SavedGames::SavePrefix(const CStrW& prefix, const CStrW& description, CSimulation2& simulation, const Script::StructuredClone& guiMetadataClone) | Status SavedGames::SavePrefix(const CStrW& prefix, const CStrW& description, CSimulation2& simulation, const Script::StructuredClone& guiMetadataClone) | ||||||||||||||||
{ | { | ||||||||||||||||
// Determine the filename to save under | // Determine the filename to save under | ||||||||||||||||
const VfsPath basenameFormat(L"saves/" + prefix + L"-%04d"); | const VfsPath basenameFormat(L"saves/" + prefix + L"-%04d"); | ||||||||||||||||
const VfsPath filenameFormat = basenameFormat.ChangeExtension(L".0adsave"); | const VfsPath filenameFormat = basenameFormat.ChangeExtension(L".0adsave"); | ||||||||||||||||
▲ Show 20 Lines • Show All 252 Lines • ▼ Show 20 Lines | bool SavedGames::DeleteSavedGame(const std::wstring& name) | ||||||||||||||||
// Delete actual file | // Delete actual file | ||||||||||||||||
if (wunlink(realpath) != 0) | if (wunlink(realpath) != 0) | ||||||||||||||||
return false; // Error | return false; // Error | ||||||||||||||||
// Successfully deleted file | // Successfully deleted file | ||||||||||||||||
return true; | return true; | ||||||||||||||||
} | } | ||||||||||||||||
Status SavedGames::QuickSave(CSimulation2& simulation, const Script::StructuredClone& GUIMetadataClone) | |||||||||||||||||
{ | |||||||||||||||||
return Save(L"quicksave", L"quicksave", simulation, GUIMetadataClone); | |||||||||||||||||
} | |||||||||||||||||
Status SavedGames::QuickLoad(CSimulation2& simulation) | |||||||||||||||||
{ | |||||||||||||||||
ScriptRequest rq(simulation.GetScriptInterface()); | |||||||||||||||||
// Load quicksave archive | |||||||||||||||||
phosit: I don't like functions doing multiple things. You could extract some parts… | |||||||||||||||||
JS::RootedValue quickSaveMetadata(rq.cx); | |||||||||||||||||
std::string savedState; | |||||||||||||||||
Done Inline Actions#include <string> Stan: #include <string> | |||||||||||||||||
if (SavedGames::Load(L"quicksave", simulation.GetScriptInterface(), &quickSaveMetadata, savedState) < 0) | |||||||||||||||||
{ | |||||||||||||||||
LOGERROR("Failed to load quicksave file"); | |||||||||||||||||
return ERR::FAIL; | |||||||||||||||||
} | |||||||||||||||||
// Get matchID of quicksave | |||||||||||||||||
JS::RootedValue gameInitAttributes(rq.cx); | |||||||||||||||||
Script::GetProperty(rq, quickSaveMetadata, "initAttributes", &gameInitAttributes); | |||||||||||||||||
std::wstring savedMatchID; | |||||||||||||||||
Script::GetProperty(rq, gameInitAttributes, "matchID", savedMatchID); | |||||||||||||||||
// Get matchID of current game | |||||||||||||||||
std::wstring matchID; | |||||||||||||||||
JS::RootedValue gameMetadata(rq.cx, simulation.GetInitAttributes()); | |||||||||||||||||
Script::GetProperty(rq, gameMetadata, "matchID", matchID); | |||||||||||||||||
vladislavbelovUnsubmitted Done Inline ActionsEach GetProperty might fail. vladislavbelov: Each `GetProperty` might fail. | |||||||||||||||||
// Compare IDs | |||||||||||||||||
if (matchID.compare(savedMatchID) != 0) | |||||||||||||||||
{ | |||||||||||||||||
LOGMESSAGERENDER(g_L10n.Translate("Cannot quickload game - match not quicksaved")); | |||||||||||||||||
return INFO::CANNOT_HANDLE; | |||||||||||||||||
} | |||||||||||||||||
std::stringstream stream(savedState); | |||||||||||||||||
if (!simulation.DeserializeState(stream)) | |||||||||||||||||
{ | |||||||||||||||||
LOGERROR("Failed to quickload game"); | |||||||||||||||||
Done Inline Actions#include <sstream> Stan: #include <sstream> | |||||||||||||||||
return ERR::FAIL; | |||||||||||||||||
Done Inline Actions
Stan: | |||||||||||||||||
} | |||||||||||||||||
g_Game->GetTurnManager()->RewindTimeWarp(); | |||||||||||||||||
// Provide a copy, so that GUI components don't have to clone to get mutable objects | |||||||||||||||||
JS::RootedValue quickSaveMetadataClone(rq.cx, Script::DeepCopy(rq, quickSaveMetadata)); | |||||||||||||||||
JS::RootedValueArray<1> paramData(rq.cx); | |||||||||||||||||
paramData[0].set(quickSaveMetadataClone); | |||||||||||||||||
CStr EventNameSavegameLoaded = "SavegameLoaded"; | |||||||||||||||||
g_GUI->SendEventToAll(EventNameSavegameLoaded, paramData); | |||||||||||||||||
LOGMESSAGERENDER(g_L10n.Translate("Quickloaded game")); | |||||||||||||||||
return INFO::OK; | |||||||||||||||||
Done Inline Actions
Stan: | |||||||||||||||||
} | |||||||||||||||||
Done Inline Actions
Stan: | |||||||||||||||||
Not Done Inline Actions
Stan: |
Wildfire Games · Phabricator
I don't like functions doing multiple things. You could extract some parts: LoadQuickSaveArchive, GetMatchIDOfQuicksave, GetMatchIDOfCurrentGame.
If you make them static thous will be inlined and there is no overhead.