Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/source/ps/Mod.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 "ps/Mod.h" | #include "ps/Mod.h" | ||||
#include "i18n/L10n.h" | #include "i18n/L10n.h" | ||||
#include "lib/file/file_system.h" | #include "lib/file/file_system.h" | ||||
#include "lib/file/vfs/vfs.h" | #include "lib/file/vfs/vfs.h" | ||||
#include "lib/sysdep/os.h" | |||||
#include "lib/utf8.h" | #include "lib/utf8.h" | ||||
#include "ps/Filesystem.h" | #include "ps/Filesystem.h" | ||||
#include "ps/GameSetup/GameSetup.h" | #include "ps/GameSetup/GameSetup.h" | ||||
#include "ps/GameSetup/Paths.h" | #include "ps/GameSetup/Paths.h" | ||||
#include "ps/Profiler2.h" | #include "ps/Profiler2.h" | ||||
#include "scriptinterface/JSON.h" | #include "scriptinterface/JSON.h" | ||||
#include "scriptinterface/Object.h" | #include "scriptinterface/Object.h" | ||||
#include "scriptinterface/ScriptExceptions.h" | #include "scriptinterface/ScriptExceptions.h" | ||||
#include "scriptinterface/ScriptInterface.h" | #include "scriptinterface/ScriptInterface.h" | ||||
#include <algorithm> | #include <algorithm> | ||||
#include <boost/algorithm/string/split.hpp> | #include <boost/algorithm/string/split.hpp> | ||||
#include <boost/algorithm/string/classification.hpp> | #include <boost/algorithm/string/classification.hpp> | ||||
#if OS_WIN | |||||
#include <filesystem> | |||||
#endif | |||||
#include <fstream> | #include <fstream> | ||||
#include <sstream> | #include <sstream> | ||||
#include <unordered_map> | #include <unordered_map> | ||||
namespace | namespace | ||||
{ | { | ||||
/** | /** | ||||
* Global instance of Mod, always exists. | * Global instance of Mod, always exists. | ||||
*/ | */ | ||||
Mod g_ModInstance; | Mod g_ModInstance; | ||||
bool LoadModJSON(const PIVFS& vfs, OsPath modsPath, OsPath mod, std::string& text) | bool LoadModJSON(const PIVFS& vfs, OsPath modsPath, OsPath mod, std::string& text) | ||||
{ | { | ||||
#if OS_WIN | |||||
const std::filesystem::path modJsonPath = (modsPath / mod / L"mod.json").fileSystemPath(); | |||||
#else | |||||
const std::string modJsonPath = (modsPath / mod / L"mod.json").string8(); | |||||
#endif | |||||
// Attempt to open mod.json first. | // Attempt to open mod.json first. | ||||
std::ifstream modjson; | std::ifstream modjson(modJsonPath); | ||||
modjson.open((modsPath / mod / L"mod.json").string8()); | if (!modjson) | ||||
if (!modjson.is_open()) | |||||
{ | { | ||||
modjson.close(); | modjson.close(); | ||||
// Fallback: open the archive and read mod.json there. | // Fallback: open the archive and read mod.json there. | ||||
// This can take in the hundreds of milliseconds with large mods. | // This can take in the hundreds of milliseconds with large mods. | ||||
vfs->Clear(); | vfs->Clear(); | ||||
if (vfs->Mount(L"", modsPath / mod / "", VFS_MOUNT_MUST_EXIST, VFS_MIN_PRIORITY) < 0) | if (vfs->Mount(L"", modsPath / mod / "", VFS_MOUNT_MUST_EXIST, VFS_MIN_PRIORITY) < 0) | ||||
return false; | return false; | ||||
CVFSFile modinfo; | CVFSFile modinfo; | ||||
if (modinfo.Load(vfs, L"mod.json", false) != PSRETURN_OK) | if (modinfo.Load(vfs, L"mod.json", false) != PSRETURN_OK) | ||||
return false; | return false; | ||||
text = modinfo.GetAsString(); | text = modinfo.GetAsString(); | ||||
// Attempt to write the mod.json file so we'll take the fast path next time. | // Attempt to write the mod.json file so we'll take the fast path next time. | ||||
std::ofstream out_mod_json((modsPath / mod / L"mod.json").string8()); | std::ofstream out_mod_json(modJsonPath); | ||||
if (out_mod_json.good()) | if (out_mod_json) | ||||
{ | { | ||||
out_mod_json << text; | out_mod_json << text; | ||||
out_mod_json.close(); | out_mod_json.close(); | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
// Print a warning - we'll keep trying, which could have adverse effects. | // Print a warning - we'll keep trying, which could have adverse effects. | ||||
if (L10n::IsInitialised()) | if (L10n::IsInitialised()) | ||||
▲ Show 20 Lines • Show All 289 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator