Compare commits

...

12 commits

Author SHA1 Message Date
TheSillyDoggo
468dea6346
Merge bd6bfb661f into 6e11d0a6b0 2024-11-16 18:59:57 +01:00
HJfod
6e11d0a6b0 Merge branch 'main' of https://github.com/geode-sdk/geode into main
Some checks are pending
Build Binaries / Build Windows (push) Waiting to run
Build Binaries / Build macOS (push) Waiting to run
Build Binaries / Build Android (64-bit) (push) Waiting to run
Build Binaries / Build Android (32-bit) (push) Waiting to run
Build Binaries / Publish (push) Blocked by required conditions
2024-11-16 18:37:32 +02:00
HJfod
c94a533d1c fix updating causing the ui to lag out like hell 2024-11-16 18:36:45 +02:00
HJfod
b9fb2f6778 fix CCCallFuncExt 2024-11-16 18:36:34 +02:00
acaruso-xx
3fa91241aa
Add missing CCHttpRequest members and member functions (#1161) 2024-11-16 16:37:49 +01:00
HJfod
302eea1f47 disable enable button on outdated mods 2024-11-16 16:22:03 +02:00
Rod
06eb32310c
Changed PortuguesePT to Portuguese (#1160)
* Added Portuguese Portuguese

* sry i forgot this

* idk

* fixed bug

* fix

* fixed portuguese

* removed portuguese extra

---------

Co-authored-by: OmgRod <rlimafonseca2010@gmail.com>
Co-authored-by: Cvolton <cvolton@cvolton.eu>
2024-11-16 14:14:12 +01:00
Rod
a7f15bcc01
Added pt-pt (#1158)
Some checks are pending
Build Binaries / Build Windows (push) Waiting to run
Build Binaries / Build macOS (push) Waiting to run
Build Binaries / Build Android (64-bit) (push) Waiting to run
Build Binaries / Build Android (32-bit) (push) Waiting to run
Build Binaries / Publish (push) Blocked by required conditions
* Added Portuguese Portuguese

* sry i forgot this

---------

Co-authored-by: OmgRod <rlimafonseca2010@gmail.com>
2024-11-16 13:21:57 +01:00
altalk23
5919c7e09a i love tab! 2024-11-16 15:04:25 +03:00
altalk23
17bf7722c9 fix before/after priority stuff 2024-11-16 14:53:21 +03:00
Explodingbill
bd6bfb661f asdf 2024-11-16 15:03:10 +11:00
Explodingbill
03e8220dfe Add OverlayManager 2024-11-16 13:48:59 +11:00
12 changed files with 356 additions and 83 deletions

View file

@ -0,0 +1,16 @@
!insertmacro LANGFILE_EXT Portuguese
!pragma warning disable 6030
${LangFileString} MUI_TEXT_WELCOME_INFO_TEXT "O instalador irá guiá-lo através da instalação de $(^NameDA).$\r$\n$\r$\nAntes de iniciar a instalação, certifique-se de que o Geometry Dash não está aberto.$\r$\n$\r$\n$_CLICK"
${LangFileString} MUI_UNTEXT_WELCOME_INFO_TEXT "O instalador irá guiá-lo através da desinstalação de $(^NameDA).$\r$\n$\r$\nAntes de iniciar a desinstalação, certifique-se de que o Geometry Dash não está aberto.$\r$\n$\r$\n$_CLICK"
!pragma warning default 6030
; installer
${LangFileString} GEODE_TEXT_GD_MISSING "$\r$\n$\r$\nEsse caminho não tem o Geometry Dash instalado!"
${LangFileString} GEODE_TEXT_GD_OLD "$\r$\n$\r$\nA sua versão do Geometry Dash é demasiado antiga para esta versão do Geode!"
${LangFileString} GEODE_TEXT_MOD_LOADER_ALREADY_INSTALLED "Esse caminho já tem outros mods instalados!$\r$\nEles serão substituídos pelo Geode. (the dll trademark)"
; uninstaller
${LangFileString} GEODE_UNTEXT_GEODE_MISSING "Esse caminho não tem o Geode instalado!"

View file

@ -58,6 +58,7 @@
!insertmacro GEODE_LANGUAGE "Polish"
!insertmacro GEODE_LANGUAGE "Russian"
!insertmacro GEODE_LANGUAGE "PortugueseBR"
!insertmacro GEODE_LANGUAGE "Portuguese"
!insertmacro GEODE_LANGUAGE "Ukrainian"
!insertmacro GEODE_LANGUAGE "Czech"
!insertmacro GEODE_LANGUAGE "Turkish"

View file

@ -28,6 +28,8 @@
#include "../../include/cocos2d.h"
#include "../ExtensionMacros.h"
enum class GJHttpType;
NS_CC_EXT_BEGIN
class CC_DLL CCHttpClient;
@ -216,6 +218,50 @@ public:
return _headers;
}
inline int getType() {
return _type;
}
inline void setType(int type) {
_type = type;
}
// @note Geode addition
inline void setType(GJHttpType type) {
_type = static_cast<int>(type);
}
inline bool getShouldCancel() {
return _shouldCancel;
}
inline void setShouldCancel(bool shouldCancel) {
_shouldCancel = shouldCancel;
}
inline int getDownloadProgress() {
return _downloadProgress;
}
inline void setDownloadProgress(int downloadProgress) {
_downloadProgress = downloadProgress;
}
inline int getReadTimeout() {
return _readTimeout;
}
inline void setReadTimeout(int readTimeout) {
_readTimeout = readTimeout;
}
inline int getConnectTimeout() {
return _connectTimeout;
}
inline void setConnectTimeout(int connectTimeout) {
_connectTimeout = connectTimeout;
}
protected:
// properties
@ -229,13 +275,15 @@ protected:
gd::vector<gd::string> _headers; /// custom http headers
// @note RobTop Addition
int _requestTypeGJ;
int _type;
// @note RobTop Addition
bool _shouldCancel;
// @note RobTop Addition
int _downloadProgress;
// @note RobTop Addition
int _readTimeout;
// @note RobTop Addition
int _connectTimeout;
};
NS_CC_EXT_END

View file

@ -145,18 +145,19 @@ namespace geode::modifier {
/// @brief Get a hook by name
/// @param name The name of the hook to get
/// @returns Ok if the hook was found, Err if the hook was not found
Result<Hook*> getHook(std::string const& name) {
if (m_hooks.find(name) == m_hooks.end()) {
Result<Hook*> getHook(std::string_view name) {
auto key = std::string(name);
if (m_hooks.find(key) == m_hooks.end()) {
return Err("Hook not in this modify");
}
return Ok(m_hooks[name].get());
return Ok(m_hooks[key].get());
}
/// @brief Set the priority of a hook
/// @param name The name of the hook to set the priority of
/// @param priority The priority to set the hook to
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
Result<> setHookPriority(std::string const& name, int32_t priority = Priority::Normal) {
Result<> setHookPriority(std::string_view name, int32_t priority = Priority::Normal) {
GEODE_UNWRAP_INTO(auto hook, this->getHook(name));
hook->setPriority(priority);
return Ok();
@ -166,7 +167,7 @@ namespace geode::modifier {
/// @param name The name of the hook to set the priority of
/// @param priority The priority to set the hook to
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
Result<> setHookPriorityPre(std::string const& name, int32_t priority = Priority::Normal) {
Result<> setHookPriorityPre(std::string_view name, int32_t priority = Priority::Normal) {
return this->setHookPriority(name, priority);
}
@ -174,104 +175,144 @@ namespace geode::modifier {
/// @param name The name of the hook to set the priority of
/// @param priority The priority to set the hook to
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
Result<> setHookPriorityPost(std::string const& name, int32_t priority = Priority::Normal) {
Result<> setHookPriorityPost(std::string_view name, int32_t priority = Priority::Normal) {
return this->setHookPriority(name, -priority);
}
/// @brief Set the priority of a hook to be after another hook in different mods
/// @param name The name of the hook to set the priority of
/// @param after The mod ids of the mods to set the priority after
/// @param after The mod to set the priority after
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
template<class... C> requires (std::is_convertible_v<C, std::string> && ...)
Result<> setHookPriorityAfter(std::string const& name, C&&... after) {
Result<> setHookPriorityAfter(std::string_view name, Mod* mod) {
GEODE_UNWRAP_INTO(auto hook, this->getHook(name));
([&](){
auto mod = Loader::get()->getInstalledMod(after);
if (!mod) return;
auto func = [=](ModStateEvent* event){
auto hooks = mod->getHooks();
auto func = [=](){
for (auto modHook : hooks) {
if (modHook->getAddress() != hook->getAddress()) continue;
auto priority = hook->getPriority();
if (priority < modHook->getPriority()) {
hook->setPriority(modHook->getPriority() + 1);
}
for (auto modHook : hooks) {
if (modHook->getAddress() != hook->getAddress()) continue;
auto priority = modHook->getPriority();
if (hook->getPriority() <= priority) {
hook->setPriority(priority + 1);
}
};
if (Loader::get()->isModLoaded(mod)) {
func();
}
else {
new EventListener(func, ModStateFilter(mod, ModEventType::Loaded));
}
} (), ...);
return Ok();
}
/// @brief Set the priority of a hook to be before another hook in different mods
/// @param name The name of the hook to set the priority of
/// @param before The mod ids of the mods to set the priority before
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
template<class... C> requires (std::is_convertible_v<C, std::string> && ...)
Result<> setHookPriorityBefore(std::string const& name, C&&... before) {
GEODE_UNWRAP_INTO(auto hook, this->getHook(name));
([&](){
auto mod = Loader::get()->getInstalledMod(before);
if (!mod) return;
auto hooks = mod->getHooks();
auto func = [=](){
for (auto modHook : hooks) {
if (modHook->getAddress() != hook->getAddress()) continue;
auto priority = hook->getPriority();
if (priority > modHook->getPriority()) {
hook->setPriority(modHook->getPriority() - 1);
}
}
};
if (Loader::get()->isModLoaded(mod)) {
func();
}
else {
new EventListener(func, ModStateFilter(mod, ModEventType::Loaded));
}
} (), ...);
return ListenerResult::Propagate;
};
if (mod->isEnabled()) {
func(nullptr);
}
else {
new EventListener(func, ModStateFilter(mod, ModEventType::Loaded));
}
return Ok();
}
/// @brief Set the priority of a hook to be after another hook in different mods
/// @param name The name of the hook to set the priority of
/// @param after The mod ids of the mods to set the priority after
/// @param after The mod id of the mod to set the priority after
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
template<class... C> requires (std::is_convertible_v<C, std::string> && ...)
Result<> setHookPriorityAfterPre(std::string const& name, C&&... after) {
return this->setHookPriorityAfter(name, Priority::NormalPre, std::forward<C>(after)...);
Result<> setHookPriorityAfter(std::string_view name, std::string_view after) {
auto mod = Loader::get()->getInstalledMod(std::string(after));
if (!mod) return Err("Mod not found");
return this->setHookPriorityAfter(name, mod);
}
/// @brief Set the priority of a hook to be before another hook in different mods
/// @param name The name of the hook to set the priority of
/// @param before The mod ids of the mods to set the priority before
/// @param before The mod to set the priority before
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
template<class... C> requires (std::is_convertible_v<C, std::string> && ...)
Result<> setHookPriorityBeforePre(std::string const& name, C&&... before) {
return this->setHookPriorityBefore(name, Priority::NormalPre, std::forward<C>(before)...);
Result<> setHookPriorityBefore(std::string_view name, Mod* mod) {
GEODE_UNWRAP_INTO(auto hook, this->getHook(name));
auto func = [=](ModStateEvent* event){
auto hooks = mod->getHooks();
for (auto modHook : hooks) {
if (modHook->getAddress() != hook->getAddress()) continue;
auto priority = modHook->getPriority();
if (hook->getPriority() >= priority) {
hook->setPriority(priority - 1);
}
}
return ListenerResult::Propagate;
};
if (mod->isEnabled()) {
func(nullptr);
}
else {
new EventListener(func, ModStateFilter(mod, ModEventType::Loaded));
}
return Ok();
}
/// @brief Set the priority of a hook to be before another hook in different mods
/// @param name The name of the hook to set the priority of
/// @param before The mod id of the mod to set the priority before
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
Result<> setHookPriorityBefore(std::string_view name, std::string_view before) {
auto mod = Loader::get()->getInstalledMod(std::string(before));
if (!mod) return Err("Mod not found");
return this->setHookPriorityBefore(name, mod);
}
/// @brief Set the priority of a hook to be after another hook in different mods
/// @param name The name of the hook to set the priority of
/// @param after The mod ids of the mods to set the priority after
/// @param after The mod id of the mod to set the priority after
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
template<class... C> requires (std::is_convertible_v<C, std::string> && ...)
Result<> setHookPriorityAfterPost(std::string const& name, C&&... after) {
return this->setHookPriorityBefore(name, Priority::NormalPost, std::forward<C>(after)...);
Result<> setHookPriorityAfterPre(std::string_view name, std::string_view after) {
return this->setHookPriorityAfter(name, after);
}
/// @brief Set the priority of a hook to be after another hook in different mods
/// @param name The name of the hook to set the priority of
/// @param before The mod to set the priority after
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
Result<> setHookPriorityAfterPre(std::string_view name, Mod* mod) {
return this->setHookPriorityAfter(name, mod);
}
/// @brief Set the priority of a hook to be before another hook in different mods
/// @param name The name of the hook to set the priority of
/// @param before The mod ids of the mods to set the priority before
/// @param before The mod id of the mod to set the priority before
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
template<class... C> requires (std::is_convertible_v<C, std::string> && ...)
Result<> setHookPriorityBeforePost(std::string const& name, C&&... before) {
return this->setHookPriorityAfter(name, Priority::NormalPost, std::forward<C>(before)...);
Result<> setHookPriorityBeforePre(std::string_view name, std::string_view before) {
return this->setHookPriorityBefore(name, before);
}
/// @brief Set the priority of a hook to be before another hook in different mods
/// @param name The name of the hook to set the priority of
/// @param before The mod to set the priority before
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
Result<> setHookPriorityBeforePre(std::string_view name, Mod* mod) {
return this->setHookPriorityBefore(name, mod);
}
/// @brief Set the priority of a hook to be after another hook in different mods
/// @param name The name of the hook to set the priority of
/// @param after The mod id of the mod to set the priority after
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
Result<> setHookPriorityAfterPost(std::string_view name, std::string_view after) {
return this->setHookPriorityBefore(name, after);
}
/// @brief Set the priority of a hook to be after another hook in different mods
/// @param name The name of the hook to set the priority of
/// @param before The mod to set the priority after
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
Result<> setHookPriorityAfterPost(std::string_view name, Mod* mod) {
return this->setHookPriorityBefore(name, mod);
}
/// @brief Set the priority of a hook to be before another hook in different mods
/// @param name The name of the hook to set the priority of
/// @param before The mod id of the mod to set the priority before
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
Result<> setHookPriorityBeforePost(std::string_view name, std::string_view before) {
return this->setHookPriorityAfter(name, before);
}
/// @brief Set the priority of a hook to be before another hook in different mods
/// @param name The name of the hook to set the priority of
/// @param before The mod to set the priority before
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
Result<> setHookPriorityBeforePost(std::string_view name, Mod* mod) {
return this->setHookPriorityAfter(name, mod);
}
// unordered_map<handles> idea

View file

@ -0,0 +1,41 @@
#pragma once
#include "../DefaultInclude.hpp"
#include <cocos2d.h>
#include <vector>
#include <span>
#include <Geode/utils/cocos.hpp>
namespace geode
{
/*
Because cocos only allows for one notification node (a node drawn last, above the fps counter and everything),
I added this, a simple class to add nodes to a general notification node so that mods dont interfere with each other.
*/
class GEODE_DLL OverlayManager : private cocos2d::CCNode
{
private:
std::vector<cocos2d::CCNode*> nodes;
public:
/// @brief Get the overlay manager instance, and if it doesnt exist, sets the notification node to it
static OverlayManager* get();
/// @brief Adds a node to the overlay manager, overlays are sorted by ZOrder, the higher the order is the later it draws. This will retain the node
void addNode(cocos2d::CCNode* node);
/// @brief Removes a node from the overlay manager, stopping it from being drawn. This will release the node
void removeNode(cocos2d::CCNode* node);
/// @brief Util to get the highest ZOrder of all nodes
int getHighestOverlayZOrder();
/// @brief Util to get the lowest ZOrder of all nodes
int getLowestOverlayZOrder();
/// @brief Gets all the overlays
std::vector<cocos2d::CCNode*> getOverlays();
};
};

View file

@ -1331,15 +1331,13 @@ namespace geode::cocos {
class CallFuncExtImpl : public cocos2d::CCActionInstant {
public:
static CallFuncExtImpl* create(const F& func) {
auto ret = new CallFuncExtImpl;
ret->m_func = func;
auto ret = new CallFuncExtImpl(func);
ret->autorelease();
return ret;
}
static CallFuncExtImpl* create(F&& func) {
auto ret = new CallFuncExtImpl;
ret->m_func = std::move(func);
auto ret = new CallFuncExtImpl(std::move(func));
ret->autorelease();
return ret;
}
@ -1347,8 +1345,17 @@ namespace geode::cocos {
private:
F m_func;
// F may not be default-constructible
CallFuncExtImpl(F&& func) : m_func(std::move(func)) {}
CallFuncExtImpl(F const& func) : m_func(func) {}
void update(float) override {
if (m_func) this->m_func();
// Make sure any `std::function`s are valid
if constexpr (requires { static_cast<bool>(m_func); }) {
if (m_func) m_func();
} else {
m_func();
}
}
};

View file

@ -28,6 +28,7 @@ public:
DownloadStatus m_status;
EventListener<ServerRequest<ServerModVersion>> m_infoListener;
EventListener<web::WebTask> m_downloadListener;
unsigned int m_scheduledEventForFrame = 0;
Impl(
std::string const& id,
@ -83,7 +84,14 @@ public:
}
if (!ModDownloadManager::get()->checkAutoConfirm()) {
ModDownloadEvent(m_id).post();
// Throttle events to only once per frame to not cause a
// billion UI updates at once
if (m_scheduledEventForFrame != CCDirector::get()->getTotalFrames()) {
m_scheduledEventForFrame = CCDirector::get()->getTotalFrames();
Loader::get()->queueInMainThread([id = m_id]() {
ModDownloadEvent(id).post();
});
}
}
});
auto fetchVersion = version.has_value() ? ModVersion(*version) : ModVersion(ModVersionLatest());
@ -157,7 +165,14 @@ public:
else if (event->isCancelled()) {
m_status = DownloadStatusCancelled();
}
ModDownloadEvent(m_id).post();
// Throttle events to only once per frame to not cause a
// billion UI updates at once
if (m_scheduledEventForFrame != CCDirector::get()->getTotalFrames()) {
m_scheduledEventForFrame = CCDirector::get()->getTotalFrames();
Loader::get()->queueInMainThread([id = m_id]() {
ModDownloadEvent(id).post();
});
}
});
auto req = web::WebRequest();

View file

@ -466,8 +466,12 @@ void ModItem::updateState() {
if (m_enableToggle && m_source.asMod()) {
m_enableToggle->toggle(m_source.asMod()->isOrWillBeEnabled());
// Disable the toggle if the mod has been uninstalled
if (modRequestedActionIsUninstall(m_source.asMod()->getRequestedAction())) {
// Disable the toggle if the mod has been uninstalled or if the mod is
// outdated
if (
modRequestedActionIsUninstall(m_source.asMod()->getRequestedAction()) ||
m_source.asMod()->targetsOutdatedVersion()
) {
m_enableToggle->setEnabled(false);
auto off = typeinfo_cast<CCRGBAProtocol*>(m_enableToggle->m_offButton->getNormalImage());
auto on = typeinfo_cast<CCRGBAProtocol*>(m_enableToggle->m_onButton->getNormalImage());

View file

@ -672,7 +672,11 @@ void ModPopup::updateState() {
m_cancelBtn->setVisible(false);
m_enableBtn->toggle(asMod && asMod->isOrWillBeEnabled());
m_enableBtn->setVisible(asMod && asMod->getRequestedAction() == ModRequestedAction::None);
m_enableBtn->setVisible(
asMod &&
asMod->getRequestedAction() == ModRequestedAction::None &&
!asMod->targetsOutdatedVersion()
);
m_reenableBtn->toggle(m_enableBtn->isToggled());
m_reenableBtn->setVisible(asMod && modRequestedActionIsToggle(asMod->getRequestedAction()));

View file

@ -0,0 +1,62 @@
#include <Geode/ui/OverlayManager.hpp>
using namespace geode::prelude;
OverlayManager* OverlayManager::get()
{
static OverlayManager* instance;
if (!instance)
{
instance = new OverlayManager();
CCDirector::get()->setNotificationNode(instance);
}
return instance;
}
void OverlayManager::addNode(CCNode* node)
{
this->addChild(node);
nodes.push_back(node);
}
void OverlayManager::removeNode(CCNode* node)
{
this->removeChild(node);
std::erase(nodes, node);
}
int OverlayManager::getHighestOverlayZOrder()
{
int z = INT_MIN;
for (auto node : nodes)
{
if (node->getZOrder() > z)
z = node->getZOrder();
}
return z;
}
int OverlayManager::getLowestOverlayZOrder()
{
int z = INT_MAX;
for (auto node : nodes)
{
if (node->getZOrder() < z)
z = node->getZOrder();
}
return z;
}
std::vector<CCNode*> OverlayManager::getOverlays()
{
return nodes;
}

View file

@ -160,6 +160,38 @@ struct MyMenuLayer : Modify<MyMenuLayer, MenuLayer> {
}
};
struct AfterMenuLayer : Modify<AfterMenuLayer, MenuLayer> {
static void onModify(auto& self) {
if (self.setHookPriorityAfterPost("MenuLayer::init", "geode.test")) {
log::debug("priority set after test");
}
}
bool init() {
if (!MenuLayer::init()) return false;
log::debug("should run third!");
return true;
}
};
struct BeforeMenuLayer : Modify<BeforeMenuLayer, MenuLayer> {
static void onModify(auto& self) {
if (self.setHookPriorityBeforePost("MenuLayer::init", "geode.test")) {
log::debug("priority set before test");
}
}
bool init() {
if (!MenuLayer::init()) return false;
log::debug("should run first!");
return true;
}
};
$on_mod(Loaded) {
// Mod::get()->addCustomSetting<MySettingValue>("overcast-skies", DEFAULT_ICON);

View file

@ -58,6 +58,8 @@ struct $modify(MenuLayer) {
log::info("Loader flag 'bool-arg': {}", Loader::get()->getLaunchFlag("bool-arg"));
log::info("Loader int 'int-arg': {}", Loader::get()->parseLaunchArgument<int>("int-arg").unwrapOr(0));
log::debug("should run second!");
return true;
}
};