| @@ -262,12 +262,9 @@ typename C::mapped_type get(const C& m, const typename C::key_type& key, const t | |||||
| extern const std::string APP_NAME; | extern const std::string APP_NAME; | ||||
| extern const std::string APP_VARIANT; | extern const std::string APP_VARIANT; | ||||
| extern const std::string APP_VERSION; | extern const std::string APP_VERSION; | ||||
| extern const std::string APP_VERSION_MAJOR; | |||||
| extern const std::string APP_ARCH; | extern const std::string APP_ARCH; | ||||
| extern const std::string ABI_VERSION; | |||||
| extern const std::string API_URL; | extern const std::string API_URL; | ||||
| extern const std::string API_VERSION; | |||||
| } // namespace rack | } // namespace rack | ||||
| @@ -27,7 +27,7 @@ void init(); | |||||
| /** Requests a JSON API URL over HTTP(S), using the data as the query (GET) or the body (POST, etc) | /** Requests a JSON API URL over HTTP(S), using the data as the query (GET) or the body (POST, etc) | ||||
| Caller must json_decref() if return value is non-NULL. | Caller must json_decref() if return value is non-NULL. | ||||
| */ | */ | ||||
| json_t* requestJson(Method method, const std::string& url, json_t* dataJ, const CookieMap& cookies = {}); | |||||
| json_t* requestJson(Method method, const std::string& url, json_t* dataJ = NULL, const CookieMap& cookies = {}); | |||||
| /** Returns true if downloaded successfully */ | /** Returns true if downloaded successfully */ | ||||
| bool requestDownload(const std::string& url, const std::string& filename, float* progress, const CookieMap& cookies = {}); | bool requestDownload(const std::string& url, const std::string& filename, float* progress, const CookieMap& cookies = {}); | ||||
| /** URL-encodes `s` */ | /** URL-encodes `s` */ | ||||
| @@ -18,6 +18,7 @@ namespace rack { | |||||
| const std::string APP_NAME = "VCV Rack"; | const std::string APP_NAME = "VCV Rack"; | ||||
| const std::string APP_VARIANT = "Community Edition"; | const std::string APP_VARIANT = "Community Edition"; | ||||
| const std::string APP_VERSION = TOSTRING(VERSION); | const std::string APP_VERSION = TOSTRING(VERSION); | ||||
| const std::string APP_VERSION_MAJOR = "2"; | |||||
| #if defined ARCH_WIN | #if defined ARCH_WIN | ||||
| const std::string APP_ARCH = "win"; | const std::string APP_ARCH = "win"; | ||||
| #elif ARCH_MAC | #elif ARCH_MAC | ||||
| @@ -26,10 +27,7 @@ const std::string APP_VERSION = TOSTRING(VERSION); | |||||
| const std::string APP_ARCH = "lin"; | const std::string APP_ARCH = "lin"; | ||||
| #endif | #endif | ||||
| const std::string ABI_VERSION = "2"; | |||||
| const std::string API_URL = "https://api.vcvrack.com"; | const std::string API_URL = "https://api.vcvrack.com"; | ||||
| const std::string API_VERSION = "2"; | |||||
| Exception::Exception(const char* format, ...) { | Exception::Exception(const char* format, ...) { | ||||
| @@ -176,7 +176,7 @@ void checkUpdates() { | |||||
| // Get library manifests | // Get library manifests | ||||
| std::string manifestsUrl = API_URL + "/library/manifests"; | std::string manifestsUrl = API_URL + "/library/manifests"; | ||||
| json_t* manifestsReq = json_object(); | json_t* manifestsReq = json_object(); | ||||
| json_object_set(manifestsReq, "version", json_string(API_VERSION.c_str())); | |||||
| json_object_set(manifestsReq, "version", json_string(APP_VERSION_MAJOR.c_str())); | |||||
| json_t* manifestsResJ = network::requestJson(network::METHOD_GET, manifestsUrl, manifestsReq); | json_t* manifestsResJ = network::requestJson(network::METHOD_GET, manifestsUrl, manifestsReq); | ||||
| json_decref(manifestsReq); | json_decref(manifestsReq); | ||||
| if (!manifestsResJ) { | if (!manifestsResJ) { | ||||
| @@ -216,22 +216,23 @@ void checkUpdates() { | |||||
| // Get version | // Get version | ||||
| json_t* versionJ = json_object_get(manifestJ, "version"); | json_t* versionJ = json_object_get(manifestJ, "version"); | ||||
| if (!versionJ) { | if (!versionJ) { | ||||
| WARN("Plugin %s has no version in manifest", slug.c_str()); | |||||
| // WARN("Plugin %s has no version in manifest", slug.c_str()); | |||||
| continue; | continue; | ||||
| } | } | ||||
| update.version = json_string_value(versionJ); | update.version = json_string_value(versionJ); | ||||
| // Reject plugins with ABI mismatch | |||||
| if (!string::startsWith(update.version, APP_VERSION_MAJOR + ".")) { | |||||
| continue; | |||||
| } | |||||
| // Check if update is needed | // Check if update is needed | ||||
| plugin::Plugin* p = plugin::getPlugin(slug); | plugin::Plugin* p = plugin::getPlugin(slug); | ||||
| if (p && p->version == update.version) | if (p && p->version == update.version) | ||||
| continue; | continue; | ||||
| // Require that "status" is "available" | |||||
| json_t* statusJ = json_object_get(manifestJ, "status"); | |||||
| if (!statusJ) | |||||
| continue; | |||||
| std::string status = json_string_value(statusJ); | |||||
| if (status != "available") | |||||
| // Require that plugin is available | |||||
| json_t* availableJ = json_object_get(manifestJ, "available"); | |||||
| if (!json_boolean_value(availableJ)) | |||||
| continue; | continue; | ||||
| // Get changelog URL | // Get changelog URL | ||||
| @@ -28,8 +28,8 @@ PatchManager::PatchManager() { | |||||
| templatePath = asset::user("template.vcv"); | templatePath = asset::user("template.vcv"); | ||||
| } | } | ||||
| else { | else { | ||||
| autosavePath = asset::user("autosave-v" + ABI_VERSION); | |||||
| templatePath = asset::user("template-v" + ABI_VERSION + ".vcv"); | |||||
| autosavePath = asset::user("autosave-v" + APP_VERSION_MAJOR); | |||||
| templatePath = asset::user("template-v" + APP_VERSION_MAJOR + ".vcv"); | |||||
| } | } | ||||
| factoryTemplatePath = asset::system("template.vcv"); | factoryTemplatePath = asset::system("template.vcv"); | ||||
| } | } | ||||
| @@ -217,7 +217,7 @@ void init() { | |||||
| pluginsPath = asset::user("plugins"); | pluginsPath = asset::user("plugins"); | ||||
| } | } | ||||
| else { | else { | ||||
| pluginsPath = asset::user("plugins-v" + ABI_VERSION); | |||||
| pluginsPath = asset::user("plugins-v" + APP_VERSION_MAJOR); | |||||
| } | } | ||||
| // Get user plugins directory | // Get user plugins directory | ||||
| @@ -48,8 +48,8 @@ void Plugin::fromJson(json_t* rootJ) { | |||||
| json_t* versionJ = json_object_get(rootJ, "version"); | json_t* versionJ = json_object_get(rootJ, "version"); | ||||
| if (versionJ) | if (versionJ) | ||||
| version = json_string_value(versionJ); | version = json_string_value(versionJ); | ||||
| if (!string::startsWith(version, ABI_VERSION + ".")) | |||||
| throw Exception("Plugin version %s does not match Rack ABI version %s", version.c_str(), ABI_VERSION.c_str()); | |||||
| if (!string::startsWith(version, APP_VERSION_MAJOR + ".")) | |||||
| throw Exception("Plugin version %s does not match Rack ABI version %s", version.c_str(), APP_VERSION_MAJOR.c_str()); | |||||
| if (version == "") | if (version == "") | ||||
| throw Exception("No plugin version"); | throw Exception("No plugin version"); | ||||
| @@ -70,7 +70,7 @@ void init() { | |||||
| settingsPath = asset::user("settings.json"); | settingsPath = asset::user("settings.json"); | ||||
| } | } | ||||
| else { | else { | ||||
| settingsPath = asset::user("settings-v" + ABI_VERSION + ".json"); | |||||
| settingsPath = asset::user("settings-v" + APP_VERSION_MAJOR + ".json"); | |||||
| } | } | ||||
| } | } | ||||