added clang-format

This commit is contained in:
altalk23 2022-10-30 21:24:06 +03:00
parent a1c9063767
commit 94d45ccf21
10 changed files with 963 additions and 703 deletions

140
.clang-format Normal file
View file

@ -0,0 +1,140 @@
---
Language: Cpp
IndentWidth: 4
AlignAfterOpenBracket: BlockIndent
AlignEscapedNewlines: Left
AlignOperands: DontAlign
AlignTrailingComments: false
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Empty
AllowShortFunctionsOnASingleLine: Empty
AllowShortLambdasOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: true
BeforeElse: true
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeConceptDeclarations: true
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: AfterColon
BreakInheritanceList: AfterColon
BreakStringLiterals: true
ColumnLimit: 100
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DeriveLineEnding: false
UseCRLF: false
UseTab: Never
PointerAlignment: Left
ReferenceAlignment: Pointer
EmptyLineBeforeAccessModifier: Always
FixNamespaceComments: false
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^".*"'
Priority: 1
- Regex: '^<.*>'
Priority: 2
IndentAccessModifiers: false
AccessModifierOffset: -4
IndentCaseBlocks: false
IndentCaseLabels: false
IndentExternBlock: Indent
IndentGotoLabels: true
IndentPPDirectives: BeforeHash
IndentWrappedFunctionNames: true
# InsertBraces: true
InsertTrailingCommas: None
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1
LambdaBodyIndentation: Signature
NamespaceIndentation: All
PPIndentWidth: -1
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PenaltyIndentedWhitespace: 0
QualifierAlignment: Right
ReflowComments: true
SeparateDefinitionBlocks: Always
SortIncludes: CaseSensitive
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: Never
SpacesInCStyleCastParentheses: false
SpacesInConditionalStatement: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: c++20

View file

