diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c073e78..045564a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -236,8 +236,8 @@ if (ANDROID) endif() set(MAT_JSON_AS_INTERFACE ON) -CPMAddPackage("gh:geode-sdk/json#cda9807") -CPMAddPackage("gh:geode-sdk/result@1.0.1") +CPMAddPackage("gh:geode-sdk/json#1b182dd") +CPMAddPackage("gh:geode-sdk/result@1.1.0") CPMAddPackage("gh:fmtlib/fmt#10.2.1") target_compile_definitions(${PROJECT_NAME} INTERFACE MAT_JSON_DYNAMIC=1) diff --git a/loader/include/Geode/cocos/base_nodes/CCNode.h b/loader/include/Geode/cocos/base_nodes/CCNode.h index 1bbf681c..bf4f00c9 100644 --- a/loader/include/Geode/cocos/base_nodes/CCNode.h +++ b/loader/include/Geode/cocos/base_nodes/CCNode.h @@ -41,7 +41,7 @@ #include #ifndef GEODE_IS_MEMBER_TEST -#include +#include #endif namespace geode { diff --git a/loader/include/Geode/loader/Hook.hpp b/loader/include/Geode/loader/Hook.hpp index 6a3eb105..1ea4d792 100644 --- a/loader/include/Geode/loader/Hook.hpp +++ b/loader/include/Geode/loader/Hook.hpp @@ -2,7 +2,7 @@ #include "../DefaultInclude.hpp" #include "../utils/general.hpp" -#include +#include #include "Tulip.hpp" #include #include diff --git a/loader/include/Geode/loader/IPC.hpp b/loader/include/Geode/loader/IPC.hpp index 73e32d1e..015b246f 100644 --- a/loader/include/Geode/loader/IPC.hpp +++ b/loader/include/Geode/loader/IPC.hpp @@ -3,7 +3,7 @@ #include "Event.hpp" #include "Loader.hpp" #include "Mod.hpp" -#include +#include namespace geode::ipc { #ifdef GEODE_IS_WINDOWS diff --git a/loader/include/Geode/loader/Loader.hpp b/loader/include/Geode/loader/Loader.hpp index 8bab1da5..5132704e 100644 --- a/loader/include/Geode/loader/Loader.hpp +++ b/loader/include/Geode/loader/Loader.hpp @@ -8,7 +8,7 @@ #include "Types.hpp" #include -#include +#include #include #include #include @@ -121,7 +121,7 @@ namespace geode { * @param name The argument name */ template - std::optional parseLaunchArgument(std::string_view const name) const { + Result parseLaunchArgument(std::string_view const name) const { auto str = this->getLaunchArgument(name); if (!str.has_value()) { return std::nullopt; @@ -133,10 +133,7 @@ namespace geode { return std::nullopt; } auto value = jsonOpt.value(); - if (!value.is()) { - return std::nullopt; - } - return value.as(); + return value.template as(); } void queueInMainThread(ScheduledFunction&& func); diff --git a/loader/include/Geode/loader/Log.hpp b/loader/include/Geode/loader/Log.hpp index f4cbe9cd..88ad3cb5 100644 --- a/loader/include/Geode/loader/Log.hpp +++ b/loader/include/Geode/loader/Log.hpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include // for formatting std::vector and such @@ -65,12 +65,6 @@ namespace std::filesystem { } } -namespace matjson { - GEODE_INLINE GEODE_HIDDEN std::string format_as(matjson::Value const& value) { - return value.dump(matjson::NO_INDENTATION); - } -} - namespace geode { class Mod; diff --git a/loader/include/Geode/loader/Mod.hpp b/loader/include/Geode/loader/Mod.hpp index 8c78be4f..18f64048 100644 --- a/loader/include/Geode/loader/Mod.hpp +++ b/loader/include/Geode/loader/Mod.hpp @@ -13,7 +13,7 @@ #include "Types.hpp" #include "Loader.hpp" -#include +#include #include #include #include @@ -51,22 +51,6 @@ namespace geode { return action == ModRequestedAction::Uninstall || action == ModRequestedAction::UninstallWithSaveData; } - template - static consteval bool typeImplementsIsJSON() { - using namespace matjson; - if constexpr (requires(const Value& json) { Serialize>::is_json(json); }) - return true; - if constexpr (std::is_same_v) return true; - if constexpr (std::is_same_v) return true; - if constexpr (std::is_same_v) return true; - if constexpr (std::is_constructible_v) return true; - if constexpr (std::is_integral_v || std::is_floating_point_v) return true; - if constexpr (std::is_same_v) return true; - if constexpr (std::is_same_v) return true; - - return false; - } - GEODE_HIDDEN Mod* takeNextLoaderMod(); class ModImpl; @@ -264,24 +248,22 @@ namespace geode { template T getSavedValue(std::string_view const key) { - static_assert(geode::typeImplementsIsJSON(), "T must implement is_json in matjson::Serialize, otherwise this always returns default value."); auto& saved = this->getSaveContainer(); - if (saved.contains(key)) { - if (auto value = saved.try_get(key)) { - return *value; - } + if (auto res = saved.get(key).andThen([](auto&& v) { + return v.template as(); + }); res.isOk()) { + return res.unwrap(); } return T(); } template T getSavedValue(std::string_view const key, T const& defaultValue) { - static_assert(geode::typeImplementsIsJSON(), "T must implement is_json in matjson::Serialize, otherwise this always returns default value."); auto& saved = this->getSaveContainer(); - if (saved.contains(key)) { - if (auto value = saved.try_get(key)) { - return *value; - } + if (auto res = saved.get(key).andThen([](auto&& v) { + return v.template as(); + }); res.isOk()) { + return res.unwrap(); } saved[key] = defaultValue; return defaultValue; diff --git a/loader/include/Geode/loader/ModMetadata.hpp b/loader/include/Geode/loader/ModMetadata.hpp index d6338448..cf08961c 100644 --- a/loader/include/Geode/loader/ModMetadata.hpp +++ b/loader/include/Geode/loader/ModMetadata.hpp @@ -4,7 +4,7 @@ #include "../utils/VersionInfo.hpp" #include "Types.hpp" -#include +#include #include namespace geode { @@ -290,7 +290,8 @@ namespace geode { template <> struct matjson::Serialize { - static matjson::Value to_json(geode::ModMetadata const& info) { - return info.toJSON(); + static Value toJson(geode::ModMetadata const& value) + { + return Value(value.toJSON()); } }; diff --git a/loader/include/Geode/loader/SettingV3.hpp b/loader/include/Geode/loader/SettingV3.hpp index bf6e528f..b9e380c1 100644 --- a/loader/include/Geode/loader/SettingV3.hpp +++ b/loader/include/Geode/loader/SettingV3.hpp @@ -306,14 +306,15 @@ namespace geode { } bool load(matjson::Value const& json) override { - if (json.is()) { - m_impl->value = json.as(); - return true; + auto res = json.as(); + if (res.isErr()) { + return false; } - return false; + m_impl->value = res.unwrap(); + return true; } bool save(matjson::Value& json) const override { - json = m_impl->value; + json = matjson::Value(m_impl->value); return true; } }; diff --git a/loader/include/Geode/loader/Types.hpp b/loader/include/Geode/loader/Types.hpp index e5243a47..5f887925 100644 --- a/loader/include/Geode/loader/Types.hpp +++ b/loader/include/Geode/loader/Types.hpp @@ -2,7 +2,7 @@ #include "../DefaultInclude.hpp" #include "../platform/cplatform.h" -#include +#include #include diff --git a/loader/include/Geode/utils/JsonValidation.hpp b/loader/include/Geode/utils/JsonValidation.hpp index e54a16f7..1776614f 100644 --- a/loader/include/Geode/utils/JsonValidation.hpp +++ b/loader/include/Geode/utils/JsonValidation.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include "../loader/Log.hpp" #include #include @@ -104,21 +104,14 @@ namespace geode { return this->getJSONRef(); } else { - try { - if (this->getJSONRef().is()) { - return this->getJSONRef().as(); - } - else { - this->setError( - "unexpected type {}", - this->matJsonTypeToString(this->getJSONRef().type()) - ); - } - } - // matjson can throw variant exceptions too so you need to do this - catch(std::exception const& e) { - this->setError("unable to parse json: {}", e); + auto res = this->getJSONRef().as(); + if (res) { + return res.unwrap(); } + this->setError( + "unexpected type {}", + this->matJsonTypeToString(this->getJSONRef().type()) + ); } return std::nullopt; } diff --git a/loader/include/Geode/utils/VersionInfo.hpp b/loader/include/Geode/utils/VersionInfo.hpp index d1f3e57f..ad19692f 100644 --- a/loader/include/Geode/utils/VersionInfo.hpp +++ b/loader/include/Geode/utils/VersionInfo.hpp @@ -2,7 +2,7 @@ #include "../DefaultInclude.hpp" #include -#include +#include #include #include @@ -256,25 +256,17 @@ namespace geode { template requires std::is_same_v || std::is_same_v struct matjson::Serialize { - static matjson::Value to_json(V const& info) { - return info.toString(); + static geode::Result fromJson(Value const& value) + { + auto str = GEODE_UNWRAP(value.asString()); + auto version = GEODE_UNWRAP(V::parse(str).mapErr([](auto&& err) { + return geode::Err("Invalid version format: {}", err); + })); + return geode::Ok(version); } - static bool is_json(matjson::Value const& json) { - if (json.is_string()) { - auto ver = V::parse(json.as_string()); - return !ver.isErr(); - } - return false; - } - - static V from_json(matjson::Value const& json) { - auto ver = V::parse(json.as_string()); - if (!ver) { - throw matjson::JsonException( - "Invalid version format: " + ver.unwrapErr() - ); - } - return ver.unwrap(); + static Value toJson(V const& value) + { + return Value(value.toString()); } }; diff --git a/loader/include/Geode/utils/cocos.hpp b/loader/include/Geode/utils/cocos.hpp index 5eb5f557..b72c096d 100644 --- a/loader/include/Geode/utils/cocos.hpp +++ b/loader/include/Geode/utils/cocos.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include "casts.hpp" #include "general.hpp" #include "../DefaultInclude.hpp" @@ -15,16 +15,14 @@ template <> struct matjson::Serialize { - static matjson::Value GEODE_DLL to_json(cocos2d::ccColor3B const& color); - static cocos2d::ccColor3B GEODE_DLL from_json(matjson::Value const& color); - static bool GEODE_DLL is_json(matjson::Value const& json); + static geode::Result fromJson(Value const& value); + static Value toJson(cocos2d::ccColor3B const& value); }; template <> struct matjson::Serialize { - static matjson::Value GEODE_DLL to_json(cocos2d::ccColor4B const& color); - static cocos2d::ccColor4B GEODE_DLL from_json(matjson::Value const& color); - static bool GEODE_DLL is_json(matjson::Value const& json); + static geode::Result fromJson(Value const& value); + static Value toJson(cocos2d::ccColor4B const& value); }; // operators for CC geometry diff --git a/loader/include/Geode/utils/file.hpp b/loader/include/Geode/utils/file.hpp index efb2199d..2ff28895 100644 --- a/loader/include/Geode/utils/file.hpp +++ b/loader/include/Geode/utils/file.hpp @@ -5,7 +5,7 @@ #include "../loader/Event.hpp" #include "Task.hpp" -#include +#include #include #include #include @@ -13,14 +13,15 @@ template <> struct matjson::Serialize { - static matjson::Value to_json(std::filesystem::path const& path) { - return path.string(); + static geode::Result fromJson(Value const& value) + { + auto str = GEODE_UNWRAP(value.asString()); + return geode::Ok(std::filesystem::path(str).make_preferred()); } - static std::filesystem::path from_json(matjson::Value const& value) { - return std::filesystem::path(value.as_string()).make_preferred(); - } - static bool is_json(matjson::Value const& value) { - return value.is_string(); + + static Value toJson(std::filesystem::path const& value) + { + return Value(value.string()); } }; @@ -32,10 +33,7 @@ namespace geode::utils::file { template Result readFromJson(std::filesystem::path const& file) { GEODE_UNWRAP_INTO(auto json, readJson(file)); - if (!json.is()) { - return Err("JSON is not of type {}", typeid(T).name()); - } - return Ok(json.as()); + return json.as(); } GEODE_DLL Result<> writeString(std::filesystem::path const& path, std::string const& data); diff --git a/loader/include/Geode/utils/general.hpp b/loader/include/Geode/utils/general.hpp index a1912b5c..4cca1163 100644 --- a/loader/include/Geode/utils/general.hpp +++ b/loader/include/Geode/utils/general.hpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include @@ -170,7 +170,8 @@ namespace geode { template<> struct matjson::Serialize { - static matjson::Value to_json(geode::ByteVector const& bytes) { + static Value toJson(geode::ByteVector const& bytes) + { return matjson::Array(bytes.begin(), bytes.end()); } }; diff --git a/loader/include/Geode/utils/web.hpp b/loader/include/Geode/utils/web.hpp index ad06e247..5f01a89b 100644 --- a/loader/include/Geode/utils/web.hpp +++ b/loader/include/Geode/utils/web.hpp @@ -1,7 +1,7 @@ #pragma once #include // another great circular dependency fix -#include +#include #include #include "Task.hpp" #include diff --git a/loader/src/loader/IPC.cpp b/loader/src/loader/IPC.cpp index c2870fa3..d7dd4645 100644 --- a/loader/src/loader/IPC.cpp +++ b/loader/src/loader/IPC.cpp @@ -1,6 +1,6 @@ #include #include "IPC.hpp" -#include +#include #include using namespace geode::prelude; diff --git a/loader/src/loader/IPC.hpp b/loader/src/loader/IPC.hpp index 35fbc81f..7ea91ff5 100644 --- a/loader/src/loader/IPC.hpp +++ b/loader/src/loader/IPC.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include namespace geode::ipc { void setup(); diff --git a/loader/src/loader/LoaderImpl.hpp b/loader/src/loader/LoaderImpl.hpp index 7af233d5..3a340720 100644 --- a/loader/src/loader/LoaderImpl.hpp +++ b/loader/src/loader/LoaderImpl.hpp @@ -2,7 +2,7 @@ #include "FileWatcher.hpp" -#include +#include #include #include #include diff --git a/loader/src/loader/ModImpl.hpp b/loader/src/loader/ModImpl.hpp index 3491b788..5c64be24 100644 --- a/loader/src/loader/ModImpl.hpp +++ b/loader/src/loader/ModImpl.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include "ModPatch.hpp" #include #include @@ -47,7 +47,7 @@ namespace geode { /** * Saved values */ - matjson::Value m_saved = matjson::Object(); + matjson::Value m_saved = matjson::Value(); /** * Setting values. This is behind unique_ptr for interior mutability */ diff --git a/loader/src/loader/ModMetadataImpl.cpp b/loader/src/loader/ModMetadataImpl.cpp index 690e3969..6dd60bf2 100644 --- a/loader/src/loader/ModMetadataImpl.cpp +++ b/loader/src/loader/ModMetadataImpl.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include diff --git a/loader/src/loader/ModMetadataImpl.hpp b/loader/src/loader/ModMetadataImpl.hpp index f14ab996..caf4c2d1 100644 --- a/loader/src/loader/ModMetadataImpl.hpp +++ b/loader/src/loader/ModMetadataImpl.hpp @@ -74,52 +74,44 @@ namespace geode { template <> struct matjson::Serialize { - static matjson::Value GEODE_DLL to_json(geode::ModMetadata::Dependency::Importance const& importance) { - switch (importance) { - case geode::ModMetadata::Dependency::Importance::Required: return {"required"}; - case geode::ModMetadata::Dependency::Importance::Recommended: return {"recommended"}; - case geode::ModMetadata::Dependency::Importance::Suggested: return {"suggested"}; - default: return {"unknown"}; - } - } - static geode::ModMetadata::Dependency::Importance GEODE_DLL from_json(matjson::Value const& importance) { - auto impStr = importance.as_string(); - if (impStr == "required") - return geode::ModMetadata::Dependency::Importance::Required; - if (impStr == "recommended") - return geode::ModMetadata::Dependency::Importance::Recommended; - if (impStr == "suggested") - return geode::ModMetadata::Dependency::Importance::Suggested; - throw matjson::JsonException(R"(Expected importance to be "required", "recommended" or "suggested")"); + static geode::Result fromJson(Value const& value) + { + auto str = GEODE_UNWRAP(value.asString()); + if (str == "required") return geode::Ok(geode::ModMetadata::Dependency::Importance::Required); + if (str == "recommended") return geode::Ok(geode::ModMetadata::Dependency::Importance::Recommended); + if (str == "suggested") return geode::Ok(geode::ModMetadata::Dependency::Importance::Suggested); + return geode::Err("Invalid importance"); } - static bool is_json(matjson::Value const& value) { - return value.is_string(); + static Value toJson(geode::ModMetadata::Dependency::Importance const& value) + { + switch (value) { + case geode::ModMetadata::Dependency::Importance::Required: return "required"; + case geode::ModMetadata::Dependency::Importance::Recommended: return "recommended"; + case geode::ModMetadata::Dependency::Importance::Suggested: return "suggested"; + } + return "unknown"; } }; template <> struct matjson::Serialize { - static matjson::Value GEODE_DLL to_json(geode::ModMetadata::Incompatibility::Importance const& importance) { - switch (importance) { - case geode::ModMetadata::Incompatibility::Importance::Breaking: return {"breaking"}; - case geode::ModMetadata::Incompatibility::Importance::Conflicting: return {"conflicting"}; - case geode::ModMetadata::Incompatibility::Importance::Superseded: return {"superseded"}; - default: return {"unknown"}; - } - } - static geode::ModMetadata::Incompatibility::Importance GEODE_DLL from_json(matjson::Value const& importance) { - auto impStr = importance.as_string(); - if (impStr == "breaking") - return geode::ModMetadata::Incompatibility::Importance::Breaking; - if (impStr == "conflicting") - return geode::ModMetadata::Incompatibility::Importance::Conflicting; - if (impStr == "superseded") - return geode::ModMetadata::Incompatibility::Importance::Superseded; - throw matjson::JsonException(R"(Expected importance to be "breaking", "conflicting", or "superseded")"); + static geode::Result fromJson(Value const& value) + { + auto str = GEODE_UNWRAP(value.asString()); + if (str == "breaking") return geode::Ok(geode::ModMetadata::Incompatibility::Importance::Breaking); + if (str == "conflicting") return geode::Ok(geode::ModMetadata::Incompatibility::Importance::Conflicting); + if (str == "superseded") return geode::Ok(geode::ModMetadata::Incompatibility::Importance::Superseded); + return geode::Err("Invalid importance"); } - static bool is_json(matjson::Value const& value) { - return value.is_string(); + static Value toJson(geode::ModMetadata::Incompatibility::Importance const& value) + { + switch (value) { + case geode::ModMetadata::Incompatibility::Importance::Breaking: return "breaking"; + case geode::ModMetadata::Incompatibility::Importance::Conflicting: return "conflicting"; + case geode::ModMetadata::Incompatibility::Importance::Superseded: return "superseded"; + } + return "unknown"; } }; diff --git a/loader/src/loader/updater.hpp b/loader/src/loader/updater.hpp index 31641b93..07a96b7f 100644 --- a/loader/src/loader/updater.hpp +++ b/loader/src/loader/updater.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include namespace geode::updater { diff --git a/loader/src/server/Server.hpp b/loader/src/server/Server.hpp index 110f4e8f..b801f8d7 100644 --- a/loader/src/server/Server.hpp +++ b/loader/src/server/Server.hpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include using namespace geode::prelude; diff --git a/loader/src/utils/VersionInfo.cpp b/loader/src/utils/VersionInfo.cpp index 069f674b..0c5c9658 100644 --- a/loader/src/utils/VersionInfo.cpp +++ b/loader/src/utils/VersionInfo.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include using namespace geode::prelude; diff --git a/loader/src/utils/cocos.cpp b/loader/src/utils/cocos.cpp index 0ae4486b..3a8fa960 100644 --- a/loader/src/utils/cocos.cpp +++ b/loader/src/utils/cocos.cpp @@ -1,123 +1,82 @@ #include #include -#include +#include #include #include #include using namespace geode::prelude; -bool matjson::Serialize::is_json(matjson::Value const& json) { - if (json.is_array()) { - return json.as_array().size() == 3; +Result matjson::Serialize::fromJson(matjson::Value const& value) { + if (value.isArray()) { + auto arr = GEODE_UNWRAP(value.asArray()); + if (arr.size() == 3) { + auto r = GEODE_UNWRAP(arr[0].asInt()); + auto g = GEODE_UNWRAP(arr[1].asInt()); + auto b = GEODE_UNWRAP(arr[2].asInt()); + return Ok(cocos2d::ccc3(r, g, b)); + } + return Err("Expected color array to have 3 items"); } - if (json.is_object()) { - return json.contains("r") && json.contains("g") && json.contains("b"); + if (value.isObject()) { + auto r = GEODE_UNWRAP(GEODE_UNWRAP(value.get("r")).asInt()); + auto g = GEODE_UNWRAP(GEODE_UNWRAP(value.get("g")).asInt()); + auto b = GEODE_UNWRAP(GEODE_UNWRAP(value.get("b")).asInt()); + return Ok(cocos2d::ccc3(r, g, b)); } - if (json.is_string()) { - return !cc3bFromHexString(json.as_string()).isErr(); + if (value.isString()) { + auto hex = GEODE_UNWRAP(value.asString()); + auto res = cc3bFromHexString(hex); + if (!res) { + return Err("Invalid hex color string: {}", res.unwrapErr()); + } + return Ok(res.unwrap()); } - return false; +} +matjson::Value matjson::Serialize::toJson(cocos2d::ccColor3B const& value) { + return matjson::makeObject({ + { "r", value.r }, + { "g", value.g }, + { "b", value.b } + }); } -matjson::Value matjson::Serialize::to_json(ccColor3B const& color) { - return matjson::Object { - { "r", color.r }, - { "g", color.g }, - { "b", color.b } - }; +Result matjson::Serialize::fromJson(matjson::Value const& value) { + if (value.isArray()) { + auto arr = GEODE_UNWRAP(value.asArray()); + if (arr.size() == 4) { + auto r = GEODE_UNWRAP(arr[0].asInt()); + auto g = GEODE_UNWRAP(arr[1].asInt()); + auto b = GEODE_UNWRAP(arr[2].asInt()); + auto a = GEODE_UNWRAP(arr[3].asInt()); + return Ok(cocos2d::ccc4(r, g, b, a)); + } + return Err("Expected color array to have 4 items"); + } + if (value.isObject()) { + auto r = GEODE_UNWRAP(GEODE_UNWRAP(value.get("r")).asInt()); + auto g = GEODE_UNWRAP(GEODE_UNWRAP(value.get("g")).asInt()); + auto b = GEODE_UNWRAP(GEODE_UNWRAP(value.get("b")).asInt()); + auto a = GEODE_UNWRAP(GEODE_UNWRAP(value.get("a")).asInt()); + return Ok(cocos2d::ccc4(r, g, b, a)); + } + if (value.isString()) { + auto hex = GEODE_UNWRAP(value.asString()); + auto res = cc4bFromHexString(hex); + if (!res) { + return Err("Invalid hex color string: {}", res.unwrapErr()); + } + return Ok(res.unwrap()); + } } -ccColor3B matjson::Serialize::from_json(matjson::Value const& json) { - ccColor3B color; - // array - if (json.is_array()) { - if (json.as_array().size() == 3) { - color.r = json[0].as_int(); - color.g = json[1].as_int(); - color.b = json[2].as_int(); - } - else { - throw matjson::JsonException("Expected color array to have 3 items"); - } - } - // object - else if (json.is_object()) { - color.r = json["r"].as_int(); - color.g = json["g"].as_int(); - color.b = json["b"].as_int(); - } - // hex string - else if (json.is_string()) { - auto c = cc3bFromHexString(json.as_string()); - if (!c) { - throw matjson::JsonException("Invalid color hex string"); - } - color = c.unwrap(); - } - // bad - else { - throw matjson::JsonException("Expected color to be array, object or hex string"); - } - return color; -} - -bool matjson::Serialize::is_json(matjson::Value const& json) { - if (json.is_array()) { - return json.as_array().size() == 4; - } - if (json.is_object()) { - return json.contains("r") && json.contains("g") && json.contains("b") && json.contains("a"); - } - if (json.is_string()) { - return !cc4bFromHexString(json.as_string()).isErr(); - } - return false; -} - -matjson::Value matjson::Serialize::to_json(ccColor4B const& color) { - return matjson::Object { - { "r", color.r }, - { "g", color.g }, - { "b", color.b }, - { "a", color.a } - }; -} - -ccColor4B matjson::Serialize::from_json(matjson::Value const& json) { - ccColor4B color; - // array - if (json.is_array()) { - if (json.as_array().size() == 4) { - color.r = json[0].as_int(); - color.g = json[1].as_int(); - color.b = json[2].as_int(); - color.a = json[3].as_int(); - } - else { - throw matjson::JsonException("Expected color array to have 4 items"); - } - } - // object - else if (json.is_object()) { - color.r = json["r"].as_int(); - color.g = json["g"].as_int(); - color.b = json["b"].as_int(); - color.a = json["a"].as_int(); - } - // hex string - else if (json.is_string()) { - auto c = cc4bFromHexString(json.as_string()); - if (!c) { - throw matjson::JsonException("Invalid color hex string: " + c.unwrapErr()); - } - color = c.unwrap(); - } - // bad - else { - throw matjson::JsonException("Expected color to be array, object or hex string"); - } - return color; +matjson::Value matjson::Serialize::toJson(cocos2d::ccColor4B const& value) { + return matjson::makeObject({ + { "r", value.r }, + { "g", value.g }, + { "b", value.b }, + { "a", value.a } + }); } Result geode::cocos::cc3bFromHexString(std::string const& rawHexValue, bool permissive) { diff --git a/loader/src/utils/file.cpp b/loader/src/utils/file.cpp index caeba44e..5cba9d46 100644 --- a/loader/src/utils/file.cpp +++ b/loader/src/utils/file.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/loader/src/utils/web.cpp b/loader/src/utils/web.cpp index c7f00e04..0cf732ec 100644 --- a/loader/src/utils/web.cpp +++ b/loader/src/utils/web.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #define CURL_STATICLIB #include diff --git a/loader/test/main/main.cpp b/loader/test/main/main.cpp index 6603f687..af1a2beb 100644 --- a/loader/test/main/main.cpp +++ b/loader/test/main/main.cpp @@ -54,7 +54,7 @@ struct $modify(MenuLayer) { log::popNest(); log::info("Mod has launch arg 'mod-arg': {}", Mod::get()->hasLaunchArgument("mod-arg")); log::info("Loader flag 'bool-arg': {}", Loader::get()->getLaunchFlag("bool-arg")); - log::info("Loader int 'int-arg': {}", Loader::get()->parseLaunchArgument("int-arg")); + log::info("Loader int 'int-arg': {}", Loader::get()->parseLaunchArgument("int-arg").unwrapOr(0)); log::popNest(); return true;