diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 16760c49..b862f9d2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -96,6 +96,7 @@ jobs: - name: Delete resource cache file run: | rm ./bin/nightly/resources/.geode_cache + rm ./bin/nightly/resources/dont-update.txt - name: Upload resources uses: actions/upload-artifact@v2 with: diff --git a/.gitignore b/.gitignore index e54eeeac..88a4d1c7 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,7 @@ docs loader/src/internal/about.hpp loader/src/internal/resources.hpp loader/resources/mod.json +loader/resources/version loader/resources/blanks/rename.js loader/resources/changelog.md fods-catgirl-hideout.txt diff --git a/VERSION b/VERSION index 90c9f191..1d66b90b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.0-beta.16 \ No newline at end of file +1.0.0-beta.17 \ No newline at end of file diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt index 0b5ea1c4..32632104 100644 --- a/loader/CMakeLists.txt +++ b/loader/CMakeLists.txt @@ -29,6 +29,7 @@ execute_process( # Package info file for internal representation configure_file(resources/mod.json.in ${CMAKE_CURRENT_SOURCE_DIR}/resources/mod.json) file(READ resources/mod.json LOADER_MOD_JSON) +configure_file(${GEODE_ROOT_PATH}/VERSION ${CMAKE_CURRENT_SOURCE_DIR}/resources/version COPYONLY) configure_file(${GEODE_ROOT_PATH}/CHANGELOG.md ${CMAKE_CURRENT_SOURCE_DIR}/resources/changelog.md COPYONLY) configure_file(src/internal/about.hpp.in ${CMAKE_CURRENT_SOURCE_DIR}/src/internal/about.hpp) diff --git a/loader/resources/mod.json.in b/loader/resources/mod.json.in index d98ba043..3673a1ac 100644 --- a/loader/resources/mod.json.in +++ b/loader/resources/mod.json.in @@ -37,7 +37,8 @@ "about.md", "changelog.md", "support.md", - "mod.json" + "mod.json", + "version" ], "spritesheets": { "LogoSheet": [ diff --git a/loader/src/loader/Index.cpp b/loader/src/loader/Index.cpp index f704979c..91fb98b7 100644 --- a/loader/src/loader/Index.cpp +++ b/loader/src/loader/Index.cpp @@ -463,8 +463,8 @@ void Index::update(bool force) { std::vector Index::getItems() const { std::vector res; for (auto& items : map::values(m_items)) { - if (items.size()) { - res.push_back(items.rbegin()->second); + for (auto& item : items) { + res.push_back(item.second); } } return res; @@ -473,9 +473,9 @@ std::vector Index::getItems() const { std::vector Index::getFeaturedItems() const { std::vector res; for (auto& items : map::values(m_items)) { - if (items.size()) { - if (items.rbegin()->second->isFeatured) { - res.push_back(items.rbegin()->second); + for (auto& item : items) { + if (item.second->isFeatured) { + res.push_back(item.second); } } } @@ -487,9 +487,9 @@ std::vector Index::getItemsByDeveloper( ) const { std::vector res; for (auto& items : map::values(m_items)) { - if (items.size()) { - if (items.rbegin()->second->info.developer() == name) { - res.push_back(items.rbegin()->second); + for (auto& item : items) { + if (item.second->info.developer() == name) { + res.push_back(item.second); } } } @@ -503,6 +503,15 @@ bool Index::isKnownItem( return this->getItem(id, version).get(); } +IndexItemHandle Index::getMajorItem( + std::string const& id +) const { + if (m_items.count(id)) { + return m_items.at(id).rbegin()->second; + } + return nullptr; +} + IndexItemHandle Index::getItem( std::string const& id, std::optional version @@ -558,7 +567,7 @@ bool Index::isUpdateAvailable(IndexItemHandle item) const { bool Index::areUpdatesAvailable() const { for (auto& mod : Loader::get()->getAllMods()) { - auto item = this->getItem(mod); + auto item = this->getMajorItem(mod->getID()); if (item && item->info.version() > mod->getVersion()) { return true; } diff --git a/loader/src/loader/LoaderImpl.cpp b/loader/src/loader/LoaderImpl.cpp index baa0d4c1..70c9e374 100644 --- a/loader/src/loader/LoaderImpl.cpp +++ b/loader/src/loader/LoaderImpl.cpp @@ -624,6 +624,15 @@ bool Loader::Impl::verifyLoaderResources() { return false; } + // TODO: actually have a proper way to disable checking resources + // for development builds + if (ghc::filesystem::exists(resourcesDir / "dont-update.txt")) { + // this is kind of a hack, but it's the easiest way to prevent + // auto update while developing + log::debug("Not updating resources since dont-update.txt exists"); + return true; + } + // make sure every file was covered size_t coverage = 0; diff --git a/loader/src/ui/internal/info/ModInfoPopup.cpp b/loader/src/ui/internal/info/ModInfoPopup.cpp index 57af6344..3207f769 100644 --- a/loader/src/ui/internal/info/ModInfoPopup.cpp +++ b/loader/src/ui/internal/info/ModInfoPopup.cpp @@ -347,13 +347,12 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) { uninstallBtn->setPosition(-85.f, 75.f); m_buttonMenu->addChild(uninstallBtn); - auto indexItem = Index::get()->getItem( - mod->getModInfo().id(), - ComparableVersionInfo(mod->getModInfo().version(), VersionCompare::More) + auto latestIndexItem = Index::get()->getMajorItem( + mod->getModInfo().id() ); // todo: show update button on loader that invokes the installer - if (indexItem && Index::get()->isUpdateAvailable(indexItem)) { + if (latestIndexItem && Index::get()->isUpdateAvailable(latestIndexItem)) { m_installBtnSpr = IconButtonSprite::create( "GE_button_01.png"_spr, CCSprite::createWithSpriteFrameName("install.png"_spr), @@ -371,15 +370,49 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) { m_installStatus->setVisible(false); m_mainLayer->addChild(m_installStatus); - m_updateVersionLabel = CCLabelBMFont::create( - ("Available: " + indexItem->info.version().toString()).c_str(), - "bigFont.fnt" + auto minorIndexItem = Index::get()->getItem( + mod->getModInfo().id(), + ComparableVersionInfo(mod->getModInfo().version(), VersionCompare::MoreEq) ); - m_updateVersionLabel->setScale(.35f); - m_updateVersionLabel->setAnchorPoint({.0f, .5f}); - m_updateVersionLabel->setColor({94, 219, 255}); - m_updateVersionLabel->setPosition(winSize.width / 2 + 35.f, winSize.height / 2 + 75.f); - m_mainLayer->addChild(m_updateVersionLabel); + + // TODO: use column layout here? + + if (latestIndexItem->info.version().getMajor() > minorIndexItem->info.version().getMajor()) { + // has major update + m_latestVersionLabel = CCLabelBMFont::create( + ("Available: " + latestIndexItem->info.version().toString()).c_str(), + "bigFont.fnt" + ); + m_latestVersionLabel->setScale(.35f); + m_latestVersionLabel->setAnchorPoint({.0f, .5f}); + m_latestVersionLabel->setColor({94, 219, 255}); + m_latestVersionLabel->setPosition(winSize.width / 2 + 35.f, winSize.height / 2 + 75.f); + m_mainLayer->addChild(m_latestVersionLabel); + } + + if (minorIndexItem->info.version() > mod->getModInfo().version()) { + // has minor update + m_minorVersionLabel = CCLabelBMFont::create( + ("Available: " + minorIndexItem->info.version().toString()).c_str(), + "bigFont.fnt" + ); + m_minorVersionLabel->setScale(.35f); + m_minorVersionLabel->setAnchorPoint({.0f, .5f}); + m_minorVersionLabel->setColor({94, 219, 255}); + if (m_latestVersionLabel) { + m_latestVersionLabel->setPosition( + winSize.width / 2 + 35.f, winSize.height / 2 + 81.f + ); + m_minorVersionLabel->setPosition( + winSize.width / 2 + 35.f, winSize.height / 2 + 69.f + ); + } else { + m_minorVersionLabel->setPosition( + winSize.width / 2 + 35.f, winSize.height / 2 + 75.f + ); + } + m_mainLayer->addChild(m_minorVersionLabel); + } } } else { auto* label = CCLabelBMFont::create(LOADER_COMMIT_HASH, "chatFont.fnt"); @@ -647,8 +680,8 @@ void IndexItemInfoPopup::onCancel(CCObject*) { } void IndexItemInfoPopup::doInstall() { - if (m_updateVersionLabel) { - m_updateVersionLabel->setVisible(false); + if (m_latestVersionLabel) { + m_latestVersionLabel->setVisible(false); } this->setInstallStatus(UpdateProgress(0, "Starting install")); diff --git a/loader/src/ui/internal/info/ModInfoPopup.hpp b/loader/src/ui/internal/info/ModInfoPopup.hpp index aed289ed..9b671490 100644 --- a/loader/src/ui/internal/info/ModInfoPopup.hpp +++ b/loader/src/ui/internal/info/ModInfoPopup.hpp @@ -33,7 +33,8 @@ protected: IconButtonSprite* m_installBtnSpr; CCMenuItemSpriteExtra* m_installBtn; CCMenuItemSpriteExtra* m_infoBtn; - CCLabelBMFont* m_updateVersionLabel = nullptr; + CCLabelBMFont* m_latestVersionLabel = nullptr; + CCLabelBMFont* m_minorVersionLabel = nullptr; MDTextArea* m_detailsArea; MDTextArea* m_changelogArea = nullptr; Scrollbar* m_scrollbar; diff --git a/loader/src/ui/internal/list/ModListCell.cpp b/loader/src/ui/internal/list/ModListCell.cpp index cdcbbe16..deaffc4c 100644 --- a/loader/src/ui/internal/list/ModListCell.cpp +++ b/loader/src/ui/internal/list/ModListCell.cpp @@ -260,19 +260,26 @@ bool ModCell::init( m_menu->addChild(m_unresolvedExMark); if (m_mod->wasSuccesfullyLoaded()) { - auto indexItem = Index::get()->getItem( - mod->getModInfo().id(), - ComparableVersionInfo(mod->getModInfo().version(), VersionCompare::More) + + auto latestIndexItem = Index::get()->getMajorItem( + mod->getModInfo().id() ); - if (indexItem) { + if (latestIndexItem && Index::get()->isUpdateAvailable(latestIndexItem)) { viewSpr->updateBGImage("GE_button_01.png"_spr); - auto updateIcon = CCSprite::createWithSpriteFrameName("updates-available.png"_spr); - updateIcon->setPosition(viewSpr->getContentSize() - CCSize { 2.f, 2.f }); - updateIcon->setZOrder(99); - updateIcon->setScale(.5f); - viewSpr->addChild(updateIcon); + auto minorIndexItem = Index::get()->getItem( + mod->getModInfo().id(), + ComparableVersionInfo(mod->getModInfo().version(), VersionCompare::MoreEq) + ); + + if (latestIndexItem->info.version().getMajor() > minorIndexItem->info.version().getMajor()) { + auto updateIcon = CCSprite::createWithSpriteFrameName("updates-available.png"_spr); + updateIcon->setPosition(viewSpr->getContentSize() - CCSize { 2.f, 2.f }); + updateIcon->setZOrder(99); + updateIcon->setScale(.5f); + viewSpr->addChild(updateIcon); + } } }