Changeset View
Changeset View
Standalone View
Standalone View
source/ps/Mod.cpp
Show All 14 Lines | |||||
* 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 <algorithm> | #include <algorithm> | ||||
#include <regex> | |||||
#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/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/Pyrogenesis.h" | #include "ps/Pyrogenesis.h" | ||||
#include "scriptinterface/ScriptInterface.h" | #include "scriptinterface/ScriptInterface.h" | ||||
std::vector<CStr> g_modsLoaded; | std::vector<CStr> g_modsLoaded; | ||||
std::vector<std::vector<CStr>> g_LoadedModVersions; | std::vector<std::vector<CStr>> g_LoadedModVersions; | ||||
CmdLineArgs g_args; | CmdLineArgs g_args; | ||||
JS::Value Mod::GetAvailableMods(const ScriptInterface& scriptInterface) | JS::Value Mod::GetAvailableMods(const ScriptInterface& scriptInterface) | ||||
{ | { | ||||
ScriptRequest rq(scriptInterface); | const ScriptRequest rq(scriptInterface); | ||||
JS::RootedObject obj(rq.cx, JS_NewPlainObject(rq.cx)); | JS::RootedObject obj(rq.cx, JS_NewPlainObject(rq.cx)); | ||||
const Paths paths(g_args); | const Paths paths(g_args); | ||||
// loop over all possible paths | // loop over all possible paths | ||||
OsPath modPath = paths.RData()/"mods"; | OsPath modPath = paths.RData()/"mods"; | ||||
OsPath modUserPath = paths.UserData()/"mods"; | OsPath modUserPath = paths.UserData()/"mods"; | ||||
Show All 16 Lines | for (DirectoryNames::iterator iter = modDirs.begin(); iter != modDirs.end(); ++iter) | ||||
CVFSFile modinfo; | CVFSFile modinfo; | ||||
if (modinfo.Load(vfs, L"mod.json", false) != PSRETURN_OK) | if (modinfo.Load(vfs, L"mod.json", false) != PSRETURN_OK) | ||||
continue; | continue; | ||||
JS::RootedValue json(rq.cx); | JS::RootedValue json(rq.cx); | ||||
if (!scriptInterface.ParseJSON(modinfo.GetAsString(), &json)) | if (!scriptInterface.ParseJSON(modinfo.GetAsString(), &json)) | ||||
continue; | continue; | ||||
// Valid mod, add it to our structure | // Validate mod | ||||
if (!json.isObject()) | |||||
continue; | |||||
JS::RootedObject jsonObj(rq.cx, &json.toObject()); | |||||
bool hasProperty; | |||||
if (!JS_HasProperty(rq.cx, jsonObj, "name", &hasProperty) || !hasProperty) | |||||
{ | |||||
scriptInterface.SetProperty(json, "invalid", true); | |||||
scriptInterface.SetProperty(json, "error", 1); | |||||
JS_SetProperty(rq.cx, obj, utf8_from_wstring(iter->string()).c_str(), json); | |||||
continue; | |||||
} | |||||
std::string name; | |||||
scriptInterface.FromJSProperty(rq, json, "name", name, false); | |||||
if (!std::regex_match(name, std::regex("^[a-zA-Z0-9\-\_]+$"))) | |||||
{ | |||||
scriptInterface.SetProperty(json, "invalid", true); | |||||
scriptInterface.SetProperty(json, "error", 7); | |||||
JS_SetProperty(rq.cx, obj, utf8_from_wstring(iter->string()).c_str(), json); | |||||
continue; | |||||
} | |||||
if (!JS_HasProperty(rq.cx, jsonObj, "version", &hasProperty) || !hasProperty) | |||||
{ | |||||
scriptInterface.SetProperty(json, "invalid", true); | |||||
scriptInterface.SetProperty(json, "error", 2); | |||||
JS_SetProperty(rq.cx, obj, utf8_from_wstring(iter->string()).c_str(), json); | |||||
continue; | |||||
} | |||||
std::string version; | |||||
scriptInterface.FromJSProperty(rq, json, "version", version, false); | |||||
if (!std::regex_match(version, std::regex("^[0-9]+(\.[0-9]+){0,2}$"))) | |||||
{ | |||||
scriptInterface.SetProperty(json, "invalid", true); | |||||
scriptInterface.SetProperty(json, "error", 8); | |||||
JS_SetProperty(rq.cx, obj, utf8_from_wstring(iter->string()).c_str(), json); | |||||
continue; | |||||
} | |||||
if (!JS_HasProperty(rq.cx, jsonObj, "dependencies", &hasProperty) || !hasProperty) | |||||
{ | |||||
scriptInterface.SetProperty(json, "invalid", true); | |||||
scriptInterface.SetProperty(json, "error", 3); | |||||
JS_SetProperty(rq.cx, obj, utf8_from_wstring(iter->string()).c_str(), json); | |||||
continue; | |||||
} | |||||
JS::RootedValue dependencies(rq.cx); | |||||
JS_GetProperty(rq.cx, jsonObj, "dependencies", &dependencies); | |||||
if (!dependencies.isObject()) | |||||
{ | |||||
scriptInterface.SetProperty(json, "invalid", true); | |||||
scriptInterface.SetProperty(json, "error", 4); | |||||
JS_SetProperty(rq.cx, obj, utf8_from_wstring(iter->string()).c_str(), json); | |||||
continue; | |||||
} | |||||
if (!JS_HasProperty(rq.cx, jsonObj, "label", &hasProperty) || !hasProperty) | |||||
{ | |||||
scriptInterface.SetProperty(json, "invalid", true); | |||||
scriptInterface.SetProperty(json, "error", 5); | |||||
JS_SetProperty(rq.cx, obj, utf8_from_wstring(iter->string()).c_str(), json); | |||||
continue; | |||||
} | |||||
std::string label; | |||||
scriptInterface.FromJSProperty(rq, json, "label", label, false); | |||||
if (!std::regex_match(label, std::regex(".*\\S.*"))) | |||||
{ | |||||
scriptInterface.SetProperty(json, "invalid", true); | |||||
scriptInterface.SetProperty(json, "error", 9); | |||||
JS_SetProperty(rq.cx, obj, utf8_from_wstring(iter->string()).c_str(), json); | |||||
continue; | |||||
} | |||||
if (!JS_HasProperty(rq.cx, jsonObj, "description", &hasProperty) || !hasProperty) | |||||
{ | |||||
scriptInterface.SetProperty(json, "invalid", true); | |||||
scriptInterface.SetProperty(json, "error", 6); | |||||
JS_SetProperty(rq.cx, obj, utf8_from_wstring(iter->string()).c_str(), json); | |||||
continue; | |||||
} | |||||
JS_SetProperty(rq.cx, obj, utf8_from_wstring(iter->string()).c_str(), json); | JS_SetProperty(rq.cx, obj, utf8_from_wstring(iter->string()).c_str(), json); | ||||
} | } | ||||
GetDirectoryEntries(modUserPath, NULL, &modDirsUser); | GetDirectoryEntries(modUserPath, NULL, &modDirsUser); | ||||
bool dev = InDevelopmentCopy(); | bool dev = InDevelopmentCopy(); | ||||
for (DirectoryNames::iterator iter = modDirsUser.begin(); iter != modDirsUser.end(); ++iter) | for (DirectoryNames::iterator iter = modDirsUser.begin(); iter != modDirsUser.end(); ++iter) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 74 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator