Merge branch 'main' into new-index-but-better
16
CHANGELOG.md
|
@ -1,5 +1,21 @@
|
|||
# Geode Changelog
|
||||
|
||||
## v2.0.0-beta.21
|
||||
* Fix `numFromString` for floating point numbers (6d91804)
|
||||
* Fix `ScrollLayer` cropping (5c8ee29)
|
||||
* Show featured mods on top (4e06c20)
|
||||
* Don't require admin for installer (5f8dc3a)
|
||||
* Add `char const*` and `std::string` overloads for `gd::string` (982e8ab, a19d26d)
|
||||
* Remove dithering from some textures (b9a76b3, 76a615c)
|
||||
* Replace node attributes with id based user objects (363a028)
|
||||
* Add FMOD initialization check for Android (0623563)
|
||||
* Remove deprecated values from `Permissions` (b082dd1)
|
||||
* Add a progress percentage to index unzipping (baf3a6b)
|
||||
* Fix `pushNest/popNest` not doing correct indent value (c7a1f76)
|
||||
* Optimize `DispatchEvent` to use their own pools, greatly increasing performance (d8ac85b)
|
||||
* Check for presence of children in `handleTouchPriority` (28bd757)
|
||||
* Fix floating point returns for optcall/membercall functions (dba5b01)
|
||||
|
||||
## v2.0.0-beta.20
|
||||
* Enable PCH on Mac for better compile times (dd62eac)
|
||||
* Add `numFromString` utility for safely parsing numbers (c4e9c17)
|
||||
|
|
|
@ -192,10 +192,10 @@ if (WIN32)
|
|||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
|
||||
CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
|
||||
# target x86 on windows with clang
|
||||
target_compile_options(${PROJECT_NAME} INTERFACE --target=i686-windows-msvc)
|
||||
target_link_options(${PROJECT_NAME} INTERFACE --target=i686-windows-msvc)
|
||||
add_compile_options(--target=i686-windows-msvc)
|
||||
add_link_options(--target=i686-windows-msvc)
|
||||
target_compile_options(${PROJECT_NAME} INTERFACE --target=i686-pc-windows-msvc)
|
||||
target_link_options(${PROJECT_NAME} INTERFACE --target=i686-pc-windows-msvc)
|
||||
add_compile_options(--target=i686-pc-windows-msvc)
|
||||
add_link_options(--target=i686-pc-windows-msvc)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -231,7 +231,7 @@ if (DEFINED GEODE_TULIPHOOK_REPO_PATH)
|
|||
message(STATUS "Using ${GEODE_TULIPHOOK_REPO_PATH} for TulipHook")
|
||||
add_subdirectory(${GEODE_TULIPHOOK_REPO_PATH} ${GEODE_TULIPHOOK_REPO_PATH}/build)
|
||||
else()
|
||||
CPMAddPackage("gh:geode-sdk/TulipHook#9dc223d")
|
||||
CPMAddPackage("gh:geode-sdk/TulipHook#047031e")
|
||||
endif()
|
||||
set(CMAKE_WARN_DEPRECATED ON CACHE BOOL "" FORCE)
|
||||
|
||||
|
|
2
VERSION
|
@ -1 +1 @@
|
|||
2.0.0-beta.20
|
||||
2.0.0-beta.21
|
|
@ -75,6 +75,7 @@ elseif (GEODE_TARGET_PLATFORM STREQUAL "Android32")
|
|||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} INTERFACE
|
||||
c
|
||||
${GEODE_LOADER_PATH}/include/link/android32/libcurl.a
|
||||
${GEODE_LOADER_PATH}/include/link/android32/libssl.a
|
||||
${GEODE_LOADER_PATH}/include/link/android32/libcrypto.a
|
||||
|
@ -93,6 +94,7 @@ elseif (GEODE_TARGET_PLATFORM STREQUAL "Android64")
|
|||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} INTERFACE
|
||||
c
|
||||
${GEODE_LOADER_PATH}/include/link/android64/libcurl.a
|
||||
${GEODE_LOADER_PATH}/include/link/android64/libssl.a
|
||||
${GEODE_LOADER_PATH}/include/link/android64/libcrypto.a
|
||||
|
|
10
loader/include/Geode/cocos/base_nodes/CCNode.h
vendored
|
@ -868,7 +868,17 @@ private:
|
|||
geode::EventListenerProtocol* protocol
|
||||
);
|
||||
|
||||
#ifdef GEODE_EXPORTING
|
||||
[[deprecated("Will be removed, it's an ABI break")]]
|
||||
GEODE_DLL std::optional<matjson::Value> getAttributeInternal(std::string const& attribute);
|
||||
#endif
|
||||
|
||||
public:
|
||||
#ifdef GEODE_EXPORTING
|
||||
[[deprecated("Will be removed, it's an ABI break")]]
|
||||
GEODE_DLL void setAttribute(std::string const& attribute, matjson::Value const& value);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the string ID of this node
|
||||
* @returns The ID, or an empty string if the node has no ID.
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
namespace geode {
|
||||
// Mod interoperability
|
||||
|
||||
GEODE_DLL std::unordered_map<std::string, EventListenerPool*>& dispatchPools();
|
||||
|
||||
template <class... Args>
|
||||
class DispatchEvent : public Event {
|
||||
protected:
|
||||
|
@ -26,6 +28,13 @@ namespace geode {
|
|||
std::string getID() const {
|
||||
return m_id;
|
||||
}
|
||||
|
||||
EventListenerPool* getPool() const override {
|
||||
if (dispatchPools().count(m_id) == 0) {
|
||||
dispatchPools()[m_id] = new DefaultEventListenerPool();
|
||||
}
|
||||
return dispatchPools()[m_id];
|
||||
}
|
||||
};
|
||||
|
||||
template <class... Args>
|
||||
|
@ -37,6 +46,13 @@ namespace geode {
|
|||
using Ev = DispatchEvent<Args...>;
|
||||
using Callback = ListenerResult(Args...);
|
||||
|
||||
EventListenerPool* getPool() const {
|
||||
if (dispatchPools().count(m_id) == 0) {
|
||||
dispatchPools()[m_id] = new DefaultEventListenerPool();
|
||||
}
|
||||
return dispatchPools()[m_id];
|
||||
}
|
||||
|
||||
ListenerResult handle(utils::MiniFunction<Callback> fn, Ev* event) {
|
||||
if (event->getID() == m_id) {
|
||||
return std::apply(fn, event->getArgs());
|
||||
|
|
|
@ -109,8 +109,16 @@ namespace geode {
|
|||
logImpl(Severity::Error, getMod(), str, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
GEODE_DLL void pushNest();
|
||||
GEODE_DLL void popNest();
|
||||
GEODE_DLL void pushNest(Mod* mod);
|
||||
GEODE_DLL void popNest(Mod* mod);
|
||||
|
||||
inline void pushNest() {
|
||||
pushNest(getMod());
|
||||
}
|
||||
|
||||
inline void popNest() {
|
||||
popNest(getMod());
|
||||
}
|
||||
|
||||
class Nest final {
|
||||
private:
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
#include "Mod.hpp"
|
||||
|
||||
#include <matjson.hpp>
|
||||
|
||||
namespace geode {}
|
|
@ -288,6 +288,19 @@ namespace geode {
|
|||
static T get(SettingValue* setting);
|
||||
static void set(SettingValue* setting, T const& value);
|
||||
};
|
||||
|
||||
template<class T>
|
||||
bool GeodeSettingValue<T>::load(matjson::Value const& json) {
|
||||
if (!json.is<ValueType>()) return false;
|
||||
m_value = json.as<ValueType>();
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool GeodeSettingValue<T>::save(matjson::Value& json) const {
|
||||
json = m_value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
#include "Setting.hpp"
|
||||
#include <matjson.hpp>
|
||||
|
||||
namespace geode {
|
||||
template<class T>
|
||||
bool GeodeSettingValue<T>::load(matjson::Value const& json) {
|
||||
if (!json.is<ValueType>()) return false;
|
||||
m_value = json.as<ValueType>();
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool GeodeSettingValue<T>::save(matjson::Value& json) const {
|
||||
json = m_value;
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <Geode/utils/Result.hpp>
|
||||
#include <tulip/TulipHook.hpp>
|
||||
|
||||
namespace geode::modifier {
|
||||
// template <uint32_t Id>
|
||||
// GEODE_HIDDEN uintptr_t address();
|
||||
|
||||
// Result<tulip::hook::HandlerMetadata> handlerMetadataForAddress(uintptr_t address);
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
#pragma once
|
||||
#include <Geode/Bindings.hpp>
|
||||
|
||||
namespace geode::modifier {
|
||||
// struct types {
|
||||
// #include <Geode/GeneratedType.hpp>
|
||||
// };
|
||||
}
|
|
@ -154,6 +154,16 @@ namespace geode::utils::file {
|
|||
*/
|
||||
static Result<Unzip> create(ByteVector const& data);
|
||||
|
||||
/**
|
||||
* Set a callback to be called with the progress of the unzip operation, first
|
||||
* argument is the current entry, second argument is the total entries
|
||||
* @note This is not thread-safe
|
||||
* @param callback Callback to call with the progress of the unzip operation
|
||||
*/
|
||||
void setProgressCallback(
|
||||
utils::MiniFunction<void(uint32_t, uint32_t)> callback
|
||||
);
|
||||
|
||||
/**
|
||||
* Path to the opened zip
|
||||
* @returns The path to the zip that is being read, or an empty path
|
||||
|
@ -200,6 +210,13 @@ namespace geode::utils::file {
|
|||
Path const& to,
|
||||
bool deleteZipAfter = false
|
||||
);
|
||||
|
||||
static Result<> intoDir(
|
||||
utils::MiniFunction<void(uint32_t, uint32_t)> progressCallback,
|
||||
Path const& from,
|
||||
Path const& to,
|
||||
bool deleteZipAfter = false
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,11 +6,8 @@
|
|||
|
||||
namespace geode::utils::permission {
|
||||
enum class Permission {
|
||||
ReadAudio [[deprecated("This permission is Android 13+ specific! Use ReadFiles instead.")]],
|
||||
ReadImages [[deprecated("This permission is Android 13+ specific! Use ReadFiles instead.")]],
|
||||
ReadVideo [[deprecated("This permission is Android 13+ specific! Use ReadFiles instead.")]],
|
||||
ReadAllFiles,
|
||||
RecordAudio,
|
||||
ReadAllFiles = 0x3, // maintain compatibility with some older mods
|
||||
RecordAudio
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Before ![]() (image error) Size: 26 KiB After ![]() (image error) Size: 12 KiB ![]() ![]() |
Before ![]() (image error) Size: 41 KiB After ![]() (image error) Size: 12 KiB ![]() ![]() |
Before ![]() (image error) Size: 45 KiB After ![]() (image error) Size: 11 KiB ![]() ![]() |
Before ![]() (image error) Size: 44 KiB After ![]() (image error) Size: 12 KiB ![]() ![]() |
Before ![]() (image error) Size: 32 KiB After ![]() (image error) Size: 12 KiB ![]() ![]() |
Before ![]() (image error) Size: 34 KiB After ![]() (image error) Size: 12 KiB ![]() ![]() |
Before ![]() (image error) Size: 41 KiB After ![]() (image error) Size: 12 KiB ![]() ![]() |
Before ![]() (image error) Size: 41 KiB After ![]() (image error) Size: 12 KiB ![]() ![]() |
Before ![]() (image error) Size: 25 KiB After ![]() (image error) Size: 12 KiB ![]() ![]() |
Before ![]() (image error) Size: 45 KiB After ![]() (image error) Size: 18 KiB ![]() ![]() |
Before ![]() (image error) Size: 57 KiB After ![]() (image error) Size: 18 KiB ![]() ![]() |
Before ![]() (image error) Size: 71 KiB After ![]() (image error) Size: 18 KiB ![]() ![]() |
Before ![]() (image error) Size: 42 KiB After ![]() (image error) Size: 18 KiB ![]() ![]() |
Before ![]() (image error) Size: 40 KiB After ![]() (image error) Size: 18 KiB ![]() ![]() |
Before ![]() (image error) Size: 31 KiB After ![]() (image error) Size: 11 KiB ![]() ![]() |
Before ![]() (image error) Size: 36 KiB After ![]() (image error) Size: 11 KiB ![]() ![]() |
Before ![]() (image error) Size: 41 KiB After ![]() (image error) Size: 11 KiB ![]() ![]() |
Before ![]() (image error) Size: 26 KiB After ![]() (image error) Size: 11 KiB ![]() ![]() |
Before ![]() (image error) Size: 29 KiB After ![]() (image error) Size: 11 KiB ![]() ![]() |
Before ![]() (image error) Size: 30 KiB After ![]() (image error) Size: 9.8 KiB ![]() ![]() |
Before ![]() (image error) Size: 29 KiB After ![]() (image error) Size: 9.8 KiB ![]() ![]() |
Before ![]() (image error) Size: 39 KiB After ![]() (image error) Size: 9.7 KiB ![]() ![]() |
Before ![]() (image error) Size: 30 KiB After ![]() (image error) Size: 9.7 KiB ![]() ![]() |
Before ![]() (image error) Size: 26 KiB After ![]() (image error) Size: 10 KiB ![]() ![]() |
Before ![]() (image error) Size: 28 KiB After ![]() (image error) Size: 8.9 KiB ![]() ![]() |
Before ![]() (image error) Size: 33 KiB After ![]() (image error) Size: 9 KiB ![]() ![]() |
Before ![]() (image error) Size: 22 KiB After ![]() (image error) Size: 8.7 KiB ![]() ![]() |
Before ![]() (image error) Size: 34 KiB After ![]() (image error) Size: 8.8 KiB ![]() ![]() |
Before ![]() (image error) Size: 26 KiB After ![]() (image error) Size: 9 KiB ![]() ![]() |
Before ![]() (image error) Size: 27 KiB After ![]() (image error) Size: 8.1 KiB ![]() ![]() |
Before ![]() (image error) Size: 24 KiB After ![]() (image error) Size: 8.1 KiB ![]() ![]() |
Before ![]() (image error) Size: 30 KiB After ![]() (image error) Size: 7.9 KiB ![]() ![]() |
Before ![]() (image error) Size: 32 KiB After ![]() (image error) Size: 8 KiB ![]() ![]() |
Before ![]() (image error) Size: 26 KiB After ![]() (image error) Size: 8.2 KiB ![]() ![]() |
Before ![]() (image error) Size: 23 KiB After ![]() (image error) Size: 5.3 KiB ![]() ![]() |
Before ![]() (image error) Size: 24 KiB After ![]() (image error) Size: 5.3 KiB ![]() ![]() |
Before ![]() (image error) Size: 20 KiB After ![]() (image error) Size: 5.2 KiB ![]() ![]() |
Before ![]() (image error) Size: 25 KiB After ![]() (image error) Size: 5.3 KiB ![]() ![]() |
Before ![]() (image error) Size: 22 KiB After ![]() (image error) Size: 5.3 KiB ![]() ![]() |
27
loader/resources/blanks/svgs/baseCircle_Big.svg
Normal file
|
@ -0,0 +1,27 @@
|
|||
<svg width="216" height="226" viewBox="0 0 216 226" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d_732_175)">
|
||||
<circle cx="108" cy="113" r="103" fill="white"/>
|
||||
</g>
|
||||
<circle cx="108" cy="113" r="95" fill="black"/>
|
||||
<circle cx="108" cy="113" r="86" fill="url(#paint0_linear_732_175)"/>
|
||||
<path d="M108 199C155.496 199 194 160.496 194 113H22C22 160.496 60.5035 199 108 199Z" fill="url(#paint1_linear_732_175)"/>
|
||||
<defs>
|
||||
<filter id="filter0_d_732_175" x="5" y="10" width="210.1" height="213" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="4.1" dy="7"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_732_175"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_732_175" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_732_175" x1="22" y1="199" x2="194" y2="199" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D6FF5A"/>
|
||||
<stop offset="1" stop-color="#66CC11"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_732_175" x1="22" y1="113.348" x2="194" y2="113.348" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#90FF44"/>
|
||||
<stop offset="1" stop-color="#449906"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After (image error) Size: 1.5 KiB |
27
loader/resources/blanks/svgs/baseCircle_BigAlt.svg
Normal file
|
@ -0,0 +1,27 @@
|
|||
<svg width="225" height="243" viewBox="0 0 225 243" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d_732_207)">
|
||||
<circle cx="112" cy="120" r="102" fill="white"/>
|
||||
</g>
|
||||
<circle cx="112" cy="120" r="93.5" fill="black"/>
|
||||
<circle cx="112" cy="120" r="85.5" fill="url(#paint0_linear_732_207)"/>
|
||||
<path d="M112 205.5C159.22 205.5 197.5 167.22 197.5 120H26.5C26.5 167.22 64.7797 205.5 112 205.5Z" fill="url(#paint1_linear_732_207)"/>
|
||||
<defs>
|
||||
<filter id="filter0_d_732_207" x="10" y="18" width="211" height="218" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="7" dy="14"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_732_207"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_732_207" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_732_207" x1="26.5" y1="205.5" x2="197.5" y2="205.5" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D6FF5A"/>
|
||||
<stop offset="1" stop-color="#66CC11"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_732_207" x1="26.5" y1="120.346" x2="197.5" y2="120.346" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#90FF44"/>
|
||||
<stop offset="1" stop-color="#449906"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After (image error) Size: 1.5 KiB |
27
loader/resources/blanks/svgs/baseCircle_Large.svg
Normal file
|
@ -0,0 +1,27 @@
|
|||
<svg width="321" height="333" viewBox="0 0 321 333" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d_727_17)">
|
||||
<circle cx="160.5" cy="163.5" r="148.5" fill="white"/>
|
||||
</g>
|
||||
<circle cx="160.5" cy="163.5" r="137" fill="black"/>
|
||||
<circle cx="160.5" cy="163.5" r="124" fill="url(#paint0_linear_727_17)"/>
|
||||
<path d="M160.5 287.5C228.983 287.5 284.5 231.983 284.5 163.5H36.5C36.5 231.983 92.0167 287.5 160.5 287.5Z" fill="url(#paint1_linear_727_17)"/>
|
||||
<defs>
|
||||
<filter id="filter0_d_727_17" x="12" y="15" width="304.905" height="310.834" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="7.90537" dy="13.8344"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_727_17"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_727_17" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_727_17" x1="36.5" y1="287.5" x2="284.5" y2="287.5" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D6FF5A"/>
|
||||
<stop offset="1" stop-color="#66CC11"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_727_17" x1="36.5" y1="164.002" x2="284.5" y2="164.002" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#90FF44"/>
|
||||
<stop offset="1" stop-color="#449906"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After (image error) Size: 1.5 KiB |
27
loader/resources/blanks/svgs/baseCircle_Medium.svg
Normal file
|
@ -0,0 +1,27 @@
|
|||
<svg width="187" height="196" viewBox="0 0 187 196" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d_910_101)">
|
||||
<ellipse cx="93.5" cy="98" rx="87.5" ry="87" fill="white"/>
|
||||
</g>
|
||||
<ellipse cx="93.5" cy="98" rx="80.5" ry="81" fill="black"/>
|
||||
<circle cx="93.5" cy="98" r="73" fill="url(#paint0_linear_910_101)"/>
|
||||
<path d="M93.5 171C133.817 171 166.5 138.317 166.5 98H20.5C20.5 138.317 53.1832 171 93.5 171Z" fill="url(#paint1_linear_910_101)"/>
|
||||
<defs>
|
||||
<filter id="filter0_d_910_101" x="6" y="11" width="178.556" height="182" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="3.55575" dy="8"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_910_101"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_910_101" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_910_101" x1="20.5" y1="171" x2="166.5" y2="171" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D6FF5A"/>
|
||||
<stop offset="1" stop-color="#66CC11"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_910_101" x1="20.5" y1="98.2955" x2="166.5" y2="98.2955" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#90FF44"/>
|
||||
<stop offset="1" stop-color="#449906"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After (image error) Size: 1.5 KiB |
27
loader/resources/blanks/svgs/baseCircle_MediumAlt.svg
Normal file
|
@ -0,0 +1,27 @@
|
|||
<svg width="210" height="228" viewBox="0 0 210 228" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d_910_124)">
|
||||
<ellipse cx="105" cy="113.5" rx="94" ry="93.5" fill="white"/>
|
||||
</g>
|
||||
<circle cx="105" cy="113.5" r="86" fill="black"/>
|
||||
<circle cx="105" cy="113.5" r="78.5" fill="url(#paint0_linear_910_124)"/>
|
||||
<path d="M105 192C148.354 192 183.5 156.854 183.5 113.5H26.5C26.5 156.854 61.6456 192 105 192Z" fill="url(#paint1_linear_910_124)"/>
|
||||
<defs>
|
||||
<filter id="filter0_d_910_124" x="11" y="20" width="195" height="202" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="7" dy="15"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_910_124"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_910_124" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_910_124" x1="26.5" y1="192" x2="183.5" y2="192" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D6FF5A"/>
|
||||
<stop offset="1" stop-color="#66CC11"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_910_124" x1="26.5" y1="113.818" x2="183.5" y2="113.818" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#90FF44"/>
|
||||
<stop offset="1" stop-color="#449906"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After (image error) Size: 1.5 KiB |
27
loader/resources/blanks/svgs/baseCircle_Small.svg
Normal file
|
@ -0,0 +1,27 @@
|
|||
<svg width="154" height="164" viewBox="0 0 154 164" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d_910_130)">
|
||||
<circle cx="77" cy="82" r="71.9497" fill="white"/>
|
||||
</g>
|
||||
<circle cx="77.0001" cy="82" r="66.3614" fill="black"/>
|
||||
<circle cx="77" cy="82" r="60" fill="url(#paint0_linear_910_130)"/>
|
||||
<path d="M77 142C110.137 142 137 115.137 137 82H17C17 115.137 43.8629 142 77 142Z" fill="url(#paint1_linear_910_130)"/>
|
||||
<defs>
|
||||
<filter id="filter0_d_910_130" x="5.05029" y="10.0503" width="147.899" height="150.899" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="4" dy="7"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_910_130"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_910_130" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_910_130" x1="17" y1="142" x2="137" y2="142" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D6FF5A"/>
|
||||
<stop offset="1" stop-color="#66CC11"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_910_130" x1="17" y1="82.2429" x2="137" y2="82.2429" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#90FF44"/>
|
||||
<stop offset="1" stop-color="#449906"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After (image error) Size: 1.5 KiB |
27
loader/resources/blanks/svgs/baseCircle_SmallAlt.svg
Normal file
|
@ -0,0 +1,27 @@
|
|||
<svg width="166" height="176" viewBox="0 0 166 176" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d_911_204)">
|
||||
<ellipse cx="83.0529" cy="87.614" rx="78.1505" ry="77.7348" fill="white"/>
|
||||
</g>
|
||||
<circle cx="83.0526" cy="87.614" r="71.4994" fill="black"/>
|
||||
<circle cx="83" cy="87.614" r="64" fill="url(#paint0_linear_911_204)"/>
|
||||
<path d="M83 151.614C118.346 151.614 147 122.96 147 87.614H19C19 122.96 47.6538 151.614 83 151.614Z" fill="url(#paint1_linear_911_204)"/>
|
||||
<defs>
|
||||
<filter id="filter0_d_911_204" x="4.90234" y="9.87921" width="160.301" height="163.47" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="4" dy="8"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_911_204"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_911_204" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_911_204" x1="19" y1="151.614" x2="147" y2="151.614" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D6FF5A"/>
|
||||
<stop offset="1" stop-color="#66CC11"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_911_204" x1="19" y1="87.8731" x2="147" y2="87.8731" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#90FF44"/>
|
||||
<stop offset="1" stop-color="#449906"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After (image error) Size: 1.6 KiB |
27
loader/resources/blanks/svgs/baseCircle_Tiny.svg
Normal file
|
@ -0,0 +1,27 @@
|
|||
<svg width="106" height="116" viewBox="0 0 106 116" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d_911_217)">
|
||||
<ellipse cx="52.7393" cy="57.7456" rx="48.4141" ry="48.1565" fill="white"/>
|
||||
</g>
|
||||
<circle cx="52.7395" cy="57.7456" r="44.2937" fill="black"/>
|
||||
<circle cx="52.7393" cy="57.7456" r="39.5" fill="url(#paint0_linear_911_217)"/>
|
||||
<path d="M52.7393 97.2456C74.5545 97.2456 92.2393 79.5609 92.2393 57.7456H13.2393C13.2393 79.5609 30.924 97.2456 52.7393 97.2456Z" fill="url(#paint1_linear_911_217)"/>
|
||||
<defs>
|
||||
<filter id="filter0_d_911_217" x="4.3252" y="9.58908" width="100.828" height="103.313" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="4" dy="7"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_911_217"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_911_217" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_911_217" x1="13.2393" y1="97.2456" x2="92.2393" y2="97.2456" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D6FF5A"/>
|
||||
<stop offset="1" stop-color="#66CC11"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_911_217" x1="13.2393" y1="57.9055" x2="92.2393" y2="57.9055" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#90FF44"/>
|
||||
<stop offset="1" stop-color="#449906"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After (image error) Size: 1.6 KiB |
42
loader/resources/blanks/svgs/gen.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
import subprocess
|
||||
|
||||
# you must run this in the same directory as the script!
|
||||
# and also you must have rsvg-convert
|
||||
# on ubuntu you can get this with `apt install librsvg2-bin`
|
||||
|
||||
sizes = [
|
||||
"Large",
|
||||
"Big",
|
||||
"BigAlt",
|
||||
"Medium",
|
||||
"MediumAlt",
|
||||
"Small",
|
||||
"SmallAlt",
|
||||
"Tiny",
|
||||
]
|
||||
|
||||
# the green gradient colors we are replacing in the base svgs
|
||||
color_from = ["#D6FF5A", "#66CC11", "#90FF44", "#449906"]
|
||||
|
||||
# each pair of colors represents a gradient,
|
||||
# first pair is for the top part of the button,
|
||||
# second pair is for the bottom.
|
||||
colors = {
|
||||
"Green": ["#D6FF5A", "#66CC11", "#90FF44", "#449906"],
|
||||
"Pink": ["#FACCFC", "#FF71FF", "#FBB1FF", "#FB58FF"],
|
||||
"Cyan": ["#58FDFA", "#13D5EA", "#44F9F6", "#0B9FBE"],
|
||||
"Blue": ["#1AF1F8", "#0AB4FF", "#23DCFA", "#0077FA"],
|
||||
"Gray": ["#DEDEE0", "#979997", "#CACCCA", "#747472"],
|
||||
# "DarkPurple": ["#41384b", "#2f2937", "#393142", "#221e28"],
|
||||
}
|
||||
|
||||
for size in sizes:
|
||||
with open(f"baseCircle_{size}.svg", "r") as file:
|
||||
svg_base = file.read()
|
||||
for name, cols in colors.items():
|
||||
svg = svg_base
|
||||
out = f"../baseCircle_{size}_{name.title()}.png"
|
||||
print(f"Generating {out}")
|
||||
for color_orig, color_to in zip(color_from, cols):
|
||||
svg = svg.replace(color_orig, color_to)
|
||||
subprocess.run(["rsvg-convert", "-o", out], input=svg.encode())
|
67
loader/src/hooks/AndroidFMODFix.cpp
Normal file
|
@ -0,0 +1,67 @@
|
|||
#include <Geode/Geode.hpp>
|
||||
|
||||
#ifdef GEODE_IS_ANDROID
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
||||
auto g_systemInitialized = false;
|
||||
|
||||
FMOD_RESULT FMOD_System_init_hook(
|
||||
FMOD::System* system, int maxChannels, FMOD_INITFLAGS flags, void* extraData
|
||||
) {
|
||||
g_systemInitialized = true;
|
||||
return system->init(maxChannels, flags, extraData);
|
||||
}
|
||||
|
||||
FMOD_RESULT FMOD_ChannelControl_setVolume_hook(FMOD::ChannelControl* channel, float volume) {
|
||||
if (!g_systemInitialized) {
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
return channel->setVolume(volume);
|
||||
}
|
||||
|
||||
$execute {
|
||||
// Workaround for a bug where FMOD::ChannelControl::setVolume is called with
|
||||
// uninitialized (invalid) channel pointers from FMODAudioEngine.
|
||||
// This creates a very annoying crash during load in some cases.
|
||||
|
||||
(void)geode::Mod::get()->hook(
|
||||
reinterpret_cast<void*>(geode::addresser::getNonVirtual(&FMOD::System::init)),
|
||||
&FMOD_System_init_hook,
|
||||
"FMOD::System::init"
|
||||
);
|
||||
|
||||
(void)geode::Mod::get()->hook(
|
||||
reinterpret_cast<void*>(geode::addresser::getNonVirtual(&FMOD::ChannelControl::setVolume)),
|
||||
&FMOD_ChannelControl_setVolume_hook,
|
||||
"FMOD::ChannelControl::setVolume"
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
// this hook requires a tuliphook update
|
||||
// (setEffectsVolume is too small to hook, so it overwrites the stopAllMusic call below it)
|
||||
|
||||
#include <Geode/modify/FMODAudioEngine.hpp>
|
||||
|
||||
struct AndroidFMODFix : Modify<AndroidFMODFix, FMODAudioEngine> {
|
||||
void setEffectsVolume(float volume) {
|
||||
if (this->m_system == nullptr) [[unlikely]] {
|
||||
return;
|
||||
}
|
||||
|
||||
FMODAudioEngine::setEffectsVolume(volume);
|
||||
}
|
||||
|
||||
void setBackgroundMusicVolume(float volume) {
|
||||
if (this->m_system == nullptr) [[unlikely]] {
|
||||
return;
|
||||
}
|
||||
|
||||
FMODAudioEngine::setBackgroundMusicVolume(volume);
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
#endif
|
|
@ -285,4 +285,13 @@ void CCNode::updateAnchoredPosition(Anchor anchor, CCPoint const& offset, CCPoin
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef GEODE_EXPORTING
|
||||
|
||||
void CCNode::setAttribute(std::string const& attr, matjson::Value const& value) {}
|
||||
std::optional<matjson::Value> CCNode::getAttributeInternal(std::string const& attr) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#pragma warning(pop)
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include <Geode/loader/Log.hpp>
|
||||
#include <Geode/loader/Mod.hpp>
|
||||
#include <Geode/loader/SettingEvent.hpp>
|
||||
#include <Geode/loader/ModJsonTest.hpp>
|
||||
#include <Geode/utils/JsonValidation.hpp>
|
||||
#include <loader/LogImpl.hpp>
|
||||
|
||||
|
|
8
loader/src/loader/Dispatch.cpp
Normal file
|
@ -0,0 +1,8 @@
|
|||
#include <Geode/loader/Dispatch.hpp>
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
||||
std::unordered_map<std::string, EventListenerPool*>& geode::dispatchPools() {
|
||||
static std::unordered_map<std::string, EventListenerPool*> pools;
|
||||
return pools;
|
||||
}
|
|
@ -337,9 +337,20 @@ void Index::Impl::downloadIndex(std::string commitHash) {
|
|||
|
||||
// unzip new index
|
||||
log::debug("Unzipping index");
|
||||
IndexUpdateEvent(UpdateProgress(100, "Unzipping index")).post();
|
||||
auto unzip = file::Unzip::intoDir(targetFile, targetDir, true)
|
||||
.expect("Unable to unzip new index");
|
||||
uint32_t nextPercent = 1;
|
||||
auto unzip = file::Unzip::intoDir(
|
||||
[&](uint32_t current, uint32_t total) {
|
||||
if (total == 0) return;
|
||||
|
||||
if (static_cast<float>(current) / total * 100 >= nextPercent) {
|
||||
Loader::get()->queueInMainThread([nextPercent]() {
|
||||
IndexUpdateEvent(UpdateProgress(nextPercent, "Extracting")).post();
|
||||
});
|
||||
nextPercent++;
|
||||
}
|
||||
},
|
||||
targetFile, targetDir, true
|
||||
).expect("Unable to unzip new index");
|
||||
if (!unzip) {
|
||||
auto const err = unzip.unwrapErr();
|
||||
log::error("Failed to unzip latest index: {}", err);
|
||||
|
|
|
@ -255,14 +255,16 @@ std::string geode::log::generateLogName() {
|
|||
return fmt::format("Geode {:%F %H.%M.%S}.log", convertTime(log_clock::now()));
|
||||
}
|
||||
|
||||
void log::pushNest() {
|
||||
void log::pushNest(Mod* mod) {
|
||||
if (s_nestLevel == 0)
|
||||
s_nestCountOffset = static_cast<int32_t>(Mod::get()->getName().size() + thread::getName().size());
|
||||
s_nestCountOffset = static_cast<int32_t>(mod->getName().size() + thread::getName().size());
|
||||
s_nestLevel++;
|
||||
}
|
||||
|
||||
void log::popNest() {
|
||||
void log::popNest(Mod* mod) {
|
||||
s_nestLevel--;
|
||||
if (s_nestLevel == 0)
|
||||
s_nestCountOffset = 0;
|
||||
}
|
||||
|
||||
std::shared_ptr<Nest> log::saveNest() {
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include <Geode/loader/Setting.hpp>
|
||||
#include <Geode/loader/SettingEvent.hpp>
|
||||
#include <Geode/loader/SettingNode.hpp>
|
||||
#include <Geode/loader/SettingJsonTest.hpp>
|
||||
#include <Geode/utils/general.hpp>
|
||||
#include <Geode/utils/JsonValidation.hpp>
|
||||
#include <re2/re2.h>
|
||||
|
|
|
@ -321,9 +321,6 @@ static const char* permissionToName(Permission permission) {
|
|||
#define PERM(x) "android.permission." x
|
||||
#define INTERNAL_PERM(x) "geode.permission_internal." x
|
||||
switch (permission) {
|
||||
case Permission::ReadAudio: return PERM("READ_MEDIA_AUDIO");
|
||||
case Permission::ReadImages: return PERM("READ_MEDIA_IMAGES");
|
||||
case Permission::ReadVideo: return PERM("READ_MEDIA_VIDEO");
|
||||
case Permission::RecordAudio: return PERM("RECORD_AUDIO");
|
||||
case Permission::ReadAllFiles: return INTERNAL_PERM("MANAGE_ALL_FILES");
|
||||
}
|
||||
|
|
|
@ -628,7 +628,7 @@ void ModListLayer::onIndexUpdate(IndexUpdateEvent* event) {
|
|||
[&](UpdateProgress const& prog) {
|
||||
auto msg = prog.second;
|
||||
// amazing
|
||||
if (prog.second == "Downloading") {
|
||||
if (prog.second == "Downloading" || prog.second == "Extracting") {
|
||||
msg += fmt::format(" {}%", prog.first);
|
||||
}
|
||||
m_listLabel->setString((msg + "...").c_str());
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "ModsLayer.hpp"
|
||||
#include "SwelvyBG.hpp"
|
||||
#include <Geode/ui/TextInput.hpp>
|
||||
|
||||
static bool BIG_VIEW = false;
|
||||
|
||||
|
@ -58,9 +59,20 @@ bool ModList::init(ModListSource* src, CCSize const& size) {
|
|||
);
|
||||
this->addChildAtPosition(pageRightMenu, Anchor::Right, ccp(5, 0));
|
||||
|
||||
auto pageLabelMenu = CCMenu::create();
|
||||
pageLabelMenu->setContentWidth(30.f);
|
||||
pageLabelMenu->setAnchorPoint({ .5f, 1.f });
|
||||
|
||||
m_pageLabel = CCLabelBMFont::create("", "bigFont.fnt");
|
||||
m_pageLabel->setAnchorPoint({ .5f, 1.f });
|
||||
this->addChildAtPosition(m_pageLabel, Anchor::Bottom, ccp(0, -5));
|
||||
|
||||
m_pageLabelBtn = CCMenuItemSpriteExtra::create(
|
||||
m_pageLabel, this, menu_selector(ModList::onGoToPage)
|
||||
);
|
||||
pageLabelMenu->addChild(m_pageLabelBtn);
|
||||
|
||||
pageLabelMenu->setLayout(RowLayout::create());
|
||||
this->addChildAtPosition(pageLabelMenu, Anchor::Bottom, ccp(0, -5));
|
||||
|
||||
m_statusText = SimpleTextArea::create("", "bigFont.fnt", .6f);
|
||||
m_statusText->setAlignment(kCCTextAlignmentCenter);
|
||||
|
@ -114,6 +126,14 @@ void ModList::onPromise(PromiseEvent<typename ModListSource::Page>* event) {
|
|||
}
|
||||
}
|
||||
|
||||
void ModList::onGoToPage(CCObject*) {
|
||||
auto popup = SetTextPopup::create("", "Page", 5, "Go to Page", "OK", true, 60.f);
|
||||
popup->m_delegate = this;
|
||||
popup->m_input->m_allowedChars = getCommonFilterAllowedChars(CommonFilter::Uint);
|
||||
popup->setID("go-to-page"_spr);
|
||||
popup->show();
|
||||
}
|
||||
|
||||
void ModList::onPage(CCObject* sender) {
|
||||
// If no page count has been loaded yet, we can't do anything
|
||||
if (!m_source->getPageCount()) return;
|
||||
|
@ -148,7 +168,7 @@ void ModList::updatePageUI(bool hide) {
|
|||
}
|
||||
m_pagePrevBtn->setVisible(!hide && m_page > 0);
|
||||
m_pageNextBtn->setVisible(!hide && m_page < pageCount.value() - 1);
|
||||
m_pageLabel->setVisible(!hide);
|
||||
m_pageLabelBtn->setVisible(!hide);
|
||||
if (pageCount > 0u) {
|
||||
auto fmt = fmt::format("Page {}/{}", m_page + 1, pageCount.value());
|
||||
m_pageLabel->setString(fmt.c_str());
|
||||
|
@ -156,6 +176,14 @@ void ModList::updatePageUI(bool hide) {
|
|||
}
|
||||
}
|
||||
|
||||
void ModList::setTextPopupClosed(SetTextPopup* popup, gd::string value) {
|
||||
if (popup->getID() == "go-to-page"_spr) {
|
||||
if (auto num = numFromString<size_t>(value)) {
|
||||
this->gotoPage(num.unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModList::reloadPage() {
|
||||
// Just force an update on the current page
|
||||
this->gotoPage(m_page, true);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
using namespace geode::prelude;
|
||||
|
||||
class ModList : public CCNode {
|
||||
class ModList : public CCNode, public SetTextPopupDelegate {
|
||||
protected:
|
||||
ModListSource* m_source;
|
||||
size_t m_page = 0;
|
||||
|
@ -18,12 +18,16 @@ protected:
|
|||
ModListSource::PageLoadEventListener m_listener;
|
||||
CCMenuItemSpriteExtra* m_pagePrevBtn;
|
||||
CCMenuItemSpriteExtra* m_pageNextBtn;
|
||||
CCMenuItemSpriteExtra* m_pageLabelBtn;
|
||||
CCLabelBMFont* m_pageLabel;
|
||||
|
||||
bool init(ModListSource* src, CCSize const& size);
|
||||
|
||||
void onPromise(PromiseEvent<ModListSource::Page>* event);
|
||||
void onPage(CCObject*);
|
||||
void onGoToPage(CCObject*);
|
||||
|
||||
void setTextPopupClosed(SetTextPopup*, gd::string value) override;
|
||||
|
||||
void updatePageUI(bool hide = false);
|
||||
|
||||
|
|
|
@ -463,6 +463,9 @@ void geode::cocos::reloadTextures(CreateLayerFunc returnTo) {
|
|||
}
|
||||
|
||||
void GEODE_DLL geode::cocos::handleTouchPriorityWith(cocos2d::CCNode* node, int priority, bool force) {
|
||||
if (node == nullptr) return;
|
||||
if (node->getChildrenCount() == 0) return;
|
||||
|
||||
for (auto child : CCArrayExt<CCNode*>(node->getChildren())) {
|
||||
if (auto delegate = typeinfo_cast<CCTouchDelegate*>(child)) {
|
||||
if (auto handler = CCTouchDispatcher::get()->findHandler(delegate)) {
|
||||
|
|
|
@ -170,6 +170,7 @@ private:
|
|||
int32_t m_mode;
|
||||
std::variant<Path, ByteVector> m_srcDest;
|
||||
std::unordered_map<Path, ZipEntry> m_entries;
|
||||
utils::MiniFunction<void(uint32_t, uint32_t)> m_progressCallback;
|
||||
|
||||
Result<> init() {
|
||||
// open stream from file
|
||||
|
@ -281,6 +282,10 @@ public:
|
|||
return Ok(std::move(ret));
|
||||
}
|
||||
|
||||
void setProgressCallback(utils::MiniFunction<void(uint32_t, uint32_t)> callback) {
|
||||
m_progressCallback = callback;
|
||||
}
|
||||
|
||||
Result<> extractAt(Path const& dir, Path const& name) {
|
||||
auto entry = m_entries.at(name);
|
||||
|
||||
|
@ -318,12 +323,21 @@ public:
|
|||
.expect("Unable to navigate to first entry (code {error})")
|
||||
);
|
||||
|
||||
uint64_t numEntries;
|
||||
|
||||
GEODE_UNWRAP(
|
||||
mzTry(mz_zip_get_number_entry(m_handle, &numEntries))
|
||||
.expect("Unable to get number of entries (code {error})")
|
||||
);
|
||||
|
||||
uint32_t currentEntry = 0;
|
||||
// while not at MZ_END_OF_LIST
|
||||
do {
|
||||
mz_zip_file* info = nullptr;
|
||||
if (mz_zip_entry_get_info(m_handle, &info) != MZ_OK) {
|
||||
return Err("Unable to get entry info");
|
||||
}
|
||||
currentEntry++;
|
||||
|
||||
Path filePath;
|
||||
filePath.assign(info->filename, info->filename + info->filename_size);
|
||||
|
@ -341,6 +355,7 @@ public:
|
|||
else {
|
||||
GEODE_UNWRAP(this->extractAt(dir, filePath));
|
||||
}
|
||||
m_progressCallback(currentEntry, numEntries);
|
||||
}
|
||||
else {
|
||||
log::error(
|
||||
|
@ -505,6 +520,12 @@ Unzip::Path Unzip::getPath() const {
|
|||
return m_impl->getPath();
|
||||
}
|
||||
|
||||
void Unzip::setProgressCallback(
|
||||
utils::MiniFunction<void(uint32_t, uint32_t)> callback
|
||||
) {
|
||||
return m_impl->setProgressCallback(callback);
|
||||
}
|
||||
|
||||
std::vector<Unzip::Path> Unzip::getEntries() const {
|
||||
return map::keys(m_impl->getEntries());
|
||||
}
|
||||
|
@ -550,6 +571,22 @@ Result<> Unzip::intoDir(
|
|||
return Ok();
|
||||
}
|
||||
|
||||
Result<> Unzip::intoDir(
|
||||
utils::MiniFunction<void(uint32_t, uint32_t)> progressCallback,
|
||||
Path const& from,
|
||||
Path const& to,
|
||||
bool deleteZipAfter
|
||||
) {
|
||||
GEODE_UNWRAP_INTO(auto unzip, Unzip::create(from));
|
||||
unzip.setProgressCallback(progressCallback);
|
||||
GEODE_UNWRAP(unzip.extractAllTo(to));
|
||||
if (deleteZipAfter) {
|
||||
std::error_code ec;
|
||||
ghc::filesystem::remove(from, ec);
|
||||
}
|
||||
return Ok();
|
||||
}
|
||||
|
||||
// Zip
|
||||
|
||||
Zip::Zip() : m_impl(nullptr) {}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
#include <Geode/Loader.hpp>
|
||||
#include <Geode/modify/MenuLayer.hpp>
|
||||
#include <Geode/loader/SettingNode.hpp>
|
||||
#include <Geode/loader/ModJsonTest.hpp>
|
||||
#include <Geode/binding/CCMenuItemSpriteExtra.hpp>
|
||||
#include <Geode/binding/FLAlertLayer.hpp>
|
||||
#include <Geode/loader/Dispatch.hpp>
|
||||
#include <Geode/Bindings.hpp>
|
||||
#include "main.hpp"
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
@ -164,11 +163,12 @@ struct MyMenuLayer : Modify<MyMenuLayer, MenuLayer> {
|
|||
$on_mod(Loaded) {
|
||||
Mod::get()->addCustomSetting<MySettingValue>("overcast-skies", DEFAULT_ICON);
|
||||
|
||||
// Dispatcher::get()->addFunction<void(GJGarageLayer*)>("test-garage-open", [](GJGarageLayer*
|
||||
// gl) { auto label = CCLabelBMFont::create("Dispatcher works!", "bigFont.fnt");
|
||||
// label->setPosition(100, 80);
|
||||
// label->setScale(.4f);
|
||||
// label->setZOrder(99999);
|
||||
// gl->addChild(label);
|
||||
// });
|
||||
}
|
||||
(void)new EventListener(+[](GJGarageLayer* gl) {
|
||||
auto label = CCLabelBMFont::create("Dispatcher works!", "bigFont.fnt");
|
||||
label->setPosition(100, 80);
|
||||
label->setScale(.4f);
|
||||
label->setZOrder(99999);
|
||||
gl->addChild(label);
|
||||
return ListenerResult::Propagate;
|
||||
}, MyDispatchFilter("geode.test/test-garage-open"));
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <Geode/loader/Event.hpp>
|
||||
#include <Geode/loader/Dispatch.hpp>
|
||||
#include <Geode/binding/GJGarageLayer.hpp>
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
||||
|
@ -31,3 +33,6 @@ public:
|
|||
TestEventFilter();
|
||||
TestEventFilter(TestEventFilter const&) = default;
|
||||
};
|
||||
|
||||
using MyDispatchEvent = geode::DispatchEvent<GJGarageLayer*>;
|
||||
using MyDispatchFilter = geode::DispatchFilter<GJGarageLayer*>;
|
|
@ -1,5 +1,4 @@
|
|||
#include <Geode/Loader.hpp>
|
||||
#include <Geode/loader/ModJsonTest.hpp>
|
||||
#include <Geode/loader/ModEvent.hpp>
|
||||
#include <Geode/utils/cocos.hpp>
|
||||
#include "../dependency/main.hpp"
|
||||
|
@ -12,23 +11,17 @@ auto test = []() {
|
|||
};
|
||||
|
||||
// Exported functions
|
||||
$on_mod(Enabled) {
|
||||
log::info("Enabled");
|
||||
}
|
||||
$on_mod(Disabled) {
|
||||
log::info("Disabled");
|
||||
}
|
||||
$on_mod(Loaded) {
|
||||
log::info("Loaded");
|
||||
}
|
||||
$on_mod(Unloaded) {
|
||||
log::info("Unloaded");
|
||||
}
|
||||
|
||||
static std::string s_recievedEvent;
|
||||
|
||||
// Events
|
||||
$execute {
|
||||
new EventListener<TestEventFilter>(+[](TestEvent* event) {
|
||||
log::info("Received event: {}", event->getData());
|
||||
s_recievedEvent = event->getData();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -108,37 +101,16 @@ struct GJGarageLayerTest : Modify<GJGarageLayerTest, GJGarageLayer> {
|
|||
addChild(label2);
|
||||
|
||||
// Dispatch system pt. 1
|
||||
// auto fn = Dispatcher::get()->getFunction<void(GJGarageLayer*)>("test-garage-open");
|
||||
// fn(this);
|
||||
MyDispatchEvent("geode.test/test-garage-open", this).post();
|
||||
|
||||
if (s_recievedEvent.size() > 0) {
|
||||
auto label = CCLabelBMFont::create("Event works!", "bigFont.fnt");
|
||||
label->setPosition(100, 70);
|
||||
label->setScale(.4f);
|
||||
label->setZOrder(99999);
|
||||
addChild(label);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/*// Event system pt. 2
|
||||
int a = (0, []() {
|
||||
|
||||
Dispatcher::get()->addSelector("test-garage-open", [](GJGarageLayer* gl) {
|
||||
auto label = CCLabelBMFont::create("EventCenter works!", "bigFont.fnt");
|
||||
label->setPosition(100, 80);
|
||||
label->setScale(.4f);
|
||||
label->setZOrder(99999);
|
||||
gl->addChild(label);
|
||||
|
||||
TestDependency::depTest(gl);
|
||||
});
|
||||
|
||||
// Event system pt. 2
|
||||
// $observe("test-garage-open", GJGarageLayer*, evt) {
|
||||
// auto gl = evt.object();
|
||||
// auto label = CCLabelBMFont::create("EventCenter works!", "bigFont.fnt");
|
||||
// label->setPosition(100, 80);
|
||||
// label->setScale(.4f);
|
||||
// label->setZOrder(99999);
|
||||
// gl->addChild(label);
|
||||
|
||||
// // API pt. 2
|
||||
// TestDependency::depTest(gl);
|
||||
// }
|
||||
return 0;
|
||||
}());*/
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
{
|
||||
"id": "geode.testdep",
|
||||
"version": ">=1.0.0",
|
||||
"required": true
|
||||
"importance": "required"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
#define EXPORT_NAME TestDependency
|
||||
#include <Geode/Loader.hpp>
|
||||
|
||||
API_INIT("com.geode.testdep")
|
||||
|
||||
class TestDependency {
|
||||
public:
|
||||
static void depTest(GJGarageLayer* gl);
|
||||
// API_DECL(&TestDependency::depTest, gl);
|
||||
};
|