mirror of
https://github.com/geode-sdk/geode.git
synced 2025-03-22 02:45:49 -04:00
working on more filters for index mods
This commit is contained in:
parent
f832dbf89a
commit
035091fbc2
9 changed files with 95 additions and 120 deletions
cmake
loader
include/Geode
src
|
@ -19,6 +19,22 @@ function(create_geode_file proname)
|
|||
|
||||
message(STATUS "Creating geode file")
|
||||
|
||||
if(GEODE_CLI STREQUAL "GEODE_CLI-NOTFOUND")
|
||||
message(WARNING "create_geode_file called, but Geode CLI was not found - You will need to manually package the .geode files")
|
||||
else()
|
||||
|
||||
add_custom_target(${proname}_PACKAGE ALL
|
||||
DEPENDS ${proname}
|
||||
COMMAND ${GEODE_CLI} pkg ${CMAKE_CURRENT_SOURCE_DIR} $<TARGET_FILE_DIR:${proname}> $<TARGET_FILE_DIR:${proname}>/${proname}.geode --install --cached
|
||||
VERBATIM USES_TERMINAL
|
||||
)
|
||||
endif()
|
||||
|
||||
endfunction()
|
||||
|
||||
function(create_geode_file_v2 proname)
|
||||
message(STATUS "Creating geode file")
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/mod.json ${CMAKE_CURRENT_BINARY_DIR}/what.txt)
|
||||
set_target_properties(${proname} PROPERTIES CMAKE_CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/mod.json)
|
||||
|
||||
|
@ -39,23 +55,6 @@ function(create_geode_file proname)
|
|||
VERBATIM USES_TERMINAL
|
||||
)
|
||||
endif()
|
||||
|
||||
endfunction()
|
||||
|
||||
function(create_geode_file_v2 proname)
|
||||
message(STATUS "Creating geode file")
|
||||
|
||||
if(GEODE_CLI STREQUAL "GEODE_CLI-NOTFOUND")
|
||||
message(WARNING "create_geode_file called, but Geode CLI was not found - You will need to manually package the .geode files")
|
||||
else()
|
||||
|
||||
add_custom_target(${proname}_PACKAGE ALL
|
||||
DEPENDS ${proname}
|
||||
COMMAND ${GEODE_CLI} package new ${CMAKE_CURRENT_SOURCE_DIR} --out $<TARGET_FILE_DIR:${proname}>/${proname}.geode --install
|
||||
VERBATIM USES_TERMINAL
|
||||
)
|
||||
endif()
|
||||
|
||||
endfunction()
|
||||
|
||||
function(package_geode_resources proname src dest prefix)
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace geode {
|
|||
bool operator==(PlatformID const& other) const { return m_value == other.m_value; }
|
||||
bool operator<(PlatformID const& other) const { return m_value < other.m_value; }
|
||||
bool operator>(PlatformID const& other) const { return m_value > other.m_value; }
|
||||
operator int() { return m_value; }
|
||||
operator int() const { return m_value; }
|
||||
|
||||
template<class T>
|
||||
static Type cast(T t) {
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace geode {
|
|||
m_mainLayer->addChild(m_bgSprite);
|
||||
|
||||
m_buttonMenu = cocos2d::CCMenu::create();
|
||||
m_buttonMenu->setZOrder(100);
|
||||
m_mainLayer->addChild(m_buttonMenu);
|
||||
|
||||
cocos2d::CCDirector::sharedDirector()->getTouchDispatcher()->incrementForcePrio(2);
|
||||
|
|
|
@ -337,76 +337,28 @@ void Index::addIndexItemFromFolder(ghc::filesystem::path const& dir) {
|
|||
Log::get() << Severity::Warning
|
||||
<< "[index.json].download is not an object, "
|
||||
"skipping";
|
||||
return;
|
||||
}
|
||||
|
||||
auto download = json["download"];
|
||||
std::set<PlatformID> unsetPlatforms = {
|
||||
PlatformID::Windows,
|
||||
PlatformID::MacOS,
|
||||
PlatformID::iOS,
|
||||
PlatformID::Android,
|
||||
PlatformID::Linux,
|
||||
};
|
||||
for (auto& key : std::initializer_list<std::string> {
|
||||
"windows",
|
||||
"macos",
|
||||
"android",
|
||||
"ios",
|
||||
"*",
|
||||
}) {
|
||||
if (download.contains(key)) {
|
||||
auto platformDownload = download[key];
|
||||
if (!platformDownload.is_object()) {
|
||||
Log::get() << Severity::Warning
|
||||
<< "[index.json].download."
|
||||
<< key
|
||||
<< " is not an object, skipping";
|
||||
return;
|
||||
}
|
||||
if (
|
||||
!platformDownload.contains("url") ||
|
||||
!platformDownload["url"].is_string()
|
||||
) {
|
||||
Log::get() << Severity::Warning
|
||||
<< "[index.json].download."
|
||||
<< key
|
||||
<< ".url is not a string, skipping";
|
||||
return;
|
||||
}
|
||||
if (
|
||||
!platformDownload.contains("name") ||
|
||||
!platformDownload["name"].is_string()
|
||||
) {
|
||||
Log::get() << Severity::Warning
|
||||
<< "[index.json].download."
|
||||
<< key
|
||||
<< ".name is not a string, skipping";
|
||||
return;
|
||||
}
|
||||
if (
|
||||
!platformDownload.contains("hash") ||
|
||||
!platformDownload["hash"].is_string()
|
||||
) {
|
||||
Log::get() << Severity::Warning
|
||||
<< "[index.json].download."
|
||||
<< key
|
||||
<< ".hash is not a string, skipping";
|
||||
return;
|
||||
}
|
||||
IndexItem::Download down;
|
||||
down.m_url = platformDownload["url"];
|
||||
down.m_filename = platformDownload["name"];
|
||||
down.m_hash = platformDownload["hash"];
|
||||
if (key == "*") {
|
||||
for (auto& platform : unsetPlatforms) {
|
||||
item.m_download[platform] = down;
|
||||
}
|
||||
} else {
|
||||
auto id = platformFromString(key);
|
||||
item.m_download[id] = down;
|
||||
unsetPlatforms.erase(id);
|
||||
}
|
||||
#define REQUIRE_DOWNLOAD_KEY(key, type) \
|
||||
if (!download.contains(key) || !download[key].is_##type()) {\
|
||||
Log::get() << Severity::Warning\
|
||||
<< "[index.json].download." key " is not a " #type ", skipping";\
|
||||
return;\
|
||||
}
|
||||
|
||||
auto download = json["download"];
|
||||
|
||||
REQUIRE_DOWNLOAD_KEY("url", string);
|
||||
REQUIRE_DOWNLOAD_KEY("name", string);
|
||||
REQUIRE_DOWNLOAD_KEY("hash", string);
|
||||
REQUIRE_DOWNLOAD_KEY("platforms", array);
|
||||
|
||||
item.m_download.m_url = download["url"];
|
||||
item.m_download.m_filename = download["name"];
|
||||
item.m_download.m_hash = download["hash"];
|
||||
for (auto& platform : download["platforms"]) {
|
||||
item.m_download.m_platforms.insert(platformFromString(platform));
|
||||
}
|
||||
|
||||
m_items.push_back(item);
|
||||
|
@ -435,7 +387,7 @@ std::vector<IndexItem> Index::getUninstalledItems() const {
|
|||
std::vector<IndexItem> items;
|
||||
for (auto& item : m_items) {
|
||||
if (!Loader::get()->isModInstalled(item.m_info.m_id)) {
|
||||
if (item.m_download.count(GEODE_PLATFORM_TARGET)) {
|
||||
if (item.m_download.m_platforms.count(GEODE_PLATFORM_TARGET)) {
|
||||
items.push_back(item);
|
||||
}
|
||||
}
|
||||
|
@ -528,26 +480,25 @@ Result<InstallTicket*> Index::installItems(
|
|||
) {
|
||||
std::vector<std::string> ids {};
|
||||
for (auto& item : items) {
|
||||
if (!item.m_download.count(GEODE_PLATFORM_TARGET)) {
|
||||
if (!item.m_download.m_platforms.count(GEODE_PLATFORM_TARGET)) {
|
||||
return Err(
|
||||
"This mod is not available on your "
|
||||
"current platform \"" GEODE_PLATFORM_NAME "\" - Sorry! :("
|
||||
);
|
||||
}
|
||||
auto download = item.m_download.at(GEODE_PLATFORM_TARGET);
|
||||
if (!download.m_url.size()) {
|
||||
if (!item.m_download.m_url.size()) {
|
||||
return Err(
|
||||
"Download URL not set! Report this bug to "
|
||||
"the Geode developers - this should not happen, ever."
|
||||
);
|
||||
}
|
||||
if (!download.m_filename.size()) {
|
||||
if (!item.m_download.m_filename.size()) {
|
||||
return Err(
|
||||
"Download filename not set! Report this bug to "
|
||||
"the Geode developers - this should not happen, ever."
|
||||
);
|
||||
}
|
||||
if (!download.m_hash.size()) {
|
||||
if (!item.m_download.m_hash.size()) {
|
||||
return Err(
|
||||
"Checksum not set! Report this bug to "
|
||||
"the Geode developers - this should not happen, ever."
|
||||
|
|
|
@ -29,12 +29,12 @@ struct IndexItem {
|
|||
std::string m_url;
|
||||
std::string m_filename;
|
||||
std::string m_hash;
|
||||
std::unordered_set<PlatformID> m_platforms;
|
||||
};
|
||||
|
||||
ghc::filesystem::path m_path;
|
||||
ModInfo m_info;
|
||||
std::unordered_map<PlatformID, Download> m_download;
|
||||
std::string m_installFailed;
|
||||
Download m_download;
|
||||
};
|
||||
|
||||
enum class InstallMode {
|
||||
|
|
|
@ -39,16 +39,15 @@ void InstallTicket::install(std::string const& id) {
|
|||
auto indexDir = Loader::get()->getGeodeDirectory() / "index";
|
||||
|
||||
auto item = m_index->getKnownItem(id);
|
||||
auto download = item.m_download.at(GEODE_PLATFORM_TARGET);
|
||||
|
||||
this->postProgress(UpdateStatus::Progress, "Checking status", 0);
|
||||
|
||||
// download to temp file in index dir
|
||||
auto tempFile = indexDir / download.m_filename;
|
||||
auto tempFile = indexDir / item.m_download.m_filename;
|
||||
|
||||
this->postProgress(UpdateStatus::Progress, "Fetching binary", 0);
|
||||
auto res = fetchFile(
|
||||
download.m_url,
|
||||
item.m_download.m_url,
|
||||
tempFile,
|
||||
[this, tempFile](double now, double total) -> int {
|
||||
// check if cancelled
|
||||
|
@ -104,7 +103,7 @@ void InstallTicket::install(std::string const& id) {
|
|||
|
||||
auto checksum = ::calculateHash(tempFile.string());
|
||||
|
||||
if (checksum != download.m_hash) {
|
||||
if (checksum != item.m_download.m_hash) {
|
||||
try { ghc::filesystem::remove(tempFile); } catch(...) {}
|
||||
return this->postProgress(
|
||||
UpdateStatus::Failed,
|
||||
|
@ -117,12 +116,12 @@ void InstallTicket::install(std::string const& id) {
|
|||
// move temp file to geode directory
|
||||
try {
|
||||
auto modDir = Loader::get()->getGeodeDirectory() / "mods";
|
||||
auto targetFile = modDir / download.m_filename;
|
||||
auto targetFile = modDir / item.m_download.m_filename;
|
||||
|
||||
// find valid filename that doesn't exist yet
|
||||
if (!m_replaceFiles) {
|
||||
auto filename = ghc::filesystem::path(
|
||||
download.m_filename
|
||||
item.m_download.m_filename
|
||||
).replace_extension("").string();
|
||||
|
||||
size_t number = 0;
|
||||
|
|
|
@ -125,6 +125,8 @@ std::tuple<CCNode*, CCTextInputNode*> ModListLayer::createSearchControl() {
|
|||
auto menu = CCMenu::create();
|
||||
menu->setPosition(340.f, 15.f);
|
||||
|
||||
constexpr float buttonSpace = 50.f;
|
||||
|
||||
// filters
|
||||
auto filterSpr = EditorButtonSprite::createWithSpriteFrameName(
|
||||
"filters.png"_spr, 1.0f, EditorBaseColor::Gray
|
||||
|
@ -133,7 +135,7 @@ std::tuple<CCNode*, CCTextInputNode*> ModListLayer::createSearchControl() {
|
|||
|
||||
auto filterBtn = CCMenuItemSpriteExtra::create(
|
||||
filterSpr, this, makeMenuSelector([this](CCObject*) {
|
||||
SearchFilterPopup::create(this)->show();
|
||||
SearchFilterPopup::create(this, g_tab)->show();
|
||||
})
|
||||
);
|
||||
filterBtn->setPosition(-10.f, 0.f);
|
||||
|
@ -162,12 +164,12 @@ std::tuple<CCNode*, CCTextInputNode*> ModListLayer::createSearchControl() {
|
|||
"square02b_001.png", { 0.0f, 0.0f, 80.0f, 80.0f }
|
||||
);
|
||||
inputBG->setColor({ 126, 59, 7 });
|
||||
inputBG->setContentSize({ 550.f, 40.f });
|
||||
inputBG->setPosition(150.f, 15.f);
|
||||
inputBG->setContentSize({ 650.f - buttonSpace * 2, 40.f });
|
||||
inputBG->setPosition(175.f - buttonSpace / 2, 15.f);
|
||||
inputBG->setScale(.5f);
|
||||
layer->addChild(inputBG);
|
||||
|
||||
auto input = CCTextInputNode::create(260.f, 20.f, "Search Mods...", "bigFont.fnt");
|
||||
auto input = CCTextInputNode::create(310.f - buttonSpace, 20.f, "Search Mods...", "bigFont.fnt");
|
||||
input->setLabelPlaceholderColor({ 150, 150, 150 });
|
||||
input->setLabelPlaceholderScale(.4f);
|
||||
input->setMaxLabelScale(.4f);
|
||||
|
|
|
@ -2,27 +2,49 @@
|
|||
#include "ModListLayer.hpp"
|
||||
#include "ModListView.hpp"
|
||||
|
||||
bool SearchFilterPopup::setup(ModListLayer* layer) {
|
||||
bool SearchFilterPopup::setup(ModListLayer* layer, ModListType type) {
|
||||
// todo: clean this shitty ass popup up
|
||||
m_noElasticity = true;
|
||||
m_modLayer = layer;
|
||||
|
||||
this->setTitle("Match Fields");
|
||||
this->setTitle("Search Filters");
|
||||
|
||||
auto winSize = CCDirector::sharedDirector()->getWinSize();
|
||||
auto pos = CCPoint { winSize.width / 2 - 55.f, winSize.height / 2 + 50.f };
|
||||
auto pos = CCPoint { winSize.width / 2 - 145.f, winSize.height / 2 + 35.f };
|
||||
|
||||
this->addToggle("Name", ModListView::SearchFlags::Name, pos);
|
||||
this->addToggle("ID", ModListView::SearchFlags::ID, pos);
|
||||
this->addToggle("Credits", ModListView::SearchFlags::Credits, pos);
|
||||
this->addToggle("Description", ModListView::SearchFlags::Description, pos);
|
||||
this->addToggle("Details", ModListView::SearchFlags::Details, pos);
|
||||
this->addToggle("Developer", ModListView::SearchFlags::Developer, pos);
|
||||
auto matchTitle = CCLabelBMFont::create("Search fields", "goldFont.fnt");
|
||||
matchTitle->setPosition(winSize.width / 2 - 90.f, winSize.height / 2 + 65.f);
|
||||
matchTitle->setScale(.5f);
|
||||
m_mainLayer->addChild(matchTitle);
|
||||
|
||||
auto matchBG = CCScale9Sprite::create(
|
||||
"square02b_001.png", { 0.0f, 0.0f, 80.0f, 80.0f }
|
||||
);
|
||||
matchBG->setColor({ 0, 0, 0 });
|
||||
matchBG->setOpacity(90);
|
||||
matchBG->setContentSize({ 290.f, 300.f });
|
||||
matchBG->setPosition(winSize.width / 2 - 90.f, winSize.height / 2 - 21.f);
|
||||
matchBG->setScale(.5f);
|
||||
m_mainLayer->addChild(matchBG);
|
||||
|
||||
this->addSearchMatch("Name", ModListView::SearchFlags::Name, pos);
|
||||
this->addSearchMatch("ID", ModListView::SearchFlags::ID, pos);
|
||||
this->addSearchMatch("Credits", ModListView::SearchFlags::Credits, pos);
|
||||
this->addSearchMatch("Description", ModListView::SearchFlags::Description, pos);
|
||||
this->addSearchMatch("Details", ModListView::SearchFlags::Details, pos);
|
||||
this->addSearchMatch("Developer", ModListView::SearchFlags::Developer, pos);
|
||||
|
||||
|
||||
auto line = CCSprite::createWithSpriteFrameName("edit_vLine_001.png");
|
||||
line->setPosition({ winSize.width / 2, winSize.height / 2 - 20.f });
|
||||
line->setScaleY(1.65f);
|
||||
line->setOpacity(100);
|
||||
m_mainLayer->addChild(line);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SearchFilterPopup::addToggle(const char* title, int flag, CCPoint& pos) {
|
||||
void SearchFilterPopup::addSearchMatch(const char* title, int flag, CCPoint& pos) {
|
||||
GameToolbox::createToggleButton(
|
||||
title, menu_selector(SearchFilterPopup::onToggle),
|
||||
m_modLayer->m_searchFlags & flag,
|
||||
|
@ -30,7 +52,7 @@ void SearchFilterPopup::addToggle(const char* title, int flag, CCPoint& pos) {
|
|||
m_buttonMenu, .5f, .5f, 100.f,
|
||||
{ 10.f, .0f }, nullptr, false, flag, nullptr
|
||||
)->setTag(flag);
|
||||
pos.y -= 25.f;
|
||||
pos.y -= 22.5f;
|
||||
}
|
||||
|
||||
void SearchFilterPopup::onToggle(cocos2d::CCObject* pSender) {
|
||||
|
@ -41,9 +63,9 @@ void SearchFilterPopup::onToggle(cocos2d::CCObject* pSender) {
|
|||
}
|
||||
}
|
||||
|
||||
SearchFilterPopup* SearchFilterPopup::create(ModListLayer* layer) {
|
||||
SearchFilterPopup* SearchFilterPopup::create(ModListLayer* layer, ModListType type) {
|
||||
auto ret = new SearchFilterPopup();
|
||||
if (ret && ret->init(200.f, 200.f, layer, "GJ_square05.png")) {
|
||||
if (ret && ret->init(350.f, 220.f, layer, type)) {
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -5,17 +5,18 @@
|
|||
USE_GEODE_NAMESPACE();
|
||||
|
||||
class ModListLayer;
|
||||
enum class ModListType;
|
||||
|
||||
class SearchFilterPopup : public Popup<ModListLayer*> {
|
||||
class SearchFilterPopup : public Popup<ModListLayer*, ModListType> {
|
||||
protected:
|
||||
ModListLayer* m_modLayer;
|
||||
|
||||
bool setup(ModListLayer* layer) override;
|
||||
void addToggle(const char* title, int flag, CCPoint& pos);
|
||||
bool setup(ModListLayer* layer, ModListType type) override;
|
||||
void addSearchMatch(const char* title, int flag, CCPoint& pos);
|
||||
|
||||
void onToggle(cocos2d::CCObject*);
|
||||
|
||||
public:
|
||||
static SearchFilterPopup* create(ModListLayer* layer);
|
||||
static SearchFilterPopup* create(ModListLayer* layer, ModListType type);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue