mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-29 19:05:44 -05:00
add featured items to Index
- also fix index checksum not being saved if you close the game with the console X button like i do when developing
This commit is contained in:
parent
596c806fa4
commit
afe57c4bc1
3 changed files with 48 additions and 28 deletions
|
@ -115,16 +115,19 @@ namespace geode {
|
||||||
void removeSource(std::string const& repository);
|
void removeSource(std::string const& repository);
|
||||||
std::vector<std::string> getSources() const;
|
std::vector<std::string> getSources() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all tags
|
||||||
|
*/
|
||||||
std::unordered_set<std::string> getTags() const;
|
std::unordered_set<std::string> getTags() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all index items available on this platform
|
* Get all index items
|
||||||
*/
|
*/
|
||||||
std::vector<IndexItemHandle> getItems() const;
|
std::vector<IndexItemHandle> getItems() const;
|
||||||
/**
|
/**
|
||||||
* Get all index items regardless of platform
|
* Get all featured index items
|
||||||
*/
|
*/
|
||||||
std::vector<IndexItemHandle> getAllItems() const;
|
std::vector<IndexItemHandle> getFeaturedItems() const;
|
||||||
/**
|
/**
|
||||||
* Check if an item with this ID is found on the index, and optionally
|
* Check if an item with this ID is found on the index, and optionally
|
||||||
* provide the version sought after
|
* provide the version sought after
|
||||||
|
|
|
@ -9,18 +9,6 @@
|
||||||
|
|
||||||
USE_GEODE_NAMESPACE();
|
USE_GEODE_NAMESPACE();
|
||||||
|
|
||||||
// Save data
|
|
||||||
|
|
||||||
struct IndexSourceSaveData {
|
|
||||||
std::string downloadedCommitSHA;
|
|
||||||
};
|
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(IndexSourceSaveData, downloadedCommitSHA);
|
|
||||||
|
|
||||||
struct IndexSaveData {
|
|
||||||
std::unordered_map<std::string, IndexSourceSaveData> sources;
|
|
||||||
};
|
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(IndexSaveData, sources);
|
|
||||||
|
|
||||||
// ModInstallEvent
|
// ModInstallEvent
|
||||||
|
|
||||||
ModInstallEvent::ModInstallEvent(
|
ModInstallEvent::ModInstallEvent(
|
||||||
|
@ -54,6 +42,12 @@ struct geode::IndexSourceImpl final {
|
||||||
ghc::filesystem::path path() const {
|
ghc::filesystem::path path() const {
|
||||||
return dirs::getIndexDir() / this->dirname();
|
return dirs::getIndexDir() / this->dirname();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ghc::filesystem::path checksum() const {
|
||||||
|
// not storing this in the source's directory as that gets replaced by
|
||||||
|
// the newly fetched index
|
||||||
|
return dirs::getIndexDir() / (this->dirname() + ".checksum");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void IndexSourceImplDeleter::operator()(IndexSourceImpl* src) {
|
void IndexSourceImplDeleter::operator()(IndexSourceImpl* src) {
|
||||||
|
@ -124,7 +118,7 @@ Result<IndexItemHandle> IndexItem::createFromDir(
|
||||||
.hash = root.has("mod").obj().has("hash").template get<std::string>(),
|
.hash = root.has("mod").obj().has("hash").template get<std::string>(),
|
||||||
.platforms = platforms,
|
.platforms = platforms,
|
||||||
},
|
},
|
||||||
.isFeatured = root.has("is-featured").template get<bool>(),
|
.isFeatured = root.has("featured").template get<bool>(),
|
||||||
.tags = root.has("tags").template get<std::unordered_set<std::string>>()
|
.tags = root.has("tags").template get<std::unordered_set<std::string>>()
|
||||||
});
|
});
|
||||||
if (checker.isError()) {
|
if (checker.isError()) {
|
||||||
|
@ -219,6 +213,7 @@ void Index::onSourceUpdate(SourceUpdateEvent* event) {
|
||||||
|
|
||||||
switch (whatToPost) {
|
switch (whatToPost) {
|
||||||
case Finished: {
|
case Finished: {
|
||||||
|
log::debug("Index up-to-date");
|
||||||
// clear source statuses to allow updating index again
|
// clear source statuses to allow updating index again
|
||||||
m_sourceStatuses.clear();
|
m_sourceStatuses.clear();
|
||||||
// post finish event
|
// post finish event
|
||||||
|
@ -250,6 +245,7 @@ void Index::onSourceUpdate(SourceUpdateEvent* event) {
|
||||||
info += src + ": " + std::get<UpdateFailed>(status) + "\n";
|
info += src + ": " + std::get<UpdateFailed>(status) + "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
log::debug("Index update failed: {}", info);
|
||||||
// clear source statuses to allow updating index again
|
// clear source statuses to allow updating index again
|
||||||
m_sourceStatuses.clear();
|
m_sourceStatuses.clear();
|
||||||
// post finish event
|
// post finish event
|
||||||
|
@ -262,9 +258,14 @@ void Index::checkSourceUpdates(IndexSourceImpl* src) {
|
||||||
if (src->isUpToDate) {
|
if (src->isUpToDate) {
|
||||||
return this->updateSourceFromLocal(src);
|
return this->updateSourceFromLocal(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log::debug("Checking updates for source {}", src->repository);
|
||||||
SourceUpdateEvent(src, UpdateProgress(0, "Checking status")).post();
|
SourceUpdateEvent(src, UpdateProgress(0, "Checking status")).post();
|
||||||
auto data = Mod::get()->getSavedMutable<IndexSaveData>("index");
|
|
||||||
auto oldSHA = data.sources[src->repository].downloadedCommitSHA;
|
// read old commit SHA
|
||||||
|
// not using saved values for this one as we don't want to refetch
|
||||||
|
// index even if the game crashes
|
||||||
|
auto oldSHA = file::readString(src->checksum()).unwrapOr("");
|
||||||
web::AsyncWebRequest()
|
web::AsyncWebRequest()
|
||||||
.join(fmt::format("index-update-{}", src->repository))
|
.join(fmt::format("index-update-{}", src->repository))
|
||||||
.header(fmt::format("If-None-Match: \"{}\"", oldSHA))
|
.header(fmt::format("If-None-Match: \"{}\"", oldSHA))
|
||||||
|
@ -285,8 +286,7 @@ void Index::checkSourceUpdates(IndexSourceImpl* src) {
|
||||||
}
|
}
|
||||||
// otherwise save hash and download source
|
// otherwise save hash and download source
|
||||||
else {
|
else {
|
||||||
auto data = Mod::get()->getSavedMutable<IndexSaveData>("index");
|
(void)file::writeString(src->checksum(), newSHA);
|
||||||
data.sources[src->repository].downloadedCommitSHA = newSHA;
|
|
||||||
this->downloadSource(src);
|
this->downloadSource(src);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -299,6 +299,8 @@ void Index::checkSourceUpdates(IndexSourceImpl* src) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Index::downloadSource(IndexSourceImpl* src) {
|
void Index::downloadSource(IndexSourceImpl* src) {
|
||||||
|
log::debug("Downloading source {}", src->repository);
|
||||||
|
|
||||||
SourceUpdateEvent(src, UpdateProgress(0, "Beginning download")).post();
|
SourceUpdateEvent(src, UpdateProgress(0, "Beginning download")).post();
|
||||||
|
|
||||||
auto targetFile = dirs::getIndexDir() / fmt::format("{}.zip", src->dirname());
|
auto targetFile = dirs::getIndexDir() / fmt::format("{}.zip", src->dirname());
|
||||||
|
@ -353,6 +355,7 @@ void Index::downloadSource(IndexSourceImpl* src) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Index::updateSourceFromLocal(IndexSourceImpl* src) {
|
void Index::updateSourceFromLocal(IndexSourceImpl* src) {
|
||||||
|
log::debug("Updating local cache for source {}", src->repository);
|
||||||
SourceUpdateEvent(src, UpdateProgress(100, "Updating local cache")).post();
|
SourceUpdateEvent(src, UpdateProgress(100, "Updating local cache")).post();
|
||||||
// delete old items from this url if such exist
|
// delete old items from this url if such exist
|
||||||
for (auto& [_, versions] : m_items) {
|
for (auto& [_, versions] : m_items) {
|
||||||
|
@ -457,20 +460,19 @@ std::vector<IndexItemHandle> Index::getItems() const {
|
||||||
std::vector<IndexItemHandle> res;
|
std::vector<IndexItemHandle> res;
|
||||||
for (auto& items : map::values(m_items)) {
|
for (auto& items : map::values(m_items)) {
|
||||||
if (items.size()) {
|
if (items.size()) {
|
||||||
auto item = items.rbegin()->second;
|
res.push_back(items.rbegin()->second);
|
||||||
if (item->download.platforms.count(GEODE_PLATFORM_TARGET)) {
|
|
||||||
res.push_back(item);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<IndexItemHandle> Index::getAllItems() const {
|
std::vector<IndexItemHandle> Index::getFeaturedItems() const {
|
||||||
std::vector<IndexItemHandle> res;
|
std::vector<IndexItemHandle> res;
|
||||||
for (auto& items : map::values(m_items)) {
|
for (auto& items : map::values(m_items)) {
|
||||||
if (items.size()) {
|
if (items.size()) {
|
||||||
res.push_back(items.rbegin()->second);
|
if (items.rbegin()->second->isFeatured) {
|
||||||
|
res.push_back(items.rbegin()->second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
@ -549,6 +551,10 @@ bool Index::areUpdatesAvailable() const {
|
||||||
// Item installation
|
// Item installation
|
||||||
|
|
||||||
Result<IndexInstallList> Index::getInstallList(IndexItemHandle item) const {
|
Result<IndexInstallList> Index::getInstallList(IndexItemHandle item) const {
|
||||||
|
if (!item->download.platforms.count(GEODE_PLATFORM_TARGET)) {
|
||||||
|
return Err("Mod is not available on {}", GEODE_PLATFORM_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
IndexInstallList list;
|
IndexInstallList list;
|
||||||
list.target = item;
|
list.target = item;
|
||||||
for (auto& dep : item->info.dependencies) {
|
for (auto& dep : item->info.dependencies) {
|
||||||
|
|
|
@ -185,7 +185,6 @@ CCArray* ModListLayer::createModCells(ModListType type, ModListQuery const& quer
|
||||||
if (auto match = queryMatch(query, item)) {
|
if (auto match = queryMatch(query, item)) {
|
||||||
sorted.insert({ match.value(), item });
|
sorted.insert({ match.value(), item });
|
||||||
}
|
}
|
||||||
if (!queryMatch(query, item)) continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the mods sorted
|
// add the mods sorted
|
||||||
|
@ -195,7 +194,19 @@ CCArray* ModListLayer::createModCells(ModListType type, ModListQuery const& quer
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case ModListType::Featured: {
|
case ModListType::Featured: {
|
||||||
// todo: featured
|
// sort the mods by match score
|
||||||
|
std::multimap<int, IndexItemHandle> sorted;
|
||||||
|
|
||||||
|
for (auto const& item : Index::get()->getFeaturedItems()) {
|
||||||
|
if (auto match = queryMatch(query, item)) {
|
||||||
|
sorted.insert({ match.value(), item });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the mods sorted
|
||||||
|
for (auto& [score, item] : ranges::reverse(sorted)) {
|
||||||
|
mods->addObject(IndexItemCell::create(item, this, this->getCellSize()));
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
return mods;
|
return mods;
|
||||||
|
|
Loading…
Reference in a new issue