@ -952,6 +952,7 @@ class cocos2d::extension::CCScale9Sprite {
CCScale9Sprite() = mac 0x211330;
static cocos2d::extension::CCScale9Sprite* create(char const*) = mac 0x2130d0;
static cocos2d::extension::CCScale9Sprite* create(char const*, cocos2d::CCRect) = mac 0x212ef0;
static cocos2d::extension::CCScale9Sprite* create(char const*, cocos2d::CCRect, cocos2d::CCRect) = mac 0x212dd0;
static cocos2d::extension::CCScale9Sprite* createWithSpriteFrameName(char const*, cocos2d::CCRect) = mac 0x213380;
static cocos2d::extension::CCScale9Sprite* createWithSpriteFrameName(char const*) = mac 0x213460;
virtual ~CCScale9Sprite() = mac 0x211590;

View file

@ -1,3 +1,22 @@
// geode additions to make stl containers easier
class GDString {
void winDtor() = win 0xf6e0;
char const* winCStr() = win 0xf710;
GDString& winAssign(GDString const&, size_t, size_t) = win 0xf720;
GDString& winAssign(char const*) = win 0xf680;
GDString& winAssign(char const*, size_t) = win 0xf840;
static uintptr_t macEmptyContainer() {
return geode::base::get() + 0x6030d0;
}
void macCtor(char const*) = mac 0x489fc0;
void macCtor(GDString const&) = mac 0x489fcc;
GDString& macAssign(char const*) = mac 0x489f96;
GDString& macAssign(GDString const&) = mac 0x489f9c;
void macDestroy() = mac 0x489f78;
}
class AchievementBar : cocos2d::CCNodeRGBA {
static AchievementBar* create(const char* title, const char* desc, const char* icon, bool quest) = mac 0x379f80, win 0x3b120, ios 0x1a4784;
@ -67,7 +86,9 @@ class AppDelegate : cocos2d::CCApplication {
virtual void applicationWillResignActive() = mac 0x3aab50, win 0x3cf20;
virtual void trySaveGame() = mac 0x3aaf10, win 0x3d5e0, ios 0x1a28f0;
virtual void willSwitchToScene(cocos2d::CCScene*) = mac 0x3aaf40, win 0x3d690;
static AppDelegate* get() = mac 0x3aab10;
static AppDelegate* get() {
return static_cast<AppDelegate*>(cocos2d::CCApplication::sharedApplication());
}
bool musicTest() = win 0x3d580;
void pauseGame() = mac 0x3aab60, win 0x3d3e0;
void resumeSound() = win 0x3d4d0;
@ -814,7 +835,7 @@ class CreatorLayer : cocos2d::CCLayer {
void onBack(cocos2d::CCObject*) = win 0x4fae0;
void onChallenge(cocos2d::CCObject*) = win 0x4f1b0;
void onLeaderboards(cocos2d::CCObject*) = win 0x4ed20;
void onMyLevels(cocos2d::CCObject*) = mac 0x142b70;
void onMyLevels(cocos2d::CCObject*) = mac 0x142b70, win 0x4eaa0;
void onSavedLevels(cocos2d::CCObject*) = mac 0x142860;
virtual void sceneWillResume() = win 0x4fb50;
virtual bool init() = mac 0x141c10, win 0x4de40;
@ -910,6 +931,7 @@ class DailyLevelPage : FLAlertLayer {
static DailyLevelPage* create(bool weekly) = win 0x6a860;
bool init(bool weekly) = win 0x6a900;
void updateTimers(float) = win 0x6bef0;
virtual void show() = mac 0x10a4b0, win 0x3f360;
PAD = win 0x21;
bool m_weekly;
@ -1021,7 +1043,7 @@ class EditButtonBar : cocos2d::CCNode {
}
void addButton(CCMenuItemSpriteExtra* btn, bool reload) {
if (this->m_buttonArray)
this->m_buttonArray->addObject(static_cast<cocos2d::CCObject*>(btn));
this->m_buttonArray->addObject(btn);
if (reload)
this->reloadItemsInNormalSize();
}
@ -1040,7 +1062,7 @@ class EditLevelLayer : cocos2d::CCLayer, FLAlertLayerProtocol, TextInputDelegate
static void scene(GJGameLevel* level) {
auto scene = cocos2d::CCScene::create();
scene->addChild(static_cast<cocos2d::CCNode*>(EditLevelLayer::create(level)));
scene->addChild(EditLevelLayer::create(level));
cocos2d::CCDirector::sharedDirector()->replaceScene(
cocos2d::CCTransitionFade::create(.5f, scene)
@ -4826,6 +4848,7 @@ class SelectArtLayer {
}
class SetGroupIDLayer : FLAlertLayer, TextInputDelegate {
bool init(GameObject* object, cocos2d::CCArray* objects) = mac 0x1947c0, win 0x22b670;
void onNextGroupID1(cocos2d::CCObject*) = mac 0x1967a0, win 0x22d790;
void textChanged(CCTextInputNode*) = mac 0x197af0, win 0x22d610;
void updateGroupIDLabel() = mac 0x197260, win 0x22e450;

View file

@ -1,513 +1,2 @@
#pragma once
#include <string>
#include <map>
#include <vector>
#include <iostream>
#include <variant> // for std::monostate
#include <algorithm>
#include <Geode/platform/platform.hpp>
//#include "../utils/platform.hpp"
namespace geode::base {
uintptr_t get();
}
#if defined(GEODE_IS_MACOS) || defined(GEODE_IS_ANDROID)
namespace gd {
struct _internal_string {
size_t m_len;
size_t m_capacity;
int m_refcount;
};
class GEODE_DLL string {
public:
string();
string(char const* ok);
string(std::string ok) : string(ok.c_str()) {}
operator std::string() const {
return std::string((char*)m_data, m_data[-1].m_len);
}
bool operator==(string const& other) const;
string(string const& ok);
string& operator=(char const* ok);
string& operator=(string const& ok);
__attribute__((noinline)) ~string();
char const* c_str() const { return (char const*)m_data; }
size_t size() const { return m_data[-1].m_len; }
protected:
_internal_string* m_data;
};
struct _rb_tree_base {
bool m_isblack;
_rb_tree_base* m_parent;
_rb_tree_base* m_left;
_rb_tree_base* m_right;
};
template<typename T>
struct _rb_tree_node : public _rb_tree_base {
T m_value;
};
static void _rb_tree_rotate_left(_rb_tree_base* const x, _rb_tree_base*& root) {
_rb_tree_base* const y = x->m_right;
x->m_right = y->m_left;
if (y->m_left !=0)
y->m_left->m_parent = x;
y->m_parent = x->m_parent;
if (x == root)
root = y;
else if (x == x->m_parent->m_left)
x->m_parent->m_left = y;
else
x->m_parent->m_right = y;
y->m_left = x;
x->m_parent = y;
}
static void _rb_tree_rotate_right(_rb_tree_base* const x, _rb_tree_base*& root) {
_rb_tree_base* const y = x->m_left;
x->m_left = y->m_right;
if (y->m_right != 0)
y->m_right->m_parent = x;
y->m_parent = x->m_parent;
if (x == root)
root = y;
else if (x == x->m_parent->m_right)
x->m_parent->m_right = y;
else
x->m_parent->m_left = y;
y->m_right = x;
x->m_parent = y;
}
static void _rb_insert_rebalance(const bool insert_left, _rb_tree_base* x, _rb_tree_base* p, _rb_tree_base& header) {
_rb_tree_base *& root = header.m_parent;
x->m_parent = p;
x->m_left = 0;
x->m_right = 0;
x->m_isblack = false;
if (insert_left) {
p->m_left = x;
if (p == &header) {
header.m_parent = x;
header.m_right = x;
} else if (p == header.m_left){
header.m_left = x;
}
} else {
p->m_right = x;
if (p == header.m_right) {
header.m_right = x;
}
}
while (x != root && x->m_parent->m_isblack == false) {
_rb_tree_base* const xpp = x->m_parent->m_parent;
if (x->m_parent == xpp->m_left) {
_rb_tree_base* const y = xpp->m_right;
if (y && y->m_isblack == false) {
x->m_parent->m_isblack = true;
y->m_isblack = true;
xpp->m_isblack = false;
x = xpp;
} else {
if (x == x->m_parent->m_right) {
x = x->m_parent;
_rb_tree_rotate_left(x, root);
}
x->m_parent->m_isblack = true;
xpp->m_isblack = false;
_rb_tree_rotate_right(xpp, root);
}
} else {
_rb_tree_base* const y = xpp->m_left;
if (y && y->m_isblack == false) {
x->m_parent->m_isblack = true;
y->m_isblack = true;
xpp->m_isblack = false;
x = xpp;
} else {
if (x == x->m_parent->m_left) {
x = x->m_parent;
_rb_tree_rotate_right(x, root);
}
x->m_parent->m_isblack = true;
xpp->m_isblack = false;
_rb_tree_rotate_left(xpp, root);
}
}
}
root->m_isblack = true;
}
static _rb_tree_base* _rb_increment(_rb_tree_base* __x) throw () {
if (__x->m_right != 0) {
__x = __x->m_right;
while (__x->m_left != 0)
__x = __x->m_left;
} else {
_rb_tree_base* __y = __x->m_parent;
while (__x == __y->m_right) {
__x = __y;
__y = __y->m_parent;
}
if (__x->m_right != __y)
__x = __y;
}
return __x;
}
static _rb_tree_base* _rb_decrement(_rb_tree_base* __x) throw () {
if (!__x->m_isblack && __x->m_parent->m_parent == __x)
__x = __x->m_right;
else if (__x->m_left != 0) {
_rb_tree_base* __y = __x->m_left;
while (__y->m_right != 0)
__y = __y->m_right;
__x = __y;
} else {
_rb_tree_base* __y = __x->m_parent;
while (__x == __y->m_left) {
__x = __y;
__y = __y->m_parent;
}
__x = __y;
}
return __x;
}
template <typename K, typename V>
class GEODE_DLL map {
protected:
std::less<K> compare;
_rb_tree_base m_header;
size_t m_nodecount;
public:
typedef _rb_tree_node<std::pair<K,V> >* _tree_node;
std::map<K, V> std() {
return (std::map<K, V>)(*this);
}
operator std::map<K, V>() {
auto iter_node = static_cast<_tree_node>(m_header.m_left);
auto end_node = static_cast<_tree_node>(&m_header);
std::map<K, V> out;
for (;iter_node != end_node; iter_node = static_cast<_tree_node>(_rb_increment(iter_node))) {
out[iter_node->m_value.first] = iter_node->m_value.second;
}
return out;
}
operator std::map<K, V>() const {
auto iter_node = static_cast<_tree_node>(m_header.m_left);
auto end_node = (_tree_node)(&m_header);
std::map<K, V> out;
for (;iter_node != end_node; iter_node = static_cast<_tree_node>(_rb_increment(iter_node))) {
out[iter_node->m_value.first] = iter_node->m_value.second;
}
return out;
}
void insert(_tree_node x, _tree_node p, const std::pair<K, V>& val) {
bool insert_left = (x != 0 || p == static_cast<_tree_node>(&m_header) || val.first < p->m_value.first);
_tree_node z = new _rb_tree_node<std::pair<K,V> >();
z->m_value = val;
_rb_insert_rebalance(insert_left, z, p, m_header);
++m_nodecount;
}
void insert_pair(const std::pair<K, V>& val) {
_tree_node x = static_cast<_tree_node>(m_header.m_parent);
_tree_node y = static_cast<_tree_node>(&m_header);
bool comp = true;
while (x != 0) {
y = x;
comp = val.first < x->m_value.first;
x = comp ? static_cast<_tree_node>(x->m_left) : static_cast<_tree_node>(x->m_right);
}
auto iter = y;
if (comp) {
if (iter == static_cast<_tree_node>(m_header.m_left)) {
insert(x, y, val);
} else {
iter = static_cast<_tree_node>(_rb_decrement(iter));
}
}
if (iter->m_value.first < val.first) {
insert(x, y, val);
}
}
map(std::map<K, V> input) {
m_header.m_isblack = false;
m_header.m_parent = 0;
m_header.m_left = &m_header;
m_header.m_right = &m_header;
for (auto i : input) {
insert_pair(i);
}
}
void erase(_tree_node x) {
while (x != 0) {
erase(static_cast<_tree_node>(x->m_right));
auto y = static_cast<_tree_node>(x->m_left);
delete y;
x = y;
}
}
map(map const& lol) : map(std::map<K, V>(lol)) {}
map() : map(std::map<K, V>()) {}
~map() {
erase(static_cast<_tree_node>(m_header.m_parent));
}
};
template <typename T>
class GEODE_DLL vector {
public:
using value_type = T;
operator std::vector<T>() const {
std::vector<T> out;
for (auto i = m_start; i != m_finish; ++i) {
out.push_back(*i);
}
return out;
}
vector(std::vector<T> input) {
auto tmp = new T[input.size()];
m_start = tmp;
m_finish = m_start + input.size();
m_capacity_end = m_start + input.size();
for (auto i : input) {
*tmp = i;
tmp++;
}
}
vector(std::initializer_list<T> const& input) {
auto tmp = new T[input.size()];
m_start = tmp;
m_finish = m_start + input.size();
m_capacity_end = m_start + input.size();
std::copy(input.begin(), input.end(), tmp);
}
T& front() {
return *m_start;
}
auto begin() { return m_start; }
auto end() { return m_finish; }
auto begin() const { return static_cast<const T*>(m_start); }
auto end() const { return static_cast<const T*>(m_finish); }
vector(vector const& lol) : vector(std::vector<T>(lol)) {}
vector() : vector(std::vector<T>()) {}
~vector() {
delete[] m_start;
}
protected:
T* m_start;
T* m_finish;
T* m_capacity_end;
};
struct _bit_reference {
uintptr_t* m_bitptr;
uintptr_t m_mask;
_bit_reference(uintptr_t* x, uintptr_t y) : m_bitptr(x), m_mask(y) {}
_bit_reference() : m_bitptr(0), m_mask(0) {}
operator bool() const {
return !!(*m_bitptr & m_mask);
}
_bit_reference& operator=(bool x) {
if (x)
*m_bitptr |= m_mask;
else
*m_bitptr &= ~m_mask;
return *this;
}
_bit_reference& operator=(const _bit_reference& x) {
return *this = bool(x);
}
bool operator==(const _bit_reference& x) const {
return bool(*this) == bool(x);
}
bool operator<(const _bit_reference& x) const {
return !bool(*this) && bool(x);
}
void flip() {
*m_bitptr ^= m_mask;
}
};
struct _bit_iterator {
uintptr_t* m_bitptr;
unsigned int m_offset;
_bit_iterator(uintptr_t* x) : m_bitptr(x), m_offset(0) {}
_bit_iterator(uintptr_t* x, unsigned o) : m_bitptr(x), m_offset(o) {}
_bit_reference operator*() const {
return _bit_reference(m_bitptr, 1UL << m_offset);
}
_bit_iterator& operator++() {
if (m_offset++ == sizeof(uintptr_t)-1) {
m_offset = 0;
m_bitptr++;
}
return *this;
}
bool operator!=(const _bit_iterator& b) {
return !(m_bitptr == b.m_bitptr && m_offset == b.m_offset);
}
};
template <>
class vector<bool> {
protected:
_bit_iterator m_start;
_bit_iterator m_end;
uintptr_t* m_capacity_end;
public:
vector(std::vector<bool> input) : m_start(0), m_end(0) {
auto realsize = input.size()/int(sizeof(uintptr_t));
auto tmp = new uintptr_t[realsize];
m_start = _bit_iterator(tmp);
m_end = _bit_iterator(tmp + realsize, input.size()%sizeof(uintptr_t));
m_capacity_end = tmp + realsize;
auto itmp = m_start;
for (auto i : input) {
*itmp = i;
++itmp;
}
}
operator std::vector<bool>() {
std::vector<bool> out;
for (auto i = m_start; i != m_end; ++i) {
out.push_back(*i);
}
return out;
}
operator std::vector<bool>() const {
std::vector<bool> out;
for (auto i = m_start; i != m_end; ++i) {
out.push_back(*i);
}
return out;
}
vector(vector<bool> const& lol) : vector(std::vector<bool>(lol)) {}
vector() : vector(std::vector<bool>()) {}
~vector() {
delete[] m_start.m_bitptr;
}
};
};
#elif defined(GEODE_IS_IOS)
namespace gd {
class GEODE_DLL string {
public:
string() {}
string(char const* ok) : m_internal(ok) {}
string(std::string ok) : m_internal(ok) {}
operator std::string() {
return m_internal;
}
operator std::string() const {
return m_internal;
}
string(string const& ok) : m_internal(ok) {}
string& operator=(char const* ok) {m_internal = ok; return *this;}
string& operator=(string const& ok) {m_internal = ok; return *this;}
~string() {}
char const* c_str() const {return m_internal.c_str(); }
protected:
std::string m_internal;
};
template <typename T>
class GEODE_DLL vector {
public:
using value_type = T;
operator std::vector<T>() {
return m_internal;
}
operator std::vector<T>() const {
return m_internal;
}
vector(std::vector<T> input) : m_internal(input) {}
T& front() {
return m_internal.front();
}
vector(vector const& lol) : m_internal(lol) {}
vector() : m_internal() {}
~vector() {}
protected:
std::vector<T> m_internal;
};
template <typename K, typename V>
class GEODE_DLL map {
protected:
std::map<K, V> m_internal;
public:
operator std::map<K, V>() {
return m_internal;
}
operator std::map<K, V>() const {
return m_internal;
}
map(std::map<K, V> input) : m_internal(input) {}
map(map const& lol) : m_internal(lol) {}
map() {}
~map() {}
};
}
#else
namespace gd = std;
#endif
#include "gnustl.hpp"
// #include "msvcstl.hpp"

View file

@ -0,0 +1,512 @@
#pragma once
#include <string>
#include <map>
#include <vector>
#include <algorithm>
#include <Geode/platform/platform.hpp>
// #include <Geode/binding/GDString.hpp>
//#include "../utils/platform.hpp"
namespace geode::base {
uintptr_t get();
}
#if defined(GEODE_IS_MACOS) || defined(GEODE_IS_ANDROID)
namespace gd {
struct _internal_string {
size_t m_len;
size_t m_capacity;
int m_refcount;
};
class GEODE_DLL string {
public:
string();
string(char const* ok);
string(std::string ok) : string(ok.c_str()) {}
operator std::string() const {
return std::string((char*)m_data, m_data[-1].m_len);
}
bool operator==(string const& other) const;
string(string const& ok);
string& operator=(char const* ok);
string& operator=(string const& ok);
__attribute__((noinline)) ~string();
char const* c_str() const { return (char const*)m_data; }
size_t size() const { return m_data[-1].m_len; }
protected:
_internal_string* m_data;
};
struct _rb_tree_base {
bool m_isblack;
_rb_tree_base* m_parent;
_rb_tree_base* m_left;
_rb_tree_base* m_right;
};
template<typename T>
struct _rb_tree_node : public _rb_tree_base {
T m_value;
};
static void _rb_tree_rotate_left(_rb_tree_base* const x, _rb_tree_base*& root) {
_rb_tree_base* const y = x->m_right;
x->m_right = y->m_left;
if (y->m_left !=0)
y->m_left->m_parent = x;
y->m_parent = x->m_parent;
if (x == root)
root = y;
else if (x == x->m_parent->m_left)
x->m_parent->m_left = y;
else
x->m_parent->m_right = y;
y->m_left = x;
x->m_parent = y;
}
static void _rb_tree_rotate_right(_rb_tree_base* const x, _rb_tree_base*& root) {
_rb_tree_base* const y = x->m_left;
x->m_left = y->m_right;
if (y->m_right != 0)
y->m_right->m_parent = x;
y->m_parent = x->m_parent;
if (x == root)
root = y;
else if (x == x->m_parent->m_right)
x->m_parent->m_right = y;
else
x->m_parent->m_left = y;
y->m_right = x;
x->m_parent = y;
}
static void _rb_insert_rebalance(const bool insert_left, _rb_tree_base* x, _rb_tree_base* p, _rb_tree_base& header) {
_rb_tree_base *& root = header.m_parent;
x->m_parent = p;
x->m_left = 0;
x->m_right = 0;
x->m_isblack = false;
if (insert_left) {
p->m_left = x;
if (p == &header) {
header.m_parent = x;
header.m_right = x;
} else if (p == header.m_left){
header.m_left = x;
}
} else {
p->m_right = x;
if (p == header.m_right) {
header.m_right = x;
}
}
while (x != root && x->m_parent->m_isblack == false) {
_rb_tree_base* const xpp = x->m_parent->m_parent;
if (x->m_parent == xpp->m_left) {
_rb_tree_base* const y = xpp->m_right;
if (y && y->m_isblack == false) {
x->m_parent->m_isblack = true;
y->m_isblack = true;
xpp->m_isblack = false;
x = xpp;
} else {
if (x == x->m_parent->m_right) {
x = x->m_parent;
_rb_tree_rotate_left(x, root);
}
x->m_parent->m_isblack = true;
xpp->m_isblack = false;
_rb_tree_rotate_right(xpp, root);
}
} else {
_rb_tree_base* const y = xpp->m_left;
if (y && y->m_isblack == false) {
x->m_parent->m_isblack = true;
y->m_isblack = true;
xpp->m_isblack = false;
x = xpp;
} else {
if (x == x->m_parent->m_left) {
x = x->m_parent;
_rb_tree_rotate_right(x, root);
}
x->m_parent->m_isblack = true;
xpp->m_isblack = false;
_rb_tree_rotate_left(xpp, root);
}
}
}
root->m_isblack = true;
}
static _rb_tree_base* _rb_increment(_rb_tree_base* __x) throw () {
if (__x->m_right != 0) {
__x = __x->m_right;
while (__x->m_left != 0)
__x = __x->m_left;
} else {
_rb_tree_base* __y = __x->m_parent;
while (__x == __y->m_right) {
__x = __y;
__y = __y->m_parent;
}
if (__x->m_right != __y)
__x = __y;
}
return __x;
}
static _rb_tree_base* _rb_decrement(_rb_tree_base* __x) throw () {
if (!__x->m_isblack && __x->m_parent->m_parent == __x)
__x = __x->m_right;
else if (__x->m_left != 0) {
_rb_tree_base* __y = __x->m_left;
while (__y->m_right != 0)
__y = __y->m_right;
__x = __y;
} else {
_rb_tree_base* __y = __x->m_parent;
while (__x == __y->m_left) {
__x = __y;
__y = __y->m_parent;
}
__x = __y;
}
return __x;
}
template <typename K, typename V>
class GEODE_DLL map {
protected:
std::less<K> compare;
_rb_tree_base m_header;
size_t m_nodecount;
public:
typedef _rb_tree_node<std::pair<K,V> >* _tree_node;
std::map<K, V> std() {
return (std::map<K, V>)(*this);
}
operator std::map<K, V>() {
auto iter_node = static_cast<_tree_node>(m_header.m_left);
auto end_node = static_cast<_tree_node>(&m_header);
std::map<K, V> out;
for (;iter_node != end_node; iter_node = static_cast<_tree_node>(_rb_increment(iter_node))) {
out[iter_node->m_value.first] = iter_node->m_value.second;
}
return out;
}
operator std::map<K, V>() const {
auto iter_node = static_cast<_tree_node>(m_header.m_left);
auto end_node = (_tree_node)(&m_header);
std::map<K, V> out;
for (;iter_node != end_node; iter_node = static_cast<_tree_node>(_rb_increment(iter_node))) {
out[iter_node->m_value.first] = iter_node->m_value.second;
}
return out;
}
void insert(_tree_node x, _tree_node p, const std::pair<K, V>& val) {
bool insert_left = (x != 0 || p == static_cast<_tree_node>(&m_header) || val.first < p->m_value.first);
_tree_node z = new _rb_tree_node<std::pair<K,V> >();
z->m_value = val;
_rb_insert_rebalance(insert_left, z, p, m_header);
++m_nodecount;
}
void insert_pair(const std::pair<K, V>& val) {
_tree_node x = static_cast<_tree_node>(m_header.m_parent);
_tree_node y = static_cast<_tree_node>(&m_header);
bool comp = true;
while (x != 0) {
y = x;
comp = val.first < x->m_value.first;
x = comp ? static_cast<_tree_node>(x->m_left) : static_cast<_tree_node>(x->m_right);
}
auto iter = y;
if (comp) {
if (iter == static_cast<_tree_node>(m_header.m_left)) {
insert(x, y, val);
} else {
iter = static_cast<_tree_node>(_rb_decrement(iter));
}
}
if (iter->m_value.first < val.first) {
insert(x, y, val);
}
}
map(std::map<K, V> input) {
m_header.m_isblack = false;
m_header.m_parent = 0;
m_header.m_left = &m_header;
m_header.m_right = &m_header;
for (auto i : input) {
insert_pair(i);
}
}
void erase(_tree_node x) {
while (x != 0) {
erase(static_cast<_tree_node>(x->m_right));
auto y = static_cast<_tree_node>(x->m_left);
delete y;
x = y;
}
}
map(map const& lol) : map(std::map<K, V>(lol)) {}
map() : map(std::map<K, V>()) {}
~map() {
erase(static_cast<_tree_node>(m_header.m_parent));
}
};
template <typename T>
class GEODE_DLL vector {
public:
using value_type = T;
operator std::vector<T>() const {
std::vector<T> out;
for (auto i = m_start; i != m_finish; ++i) {
out.push_back(*i);
}
return out;
}
vector(std::vector<T> input) {
auto tmp = new T[input.size()];
m_start = tmp;
m_finish = m_start + input.size();
m_capacity_end = m_start + input.size();
for (auto i : input) {
*tmp = i;
tmp++;
}
}
vector(std::initializer_list<T> const& input) {
auto tmp = new T[input.size()];
m_start = tmp;
m_finish = m_start + input.size();
m_capacity_end = m_start + input.size();
std::copy(input.begin(), input.end(), tmp);
}
T& front() {
return *m_start;
}
auto begin() { return m_start; }
auto end() { return m_finish; }
auto begin() const { return static_cast<const T*>(m_start); }
auto end() const { return static_cast<const T*>(m_finish); }
vector(vector const& lol) : vector(std::vector<T>(lol)) {}
vector() : vector(std::vector<T>()) {}
~vector() {
delete[] m_start;
}
protected:
T* m_start;
T* m_finish;
T* m_capacity_end;
};
struct _bit_reference {
uintptr_t* m_bitptr;
uintptr_t m_mask;
_bit_reference(uintptr_t* x, uintptr_t y) : m_bitptr(x), m_mask(y) {}
_bit_reference() : m_bitptr(0), m_mask(0) {}
operator bool() const {
return !!(*m_bitptr & m_mask);
}
_bit_reference& operator=(bool x) {
if (x)
*m_bitptr |= m_mask;
else
*m_bitptr &= ~m_mask;
return *this;
}
_bit_reference& operator=(const _bit_reference& x) {
return *this = bool(x);
}
bool operator==(const _bit_reference& x) const {
return bool(*this) == bool(x);
}
bool operator<(const _bit_reference& x) const {
return !bool(*this) && bool(x);
}
void flip() {
*m_bitptr ^= m_mask;
}
};
struct _bit_iterator {
uintptr_t* m_bitptr;
unsigned int m_offset;
_bit_iterator(uintptr_t* x) : m_bitptr(x), m_offset(0) {}
_bit_iterator(uintptr_t* x, unsigned o) : m_bitptr(x), m_offset(o) {}
_bit_reference operator*() const {
return _bit_reference(m_bitptr, 1UL << m_offset);
}
_bit_iterator& operator++() {
if (m_offset++ == sizeof(uintptr_t)-1) {
m_offset = 0;
m_bitptr++;
}
return *this;
}
bool operator!=(const _bit_iterator& b) {
return !(m_bitptr == b.m_bitptr && m_offset == b.m_offset);
}
};
template <>
class vector<bool> {
protected:
_bit_iterator m_start;
_bit_iterator m_end;
uintptr_t* m_capacity_end;
public:
vector(std::vector<bool> input) : m_start(0), m_end(0) {
auto realsize = input.size()/int(sizeof(uintptr_t));
auto tmp = new uintptr_t[realsize];
m_start = _bit_iterator(tmp);
m_end = _bit_iterator(tmp + realsize, input.size()%sizeof(uintptr_t));
m_capacity_end = tmp + realsize;
auto itmp = m_start;
for (auto i : input) {
*itmp = i;
++itmp;
}
}
operator std::vector<bool>() {
std::vector<bool> out;
for (auto i = m_start; i != m_end; ++i) {
out.push_back(*i);
}
return out;
}
operator std::vector<bool>() const {
std::vector<bool> out;
for (auto i = m_start; i != m_end; ++i) {
out.push_back(*i);
}
return out;
}
vector(vector<bool> const& lol) : vector(std::vector<bool>(lol)) {}
vector() : vector(std::vector<bool>()) {}
~vector() {
delete[] m_start.m_bitptr;
}
};
};
#elif defined(GEODE_IS_IOS)
namespace gd {
class GEODE_DLL string {
public:
string() {}
string(char const* ok) : m_internal(ok) {}
string(std::string ok) : m_internal(ok) {}
operator std::string() {
return m_internal;
}
operator std::string() const {
return m_internal;
}
string(string const& ok) : m_internal(ok) {}
string& operator=(char const* ok) {m_internal = ok; return *this;}
string& operator=(string const& ok) {m_internal = ok; return *this;}
~string() {}
char const* c_str() const {return m_internal.c_str(); }
protected:
std::string m_internal;
};
template <typename T>
class GEODE_DLL vector {
public:
using value_type = T;
operator std::vector<T>() {
return m_internal;
}
operator std::vector<T>() const {
return m_internal;
}
vector(std::vector<T> input) : m_internal(input) {}
T& front() {
return m_internal.front();
}
vector(vector const& lol) : m_internal(lol) {}
vector() : m_internal() {}
~vector() {}
protected:
std::vector<T> m_internal;
};
template <typename K, typename V>
class GEODE_DLL map {
protected:
std::map<K, V> m_internal;
public:
operator std::map<K, V>() {
return m_internal;
}
operator std::map<K, V>() const {
return m_internal;
}
map(std::map<K, V> input) : m_internal(input) {}
map(map const& lol) : m_internal(lol) {}
map() {}
~map() {}
};
}
#else
namespace gd = std;
#endif

View file

@ -0,0 +1,96 @@
#pragma once
#include <string>
#include <map>
#include <vector>
#include <algorithm>
#include <functional>
#include <Geode/platform/platform.hpp>
// #include <Geode/binding/GDString.hpp>
#if defined(GEODE_IS_WINDOWS)
namespace gd {
struct InternalString {
union {
char m_storage[16];
char* m_pointer;
};
size_t m_length;
size_t m_capacity;
};
class GEODE_DLL string : protected GDString {
private:
InternalString m_data;
public:
template <class... Params>
string(Params&&... params) {
m_data.m_pointer = 0;
m_data.m_length = 0;
m_data.m_capacity = 15;
auto val = std::string(std::forward<Params>(params)...);
(void)this->winAssign(val.c_str(), val.size());
}
~string() {
(void)this->winDtor();
}
/*template <class... Params>
decltype(auto) operator=(Params&&... params) -> decltype(this->operator=(std::forward<Params>(params)...)) {
auto val = std::string(this->winCStr(), m_data.m_length);
val.operator=(std::forward<Params>(params)...);
(void)this->winAssign(val.c_str(), val.size());
}*/
template <class... Params>
string& operator=(Params&&... params) {
auto val = std::string(this->winCStr(), m_data.m_length);
val.operator=(std::forward<Params>(params)...);
(void)this->winAssign(val.c_str(), val.size());
return *this;
}
template <class... Params>
string& assign(Params&&... params) {
auto val = std::string(this->winCStr(), m_data.m_length);
val.assign(std::forward<Params>(params)...);
(void)this->winAssign(val.c_str(), val.size());
return *this;
}
char& at(size_t pos) {
if (pos >= m_data.m_length) throw std::out_of_range("gd::string::at");
}
char const& at(size_t pos) const {
if (pos >= m_data.m_length) throw std::out_of_range("gd::string::at");
}
char& operator[](size_t pos) {
return this->winCStr()[pos];
}
char const& operator[](size_t pos) const {
return this->winCStr()[pos];
}
char* data() {
return this->winCStr();
}
char const* data() const {
return this->winCStr();
}
char const* c_str() const {
return this->winCStr();
}
};
}
#endif

View file

@ -1,21 +1,23 @@
#pragma once
#include <Geode/DefaultInclude.hpp>
#include "Types.hpp"
#include "Hook.hpp"
#include <Geode/utils/types.hpp>
#include "Setting.hpp"
#include "Types.hpp"
#include <Geode/DefaultInclude.hpp>
#include <Geode/utils/Result.hpp>
#include <Geode/utils/VersionInfo.hpp>
#include <Geode/utils/json.hpp>
#include <string_view>
#include <vector>
#include <unordered_map>
#include <type_traits>
#include "Setting.hpp"
#include <Geode/utils/types.hpp>
#include <optional>
#include <string_view>
#include <type_traits>
#include <unordered_map>
#include <vector>
class InternalLoader;
class InternalMod;
namespace geode {
struct PlatformInfo;
@ -26,8 +28,8 @@ namespace geode {
class Setting;
class Unknown;
using unknownmemfn_t = void(Unknown::*)();
using unknownfn_t = void(*)();
using unknownmemfn_t = void (Unknown::*)();
using unknownfn_t = void (*)();
}
/**
@ -35,7 +37,7 @@ namespace geode {
*/
GEODE_API bool GEODE_CALL geode_implicit_load(geode::Mod*);
namespace geode {
namespace geode {
struct Dependency {
std::string m_id;
@ -53,7 +55,7 @@ namespace geode {
};
/**
* Represents all the data gatherable
* Represents all the data gatherable
* from mod.json
*/
struct GEODE_DLL ModInfo {
@ -62,13 +64,15 @@ namespace geode {
*/
ghc::filesystem::path m_path;
/**
* Name of the platform binary within
* Name of the platform binary within
* the mod zip
*/
// clang-format off
std::string m_binaryName = GEODE_WINDOWS("mod.dll")
GEODE_MACOS("mod.dylib")
GEODE_IOS("mod.dylib")
GEODE_ANDROID("mod.so");
// clang-format on
/**
* Mod Version. Should follow semver.
*/
@ -103,12 +107,12 @@ namespace geode {
*/
std::string m_developer;
/**
* Short & concise description of the
* Short & concise description of the
* mod.
*/
std::optional<std::string> m_description;
/**
* Detailed description of the mod, writtenin Markdown (see
* Detailed description of the mod, writtenin Markdown (see
* <Geode/ui/MDTextArea.hpp>) for more info
*/
std::optional<std::string> m_details;
@ -118,8 +122,8 @@ namespace geode {
*/
std::optional<std::string> m_changelog;
/**
* Support info for the mod; this means anything to show ways to
* support the mod's development, like donations. Written in Markdown
* Support info for the mod; this means anything to show ways to
* support the mod's development, like donations. Written in Markdown
* (see <Geode/ui/MDTextArea.hpp>) for more info
*/
std::optional<std::string> m_supportInfo;
@ -170,8 +174,8 @@ namespace geode {
private:
/**
* Version is passed for backwards
* compatibility if we update the mod.json
* Version is passed for backwards
* compatibility if we update the mod.json
* format
*/
static Result<ModInfo> createFromSchemaV010(ModJson const& json);
@ -179,10 +183,7 @@ namespace geode {
Result<> addSpecialFiles(ghc::filesystem::path const& dir);
Result<> addSpecialFiles(cocos2d::ZipFile& zip);
std::vector<std::pair<
std::string,
std::optional<std::string>*
>> getSpecialFiles();
std::vector<std::pair<std::string, std::optional<std::string>*>> getSpecialFiles();
};
/**
@ -195,7 +196,7 @@ namespace geode {
Mod* m_mod;
DataStore(Mod* m, nlohmann::json& j) : m_mod(m), m_store(j) {}
friend class Mod;
public:
@ -206,12 +207,11 @@ namespace geode {
DataStore& operator=(nlohmann::json&);
bool contains(std::string const&) const;
operator nlohmann::json();
};
/**
* @class Mod
* Represents a Mod ingame.
* Represents a Mod ingame.
* @abstract
*/
class GEODE_DLL Mod {
@ -253,9 +253,9 @@ namespace geode {
*/
ghc::filesystem::path m_saveDirPath;
/**
* Pointers to mods that depend on
* this Mod. Makes it possible to
* enable / disable them automatically,
* Pointers to mods that depend on
* this Mod. Makes it possible to
* enable / disable them automatically,
* when their dependency is disabled.
*/
std::vector<Mod*> m_parentDependencies;
@ -283,7 +283,7 @@ namespace geode {
geode_save_data m_saveDataFunc = nullptr;
geode_setting_updated m_settingUpdatedFunc = nullptr;
/**
* Whether temp/<mod id>/resources should be
* Whether temp/<mod id>/resources should be
* added to CCFileUtils search paths
*/
bool m_addResourcesToSearchPath = false;
@ -312,9 +312,9 @@ namespace geode {
static bool validateID(std::string const& id);
// no copying
Mod(Mod const&) = delete;
Mod(Mod const&) = delete;
Mod operator=(Mod const&) = delete;
/**
* Protected constructor/destructor
*/
@ -328,10 +328,10 @@ namespace geode {
friend struct ModInfo;
friend class DataStore;
template<class = void>
template <class = void>
static inline GEODE_HIDDEN Mod* sharedMod = nullptr;
template<class = void>
template <class = void>
static inline GEODE_HIDDEN void setSharedMod(Mod* mod) {
sharedMod<> = mod;
}
@ -344,17 +344,16 @@ namespace geode {
std::string getDeveloper() const;
std::optional<std::string> getDescription() const;
std::optional<std::string> getDetails() const;
[[deprecated("Use Mod::getPackagePath instead")]]
std::string getPath() const;
[[deprecated("Use Mod::getPackagePath instead")]] std::string getPath() const;
ghc::filesystem::path getPackagePath() const;
VersionInfo getVersion() const;
bool isEnabled() const;
bool isLoaded() const;
bool supportsDisabling() const;
bool supportsUnloading() const;
bool wasSuccesfullyLoaded() const;
bool isEnabled() const;
bool isLoaded() const;
bool supportsDisabling() const;
bool supportsUnloading() const;
bool wasSuccesfullyLoaded() const;
std::string getLoadErrorInfo() const;
ModInfo getModInfo() const;
ModInfo getModInfo() const;
ghc::filesystem::path getTempDir() const;
ghc::filesystem::path getBinaryPath() const;
/**
@ -370,16 +369,16 @@ namespace geode {
decltype(ModInfo::m_settings) getSettings() const;
bool hasSetting(std::string const& key) const;
std::shared_ptr<Setting> getSetting(std::string const& key) const;
template<class T>
template <class T>
T getSettingValue(std::string const& key) const {
if (this->hasSetting(key)) {
return geode::getBuiltInSettingValue<T>(
this->getSetting(key)
);
return geode::getBuiltInSettingValue<T>(this->getSetting(key));
}
return T();
}
template<class T>
template <class T>
bool setSettingValue(std::string const& key, T const& value) {
if (this->hasSetting(key)) {
geode::setBuiltInSettingValue<T>(this->getSetting(key), value);
@ -393,7 +392,7 @@ namespace geode {
* @returns nullptr if Interface is not initialized,
* the mod pointer if it is initialized
*/
template<class = void>
template <class = void>
static inline GEODE_HIDDEN Mod* get() {
return sharedMod<>;
}
@ -405,59 +404,59 @@ namespace geode {
std::vector<Hook*> getHooks() const;
/**
* Create a hook at an address. Call the original
* function by calling the original function
* Create a hook at an address. Call the original
* function by calling the original function
* no trampoline needed
* @param address The absolute address of
* @param address The absolute address of
* the function to hook, i.e. gd_base + 0xXXXX
* @param detour Pointer to your detour function
* @returns Successful result containing the
* Hook handle, errorful result with info on
* @returns Successful result containing the
* Hook handle, errorful result with info on
* error
*/
template<auto Detour, template <class, class...> class Convention>
template <auto Detour, template <class, class...> class Convention>
Result<Hook*> addHook(void* address) {
return this->addHook<Detour, Convention>("", address);
}
return this->addHook<Detour, Convention>("", address);
}
/**
* Create a hook at an address. Call the original
* function by calling the original function
* no trampoline needed. Also takes a displayName
* Create a hook at an address. Call the original
* function by calling the original function
* no trampoline needed. Also takes a displayName
* parameter to use for when visualizing the hook.
* @param address The absolute address of
* @param address The absolute address of
* the function to hook, i.e. gd_base + 0xXXXX
* @param detour Pointer to your detour function
* @returns Successful result containing the
* Hook handle, errorful result with info on
* @returns Successful result containing the
* Hook handle, errorful result with info on
* error
*/
template<auto Detour, template <class, class...> class Convention>
template <auto Detour, template <class, class...> class Convention>
Result<Hook*> addHook(std::string const& displayName, void* address) {
auto hook = Hook::create<Detour, Convention>((decltype(Detour))address, displayName, this);
return this->addHook(hook);
}
Result<Hook*> addHook(Hook* hook);
auto hook =
Hook::create<Detour, Convention>((decltype(Detour))address, displayName, this);
return this->addHook(hook);
}
Result<Hook*> addHook(Hook* hook);
/**
* Enable a hook owned by this Mod
* @returns Successful result on success,
* @returns Successful result on success,
* errorful result with info on error
*/
Result<> enableHook(Hook* hook);
/**
* Disable a hook owned by this Mod
* @returns Successful result on success,
* @returns Successful result on success,
* errorful result with info on error
*/
Result<> disableHook(Hook* hook);
/**
* Remove a hook owned by this Mod
* @returns Successful result on success,
* @returns Successful result on success,
* errorful result with info on error
*/
Result<> removeHook(Hook* hook);
@ -466,52 +465,52 @@ namespace geode {
* Write a patch at an address
* @param address The address to write into
* @param data The data to write there
* @returns Successful result on success,
* @returns Successful result on success,
* errorful result with info on error
*/
Result<Patch*> patch(void* address, byte_array data);
/**
* Remove a patch owned by this Mod
* @returns Successful result on success,
* @returns Successful result on success,
* errorful result with info on error
*/
Result<> unpatch(Patch* patch);
/**
* Load this mod
* @returns Successful result on success,
* @returns Successful result on success,
* errorful result with info on error
*/
Result<> load();
/**
* Unload this mod
* @warning May crash if the mod doesn't
* @warning May crash if the mod doesn't
* properly handle unloading!
* @returns Successful result on success,
* @returns Successful result on success,
* errorful result with info on error
*/
Result<> unload();
/**
* Enable this mod
* @returns Successful result on success,
* @returns Successful result on success,
* errorful result with info on error
*/
Result<> enable();
/**
* Disable this mod if it supports doing so
* @returns Successful result on success,
* @returns Successful result on success,
* errorful result with info on error
*/
Result<> disable();
/**
* Disable & unload this mod (if supported),
* Disable & unload this mod (if supported),
* then delete the mod's .geode file.
* @returns Successful result on success,
* @returns Successful result on success,
* errorful result with info on error
*/
Result<> uninstall();
@ -530,39 +529,38 @@ namespace geode {
*/
Result<> resetDataStore();
/**
* Check whether or not this Mod
* depends on another mod
*/
bool depends(std::string const& id) const;
/**
* Check whether all the required
* dependencies for this mod have
* Check whether all the required
* dependencies for this mod have
* been loaded or not
* @returns True if the mod has unresolved
* @returns True if the mod has unresolved
* dependencies, false if not.
*/
bool hasUnresolvedDependencies() const;
/**
* Update the state of each of the
* dependencies. Depending on if the
* mod has unresolved dependencies,
* Update the state of each of the
* dependencies. Depending on if the
* mod has unresolved dependencies,
* it will either be loaded or unloaded
* @returns True if the mod has unresolved
* @returns True if the mod has unresolved
* dependencies, false if not.
*/
bool updateDependencyStates();
/**
* Get a list of all the unresolved
* Get a list of all the unresolved
* dependencies this mod has
* @returns List of all the unresolved
* @returns List of all the unresolved
* dependencies
*/
std::vector<Dependency> getUnresolvedDependencies();
const char* expandSpriteName(const char* name);
char const* expandSpriteName(char const* name);
};
/**
@ -576,6 +574,6 @@ namespace geode {
}
}
inline const char* operator"" _spr(const char* str, size_t) {
inline char const* operator"" _spr(char const* str, size_t) {
return geode::Mod::get()->expandSpriteName(str);
}

View file

@ -31,7 +31,7 @@ namespace {
struct derived##Parent {}; \
Modify<derived<derived##Parent>, base> derived##Apply; \
struct GEODE_HIDDEN derived##Intermediate : base { \
geode::modifier::FieldIntermediate<base, \
mutable geode::modifier::FieldIntermediate<base, \
derived##Intermediate, \
derived<derived##Parent> \
> m_fields; \
@ -45,7 +45,7 @@ struct derived;
namespace { \
Modify<derived, base> derived##Apply; \
struct GEODE_HIDDEN derived##Intermediate : base { \
geode::modifier::FieldIntermediate<base, \
mutable geode::modifier::FieldIntermediate<base, \
derived##Intermediate, \
derived \
> m_fields; \

View file

@ -1,18 +1,18 @@
#include <about.hpp>
#include <Geode/cocos/support/zip_support/ZipUtils.h>
#include <Geode/loader/Hook.hpp>
#include <Geode/loader/Loader.hpp>
#include <Geode/loader/Log.hpp>
#include <Geode/loader/Mod.hpp>
#include <Geode/loader/Setting.hpp>
#include <Geode/utils/JsonValidation.hpp>
#include <Geode/utils/conststring.hpp>
#include <Geode/utils/file.hpp>
#include <Geode/utils/JsonValidation.hpp>
#include <Geode/utils/map.hpp>
#include <Geode/utils/ranges.hpp>
#include <Geode/utils/string.hpp>
#include <Geode/utils/vector.hpp>
#include <Geode/utils/ranges.hpp>
#include <InternalMod.hpp>
#include <../support/zip_support/ZipUtils.h>
#include <about.hpp>
USE_GEODE_NAMESPACE();
@ -70,22 +70,20 @@ Result<> Mod::loadSettings() {
if (auto sett = this->getSetting(key)) {
// load its value
if (!sett->load(value.json())) {
return Err(
"Unable to load value for setting \"" +
key + "\""
);
return Err("Unable to load value for setting \"" + key + "\"");
}
} else {
}
else {
log::log(
Severity::Warning,
this,
"Encountered unknown setting \"{}\" while loading settings",
Severity::Warning, this,
"Encountered unknown setting \"{}\" while loading "
"settings",
key
);
}
}
} catch(std::exception& e) {
}
catch (std::exception& e) {
return Err(std::string("Unable to parse settings: ") + e.what());
}
}
@ -94,12 +92,14 @@ Result<> Mod::loadSettings() {
auto dsPath = m_saveDirPath / "ds.json";
if (!ghc::filesystem::exists(dsPath)) {
m_dataStore = m_info.m_defaultDataStore;
} else {
}
else {
auto dsData = utils::file::readString(dsPath);
if (!dsData) return dsData;
try {
m_dataStore = nlohmann::json::parse(dsData.value());
} catch(std::exception& e) {
}
catch (std::exception& e) {
return Err(std::string("Unable to parse datastore: ") + e.what());
}
}
@ -151,8 +151,7 @@ Result<> Mod::createTempDir() {
if (!unzip.fileExists(m_info.m_binaryName)) {
return Err<>(
"Unable to find platform binary under the name \"" +
m_info.m_binaryName + "\""
"Unable to find platform binary under the name \"" + m_info.m_binaryName + "\""
);
}
@ -162,7 +161,7 @@ Result<> Mod::createTempDir() {
return Err<>("Unable to create temp directory for mods!");
}
}
auto tempPath = ghc::filesystem::path(tempDir) / m_info.m_id;
if (!ghc::filesystem::exists(tempPath) && !ghc::filesystem::create_directories(tempPath)) {
return Err<>("Unable to create temp directory");
@ -172,11 +171,11 @@ Result<> Mod::createTempDir() {
for (auto file : unzip.getAllFiles()) {
auto path = ghc::filesystem::path(file);
if (path.has_parent_path()) {
if (
!ghc::filesystem::exists(tempPath / path.parent_path()) &&
!ghc::filesystem::create_directories(tempPath / path.parent_path())
) {
return Err<>("Unable to create directories \"" + path.parent_path().string() + "\"");
if (!ghc::filesystem::exists(tempPath / path.parent_path()) &&
!ghc::filesystem::create_directories(tempPath / path.parent_path())) {
return Err<>(
"Unable to create directories \"" + path.parent_path().string() + "\""
);
}
}
unsigned long size;
@ -184,10 +183,7 @@ Result<> Mod::createTempDir() {
if (!data || !size) {
return Err<>("Unable to read \"" + std::string(file) + "\"");
}
auto wrt = utils::file::writeBinary(
tempPath / file,
byte_array(data, data + size)
);
auto wrt = utils::file::writeBinary(tempPath / file, byte_array(data, data + size));
if (!wrt) return Err<>("Unable to write \"" + file + "\": " + wrt.error());
}
@ -197,12 +193,14 @@ Result<> Mod::createTempDir() {
}
Result<> Mod::load() {
if (m_loaded) {
if (m_loaded) {
return Ok<>();
}
#define RETURN_LOAD_ERR(str) \
{m_loadErrorInfo = str; \
return Err<>(m_loadErrorInfo);}
#define RETURN_LOAD_ERR(str) \
{ \
m_loadErrorInfo = str; \
return Err<>(m_loadErrorInfo); \
}
if (!m_tempDirName.string().size()) {
auto err = this->createTempDir();
@ -247,7 +245,7 @@ Result<> Mod::unload() {
if (!m_info.m_supportsUnloading) {
return Err<>("Mod does not support unloading");
}
if (m_saveDataFunc) {
if (!m_saveDataFunc(m_saveDirPath.string().c_str())) {
log::log(Severity::Error, this, "Mod save data function returned false");
@ -286,7 +284,7 @@ Result<> Mod::enable() {
if (!m_loaded) {
return Err<>("Mod is not loaded");
}
if (m_enableFunc) {
if (!m_enableFunc()) {
return Err<>("Mod enable function returned false");
@ -361,55 +359,58 @@ bool Mod::isUninstalled() const {
bool Dependency::isUnresolved() const {
return m_required &&
(m_state == ModResolveState::Unloaded ||
m_state == ModResolveState::Unresolved ||
m_state == ModResolveState::Disabled);
(m_state == ModResolveState::Unloaded || m_state == ModResolveState::Unresolved ||
m_state == ModResolveState::Disabled);
}
bool Mod::updateDependencyStates() {
bool hasUnresolved = false;
for (auto & dep : m_info.m_dependencies) {
if (!dep.m_mod) {
dep.m_mod = Loader::get()->getLoadedMod(dep.m_id);
}
if (dep.m_mod) {
dep.m_mod->updateDependencyStates();
for (auto& dep : m_info.m_dependencies) {
if (!dep.m_mod) {
dep.m_mod = Loader::get()->getLoadedMod(dep.m_id);
}
if (dep.m_mod) {
dep.m_mod->updateDependencyStates();
if (dep.m_mod->hasUnresolvedDependencies()) {
dep.m_state = ModResolveState::Unresolved;
} else {
if (!dep.m_mod->m_resolved) {
dep.m_mod->m_resolved = true;
dep.m_state = ModResolveState::Resolved;
if (dep.m_mod->hasUnresolvedDependencies()) {
dep.m_state = ModResolveState::Unresolved;
}
else {
if (!dep.m_mod->m_resolved) {
dep.m_mod->m_resolved = true;
dep.m_state = ModResolveState::Resolved;
auto r = dep.m_mod->load();
if (!r) {
dep.m_state = ModResolveState::Unloaded;
log::log(Severity::Error, dep.m_mod, "{}", r.error());
}
else {
auto r = dep.m_mod->enable();
if (!r) {
dep.m_state = ModResolveState::Disabled;
auto r = dep.m_mod->enable();
if (!r) {
dep.m_state = ModResolveState::Disabled;
log::log(Severity::Error, dep.m_mod, "{}", r.error());
}
}
}
} else {
if (dep.m_mod->isEnabled()) {
dep.m_state = ModResolveState::Loaded;
} else {
dep.m_state = ModResolveState::Disabled;
}
}
}
} else {
dep.m_state = ModResolveState::Unloaded;
}
if (dep.isUnresolved()) {
m_resolved = false;
}
else {
if (dep.m_mod->isEnabled()) {
dep.m_state = ModResolveState::Loaded;
}
else {
dep.m_state = ModResolveState::Disabled;
}
}
}
}
else {
dep.m_state = ModResolveState::Unloaded;
}
if (dep.isUnresolved()) {
m_resolved = false;
(void)this->unload();
hasUnresolved = true;
}
}
}
}
if (!hasUnresolved && !m_resolved) {
log::debug("All dependencies for {} found", m_info.m_id);
m_resolved = true;
@ -420,12 +421,13 @@ bool Mod::updateDependencyStates() {
log::error("{} Error loading: {}", this, r.error());
}
else {
auto r = this->enable();
if (!r) {
log::error("{} Error enabling: {}", this, r.error());
}
auto r = this->enable();
if (!r) {
log::error("{} Error enabling: {}", this, r.error());
}
}
} else {
}
else {
log::debug("Resolved {}, however not loading it as it is disabled", m_info.m_id);
}
}
@ -433,21 +435,21 @@ bool Mod::updateDependencyStates() {
}
bool Mod::hasUnresolvedDependencies() const {
for (auto const& dep : m_info.m_dependencies) {
if (dep.isUnresolved()) {
return true;
}
}
return false;
for (auto const& dep : m_info.m_dependencies) {
if (dep.isUnresolved()) {
return true;
}
}
return false;
}
std::vector<Dependency> Mod::getUnresolvedDependencies() {
std::vector<Dependency> res;
for (auto const& dep : m_info.m_dependencies) {
if (dep.isUnresolved()) {
res.push_back(dep);
}
}
for (auto const& dep : m_info.m_dependencies) {
if (dep.isUnresolved()) {
res.push_back(dep);
}
}
return res;
}
@ -532,14 +534,13 @@ std::vector<Hook*> Mod::getHooks() const {
}
bool Mod::depends(std::string const& id) const {
return utils::ranges::contains(
m_info.m_dependencies,
[id](Dependency const& t) { return t.m_id == id; }
);
return utils::ranges::contains(m_info.m_dependencies, [id](Dependency const& t) {
return t.m_id == id;
});
}
const char* Mod::expandSpriteName(const char* name) {
static std::unordered_map<std::string, const char*> expanded = {};
char const* Mod::expandSpriteName(char const* name) {
static std::unordered_map<std::string, char const*> expanded = {};
if (expanded.count(name)) {
return expanded[name];
}