From eb155576c0958db7ee18727e06a2ff35362a6fc7 Mon Sep 17 00:00:00 2001 From: Justin Pridgen Date: Fri, 15 Nov 2024 03:34:51 -0500 Subject: [PATCH] 2.207 --- .github/workflows/build.yml | 2 -- CMakeLists.txt | 3 +- changelog.md | 3 ++ mod.json | 10 +++--- src/MoreIcons.cpp | 39 ++++++++++----------- src/MoreIcons.hpp | 4 +-- src/classes/ButtonHooker.cpp | 20 +++++++++++ src/classes/ButtonHooker.hpp | 11 ++++++ src/classes/LogCell.cpp | 8 ++--- src/classes/LogLayer.cpp | 6 ++-- src/hooks/GJGarageLayer.cpp | 68 +++++++++++++++--------------------- src/hooks/MenuLayer.cpp | 17 +++++++-- src/hooks/ProfilePage.cpp | 36 ++++--------------- 13 files changed, 117 insertions(+), 110 deletions(-) create mode 100644 src/classes/ButtonHooker.cpp create mode 100644 src/classes/ButtonHooker.hpp diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a3305c5..b2bb2ae 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,8 +36,6 @@ jobs: - name: Build the mod uses: geode-sdk/build-geode-mod@main with: - bindings: hiimjustin000/bindings - bindings-ref: ccdictionary build-config: ${{ matrix.config.build-config || 'Release' }} export-pdb: true combine: true diff --git a/CMakeLists.txt b/CMakeLists.txt index d1b3c69..bb33e8d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,10 +4,11 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64") set(CMAKE_CXX_VISIBILITY_PRESET hidden) -project(MoreIcons VERSION 1.4.5) +project(MoreIcons VERSION 1.4.6) add_library(${PROJECT_NAME} SHARED src/api/MoreIconsAPI.cpp + src/classes/ButtonHooker.cpp src/classes/LogCell.cpp src/classes/LogLayer.cpp src/hooks/AppDelegate.cpp diff --git a/changelog.md b/changelog.md index 1453aba..4bd1b00 100644 --- a/changelog.md +++ b/changelog.md @@ -1,4 +1,7 @@ # More Icons Changelog +## v1.4.6-beta.1 (2024-11-13) +- Ported to Geometry Dash v2.207 + ## v1.4.5 (2024-11-04) - Fixed potential blending issues with robots and spiders diff --git a/mod.json b/mod.json index 05cb78a..626dc3e 100644 --- a/mod.json +++ b/mod.json @@ -1,11 +1,11 @@ { - "geode": "3.9.0", + "geode": "4.0.0-alpha.1", "gd": { - "android": "2.206", - "win": "2.206", - "mac": "2.206" + "android": "2.2074", + "win": "2.2074", + "mac": "2.2074" }, - "version": "v1.4.5", + "version": "v1.4.6-beta.1", "id": "hiimjustin000.more_icons", "name": "More Icons", "developer": "hiimjustin000", diff --git a/src/MoreIcons.cpp b/src/MoreIcons.cpp index a2ae7d9..ff31d13 100644 --- a/src/MoreIcons.cpp +++ b/src/MoreIcons.cpp @@ -200,17 +200,16 @@ void MoreIcons::loadIcons(const std::vector& packs, const std::ifstream file(packJSON); std::stringstream bufferStream; bufferStream << file.rdbuf(); - std::string error; - auto tryJson = matjson::parse(bufferStream.str(), error); + auto tryJson = matjson::parse(bufferStream.str()); auto packFileName = rootPackPath.filename().string(); - if (!error.empty()) { + if (!tryJson.isOk()) { packName = packFileName; packID = packFileName; } - auto json = tryJson.value_or(matjson::Object()); - if (json.contains("name") && json["name"].is_string()) packName = json["name"].as_string(); + auto json = tryJson.unwrapOr(matjson::Value()); + if (json.contains("name") && json["name"].isString()) packName = json["name"].asString().unwrap(); else packName = packFileName; - if (json.contains("id") && json["id"].is_string()) packID = json["id"].as_string(); + if (json.contains("id") && json["id"].isString()) packID = json["id"].asString().unwrap(); else packID = packFileName; } } @@ -439,17 +438,16 @@ void MoreIcons::loadTrails(const std::vector& packs) { std::ifstream file(packJSON); std::stringstream bufferStream; bufferStream << file.rdbuf(); - std::string error; - auto tryJson = matjson::parse(bufferStream.str(), error); + auto tryJson = matjson::parse(bufferStream.str()); auto packFileName = rootPackPath.filename().string(); - if (!error.empty()) { + if (!tryJson.isOk()) { packName = packFileName; packID = packFileName; } - auto json = tryJson.value_or(matjson::Object()); - if (json.contains("name") && json["name"].is_string()) packName = json["name"].as_string(); + auto json = tryJson.unwrapOr(matjson::Value()); + if (json.contains("name") && json["name"].isString()) packName = json["name"].asString().unwrap(); else packName = packFileName; - if (json.contains("id") && json["id"].is_string()) packID = json["id"].as_string(); + if (json.contains("id") && json["id"].isString()) packID = json["id"].asString().unwrap(); else packID = packFileName; } } @@ -488,24 +486,23 @@ void MoreIcons::loadTrail(const std::filesystem::path& path, const TexturePack& auto name = (!pack.id.empty() ? pack.id + ":" : "") + path.stem().string(); auto jsonPath = std::filesystem::path(path).replace_extension(".json"); matjson::Value json; - if (!std::filesystem::exists(jsonPath)) json = matjson::Object { { "blend", false }, { "tint", false } }; + if (!std::filesystem::exists(jsonPath)) json = matjson::makeObject({ { "blend", false }, { "tint", false } }); else { std::ifstream file(jsonPath); std::stringstream bufferStream; bufferStream << file.rdbuf(); - std::string error; - auto tryJson = matjson::parse(bufferStream.str(), error); - if (!error.empty()) { - auto logMessage = fmt::format("{}: Failed to parse JSON file ({})", path.string(), error); + auto tryJson = matjson::parse(bufferStream.str()); + if (!tryJson.isOk()) { + auto logMessage = fmt::format("{}: Failed to parse JSON file ({})", path.string(), tryJson.unwrapErr()); log::warn("{}", logMessage); { std::lock_guard lock(LOG_MUTEX); LOGS.push_back({ .message = logMessage, .type = LogType::Warn }); if (HIGHEST_SEVERITY < LogType::Warn) HIGHEST_SEVERITY = LogType::Warn; } - json = matjson::Object { { "blend", false }, { "tint", false } }; + json = matjson::makeObject({ { "blend", false }, { "tint", false } }); } - else json = tryJson.value_or(matjson::Object { { "blend", false }, { "tint", false } }); + else json = tryJson.unwrap(); } auto fullTexturePath = path.string(); @@ -521,8 +518,8 @@ void MoreIcons::loadTrail(const std::filesystem::path& path, const TexturePack& .pack = pack, .type = IconType::Special, .index = 0, - .blend = json.contains("blend") && json["blend"].is_bool() ? json["blend"].as_bool() : false, - .tint = json.contains("tint") && json["tint"].is_bool() ? json["tint"].as_bool() : false, + .blend = json.contains("blend") && json["blend"].isBool() ? json["blend"].asBool().unwrap() : false, + .tint = json.contains("tint") && json["tint"].isBool() ? json["tint"].asBool().unwrap() : false, }); } else image->release(); diff --git a/src/MoreIcons.hpp b/src/MoreIcons.hpp index 102be22..04edcc0 100644 --- a/src/MoreIcons.hpp +++ b/src/MoreIcons.hpp @@ -156,10 +156,10 @@ class MoreIcons { static void saveTrails() { for (auto& [trail, info] : TRAIL_INFO) { std::fstream file(std::filesystem::path(info.texture).replace_extension(".json"), std::ios::out); - file << matjson::Value(matjson::Object { + file << matjson::Value(matjson::makeObject({ { "blend", info.blend }, { "tint", info.tint }, - }).dump(); + })).dump(); file.close(); } } diff --git a/src/classes/ButtonHooker.cpp b/src/classes/ButtonHooker.cpp new file mode 100644 index 0000000..2ea77f6 --- /dev/null +++ b/src/classes/ButtonHooker.cpp @@ -0,0 +1,20 @@ +#include "ButtonHooker.hpp" + +using namespace geode::prelude; + +ButtonHooker* ButtonHooker::create(CCMenuItem* button, CCObject* listener, SEL_MenuHandler selector) { + auto hooker = new ButtonHooker(); + hooker->m_listener = button->m_pListener; + hooker->m_newListener = listener; + hooker->m_selector = button->m_pfnSelector; + hooker->m_newSelector = selector; + hooker->autorelease(); + button->setTarget(hooker, menu_selector(ButtonHooker::onClick)); + button->setUserObject("hooker"_spr, hooker); + return hooker; +} + +void ButtonHooker::onClick(CCObject* sender) { + (m_listener->*m_selector)(sender); + (m_newListener->*m_newSelector)(sender); +} diff --git a/src/classes/ButtonHooker.hpp b/src/classes/ButtonHooker.hpp new file mode 100644 index 0000000..b679371 --- /dev/null +++ b/src/classes/ButtonHooker.hpp @@ -0,0 +1,11 @@ +class ButtonHooker : public cocos2d::CCObject { +private: + cocos2d::CCObject* m_listener; + cocos2d::CCObject* m_newListener; + cocos2d::SEL_MenuHandler m_selector; + cocos2d::SEL_MenuHandler m_newSelector; +public: + static ButtonHooker* create(cocos2d::CCMenuItem* button, cocos2d::CCObject* listener, cocos2d::SEL_MenuHandler selector); + + void onClick(cocos2d::CCObject* sender); +}; diff --git a/src/classes/LogCell.cpp b/src/classes/LogCell.cpp index 75c0638..dc8e82c 100644 --- a/src/classes/LogCell.cpp +++ b/src/classes/LogCell.cpp @@ -28,22 +28,22 @@ bool LogCell::init(LogData const& data, int index, int total, bool dark) { bg->ignoreAnchorPointForPosition(false); if (index == 0) { bg->setContentSize({ 400.0f, 35.0f }); - bg->setPosition(200.0f, 17.5f); + bg->setPosition({ 200.0f, 17.5f }); } else if (index == total - 1) { bg->setContentSize({ 400.0f, 35.0f }); - bg->setPosition(200.0f, 52.5f); + bg->setPosition({ 200.0f, 52.5f }); } else { bg->setContentSize({ 400.0f, 70.0f }); - bg->setPosition(200.0f, 35.0f); + bg->setPosition({ 200.0f, 35.0f }); } addChild(bg, -1); if (index == 0 || index == total - 1) { auto bgBg = CCScale9Sprite::create("square02b_001.png", { 0, 0, 80, 80 }); bgBg->setContentSize({ 400.0f, 70.0f }); - bgBg->setPosition(200.0f, 35.0f); + bgBg->setPosition({ 200.0f, 35.0f }); bgBg->setColor(bg->getColor()); addChild(bgBg, -2); } diff --git a/src/classes/LogLayer.cpp b/src/classes/LogLayer.cpp index bf29e22..32691ad 100644 --- a/src/classes/LogLayer.cpp +++ b/src/classes/LogLayer.cpp @@ -18,12 +18,12 @@ bool LogLayer::setup() { auto background = CCScale9Sprite::create("square02_001.png", { 0, 0, 80, 80 }); background->setContentSize({ 400.0f, 230.0f }); - background->setPosition(220.0f, 135.0f); + background->setPosition({ 220.0f, 135.0f }); background->setOpacity(127); m_mainLayer->addChild(background); auto scrollLayer = ScrollLayer::create({ 400.0f, 230.0f }); - scrollLayer->setPosition(20.0f, 20.0f); + scrollLayer->setPosition({ 20.0f, 20.0f }); scrollLayer->m_contentLayer->setLayout( ColumnLayout::create() ->setAxisReverse(true) @@ -44,7 +44,7 @@ bool LogLayer::setup() { scrollLayer->scrollToTop(); auto topButtons = CCMenu::create(); - topButtons->setPosition(420.0f, 270.0f); + topButtons->setPosition({ 420.0f, 270.0f }); topButtons->setContentSize({ 100.0f, 30.0f }); topButtons->setAnchorPoint({ 1.0f, 0.5f }); topButtons->setLayout( diff --git a/src/hooks/GJGarageLayer.cpp b/src/hooks/GJGarageLayer.cpp index 5f5a1db..90a98dc 100644 --- a/src/hooks/GJGarageLayer.cpp +++ b/src/hooks/GJGarageLayer.cpp @@ -1,4 +1,5 @@ #include "../MoreIcons.hpp" +#include "../classes/ButtonHooker.hpp" #include "../classes/LogLayer.hpp" using namespace geode::prelude; @@ -9,8 +10,6 @@ class $modify(MIGarageLayer, GJGarageLayer) { ListButtonBar* m_pageBar; CCMenu* m_navMenu; std::map m_pages; - SEL_MenuHandler m_originalSDISwitch; - SEL_MenuHandler m_originalSDISwap; }; static void onModify(auto& self) { @@ -37,22 +36,20 @@ class $modify(MIGarageLayer, GJGarageLayer) { if (!customIcon.empty() && MoreIconsAPI::hasIcon(customIcon, IconType::Cube)) setupCustomPage(MoreIcons::findIconPage(IconType::Cube)); else createNavMenu(); + auto shardsMenu = getChildByID("shards-menu"); if (sdi) { if (auto playerButtonsMenu = getChildByID("player-buttons-menu")) { auto p1Button = static_cast(playerButtonsMenu->getChildByID("player1-button")); auto p2Button = static_cast(playerButtonsMenu->getChildByID("player2-button")); if (p1Button && p2Button) { - f->m_originalSDISwitch = p2Button->m_pfnSelector; - p1Button->m_pfnSelector = menu_selector(MIGarageLayer::newOn2PToggle); - p2Button->m_pfnSelector = menu_selector(MIGarageLayer::newOn2PToggle); + ButtonHooker::create(p1Button, this, menu_selector(MIGarageLayer::onSelectTab)); + ButtonHooker::create(p2Button, this, menu_selector(MIGarageLayer::onSelectTab)); } } - if (auto shardsMenu = getChildByID("shards-menu")) { - if (auto swap2PButton = static_cast(shardsMenu->getChildByID("swap-2p-button"))) { - f->m_originalSDISwap = swap2PButton->m_pfnSelector; - swap2PButton->m_pfnSelector = menu_selector(MIGarageLayer::newSwap2PKit); - } + if (shardsMenu) { + if (auto swap2PButton = static_cast(shardsMenu->getChildByID("swap-2p-button"))) + ButtonHooker::create(swap2PButton, this, menu_selector(MIGarageLayer::newSwap2PKit)); } } @@ -69,12 +66,9 @@ class $modify(MIGarageLayer, GJGarageLayer) { severitySprite->setScale(0.6f); moreIconsSprite->addChild(severitySprite, 1); } - auto moreIconsButton = CCMenuItemExt::createSpriteExtra(moreIconsSprite, [this](auto) { - if (!MoreIcons::LOGS.empty()) LogLayer::create()->show(); - else MoreIcons::showInfoPopup(true); - }); + auto moreIconsButton = CCMenuItemSpriteExtra::create(moreIconsSprite, this, menu_selector(MIGarageLayer::onMoreIcons)); moreIconsButton->setID("more-icons-button"_spr); - if (auto shardsMenu = getChildByID("shards-menu")) { + if (shardsMenu) { shardsMenu->addChild(moreIconsButton); shardsMenu->updateLayout(); } @@ -82,6 +76,11 @@ class $modify(MIGarageLayer, GJGarageLayer) { return true; } + void onMoreIcons(CCObject* sender) { + if (!MoreIcons::LOGS.empty()) LogLayer::create()->show(); + else MoreIcons::showInfoPopup(true); + } + void onSelect(CCObject* sender) { auto btn = static_cast(sender); if (btn->getUserObject("name"_spr)) { @@ -98,16 +97,10 @@ class $modify(MIGarageLayer, GJGarageLayer) { } void newOn2PToggle(CCObject* sender) { - auto f = m_fields.self(); - (this->*f->m_originalSDISwitch)(sender); - - setupCustomPage(f->m_pages[m_iconType]); + setupCustomPage(m_fields->m_pages[m_iconType]); } void newSwap2PKit(CCObject* sender) { - auto f = m_fields.self(); - (this->*f->m_originalSDISwap)(sender); - MoreIcons::swapDual("icon"); MoreIcons::swapDual("ship"); MoreIcons::swapDual("ball"); @@ -123,7 +116,7 @@ class $modify(MIGarageLayer, GJGarageLayer) { auto lastmode = (IconType)Loader::get()->getLoadedMod("weebify.separate_dual_icons")->getSavedValue("lastmode", 0); MoreIconsAPI::updateSimplePlayer(static_cast(getChildByID("player2-icon")), Mod::get()->getSavedValue(MoreIconsAPI::savedForType(lastmode, true), ""), lastmode); - setupCustomPage(f->m_pages[m_iconType]); + setupCustomPage(m_fields->m_pages[m_iconType]); } void updatePlayerColors() { @@ -137,7 +130,7 @@ class $modify(MIGarageLayer, GJGarageLayer) { auto winSize = CCDirector::get()->getWinSize(); if (!f->m_navMenu) { f->m_navMenu = CCMenu::create(); - f->m_navMenu->setPosition(winSize.width / 2, 15.0f); + f->m_navMenu->setPosition({ winSize.width / 2, 15.0f }); f->m_navMenu->setLayout(RowLayout::create()->setGap(6.0f)->setAxisAlignment(AxisAlignment::Center)); f->m_navMenu->setContentSize({ winSize.width - 60.0f, 20.0f }); f->m_navMenu->setID("navdot-menu"_spr); @@ -353,19 +346,17 @@ class $modify(MIGarageLayer, GJGarageLayer) { } auto unlockType = GameManager::get()->iconTypeToUnlockType(m_iconType); auto popup = ItemInfoPopup::create(iconID, unlockType); - if (auto nameLabel = popup->m_mainLayer->getChildByType(0)) + if (auto nameLabel = static_cast(popup->m_mainLayer->getChildByID("name-label"))) nameLabel->setString(name.substr(name.find_first_of(':') + 1).c_str()); - if (auto achLabel = popup->m_mainLayer->getChildByType(1)) achLabel->setString("Custom"); - if (auto popupIcon = findFirstChildRecursive(popup->m_mainLayer, [](auto) { return true; })) + if (auto achLabel = static_cast(popup->m_mainLayer->getChildByID("achievement-label"))) achLabel->setString("Custom"); + if (auto popupIcon = static_cast(popup->m_mainLayer->getChildByIDRecursive("item-icon"))) MoreIconsAPI::updateSimplePlayer(popupIcon->m_player, name, m_iconType); - if (auto descText = popup->m_mainLayer->getChildByType