Ticket #4027: 4027_proposed.patch
File 4027_proposed.patch, 6.2 KB (added by , 7 years ago) |
---|
-
source/main.cpp
49 49 #include "ps/Globals.h" 50 50 #include "ps/Hotkey.h" 51 51 #include "ps/Loader.h" 52 #include "ps/ModInstaller.h" 52 53 #include "ps/Profile.h" 53 54 #include "ps/Profiler2.h" 54 55 #include "ps/Pyrogenesis.h" … … 443 444 return; 444 445 } 445 446 } 447 448 const bool isModInstallation = args.Has("install-mod"); 449 const CStr modPath = isModInstallation ? args.Get("install-mod") : ""; 446 450 451 if (isModInstallation) 452 { 453 if (!FileExists(OsPath(modPath))) 454 { 455 debug_printf("ERROR: The mod file '%s' does not exist!\n", modPath.c_str()); 456 return; 457 } 458 if (DirectoryExists(OsPath(modPath))) 459 { 460 debug_printf("ERROR: The mod file '%s' is a directory!\n", modPath.c_str()); 461 return; 462 } 463 } 464 447 465 // We need to initialize SpiderMonkey and libxml2 in the main thread before 448 466 // any thread uses them. So initialize them here before we might run Atlas. 449 467 ScriptEngine scriptEngine; … … 483 501 CXeromyces::Terminate(); 484 502 return; 485 503 } 504 505 if (isModInstallation) 506 { 507 Paths paths(args); 508 509 CModInstaller installer(paths.UserData() / "mods", paths.Cache()); 486 510 511 // Creates a directory with the name extracted from a `mod.json` 512 installer.Install(modPath); 513 514 CXeromyces::Terminate(); 515 return; 516 } 517 487 518 // run in archive-building mode if requested 488 519 if (args.Has("archivebuild")) 489 520 { -
source/ps/ModInstaller.cpp
1 /* Copyright (C) 2016 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "precompiled.h" 19 20 #include "ModInstaller.h" 21 22 #include "lib/file/vfs/vfs_util.h" 23 #include "lib/sysdep/sysdep.h" 24 #include "ps/Filesystem.h" 25 #include "ps/XML/Xeromyces.h" 26 27 #include <boost/filesystem/operations.hpp> 28 29 CModInstaller::CModInstaller(const OsPath& modsdir, const OsPath& tempdir) : 30 m_ModsDir(modsdir), m_TempDir(tempdir / "_modscache"), m_CacheDir("cache/") 31 { 32 m_VFS = CreateVfs(20 * MiB); 33 34 CreateDirectories(m_TempDir, 0700); 35 36 const int runtimeSize = 64 * MiB; 37 const int heapGrowthBytesGCTrigger = 16 * MiB; 38 m_ScriptRuntime = ScriptInterface::CreateRuntime(std::shared_ptr<ScriptRuntime>(), runtimeSize, heapGrowthBytesGCTrigger); 39 } 40 41 CModInstaller::~CModInstaller() 42 { 43 m_VFS.reset(); 44 45 m_ScriptRuntime.reset(); 46 47 DeleteDirectory(m_TempDir); 48 } 49 50 void CModInstaller::Install(const OsPath& mod) 51 { 52 const OsPath modTemp = m_TempDir / mod.Filename().ChangeExtension(L".zip"); 53 // TODO: move the file, not copy 54 boost::filesystem::copy_file( 55 mod.string8(), 56 modTemp.string8(), 57 boost::filesystem::copy_option::overwrite_if_exists 58 ); 59 60 m_VFS->Mount(m_CacheDir, m_TempDir / ""); 61 CVFSFile modinfo; 62 if (modinfo.Load(m_VFS, m_CacheDir / "mod.json", false) != PSRETURN_OK) 63 return; 64 m_VFS->Clear(); 65 66 ScriptInterface scriptInterface("Engine", "ModInstaller", m_ScriptRuntime); 67 JSContext* cx = scriptInterface.GetContext(); 68 JS::RootedValue json_val(cx); 69 if (!scriptInterface.ParseJSON(modinfo.GetAsString(), &json_val)) 70 return; 71 JS::RootedObject json_obj(cx, json_val.toObjectOrNull()); 72 JS::RootedValue name_val(cx); 73 JS_GetProperty(cx, json_obj, "name", &name_val); 74 std::string modName; 75 ScriptInterface::FromJSVal(cx, name_val, modName); 76 77 const OsPath modDir = m_ModsDir / modName; 78 const OsPath modPath = modDir / (modName + ".zip"); 79 80 DeleteDirectory(modDir); 81 CreateDirectories(modDir, 0700); 82 83 boost::filesystem::rename(modTemp.string8(), modPath.string8()); 84 85 #ifdef OS_WIN 86 // TODO: copy mod.json to the path 87 #endif 88 } -
source/ps/ModInstaller.h
1 /* Copyright (C) 2016 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef INCLUDED_MODINSTALLER 19 #define INCLUDED_MODINSTALLER 20 21 #include "lib/file/vfs/vfs.h" 22 #include "scriptinterface/ScriptInterface.h" 23 24 /** 25 * Install a mod into the mods directory. 26 */ 27 class CModInstaller 28 { 29 public: 30 /** 31 * Initialise the mod installer for processing the given mod. 32 * 33 * @param modsdir path to the data directory, containing mods 34 * @param tempdir path to a writable directory for temporary files 35 */ 36 CModInstaller(const OsPath& modsdir, const OsPath& tempdir); 37 38 ~CModInstaller(); 39 40 /** 41 * Do all the processing and unpacking. 42 * @param mod path of .pyromod file of mod 43 */ 44 void Install(const OsPath& mod); 45 46 private: 47 48 PIVFS m_VFS; 49 OsPath m_ModsDir; 50 OsPath m_TempDir; 51 VfsPath m_CacheDir; 52 53 std::shared_ptr<ScriptRuntime> m_ScriptRuntime; 54 }; 55 56 #endif // INCLUDED_MODINSTALLER