Merge branch 'main' of https://github.com/geode-sdk/geode into main

This commit is contained in:
HJfod 2023-01-31 21:20:05 +02:00
commit 049ff650e4
6 changed files with 105 additions and 57 deletions
CMakeLists.txt
bindings
cmake
codegen/src
loader/include/Geode

View file

@ -130,7 +130,7 @@ target_include_directories(${PROJECT_NAME} INTERFACE
)
target_link_directories(${PROJECT_NAME} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/loader/include/link)
CPMAddPackage("gh:geode-sdk/json#85be630")
CPMAddPackage("gh:geode-sdk/json#2b76460")
CPMAddPackage("gh:fmtlib/fmt#9.1.0")
CPMAddPackage("gh:gulrak/filesystem#3e5b930")

View file

@ -1,3 +1,5 @@
// clang-format off
class cocos2d::CCActionTween {
static cocos2d::CCActionTween* create(float, char const*, float, float) = mac 0x447590;
}
@ -495,11 +497,11 @@ class cocos2d::CCNode {
virtual auto addChild(cocos2d::CCNode*, int, int) = mac 0x1232a0, ios 0x15e4e4;
virtual auto addComponent(cocos2d::CCComponent*) = mac 0x124a40, ios 0x15f6a4;
virtual auto cleanup() = mac 0x123100, ios 0x15e3a4;
virtual auto convertToNodeSpace(cocos2d::CCPoint const&) = mac 0x124750, ios 0x15f55c;
virtual auto convertToWorldSpace(cocos2d::CCPoint const&) = mac 0x124790;
auto convertToNodeSpace(cocos2d::CCPoint const&) = mac 0x124750, ios 0x15f55c;
auto convertToWorldSpace(cocos2d::CCPoint const&) = mac 0x124790;
static cocos2d::CCNode* create() = mac 0x1230a0;
virtual auto draw() = mac 0x123840, ios 0x15e974;
virtual auto getActionByTag(int) = mac 0x123ee0;
auto getActionByTag(int) = mac 0x123ee0;
virtual auto getActionManager() = mac 0x123e50, ios 0x15ef54;
virtual auto getAnchorPoint() = mac 0x122d80, ios 0x15e090;
virtual auto getAnchorPointInPoints() = mac 0x122d70, ios 0x15e088;
@ -543,7 +545,7 @@ class cocos2d::CCNode {
virtual auto onExit() = mac 0x123ca0, ios 0x15edb0;
virtual auto onExitTransitionDidStart() = mac 0x123c00, ios 0x15ed18;
virtual auto parentToNodeTransform() = mac 0x1245d0, ios 0x15f410;
virtual auto pauseSchedulerAndActions() = mac 0x123d60;
auto pauseSchedulerAndActions() = mac 0x123d60;
virtual auto registerScriptHandler(int) = mac 0x123d90, ios 0x15ee94;
virtual auto removeAllChildren() = mac 0x123600, ios 0x15e788;
virtual auto removeAllChildrenWithCleanup(bool) = mac 0x123620, ios 0x15e798;
@ -558,11 +560,11 @@ class cocos2d::CCNode {
virtual auto removeFromParentAndCleanup(bool) = mac 0x123410, ios 0x15e5f8;
virtual auto removeMeAndCleanup() = mac 0x123440, ios 0x15e620;
virtual auto reorderChild(cocos2d::CCNode*, int) = mac 0x123760, ios 0x15e87c;
virtual auto resumeSchedulerAndActions() = mac 0x123b60;
virtual auto runAction(cocos2d::CCAction*) = mac 0x123e60;
virtual auto schedule(cocos2d::SEL_SCHEDULE) = mac 0x1240b0;
virtual auto schedule(cocos2d::SEL_SCHEDULE, float) = mac 0x124120;
virtual auto scheduleUpdate() = mac 0x123f80;
auto resumeSchedulerAndActions() = mac 0x123b60;
auto runAction(cocos2d::CCAction*) = mac 0x123e60;
auto schedule(cocos2d::SEL_SCHEDULE) = mac 0x1240b0;
auto schedule(cocos2d::SEL_SCHEDULE, float) = mac 0x124120;
auto scheduleUpdate() = mac 0x123f80;
virtual auto setActionManager(cocos2d::CCActionManager*) = mac 0x123e00, ios 0x15ef04;
virtual auto setAnchorPoint(cocos2d::CCPoint const&) = mac 0x122d90, ios 0x15e098;
virtual auto setContentSize(cocos2d::CCSize const&) = mac 0x122e50, ios 0x15e158;
@ -591,12 +593,12 @@ class cocos2d::CCNode {
virtual auto setVisible(bool) = mac 0x122d60, ios 0x15e080;
virtual auto setZOrder(int) = mac 0x1229a0, ios 0x15dd84;
virtual auto sortAllChildren() = mac 0x1237b0, ios 0x15e8d4;
virtual auto stopActionByTag(int) = mac 0x123ec0;
virtual auto stopAllActions() = mac 0x123190;
auto stopActionByTag(int) = mac 0x123ec0;
auto stopAllActions() = mac 0x123190;
virtual auto unregisterScriptHandler() = mac 0x123dc0, ios 0x15eec4;
virtual auto unschedule(cocos2d::SEL_SCHEDULE) = mac 0x124180;
virtual auto unscheduleAllSelectors() = mac 0x1231b0;
virtual auto unscheduleUpdate() = mac 0x124060;
auto unschedule(cocos2d::SEL_SCHEDULE) = mac 0x124180;
auto unscheduleAllSelectors() = mac 0x1231b0;
auto unscheduleUpdate() = mac 0x124060;
virtual auto update(float) = mac 0x1241a0, ios 0x15f124;
virtual auto updateTransform() = mac 0x1249d0, ios 0x15f648;
virtual auto updateTweenAction(float, char const*) = mac 0x1249c0, ios 0x15f644;
@ -1047,3 +1049,5 @@ class cocos2d {
// int getIntegerForKey(char const*) = mac 0xc1610;
// void setIntegerForKey(char const*, int) = mac 0xc26b0;
// }
// clang-format on

View file

@ -27,10 +27,12 @@ if (GEODE_TARGET_PLATFORM STREQUAL "iOS")
elseif (GEODE_TARGET_PLATFORM STREQUAL "MacOS")
set_target_properties(${PROJECT_NAME} PROPERTIES
SYSTEM_NAME MacOS
OSX_DEPLOYMENT_TARGET 10.9
APPLE_SILICON_PROCESSOR x86_64
)
# only exists as a global property
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.14)
target_link_libraries(${PROJECT_NAME} INTERFACE curl "-framework Cocoa")
target_compile_options(${PROJECT_NAME} INTERFACE -fms-extensions #[[-Wno-deprecated]] -Wno-ignored-attributes -Os #[[-flto]] #[[-fvisibility=internal]])

View file

@ -30,7 +30,7 @@ Result<tulip::hook::HandlerMetadata> geode::modifier::handlerMetadataForAddress(
char const* declare_metadata = R"GEN(
{{
using FunctionType = {return}(*)({class_name}{const}*{parameter_comma}{parameter_types});
ret[{address}] = +[](){{
ret[modifier::address<{index}>()] = +[](){{
return tulip::hook::HandlerMetadata{{
.m_convention = geode::hook::createConvention(tulip::hook::TulipConvention::{convention}),
.m_abstract = tulip::hook::AbstractFunction::from(FunctionType(nullptr)),
@ -42,7 +42,7 @@ Result<tulip::hook::HandlerMetadata> geode::modifier::handlerMetadataForAddress(
char const* declare_metadata_static = R"GEN(
{{
using FunctionType = {return}(*)({parameter_types});
ret[{address}] = +[](){{
ret[modifier::address<{index}>()] = +[](){{
return tulip::hook::HandlerMetadata{{
.m_convention = geode::hook::createConvention(tulip::hook::TulipConvention::{convention}),
.m_abstract = tulip::hook::AbstractFunction::from(FunctionType(nullptr)),
@ -54,7 +54,7 @@ Result<tulip::hook::HandlerMetadata> geode::modifier::handlerMetadataForAddress(
char const* declare_metadata_structor = R"GEN(
{{
using FunctionType = void(*)({class_name}*{parameter_comma}{parameter_types});
ret[{address}] = +[](){{
ret[modifier::address<{index}>()] = +[](){{
return tulip::hook::HandlerMetadata{{
.m_convention = geode::hook::createConvention(tulip::hook::TulipConvention::{convention}),
.m_abstract = tulip::hook::AbstractFunction::from(FunctionType(nullptr)),
@ -170,7 +170,8 @@ std::string generateAddressHeader(Root& root) {
fmt::arg("parameters", codegen::getParameters(fn->beginning)),
fmt::arg("parameter_types", codegen::getParameterTypes(fn->beginning)),
fmt::arg("arguments", codegen::getParameterNames(fn->beginning)),
fmt::arg("parameter_comma", str_if(", ", !fn->beginning.args.empty()))
fmt::arg("parameter_comma", str_if(", ", !fn->beginning.args.empty())),
fmt::arg("index", field.field_id)
);
}
}

View file

@ -112,6 +112,7 @@ class GeodeNodeMetadata;
#include <stdint.h>
#include <string>
#include <type_traits>
#include <variant>
namespace tulip::hook {
@ -133,6 +134,11 @@ namespace geode {
Result<tulip::hook::HandlerMetadata, std::string> handlerMetadataForAddress(uintptr_t address);
}
namespace addresser {
template <class Class>
Class* friendCreate(typename std::void_t<decltype(static_cast<Class* (*)()>(&Class::create))>*);
}
}
#define GEODE_FRIEND_MODIFY \
@ -142,7 +148,10 @@ namespace geode {
template <uint32_t> \
friend uintptr_t geode::modifier::address(); \
friend geode::Result<tulip::hook::HandlerMetadata, std::string> \
geode::modifier::handlerMetadataForAddress(uintptr_t address);
geode::modifier::handlerMetadataForAddress(uintptr_t address); \
template <class Class> \
friend Class* geode::addresser:: \
friendCreate(typename std::void_t<decltype(static_cast<Class* (*)()>(&Class::create))>*);
#define GEODE_ADD(...) __VA_ARGS__
@ -161,9 +170,9 @@ namespace geode {
@param varType : the type of variable.
@param varName : variable name.
@param funName : "get + funName" is the name of the getter.
@warning : The getter is a public virtual function, you should rewrite it first.
The variables and methods declared after CC_PROPERTY_READONLY are all public.
If you need protected or private, please declare.
@warning : The getter is a public virtual function, you should rewrite
it first. The variables and methods declared after CC_PROPERTY_READONLY
are all public. If you need protected or private, please declare.
*/
#define CC_PROPERTY_READONLY(varType, varName, funName) \
\
@ -182,14 +191,16 @@ public: \
virtual const varType& get##funName(void);
/** CC_PROPERTY is used to declare a protected variable.
We can use getter to read the variable, and use the setter to change the variable.
We can use getter to read the variable, and use the setter to change
the variable.
@param varType : the type of variable.
@param varName : variable name.
@param funName : "get + funName" is the name of the getter.
"set + funName" is the name of the setter.
@warning : The getter and setter are public virtual functions, you should rewrite them first.
The variables and methods declared after CC_PROPERTY are all public.
If you need protected or private, please declare.
@warning : The getter and setter are public virtual functions, you
should rewrite them first. The variables and methods declared after
CC_PROPERTY are all public. If you need protected or private, please
declare.
*/
#define CC_PROPERTY(varType, varName, funName) \
\
@ -219,8 +230,8 @@ public: \
@param varName : variable name.
@param funName : "get + funName" is the name of the getter.
@warning : The getter is a public inline function.
The variables and methods declared after CC_SYNTHESIZE_READONLY are all public.
If you need protected or private, please declare.
The variables and methods declared after CC_SYNTHESIZE_READONLY are all
public. If you need protected or private, please declare.
*/
#define CC_SYNTHESIZE_READONLY(varType, varName, funName) \
\
@ -412,11 +423,11 @@ public: \
#if defined(__GNUC__) && (__GNUC__ >= 4)
#define CC_FORMAT_PRINTF(formatPos, argPos) \
__attribute__((__format__(printf, formatPos, argPos)))
/** CC_FORMAT_PRINTF
* Visual Studio 2019 has __has_attribute,
* but __has_attribute(format) is undefined,
* leaving CC_FORMAT_PRINTF undefined by default.
*/
/** CC_FORMAT_PRINTF
* Visual Studio 2019 has __has_attribute,
* but __has_attribute(format) is undefined,
* leaving CC_FORMAT_PRINTF undefined by default.
*/
#elif defined(__has_attribute)
#if __has_attribute(format)
#define CC_FORMAT_PRINTF(formatPos, argPos) \

View file

@ -4,13 +4,15 @@
* Adapted from https://gist.github.com/altalk23/29b97969e9f0624f783b673f6c1cd279
*/
#include "../utils/casts.hpp"
#include "casts.hpp"
#include <Geode/DefaultInclude.hpp>
#include <cocos-ext.h>
#include <cstdlib>
#include <stddef.h>
#include <type_traits>
#include "../utils/casts.hpp"
#include <concepts>
namespace geode::addresser {
@ -26,6 +28,18 @@ namespace geode::addresser {
template <typename T, typename F>
inline F rthunkAdjust(T func, F self);
template <class Class>
Class* friendCreate(typename std::void_t<decltype(static_cast<Class* (*)()>(&Class::create))>*) {
auto ret = Class::create();
ret->retain();
return ret;
}
template <class Class>
concept HasCreate = requires() {
{ friendCreate<Class>(nullptr) } -> std::same_as<Class*>;
};
class GEODE_DLL Addresser final {
template <char C>
struct SingleInheritance {
@ -62,6 +76,38 @@ namespace geode::addresser {
return thunk;
}
// I gave up
template <HasCreate Class>
static Class* generateInstance(Class*) {
return friendCreate<Class>(nullptr);
}
// I extra gave up
static cocos2d::extension::CCScrollView* generateInstance(cocos2d::extension::CCScrollView*) {
return cocos2d::extension::CCScrollView::create({0.0f, 0.0f}, cocos2d::CCLayer::create());
}
template <class Class>
static Class* generateInstance(Class*) {
// Create a random memory block with the size of Class
// Assign a pointer to that block and cast it to type Class*
uint8_t dum[sizeof(Class)]{};
auto ptr = reinterpret_cast<Class*>(dum);
// Now you have a object of Class that actually isn't an object of Class and is just a
// random memory But C++ doesn't know that of course So now you can copy an object
// that wasn't there in the first place
// ((oh also get the offsets of the virtual tables))
auto ins = new Class(*ptr);
// this is how the first human was made
return ins;
}
template <class Class>
static Class* cachedInstance() {
static auto ret = generateInstance<Class>(nullptr);
return ret;
}
/**
* Specialized functionss
*/
@ -71,19 +117,9 @@ namespace geode::addresser {
) {
using geode::cast::reference_cast;
// Create a random memory block with the size of T
// Assign a pointer to that block and cast it to type T*
uint8_t dum[sizeof(T)] {};
auto ptr = reinterpret_cast<T*>(dum);
// Now you have a object of T that actually isn't an object of T and is just a random
// memory But C++ doesn't know that of course So now you can copy an object that wasn't
// there in the first place
// ((oh also get the offsets of the virtual tables))
auto ins = new T(*ptr);
// this is how the first human was made
auto index = indexOf(func);
auto thunk = thunkOf(func);
auto ins = cachedInstance<T>();
// log::debug("[[" + utils::intToHex((void*)ins) + " + " + utils::intToHex(thunk) + "] +
// " + utils::intToHex(index) + "]");
@ -93,8 +129,7 @@ namespace geode::addresser {
// );
// [[this + thunk] + offset] is the f we want
auto address =
*(intptr_t*)(*(intptr_t*)(reference_cast<intptr_t>(ins) + thunk) + index);
auto address = *(intptr_t*)(*(intptr_t*)(reference_cast<intptr_t>(ins) + thunk) + index);
#ifdef GEODE_IS_WINDOWS
// check if first instruction is a jmp, i.e. if the func is a thunk
@ -106,18 +141,13 @@ namespace geode::addresser {
}
#endif
// And we delete the new instance because we are good girls
// and we don't leak memories
operator delete(ins);
return address;
}
template <typename R, typename T, typename... Ps>
static intptr_t addressOfVirtual(
R (T::*func)(Ps...) const,
typename std::enable_if_t<std::is_copy_constructible_v<T> && !std::is_abstract_v<T>>* =
0
typename std::enable_if_t<std::is_copy_constructible_v<T> && !std::is_abstract_v<T>>* = 0
) {
return addressOfVirtual(reinterpret_cast<R (T::*)(Ps...)>(func));
}
@ -199,7 +229,7 @@ namespace geode::addresser {
template <typename T, typename F>
inline F thunkAdjust(T func, F self) {
// do NOT delete the line below.
// do NOT delete the line below.
// doing so breaks thunk adjusting on windows.
// why? bruh idk
auto _ = *geode::cast::template union_cast<ptrdiff_t*>(&func);
@ -208,7 +238,7 @@ namespace geode::addresser {
template <typename T, typename F>
inline F rthunkAdjust(T func, F self) {
// do NOT delete the line below.
// do NOT delete the line below.
// doing so breaks thunk adjusting on windows.
// why? bruh idk
auto _ = *geode::cast::template union_cast<ptrdiff_t*>(&func);