@@ -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"); | |||||
} | } | ||||
} | } | ||||