mirror of
https://github.com/geode-sdk/geode.git
synced 2025-03-25 04:11:42 -04:00
add codegenned address -> handlermetadata map
This commit is contained in:
parent
2a97fe6752
commit
ae1eb8bb71
5 changed files with 494 additions and 277 deletions
codegen/src
loader/include/Geode
|
@ -1,15 +1,19 @@
|
|||
#include "Shared.hpp"
|
||||
#include "TypeOpt.hpp"
|
||||
|
||||
namespace { namespace format_strings {
|
||||
namespace {
|
||||
namespace format_strings {
|
||||
|
||||
char const* address_begin = R"GEN(
|
||||
char const* address_begin = R"GEN(
|
||||
#include <Geode/Bindings.hpp>
|
||||
#include <Geode/modify/Addresses.hpp>
|
||||
#include <Geode/modify/Traits.hpp>
|
||||
#include <Geode/loader/Tulip.hpp>
|
||||
|
||||
using namespace geode;
|
||||
)GEN";
|
||||
|
||||
char const* declare_address = R"GEN(
|
||||
char const* declare_address = R"GEN(
|
||||
template <>
|
||||
uintptr_t geode::modifier::address<{index}>() {{
|
||||
static uintptr_t ret = {address};
|
||||
|
@ -17,46 +21,160 @@ uintptr_t geode::modifier::address<{index}>() {{
|
|||
}}
|
||||
)GEN";
|
||||
|
||||
}}
|
||||
char const* declare_metadata_begin = R"GEN(
|
||||
Result<tulip::hook::HandlerMetadata> geode::modifier::handlerMetadataForAddress(uintptr_t address) {
|
||||
static auto s_value = []() {
|
||||
std::map<uintptr_t, tulip::hook::HandlerMetadata(*)()> ret;
|
||||
)GEN";
|
||||
|
||||
char const* declare_metadata = R"GEN(
|
||||
{{
|
||||
using FunctionType = {return}(*)({class_name}{const}*{parameter_comma}{parameter_types});
|
||||
ret[{address}] = +[](){{
|
||||
return tulip::hook::HandlerMetadata{{
|
||||
.m_convention = geode::hook::createConvention(tulip::hook::TulipConvention::{convention}),
|
||||
.m_abstract = tulip::hook::AbstractFunction::from(FunctionType(nullptr)),
|
||||
}};
|
||||
}};
|
||||
}}
|
||||
)GEN";
|
||||
|
||||
char const* declare_metadata_static = R"GEN(
|
||||
{{
|
||||
using FunctionType = {return}(*)({parameter_types});
|
||||
ret[{address}] = +[](){{
|
||||
return tulip::hook::HandlerMetadata{{
|
||||
.m_convention = geode::hook::createConvention(tulip::hook::TulipConvention::{convention}),
|
||||
.m_abstract = tulip::hook::AbstractFunction::from(FunctionType(nullptr)),
|
||||
}};
|
||||
}};
|
||||
}}
|
||||
)GEN";
|
||||
|
||||
char const* declare_metadata_structor = R"GEN(
|
||||
{{
|
||||
using FunctionType = void(*)({class_name}*{parameter_comma}{parameter_types});
|
||||
ret[{address}] = +[](){{
|
||||
return tulip::hook::HandlerMetadata{{
|
||||
.m_convention = geode::hook::createConvention(tulip::hook::TulipConvention::{convention}),
|
||||
.m_abstract = tulip::hook::AbstractFunction::from(FunctionType(nullptr)),
|
||||
}};
|
||||
}};
|
||||
}}
|
||||
)GEN";
|
||||
|
||||
char const* declare_metadata_end = R"GEN(
|
||||
return ret;
|
||||
}();
|
||||
if (s_value.count(address) > 0) return geode::Ok(std::move(s_value[address]()));
|
||||
return geode::Err("Address is not registered for wrapper");
|
||||
}
|
||||
)GEN";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
std::string generateAddressHeader(Root& root) {
|
||||
std::string output;
|
||||
std::string output;
|
||||
|
||||
TypeBank bank;
|
||||
bank.loadFrom(root);
|
||||
output += format_strings::address_begin;
|
||||
TypeBank bank;
|
||||
bank.loadFrom(root);
|
||||
output += format_strings::address_begin;
|
||||
|
||||
for (auto& c : root.classes) {
|
||||
for (auto& c : root.classes) {
|
||||
for (auto& field : c.fields) {
|
||||
std::string address_str;
|
||||
|
||||
for (auto& field : c.fields) {
|
||||
std::string address_str;
|
||||
auto fn = field.get_as<FunctionBindField>();
|
||||
|
||||
auto fn = field.get_as<FunctionBindField>();
|
||||
if (!fn) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!fn) {
|
||||
continue;
|
||||
}
|
||||
if (codegen::getStatus(field) == BindStatus::Binded) {
|
||||
auto const ids = bank.getIDs(fn->beginning, c.name);
|
||||
|
||||
if (codegen::getStatus(field) == BindStatus::Binded) {
|
||||
const auto ids = bank.getIDs(fn->beginning, c.name);
|
||||
address_str = fmt::format(
|
||||
"addresser::get{}Virtual(Resolve<{}>::func(&{}::{}))",
|
||||
str_if("Non", !fn->beginning.is_virtual),
|
||||
codegen::getParameterTypes(fn->beginning),
|
||||
field.parent,
|
||||
fn->beginning.name
|
||||
);
|
||||
}
|
||||
else if (codegen::getStatus(field) == BindStatus::NeedsBinding) {
|
||||
address_str = fmt::format("base::get() + 0x{:x}", codegen::platformNumber(fn->binds));
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
|
||||
address_str = fmt::format("addresser::get{}Virtual(Resolve<{}>::func(&{}::{}))",
|
||||
str_if("Non", !fn->beginning.is_virtual),
|
||||
codegen::getParameterTypes(fn->beginning),
|
||||
field.parent,
|
||||
fn->beginning.name
|
||||
);
|
||||
} else if (codegen::getStatus(field) == BindStatus::NeedsBinding) {
|
||||
address_str = fmt::format("base::get() + 0x{:x}", codegen::platformNumber(fn->binds));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
output += fmt::format(
|
||||
::format_strings::declare_address,
|
||||
fmt::arg("address", address_str),
|
||||
fmt::arg("index", field.field_id)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
output += fmt::format(::format_strings::declare_address,
|
||||
fmt::arg("address", address_str),
|
||||
fmt::arg("index", field.field_id)
|
||||
);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
output += format_strings::declare_metadata_begin;
|
||||
|
||||
for (auto& c : root.classes) {
|
||||
for (auto& field : c.fields) {
|
||||
std::string address_str;
|
||||
|
||||
auto fn = field.get_as<FunctionBindField>();
|
||||
|
||||
if (!fn) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (codegen::getStatus(field) == BindStatus::Binded) {
|
||||
address_str = fmt::format(
|
||||
"addresser::get{}Virtual(Resolve<{}>::func(&{}::{}))",
|
||||
str_if("Non", !fn->beginning.is_virtual),
|
||||
codegen::getParameterTypes(fn->beginning),
|
||||
field.parent,
|
||||
fn->beginning.name
|
||||
);
|
||||
}
|
||||
else if (codegen::getStatus(field) == BindStatus::NeedsBinding) {
|
||||
address_str = fmt::format("base::get() + 0x{:x}", codegen::platformNumber(fn->binds));
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
|
||||
char const* used_declare_format;
|
||||
|
||||
switch (fn->beginning.type) {
|
||||
case FunctionType::Normal:
|
||||
used_declare_format = format_strings::declare_metadata;
|
||||
break;
|
||||
case FunctionType::Ctor:
|
||||
case FunctionType::Dtor:
|
||||
used_declare_format = format_strings::declare_metadata_structor;
|
||||
break;
|
||||
}
|
||||
|
||||
if (fn->beginning.is_static)
|
||||
used_declare_format = format_strings::declare_metadata_static;
|
||||
|
||||
output += fmt::format(
|
||||
used_declare_format,
|
||||
fmt::arg("address", address_str),
|
||||
fmt::arg("class_name", c.name),
|
||||
fmt::arg("const", str_if(" const ", fn->beginning.is_const)),
|
||||
fmt::arg("convention", codegen::getModifyConventionName(field)),
|
||||
fmt::arg("return", bank.getReturn(fn->beginning, c.name)),
|
||||
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()))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
output += format_strings::declare_metadata_end;
|
||||
return output;
|
||||
}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2010 cocos2d-x.org
|
||||
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
|
@ -43,44 +43,38 @@
|
|||
* define a create function for a specific type, such as CCLayer
|
||||
* @__TYPE__ class type to add create(), such as CCLayer
|
||||
*/
|
||||
#define CREATE_FUNC(__TYPE__) \
|
||||
static __TYPE__* create() \
|
||||
{ \
|
||||
__TYPE__ *pRet = new __TYPE__(); \
|
||||
if (pRet && pRet->init()) \
|
||||
{ \
|
||||
pRet->autorelease(); \
|
||||
return pRet; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
delete pRet; \
|
||||
pRet = NULL; \
|
||||
return NULL; \
|
||||
} \
|
||||
}
|
||||
#define CREATE_FUNC(__TYPE__) \
|
||||
static __TYPE__* create() { \
|
||||
__TYPE__* pRet = new __TYPE__(); \
|
||||
if (pRet && pRet->init()) { \
|
||||
pRet->autorelease(); \
|
||||
return pRet; \
|
||||
} \
|
||||
else { \
|
||||
delete pRet; \
|
||||
pRet = NULL; \
|
||||
return NULL; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* define a node function for a specific type, such as CCLayer
|
||||
* @__TYPE__ class type to add node(), such as CCLayer
|
||||
* @deprecated: This interface will be deprecated sooner or later.
|
||||
*/
|
||||
#define NODE_FUNC(__TYPE__) \
|
||||
CC_DEPRECATED_ATTRIBUTE static __TYPE__* node() \
|
||||
{ \
|
||||
__TYPE__ *pRet = new __TYPE__(); \
|
||||
if (pRet && pRet->init()) \
|
||||
{ \
|
||||
pRet->autorelease(); \
|
||||
return pRet; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
delete pRet; \
|
||||
pRet = NULL; \
|
||||
return NULL; \
|
||||
} \
|
||||
}
|
||||
#define NODE_FUNC(__TYPE__) \
|
||||
CC_DEPRECATED_ATTRIBUTE static __TYPE__* node() { \
|
||||
__TYPE__* pRet = new __TYPE__(); \
|
||||
if (pRet && pRet->init()) { \
|
||||
pRet->autorelease(); \
|
||||
return pRet; \
|
||||
} \
|
||||
else { \
|
||||
delete pRet; \
|
||||
pRet = NULL; \
|
||||
return NULL; \
|
||||
} \
|
||||
}
|
||||
|
||||
/** @def CC_ENABLE_CACHE_TEXTURE_DATA
|
||||
Enable it if you want to cache the texture data.
|
||||
|
@ -88,19 +82,21 @@ Basically, it's only enabled for Emscripten.
|
|||
|
||||
It's new in cocos2d-x since v0.99.5
|
||||
*/
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_EMSCRIPTEN) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
|
||||
#define CC_ENABLE_CACHE_TEXTURE_DATA 1
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || \
|
||||
(CC_TARGET_PLATFORM == CC_PLATFORM_EMSCRIPTEN) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
|
||||
#define CC_ENABLE_CACHE_TEXTURE_DATA 1
|
||||
#else
|
||||
#define CC_ENABLE_CACHE_TEXTURE_DATA 0
|
||||
#define CC_ENABLE_CACHE_TEXTURE_DATA 0
|
||||
#endif
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_EMSCRIPTEN)
|
||||
/* Application will crash in glDrawElements function on some win32 computers and some android devices.
|
||||
Indices should be bound again while drawing to avoid this bug.
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || \
|
||||
(CC_TARGET_PLATFORM == CC_PLATFORM_EMSCRIPTEN)
|
||||
/* Application will crash in glDrawElements function on some win32 computers and some android
|
||||
devices. Indices should be bound again while drawing to avoid this bug.
|
||||
*/
|
||||
#define CC_REBIND_INDICES_BUFFER 1
|
||||
#define CC_REBIND_INDICES_BUFFER 1
|
||||
#else
|
||||
#define CC_REBIND_INDICES_BUFFER 0
|
||||
#define CC_REBIND_INDICES_BUFFER 0
|
||||
#endif
|
||||
|
||||
// generic macros
|
||||
|
@ -115,12 +111,18 @@ It's new in cocos2d-x since v0.99.5
|
|||
class GeodeNodeMetadata;
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
namespace tulip::hook {
|
||||
struct HandlerMetadata;
|
||||
}
|
||||
|
||||
namespace geode {
|
||||
struct modify;
|
||||
template <class, class>
|
||||
class Result;
|
||||
|
||||
namespace modifier {
|
||||
struct types;
|
||||
class FieldContainer;
|
||||
|
||||
template <class Derived, class Base>
|
||||
|
@ -128,30 +130,31 @@ namespace geode {
|
|||
|
||||
template <uint32_t>
|
||||
uintptr_t address();
|
||||
|
||||
Result<tulip::hook::HandlerMetadata, std::string> handlerMetadataForAddress(uintptr_t address);
|
||||
}
|
||||
}
|
||||
|
||||
#define GEODE_FRIEND_MODIFY \
|
||||
friend struct ::geode::modify; \
|
||||
template <class Derived, class Base> \
|
||||
friend class ::geode::modifier::ModifyDerive; \
|
||||
friend struct ::geode::modifier::types; \
|
||||
friend class ::GeodeNodeMetadata; \
|
||||
template <uint32_t> \
|
||||
friend uintptr_t geode::modifier::address();
|
||||
#define GEODE_FRIEND_MODIFY \
|
||||
template <class Derived, class Base> \
|
||||
friend class ::geode::modifier::ModifyDerive; \
|
||||
friend class ::GeodeNodeMetadata; \
|
||||
template <uint32_t> \
|
||||
friend uintptr_t geode::modifier::address(); \
|
||||
friend geode::Result<tulip::hook::HandlerMetadata, std::string> \
|
||||
geode::modifier::handlerMetadataForAddress(uintptr_t address);
|
||||
|
||||
#define GEODE_ADD(...) __VA_ARGS__
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define NS_CC_BEGIN namespace cocos2d {
|
||||
#define NS_CC_END }
|
||||
#define USING_NS_CC using namespace cocos2d
|
||||
#define NS_CC_BEGIN namespace cocos2d {
|
||||
#define NS_CC_END }
|
||||
#define USING_NS_CC using namespace cocos2d
|
||||
#else
|
||||
#define NS_CC_BEGIN
|
||||
#define NS_CC_END
|
||||
#define USING_NS_CC
|
||||
#endif
|
||||
|
||||
|
||||
#define NS_CC_BEGIN
|
||||
#define NS_CC_END
|
||||
#define USING_NS_CC
|
||||
#endif
|
||||
|
||||
/** CC_PROPERTY_READONLY is used to declare a protected variable.
|
||||
We can use getter to read the variable.
|
||||
|
@ -162,13 +165,21 @@ namespace geode {
|
|||
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)\
|
||||
protected: varType varName;\
|
||||
public: virtual varType get##funName(void);
|
||||
#define CC_PROPERTY_READONLY(varType, varName, funName) \
|
||||
\
|
||||
protected: \
|
||||
varType varName; \
|
||||
\
|
||||
public: \
|
||||
virtual varType get##funName(void);
|
||||
|
||||
#define CC_PROPERTY_READONLY_PASS_BY_REF(varType, varName, funName)\
|
||||
protected: varType varName;\
|
||||
public: virtual const varType& get##funName(void);
|
||||
#define CC_PROPERTY_READONLY_PASS_BY_REF(varType, varName, funName) \
|
||||
\
|
||||
protected: \
|
||||
varType varName; \
|
||||
\
|
||||
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.
|
||||
|
@ -180,15 +191,27 @@ public: virtual const varType& get##funName(void);
|
|||
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)\
|
||||
protected: varType varName;\
|
||||
public: virtual varType get##funName(void);\
|
||||
public: virtual void set##funName(varType var);
|
||||
#define CC_PROPERTY(varType, varName, funName) \
|
||||
\
|
||||
protected: \
|
||||
varType varName; \
|
||||
\
|
||||
public: \
|
||||
virtual varType get##funName(void); \
|
||||
\
|
||||
public: \
|
||||
virtual void set##funName(varType var);
|
||||
|
||||
#define CC_PROPERTY_PASS_BY_REF(varType, varName, funName)\
|
||||
protected: varType varName;\
|
||||
public: virtual const varType& get##funName(void);\
|
||||
public: virtual void set##funName(const varType& var);
|
||||
#define CC_PROPERTY_PASS_BY_REF(varType, varName, funName) \
|
||||
\
|
||||
protected: \
|
||||
varType varName; \
|
||||
\
|
||||
public: \
|
||||
virtual const varType& get##funName(void); \
|
||||
\
|
||||
public: \
|
||||
virtual void set##funName(const varType& var);
|
||||
|
||||
/** CC_SYNTHESIZE_READONLY is used to declare a protected variable.
|
||||
We can use getter to read the variable.
|
||||
|
@ -199,18 +222,29 @@ public: virtual void set##funName(const varType& var);
|
|||
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)\
|
||||
protected: varType varName;\
|
||||
public: virtual varType get##funName(void) const { return varName; }
|
||||
#define CC_SYNTHESIZE_READONLY(varType, varName, funName) \
|
||||
\
|
||||
protected: \
|
||||
varType varName; \
|
||||
\
|
||||
public: \
|
||||
virtual varType get##funName(void) const { return varName; }
|
||||
|
||||
#define CC_SYNTHESIZE_READONLY_NC(varType, varName, funName)\
|
||||
protected: varType varName;\
|
||||
public: virtual varType get##funName(void) { return varName; }
|
||||
#define CC_SYNTHESIZE_READONLY_NC(varType, varName, funName) \
|
||||
\
|
||||
protected: \
|
||||
varType varName; \
|
||||
\
|
||||
public: \
|
||||
virtual varType get##funName(void) { return varName; }
|
||||
|
||||
|
||||
#define CC_SYNTHESIZE_READONLY_PASS_BY_REF(varType, varName, funName)\
|
||||
protected: varType varName;\
|
||||
public: virtual const varType& get##funName(void) const { return varName; }
|
||||
#define CC_SYNTHESIZE_READONLY_PASS_BY_REF(varType, varName, funName) \
|
||||
\
|
||||
protected: \
|
||||
varType varName; \
|
||||
\
|
||||
public: \
|
||||
virtual const varType& get##funName(void) const { return varName; }
|
||||
|
||||
/** CC_SYNTHESIZE is used to declare a protected variable.
|
||||
We can use getter to read the variable, and use the setter to change the variable.
|
||||
|
@ -222,78 +256,141 @@ public: virtual const varType& get##funName(void) const { return varName; }
|
|||
The variables and methods declared after CC_SYNTHESIZE are all public.
|
||||
If you need protected or private, please declare.
|
||||
*/
|
||||
#define CC_SYNTHESIZE(varType, varName, funName)\
|
||||
protected: varType varName;\
|
||||
public: virtual varType get##funName(void) const { return varName; }\
|
||||
public: virtual void set##funName(varType var){ varName = var; }
|
||||
#define CC_SYNTHESIZE(varType, varName, funName) \
|
||||
\
|
||||
protected: \
|
||||
varType varName; \
|
||||
\
|
||||
public: \
|
||||
virtual varType get##funName(void) const { return varName; } \
|
||||
\
|
||||
public: \
|
||||
virtual void set##funName(varType var) { varName = var; }
|
||||
|
||||
#define CC_SYNTHESIZE_PASS_BY_REF(varType, varName, funName)\
|
||||
protected: varType varName;\
|
||||
public: virtual const varType& get##funName(void) const { return varName; }\
|
||||
public: virtual void set##funName(const varType& var){ varName = var; }
|
||||
#define CC_SYNTHESIZE_PASS_BY_REF(varType, varName, funName) \
|
||||
\
|
||||
protected: \
|
||||
varType varName; \
|
||||
\
|
||||
public: \
|
||||
virtual const varType& get##funName(void) const { return varName; } \
|
||||
\
|
||||
public: \
|
||||
virtual void set##funName(const varType& var) { varName = var; }
|
||||
|
||||
#define CC_SYNTHESIZE_RETAIN(varType, varName, funName) \
|
||||
private: varType varName; \
|
||||
public: virtual varType get##funName(void) const { return varName; } \
|
||||
public: virtual void set##funName(varType var) \
|
||||
{ \
|
||||
if (varName != var) \
|
||||
{ \
|
||||
CC_SAFE_RETAIN(var); \
|
||||
CC_SAFE_RELEASE(varName); \
|
||||
varName = var; \
|
||||
} \
|
||||
}
|
||||
#define CC_SYNTHESIZE_RETAIN(varType, varName, funName) \
|
||||
\
|
||||
private: \
|
||||
varType varName; \
|
||||
\
|
||||
public: \
|
||||
virtual varType get##funName(void) const { return varName; } \
|
||||
\
|
||||
public: \
|
||||
virtual void set##funName(varType var) { \
|
||||
if (varName != var) { \
|
||||
CC_SAFE_RETAIN(var); \
|
||||
CC_SAFE_RELEASE(varName); \
|
||||
varName = var; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CC_SAFE_DELETE(p) do { if(p) { delete (p); (p) = 0; } } while(0)
|
||||
#define CC_SAFE_DELETE_ARRAY(p) do { if(p) { delete[] (p); (p) = 0; } } while(0)
|
||||
#define CC_SAFE_FREE(p) do { if(p) { free(p); (p) = 0; } } while(0)
|
||||
#define CC_SAFE_RELEASE(p) do { if(p) { (p)->release(); } } while(0)
|
||||
#define CC_SAFE_RELEASE_NULL(p) do { if(p) { (p)->release(); (p) = 0; } } while(0)
|
||||
#define CC_SAFE_RETAIN(p) do { if(p) { (p)->retain(); } } while(0)
|
||||
#define CC_BREAK_IF(cond) if(cond) break
|
||||
#define CC_SAFE_DELETE(p) \
|
||||
do { \
|
||||
if (p) { \
|
||||
delete (p); \
|
||||
(p) = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
#define CC_SAFE_DELETE_ARRAY(p) \
|
||||
do { \
|
||||
if (p) { \
|
||||
delete[] (p); \
|
||||
(p) = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
#define CC_SAFE_FREE(p) \
|
||||
do { \
|
||||
if (p) { \
|
||||
free(p); \
|
||||
(p) = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
#define CC_SAFE_RELEASE(p) \
|
||||
do { \
|
||||
if (p) { \
|
||||
(p)->release(); \
|
||||
} \
|
||||
} while (0)
|
||||
#define CC_SAFE_RELEASE_NULL(p) \
|
||||
do { \
|
||||
if (p) { \
|
||||
(p)->release(); \
|
||||
(p) = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
#define CC_SAFE_RETAIN(p) \
|
||||
do { \
|
||||
if (p) { \
|
||||
(p)->retain(); \
|
||||
} \
|
||||
} while (0)
|
||||
#define CC_BREAK_IF(cond) \
|
||||
if (cond) break
|
||||
|
||||
#define __CCLOGWITHFUNCTION(s, ...) \
|
||||
CCLog("%s : %s",__FUNCTION__, CCString::createWithFormat(s, ##__VA_ARGS__)->getCString())
|
||||
CCLog("%s : %s", __FUNCTION__, CCString::createWithFormat(s, ##__VA_ARGS__)->getCString())
|
||||
|
||||
// cocos2d debug
|
||||
#if !defined(COCOS2D_DEBUG) || COCOS2D_DEBUG == 0
|
||||
#define CCLOG(...) do {} while (0)
|
||||
#define CCLOGINFO(...) do {} while (0)
|
||||
#define CCLOGERROR(...) do {} while (0)
|
||||
#define CCLOGWARN(...) do {} while (0)
|
||||
#define CCLOG(...) \
|
||||
do { \
|
||||
} while (0)
|
||||
#define CCLOGINFO(...) \
|
||||
do { \
|
||||
} while (0)
|
||||
#define CCLOGERROR(...) \
|
||||
do { \
|
||||
} while (0)
|
||||
#define CCLOGWARN(...) \
|
||||
do { \
|
||||
} while (0)
|
||||
|
||||
#elif COCOS2D_DEBUG == 1
|
||||
#define CCLOG(format, ...) cocos2d::CCLog(format, ##__VA_ARGS__)
|
||||
#define CCLOGERROR(format,...) cocos2d::CCLog(format, ##__VA_ARGS__)
|
||||
#define CCLOGINFO(format,...) do {} while (0)
|
||||
#define CCLOGWARN(...) __CCLOGWITHFUNCTION(__VA_ARGS__)
|
||||
#define CCLOG(format, ...) cocos2d::CCLog(format, ##__VA_ARGS__)
|
||||
#define CCLOGERROR(format, ...) cocos2d::CCLog(format, ##__VA_ARGS__)
|
||||
#define CCLOGINFO(format, ...) \
|
||||
do { \
|
||||
} while (0)
|
||||
#define CCLOGWARN(...) __CCLOGWITHFUNCTION(__VA_ARGS__)
|
||||
|
||||
#elif COCOS2D_DEBUG > 1
|
||||
#define CCLOG(format, ...) cocos2d::CCLog(format, ##__VA_ARGS__)
|
||||
#define CCLOGERROR(format,...) cocos2d::CCLog(format, ##__VA_ARGS__)
|
||||
#define CCLOGINFO(format,...) cocos2d::CCLog(format, ##__VA_ARGS__)
|
||||
#define CCLOGWARN(...) __CCLOGWITHFUNCTION(__VA_ARGS__)
|
||||
#define CCLOG(format, ...) cocos2d::CCLog(format, ##__VA_ARGS__)
|
||||
#define CCLOGERROR(format, ...) cocos2d::CCLog(format, ##__VA_ARGS__)
|
||||
#define CCLOGINFO(format, ...) cocos2d::CCLog(format, ##__VA_ARGS__)
|
||||
#define CCLOGWARN(...) __CCLOGWITHFUNCTION(__VA_ARGS__)
|
||||
#endif // COCOS2D_DEBUG
|
||||
|
||||
// Lua engine debug
|
||||
#if !defined(COCOS2D_DEBUG) || COCOS2D_DEBUG == 0 || CC_LUA_ENGINE_DEBUG == 0
|
||||
#define LUALOG(...)
|
||||
#define LUALOG(...)
|
||||
#else
|
||||
#define LUALOG(format, ...) cocos2d::CCLog(format, ##__VA_ARGS__)
|
||||
#define LUALOG(format, ...) cocos2d::CCLog(format, ##__VA_ARGS__)
|
||||
#endif // Lua engine debug
|
||||
|
||||
#if defined(__GNUC__) && ((__GNUC__ >= 5) || ((__GNUG__ == 4) && (__GNUC_MINOR__ >= 4))) \
|
||||
|| (defined(__clang__) && (__clang_major__ >= 3))
|
||||
#define CC_DISABLE_COPY(Class) \
|
||||
private: \
|
||||
Class(const Class &) = delete; \
|
||||
Class &operator =(const Class &) = delete;
|
||||
#if defined(__GNUC__) && ((__GNUC__ >= 5) || ((__GNUG__ == 4) && (__GNUC_MINOR__ >= 4))) || \
|
||||
(defined(__clang__) && (__clang_major__ >= 3))
|
||||
#define CC_DISABLE_COPY(Class) \
|
||||
\
|
||||
private: \
|
||||
Class(const Class&) = delete; \
|
||||
Class& operator=(const Class&) = delete;
|
||||
#else
|
||||
#define CC_DISABLE_COPY(Class) \
|
||||
private: \
|
||||
Class(const Class &); \
|
||||
Class &operator =(const Class &);
|
||||
#define CC_DISABLE_COPY(Class) \
|
||||
\
|
||||
private: \
|
||||
Class(const Class&); \
|
||||
Class& operator=(const Class&);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -301,11 +398,11 @@ private: \
|
|||
*/
|
||||
#if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))
|
||||
#define CC_DEPRECATED_ATTRIBUTE __attribute__((deprecated))
|
||||
#elif _MSC_VER >= 1400 //vs 2005 or higher
|
||||
#define CC_DEPRECATED_ATTRIBUTE __declspec(deprecated)
|
||||
#elif _MSC_VER >= 1400 // vs 2005 or higher
|
||||
#define CC_DEPRECATED_ATTRIBUTE __declspec(deprecated)
|
||||
#else
|
||||
#define CC_DEPRECATED_ATTRIBUTE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* only certain compiler support __attribute__((format))
|
||||
|
@ -313,48 +410,64 @@ private: \
|
|||
* argPos - 1-based position of first format-dependent argument
|
||||
*/
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4)
|
||||
#define CC_FORMAT_PRINTF(formatPos, argPos) __attribute__((__format__(printf, formatPos, argPos)))
|
||||
#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.
|
||||
*/
|
||||
* 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) __attribute__((__format__(printf, formatPos, argPos)))
|
||||
#endif
|
||||
#if __has_attribute(format)
|
||||
#define CC_FORMAT_PRINTF(formatPos, argPos) \
|
||||
__attribute__((__format__(printf, formatPos, argPos)))
|
||||
#endif
|
||||
#else
|
||||
#define CC_FORMAT_PRINTF(formatPos, argPos)
|
||||
#define CC_FORMAT_PRINTF(formatPos, argPos)
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define CC_FORMAT_PRINTF_SIZE_T "%08lX"
|
||||
#define CC_FORMAT_PRINTF_SIZE_T "%08lX"
|
||||
#else
|
||||
#define CC_FORMAT_PRINTF_SIZE_T "%08zX"
|
||||
#define CC_FORMAT_PRINTF_SIZE_T "%08zX"
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define CC_UNUSED __attribute__ ((unused))
|
||||
#define CC_UNUSED __attribute__((unused))
|
||||
#else
|
||||
#define CC_UNUSED
|
||||
#define CC_UNUSED
|
||||
#endif
|
||||
|
||||
/** CC_PROPERTY_NV
|
||||
* CC_PROPERTY, but getters and setters are not virtual functions.
|
||||
*/
|
||||
#define CC_SYNTHESIZE_NV(varType, varName, funName)\
|
||||
protected: varType varName;\
|
||||
public: varType get##funName(void) const { return varName; }\
|
||||
public: void set##funName(varType var){ varName = var; }
|
||||
* CC_PROPERTY, but getters and setters are not virtual functions.
|
||||
*/
|
||||
#define CC_SYNTHESIZE_NV(varType, varName, funName) \
|
||||
\
|
||||
protected: \
|
||||
varType varName; \
|
||||
\
|
||||
public: \
|
||||
varType get##funName(void) const { return varName; } \
|
||||
\
|
||||
public: \
|
||||
void set##funName(varType var) { varName = var; }
|
||||
|
||||
/**
|
||||
*/
|
||||
#define CC_SYNTHESIZE_READONLY_NV(varType, varName, funName)\
|
||||
protected: varType varName;\
|
||||
public: varType get##funName(void) const { return varName; }\
|
||||
/**
|
||||
*/
|
||||
#define CC_SYNTHESIZE_READONLY_NV(varType, varName, funName) \
|
||||
\
|
||||
protected: \
|
||||
varType varName; \
|
||||
\
|
||||
public: \
|
||||
varType get##funName(void) const { return varName; }
|
||||
|
||||
#define CC_SYNTHESIZE_READONLY_NV_NC(varType, varName, funName)\
|
||||
protected: varType varName;\
|
||||
public: varType get##funName(void) { return varName; }\
|
||||
#define CC_SYNTHESIZE_READONLY_NV_NC(varType, varName, funName) \
|
||||
\
|
||||
protected: \
|
||||
varType varName; \
|
||||
\
|
||||
public: \
|
||||
varType get##funName(void) { return varName; }
|
||||
|
||||
#endif // __CC_PLATFORM_MACROS_H__
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include "../DefaultInclude.hpp"
|
||||
#include "../cocos/support/zip_support/ZipUtils.h"
|
||||
#include <json.hpp>
|
||||
#include "../utils/Result.hpp"
|
||||
#include "../utils/VersionInfo.hpp"
|
||||
#include "../utils/general.hpp"
|
||||
|
@ -11,12 +10,13 @@
|
|||
#include "Setting.hpp"
|
||||
#include "Types.hpp"
|
||||
|
||||
#include <json.hpp>
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include <tulip/TulipHook.hpp>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <tulip/TulipHook.hpp>
|
||||
|
||||
namespace geode {
|
||||
template <class T>
|
||||
|
@ -68,7 +68,6 @@ namespace geode {
|
|||
Mod() = delete;
|
||||
Mod(ModInfo const& info);
|
||||
~Mod();
|
||||
|
||||
|
||||
std::string getID() const;
|
||||
std::string getName() const;
|
||||
|
@ -103,24 +102,56 @@ namespace geode {
|
|||
bool hasSetting(std::string const& key) const;
|
||||
std::optional<Setting> getSettingDefinition(std::string const& key) const;
|
||||
SettingValue* getSetting(std::string const& key) const;
|
||||
void registerCustomSetting(
|
||||
std::string const& key,
|
||||
std::unique_ptr<SettingValue> value
|
||||
);
|
||||
void registerCustomSetting(std::string const& key, std::unique_ptr<SettingValue> value);
|
||||
|
||||
json::Value& getSaveContainer();
|
||||
|
||||
template <class T>
|
||||
T getSettingValue(std::string const& key) const;
|
||||
T getSettingValue(std::string const& key) const {
|
||||
if (auto sett = this->getSetting(key)) {
|
||||
return SettingValueSetter<T>::get(sett);
|
||||
}
|
||||
return T();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T setSettingValue(std::string const& key, T const& value);
|
||||
T setSettingValue(std::string const& key, T const& value) {
|
||||
if (auto sett = this->getSetting(key)) {
|
||||
auto old = this->getSettingValue<T>(sett);
|
||||
SettingValueSetter<T>::set(sett, value);
|
||||
return old;
|
||||
}
|
||||
return T();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T getSavedValue(std::string const& key);
|
||||
T getSavedValue(std::string const& key) {
|
||||
auto& saved = this->getSaveContainer();
|
||||
if (saved.contains(key)) {
|
||||
try {
|
||||
// json -> T may fail
|
||||
return saved.get<T>(key);
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
}
|
||||
return T();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T getSavedValue(std::string const& key, T const& defaultValue);
|
||||
T getSavedValue(std::string const& key, T const& defaultValue) {
|
||||
auto& saved = this->getSaveContainer();
|
||||
if (saved.contains(key)) {
|
||||
try {
|
||||
// json -> T may fail
|
||||
return saved.get<T>(key);
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
}
|
||||
saved[key] = defaultValue;
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of an automatically saved variable. When the game is
|
||||
|
@ -129,8 +160,13 @@ namespace geode {
|
|||
* @param value Value
|
||||
* @returns The old value
|
||||
*/
|
||||
template<class T>
|
||||
T setSavedValue(std::string const& key, T const& value);
|
||||
template <class T>
|
||||
T setSavedValue(std::string const& key, T const& value) {
|
||||
auto& saved = this->getSaveContainer();
|
||||
auto old = this->getSavedValue<T>(key);
|
||||
saved[key] = value;
|
||||
return old;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Mod of the current mod being developed
|
||||
|
@ -157,17 +193,16 @@ namespace geode {
|
|||
* @param address The absolute address of
|
||||
* the function to hook, i.e. gd_base + 0xXXXX
|
||||
* @param detour Pointer to your detour function
|
||||
* @param displayName Name of the hook that will be
|
||||
* @param displayName Name of the hook that will be
|
||||
* displayed in the hook list
|
||||
* @param hookMetadata Metadata of the hook
|
||||
* @param hookMetadata Metadata of the hook
|
||||
* @returns Successful result containing the
|
||||
* Hook pointer, errorful result with info on
|
||||
* error
|
||||
*/
|
||||
template <class Convention, class DetourType>
|
||||
Result<Hook*> addHook(
|
||||
void* address, DetourType detour,
|
||||
std::string const& displayName = "",
|
||||
void* address, DetourType detour, std::string const& displayName = "",
|
||||
tulip::hook::HookMetadata const& hookMetadata = tulip::hook::HookMetadata()
|
||||
) {
|
||||
auto hook = Hook::create<Convention>(this, address, detour, displayName, hookMetadata);
|
||||
|
|
|
@ -1,59 +1,5 @@
|
|||
#include "Mod.hpp"
|
||||
|
||||
#include <json.hpp>
|
||||
|
||||
namespace geode {
|
||||
template <class T>
|
||||
T Mod::getSettingValue(std::string const& key) const {
|
||||
if (auto sett = this->getSetting(key)) {
|
||||
return SettingValueSetter<T>::get(sett);
|
||||
}
|
||||
return T();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T Mod::setSettingValue(std::string const& key, T const& value) {
|
||||
if (auto sett = this->getSetting(key)) {
|
||||
auto old = this->getSettingValue<T>(sett);
|
||||
SettingValueSetter<T>::set(sett, value);
|
||||
return old;
|
||||
}
|
||||
return T();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T Mod::getSavedValue(std::string const& key) {
|
||||
auto& saved = this->getSaveContainer();
|
||||
if (saved.contains(key)) {
|
||||
try {
|
||||
// json -> T may fail
|
||||
return saved.get<T>(key);
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
}
|
||||
return T();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T Mod::getSavedValue(std::string const& key, T const& defaultValue) {
|
||||
auto& saved = this->getSaveContainer();
|
||||
if (saved.contains(key)) {
|
||||
try {
|
||||
// json -> T may fail
|
||||
return saved.get<T>(key);
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
}
|
||||
saved[key] = defaultValue;
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T Mod::setSavedValue(std::string const& key, T const& value) {
|
||||
auto& saved = this->getSaveContainer();
|
||||
auto old = this->getSavedValue<T>(key);
|
||||
saved[key] = value;
|
||||
return old;
|
||||
}
|
||||
}
|
||||
namespace geode {}
|
|
@ -1,6 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <Geode/utils/Result.hpp>
|
||||
#include <tulip/TulipHook.hpp>
|
||||
|
||||
namespace geode::modifier {
|
||||
template <uint32_t Id>
|
||||
uintptr_t address();
|
||||
|
||||
Result<tulip::hook::HandlerMetadata> handlerMetadataForAddress(uintptr_t address);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue