Skip to content

Commit

Permalink
The ACTUAL fix
Browse files Browse the repository at this point in the history
  • Loading branch information
hiimjustin000 committed Oct 25, 2024
1 parent 630de24 commit b14f665
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 66 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64")
set(CMAKE_CXX_VISIBILITY_PRESET hidden)

project(IntegratedDemonlist VERSION 1.6.4)
project(IntegratedDemonlist VERSION 1.6.5)

add_library(${PROJECT_NAME} SHARED
src/IDListLayer.cpp
Expand Down
5 changes: 5 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# Integrated Demonlist Changelog
## v1.6.5 (2024-10-25)
- Fixed two-player demons not appearing in the demonlist twice (Someone wanted this for some reason)
- Permanently fixed the Pemonlist issue (New API)
- Fixed the star and moon buttons reloading the demonlist

## v1.6.4 (2024-10-24)
- Temporarily fixed a crashing issue with the Pemonlist that would cause the game to not launch

Expand Down
7 changes: 5 additions & 2 deletions mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"win": "2.206",
"mac": "2.206"
},
"version": "v1.6.4",
"version": "v1.6.5",
"id": "hiimjustin000.integrated_demonlist",
"name": "Integrated Demonlist",
"developer": "hiimjustin000",
Expand Down Expand Up @@ -43,6 +43,9 @@
},
"tags": [
"content",
"online"
"enhancement",
"interface",
"online",
"utility"
]
}
6 changes: 4 additions & 2 deletions src/IDListLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ bool IDListLayer::init() {
m_infoButton->m_title = "All Rated Extreme Demons List";
m_infoButton->m_description = AREDL_INFO;
m_fullSearchResults.clear();
IntegratedDemonlist::loadAREDL(std::move(m_aredlListener), std::move(m_aredlOkListener), m_loadingCircle, [this] { page(0); });
if (!IntegratedDemonlist::AREDL.empty()) page(0);
else IntegratedDemonlist::loadAREDL(std::move(m_aredlListener), std::move(m_aredlOkListener), m_loadingCircle, [this] { page(0); });
});
m_starToggle->setPosition(30.0f, 60.0f);
m_starToggle->setColor(PEMONLIST ? ccColor3B { 125, 125, 125 } : ccColor3B { 255, 255, 255 });
Expand All @@ -123,7 +124,8 @@ bool IDListLayer::init() {
m_infoButton->m_title = "Pemonlist";
m_infoButton->m_description = PEMONLIST_INFO;
m_fullSearchResults.clear();
IntegratedDemonlist::loadPemonlist(std::move(m_pemonlistListener), std::move(m_pemonlistOkListener), m_loadingCircle, [this] { page(0); });
if (!IntegratedDemonlist::PEMONLIST.empty()) page(0);
else IntegratedDemonlist::loadPemonlist(std::move(m_pemonlistListener), std::move(m_pemonlistOkListener), m_loadingCircle, [this] { page(0); });
});
m_moonToggle->setPosition(60.0f, 60.0f);
m_moonToggle->setColor(PEMONLIST ? ccColor3B { 255, 255, 255 } : ccColor3B { 125, 125, 125 });
Expand Down
4 changes: 2 additions & 2 deletions src/IDListLayer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ class IDListLayer : public CCLayer, SetIDPopupDelegate, LevelManagerDelegate {
inline static bool PEMONLIST = false;
inline static const char* AREDL_INFO =
"The <cg>All Rated Extreme Demons List</c> (<cg>AREDL</c>) is an <cp>unofficial ranking</c> of all rated <cj>classic mode</c> <cr>extreme demons</c> in Geometry Dash.\n"
"It is managed by <cy>Kuro</c> and <cy>Padahk</c>.";
"It is managed by <cy>Padahk</c> and <cy>ley</c>.";
inline static const char* PEMONLIST_INFO =
"The <cg>Pemonlist</c> is an <cp>unofficial ranking</c> of all rated <cj>platformer mode</c> <cr>demons</c> in Geometry Dash.\n"
"It is managed by <cy>camila314</c>, <cy>Extatica</c>, <cy>IvanCrafter026</c>, and <cy>Voiddle</c>.";
"It is managed by <cy>camila314</c>, <cy>Extatica</c>, <cy>IvanCrafter026</c>, <cy>Megu</c>, and <cy>Voiddle</c>.";
public:
static IDListLayer* create();
static CCScene* scene();
Expand Down
71 changes: 49 additions & 22 deletions src/IntegratedDemonlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,44 @@

#define AREDL_URL "https://api.aredl.net/api/aredl/levels"
#define AREDL_PACKS_URL "https://api.aredl.net/api/aredl/packs"
#define PEMONLIST_URL "https://pemonlist.com/api/list?version=1"
#define PEMONLIST_UPTIME_URL "https://pemonlist.com/api/uptime?version=2"
#define PEMONLIST_URL "https://pemonlist.com/api/list?limit=500&version=2"

void IntegratedDemonlist::initializeDemons(web::WebResponse* res, bool pemonlist) {
auto& list = pemonlist ? PEMONLIST : AREDL;
list.clear();
void IntegratedDemonlist::initializeAREDL(web::WebResponse* res) {
AREDL.clear();
auto str = res->string().value();
std::string error;
auto json = matjson::parse(str, error).value_or(matjson::Array());
if (!error.empty()) log::error("Failed to parse {}: {}", pemonlist ? "Pemonlist" : "AREDL", error);
if (!error.empty()) log::error("Failed to parse AREDL: {}", error);
if (json.is_array()) for (auto const& level : json.as_array()) {
if (pemonlist || ((!level.contains("legacy") || !level["legacy"].as_bool()) && !level["two_player"].as_bool())) list.push_back({
if (level.contains("legacy") && level["legacy"].is_bool() && level["legacy"].as_bool()) continue;
if (!level.contains("level_id") || !level["level_id"].is_number()) continue;
if (!level.contains("name") || !level["name"].is_string()) continue;
if (!level.contains("position") || !level["position"].is_number()) continue;

AREDL.push_back({
level["level_id"].as_int(),
level["name"].as_string(),
level[pemonlist ? "placement" : "position"].as_int()
level["position"].as_int()
});
}
}

void IntegratedDemonlist::initializePemonlist(web::WebResponse* res) {
PEMONLIST.clear();
auto str = res->string().value();
std::string error;
auto json = matjson::parse(str, error).value_or(matjson::Object { { "data", matjson::Array() } });
if (!error.empty()) log::error("Failed to parse Pemonlist: {}", error);
if (json.is_object() && json.contains("data") && json["data"].is_array()) for (auto const& level : json["data"].as_array()) {
if (!level.contains("level_id") || !level["level_id"].is_number()) continue;
if (!level.contains("name") || !level["name"].is_string()) continue;
if (!level.contains("placement") || !level["placement"].is_number()) continue;

PEMONLIST.push_back({
level["level_id"].as_int(),
level["name"].as_string(),
level["placement"].as_int()
});
}
}
Expand All @@ -25,20 +49,22 @@ void IntegratedDemonlist::isOk(std::string const& url, EventListener<web::WebTas
listener.bind([callback](web::WebTask::Event* e) {
if (auto res = e->getValue()) callback(res->ok(), res->code());
});
listenerRef.setFilter(web::WebRequest().send("HEAD", url));
listenerRef.setFilter(web::WebRequest().downloadRange({ 0, 0 }).get(url));
}

void IntegratedDemonlist::loadAREDL() {
static std::optional<web::WebTask> task = std::nullopt;
static std::optional<web::WebTask> okTask = std::nullopt;
okTask = web::WebRequest().send("HEAD", AREDL_URL).map([](web::WebResponse* res) {
okTask = web::WebRequest().downloadRange({ 0, 0 }).get(AREDL_URL).map([](web::WebResponse* res) {
if (!res->ok()) {
log::error("Failed to load AREDL with status code {}", res->code());
okTask = std::nullopt;
return *res;
}

task = web::WebRequest().get(AREDL_URL).map([](web::WebResponse* res2) {
if (res2->ok()) initializeDemons(res2, false);
if (res2->ok()) initializeAREDL(res2);
else log::error("Failed to load AREDL with status code {}", res2->code());

task = std::nullopt;
return *res2;
Expand All @@ -57,7 +83,7 @@ void IntegratedDemonlist::loadAREDL(
listener.bind([callback](web::WebTask::Event* e) {
if (auto res = e->getValue()) {
if (res->ok()) {
initializeDemons(res, false);
initializeAREDL(res);
callback();
}
}
Expand Down Expand Up @@ -107,24 +133,25 @@ void IntegratedDemonlist::loadAREDLPacks(

void IntegratedDemonlist::loadPemonlist() {
static std::optional<web::WebTask> task = std::nullopt;
/*static std::optional<web::WebTask> okTask = std::nullopt;
okTask = web::WebRequest().send("HEAD", PEMONLIST_URL).map([](web::WebResponse* res) {
static std::optional<web::WebTask> okTask = std::nullopt;
okTask = web::WebRequest().downloadRange({ 0, 0 }).get(PEMONLIST_UPTIME_URL).map([](web::WebResponse* res) {
if (!res->ok()) {
log::error("Failed to load Pemonlist with status code {}", res->code());
okTask = std::nullopt;
return *res;
}*/
}

task = web::WebRequest().get(PEMONLIST_URL).map([](web::WebResponse* res2) {
if (res2->ok()) initializeDemons(res2, true);
if (res2->ok()) initializePemonlist(res2);
else log::error("Failed to load Pemonlist with status code {}", res2->code());

task = std::nullopt;
return *res2;
});

/*okTask = std::nullopt;
okTask = std::nullopt;
return *res;
});*/
});
}

void IntegratedDemonlist::loadPemonlist(
Expand All @@ -135,21 +162,21 @@ void IntegratedDemonlist::loadPemonlist(
listener.bind([callback, circle](web::WebTask::Event* e) {
if (auto res = e->getValue()) {
if (res->ok()) {
initializeDemons(res, true);
initializePemonlist(res);
callback();
}
else Loader::get()->queueInMainThread([circle, res] {
FLAlertLayer::create("Load Failed ({})", fmt::format("Failed to load Pemonlist. Please try again later.", res->code()).c_str(), "OK")->show();
FLAlertLayer::create(fmt::format("Load Failed ({})", res->code()).c_str(), "Failed to load Pemonlist. Please try again later.", "OK")->show();
circle->setVisible(false);
});
}
});

/*isOk(PEMONLIST_URL, std::move(okListener), [&listener, circle](bool ok, int code) {
if (ok) */listener.setFilter(web::WebRequest().get(PEMONLIST_URL));/*
isOk(PEMONLIST_UPTIME_URL, std::move(okListener), [&listener, circle](bool ok, int code) {
if (ok) listener.setFilter(web::WebRequest().get(PEMONLIST_URL));
else Loader::get()->queueInMainThread([circle, code] {
FLAlertLayer::create(fmt::format("Load Failed ({})", code).c_str(), "Failed to load Pemonlist. Please try again later.", "OK")->show();
circle->setVisible(false);
});
});*/
});
}
3 changes: 2 additions & 1 deletion src/IntegratedDemonlist.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ class IntegratedDemonlist {
inline static std::vector<IDListDemon> PEMONLIST = {};
inline static bool TRIED_LOADING = false;

static void initializeDemons(web::WebResponse*, bool);
static void initializeAREDL(web::WebResponse*);
static void initializePemonlist(web::WebResponse*);
static void isOk(std::string const&, EventListener<web::WebTask>&&, MiniFunction<void(bool, int)> callback);
static void loadAREDL();
static void loadAREDL(EventListener<web::WebTask>&&, EventListener<web::WebTask>&&, LoadingCircle*, MiniFunction<void()> callback);
Expand Down
68 changes: 32 additions & 36 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#include "IDListLayer.hpp"

#include <Geode/modify/MenuLayer.hpp>
class $modify(IDMenuLayer, MenuLayer) {
#include <Geode/modify/CreatorLayer.hpp>
class $modify(IDCreatorLayer, CreatorLayer) {
bool init() {
if (!MenuLayer::init()) return false;
if (!CreatorLayer::init()) return false;

if (IntegratedDemonlist::TRIED_LOADING) return true;
IntegratedDemonlist::TRIED_LOADING = true;
Expand Down Expand Up @@ -66,54 +66,50 @@ class $modify(IDLevelCell, LevelCell) {
void loadCustomLevelCell() {
LevelCell::loadCustomLevelCell();

if (Mod::get()->getSettingValue<bool>("enable-rank")) {
auto rankText = std::string();
auto found = std::find_if(IntegratedDemonlist::AREDL.begin(), IntegratedDemonlist::AREDL.end(), [this](auto const& demon) {
return demon.id == m_level->m_levelID;
});
if (found != IntegratedDemonlist::AREDL.end()) rankText = fmt::format("#{} AREDL", found->position);
else {
found = std::find_if(IntegratedDemonlist::PEMONLIST.begin(), IntegratedDemonlist::PEMONLIST.end(), [this](auto const& demon) {
return demon.id == m_level->m_levelID;
});
if (found != IntegratedDemonlist::PEMONLIST.end()) rankText = fmt::format("#{} Pemonlist", found->position);
}
if (!rankText.empty()) {
auto rankTextNode = CCLabelBMFont::create(rankText.c_str(), "chatFont.fnt");
rankTextNode->setPosition(346.0f, m_level->m_dailyID.value() > 0 ? 6.0f : m_compactView ? 9.0f : 12.0f);
rankTextNode->setAnchorPoint({ 1.0f, 1.0f });
rankTextNode->setScale(m_compactView ? 0.45f : 0.6f);
if (m_level->m_dailyID.value() > 0 || Mod::get()->getSettingValue<bool>("white-rank")) {
rankTextNode->setColor({ 255, 255, 255 });
rankTextNode->setOpacity(200);
}
else {
rankTextNode->setColor({ 51, 51, 51 });
rankTextNode->setOpacity(152);
}
rankTextNode->setID("level-rank-label"_spr);
m_mainLayer->addChild(rankTextNode);
}
if (m_level->m_demon.value() <= 0 || !Mod::get()->getSettingValue<bool>("enable-rank")) return;

std::vector<std::string> positions;
auto& list = m_level->m_levelLength == 5 ? IntegratedDemonlist::PEMONLIST : IntegratedDemonlist::AREDL;
for (auto const& demon : list) {
if (demon.id == m_level->m_levelID) positions.push_back(std::to_string(demon.position));
}
if (positions.empty()) return;

auto rankTextNode = CCLabelBMFont::create(fmt::format("#{} {}", string::join(positions, "/#"),
m_level->m_levelLength == 5 ? "Pemonlist" : "AREDL").c_str(), "chatFont.fnt");
rankTextNode->setPosition(346.0f, m_level->m_dailyID.value() > 0 ? 6.0f : 1.0f);
rankTextNode->setAnchorPoint({ 1.0f, 0.0f });
rankTextNode->setScale(m_compactView ? 0.45f : 0.6f);
if (m_level->m_dailyID.value() > 0 || Mod::get()->getSettingValue<bool>("white-rank")) {
rankTextNode->setColor({ 255, 255, 255 });
rankTextNode->setOpacity(200);
}
else {
rankTextNode->setColor({ 51, 51, 51 });
rankTextNode->setOpacity(152);
}
rankTextNode->setID("level-rank-label"_spr);
m_mainLayer->addChild(rankTextNode);
}
};

#include <Geode/modify/CCKeyboardDispatcher.hpp>
class $modify(IDKeyboardDispatcher, CCKeyboardDispatcher) {
bool dispatchKeyboardMSG(enumKeyCodes key, bool down, bool repeat) {
if (key == KEY_Enter && down) {
if (auto listLayer = static_cast<IDListLayer*>(CCDirector::sharedDirector()->getRunningScene()->getChildByID("IDListLayer"))) {
auto runningScene = CCDirector::sharedDirector()->getRunningScene();

if (auto listLayer = static_cast<IDListLayer*>(runningScene->getChildByID("IDListLayer"))) {
listLayer->search();
return true;
}

if (auto packLayer = static_cast<IDPackLayer*>(CCDirector::sharedDirector()->getRunningScene()->getChildByID("IDPackLayer"))) {
if (auto packLayer = static_cast<IDPackLayer*>(runningScene->getChildByID("IDPackLayer"))) {
packLayer->search();
return true;
}

return CCKeyboardDispatcher::dispatchKeyboardMSG(key, down, repeat);
}
else return CCKeyboardDispatcher::dispatchKeyboardMSG(key, down, repeat);

return CCKeyboardDispatcher::dispatchKeyboardMSG(key, down, repeat);
}
};

0 comments on commit b14f665

Please sign in to comment.