mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-27 09:55:34 -05:00
Merge remote-tracking branch 'refs/remotes/origin/1.4.0-dev' into 1.4.0-dev
This commit is contained in:
commit
f1d948f682
50 changed files with 909 additions and 292 deletions
12
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
12
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
|
@ -1,7 +1,17 @@
|
|||
name: Bug Report
|
||||
description: Report a bug where something is not working as expected in Geode Loader (not specific mods), which does not crash the game.
|
||||
description: Report a Geode bug (not mods themselves) where something is not working as expected in Geode Loader (not mods created by others), which does not crash the game.
|
||||
labels: [ "unverified", "bug" ]
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Geode Issue
|
||||
description: |
|
||||
The Geode repository is for issues of *Geode Loader*, not individual mods created by other developers.
|
||||
When submitting a bug report, please make sure that the bug is *actually* related to ***Geode Loader itself*** and not to a mod or mod combination.
|
||||
Failing to do this will get your issue *closed without explanation*.
|
||||
options:
|
||||
- label: I confirm that this bug is NOT related to a mod but directly to Geode Loader itself.
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: platform
|
||||
attributes:
|
||||
|
|
13
.github/ISSUE_TEMPLATE/crash-report.yml
vendored
13
.github/ISSUE_TEMPLATE/crash-report.yml
vendored
|
@ -1,7 +1,18 @@
|
|||
name: Crash Report
|
||||
description: Report a bug that crashes the game or prevents startup caused by Geode Loader (not individual mods).
|
||||
description: Report a Geode bug (not mods themselves) that crashes the game or prevents startup caused by Geode Loader (not mods created by others).
|
||||
labels: [ "unverified", "crash" ]
|
||||
body:
|
||||
- type: input
|
||||
id: geode-confirmation
|
||||
attributes:
|
||||
label: Geode Issue
|
||||
description: |
|
||||
The Geode repository is for issues of *Geode Loader*, not individual mods created by other developers.
|
||||
When submitting a crash report, please make sure that the crash is *actually* related to ***Geode Loader itself*** and not to a mod or mod combination, after you do that type in "confirm" in the input field above.
|
||||
Failing to do this will get your issue *closed without explanation*.
|
||||
placeholder: "Please, read the text below."
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: platform
|
||||
attributes:
|
||||
|
|
17
.github/workflows/build.yml
vendored
17
.github/workflows/build.yml
vendored
|
@ -146,21 +146,13 @@ jobs:
|
|||
files: geode-win/XInput9_1_0.dll geode-win/Geode.dll geode-win/GeodeUpdater.exe geode-win/Geode.lib geode-win/Geode.pdb
|
||||
dest: geode-${{ steps.ref.outputs.hash }}-win.zip
|
||||
|
||||
# TODO change in 2.0.0
|
||||
- name: Zip Windows Resources
|
||||
uses: vimtor/action-zip@v1.1
|
||||
with:
|
||||
files: geode-win/resources
|
||||
dest: resources-win.zip
|
||||
|
||||
# This is basically a hack because of line endings. Blame windows.
|
||||
- name: Zip MacOS Resources
|
||||
- name: Zip Resources
|
||||
uses: vimtor/action-zip@v1.1
|
||||
with:
|
||||
files: geode-mac/resources
|
||||
dest: resources-mac.zip
|
||||
dest: resources.zip
|
||||
|
||||
- name: Update Nightly Release
|
||||
- name: Update Development Release
|
||||
uses: andelf/nightly-release@main
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
@ -174,5 +166,4 @@ jobs:
|
|||
./geode-installer-${{ steps.ref.outputs.hash }}-win.exe
|
||||
./geode-${{ steps.ref.outputs.hash }}-mac.zip
|
||||
./geode-${{ steps.ref.outputs.hash }}-win.zip
|
||||
./resources-win.zip
|
||||
./resources-mac.zip
|
||||
./resources.zip
|
||||
|
|
6
.github/workflows/draft.yml
vendored
6
.github/workflows/draft.yml
vendored
|
@ -28,8 +28,7 @@ jobs:
|
|||
mv dev/geode-installer-*-win.exe geode-installer-v${{ steps.ref.outputs.version }}-win.exe
|
||||
mv dev/geode-*-mac.zip geode-v${{ steps.ref.outputs.version }}-mac.zip
|
||||
mv dev/geode-*-win.zip geode-v${{ steps.ref.outputs.version }}-win.zip
|
||||
mv dev/resources-win.zip resources-win.zip
|
||||
mv dev/resources-mac.zip resources-mac.zip
|
||||
mv dev/resources.zip resources.zip
|
||||
|
||||
- name: Create Draft Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
|
@ -49,5 +48,4 @@ jobs:
|
|||
./geode-installer-v${{ steps.ref.outputs.version }}-win.exe
|
||||
./geode-v${{ steps.ref.outputs.version }}-mac.zip
|
||||
./geode-v${{ steps.ref.outputs.version }}-win.zip
|
||||
./resources-win.zip
|
||||
./resources-mac.zip
|
||||
./resources.zip
|
||||
|
|
3
.github/workflows/test-offsets.yml
vendored
3
.github/workflows/test-offsets.yml
vendored
|
@ -3,6 +3,9 @@ name: Test Offsets
|
|||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- 'bindings/**' # only when adjusting bindings
|
||||
- 'loader/test/members/**'
|
||||
branches:
|
||||
- '**' # every branch
|
||||
- '!no-build-**' # unless marked as no-build
|
||||
|
|
19
.gitignore
vendored
19
.gitignore
vendored
|
@ -46,20 +46,29 @@ build2
|
|||
build-docs/
|
||||
bin
|
||||
|
||||
# Ignore docs folders
|
||||
docs/**
|
||||
docs
|
||||
|
||||
# Ignore codegenned files
|
||||
loader/src/internal/about.hpp
|
||||
loader/src/internal/resources.hpp
|
||||
loader/resources/mod.json
|
||||
loader/resources/version
|
||||
loader/resources/blanks/rename.js
|
||||
loader/resources/about.md
|
||||
loader/resources/changelog.md
|
||||
fods-catgirl-hideout.txt
|
||||
test-docs.bat
|
||||
|
||||
# krita files too because alk is funny
|
||||
**/*.kra
|
||||
loader/resources/support.md
|
||||
|
||||
# Ignore generated files
|
||||
installer/mac/*.pkg
|
||||
installer/windows/*.exe
|
||||
|
||||
# Ignore fod's include directories which are stored in this funny file
|
||||
fods-catgirl-hideout.txt
|
||||
|
||||
# Ignore I don't even know what that is probably fod's flash testing script
|
||||
test-docs.bat
|
||||
|
||||
# Ignore krita files too because we don't want our project files shaking my head
|
||||
**/*.kra
|
||||
|
|
25
CHANGELOG.md
25
CHANGELOG.md
|
@ -1,5 +1,30 @@
|
|||
# Geode Changelog
|
||||
|
||||
## v1.3.5
|
||||
* Follow redirect in web::utils functions (a942a45)
|
||||
* Lots of bindings
|
||||
* Make codegen symbols private visibility (696a2ca)
|
||||
* Add deadstrip to macos (0d62940)
|
||||
* Readd the nullptr check in InstallListPopup::createCells (499f256)
|
||||
* Fix garagelayer ids on not logged in users (dd0179c)
|
||||
|
||||
## v1.3.4
|
||||
* Implement string setting character filters (cf8fbba)
|
||||
* Update bindings
|
||||
|
||||
## v1.3.3
|
||||
* Reunify resources.zip (81de161)
|
||||
|
||||
## v1.3.2
|
||||
* Fix alignment of some textures (8f39c38)
|
||||
* Bring back unknown problems (0663569)
|
||||
* Fix some Windows 7 incompatibility (2d2bdd1)
|
||||
* Remove enabled from the crashlogs (5b7d318)
|
||||
* Make index unzipping async (7c582f1)
|
||||
* Fix mods by developer crashing when mod was toggled (a6a47bf)
|
||||
* Fix nested lists in the markdown (2723588)
|
||||
* Fix search paths (8f39c38, aa55ebe)
|
||||
|
||||
## v1.3.1
|
||||
* Fix TulipHook not relocating RIP relative operands on MacOS (6cad19d)
|
||||
|
||||
|
|
|
@ -185,7 +185,14 @@ target_include_directories(GeodeCodegenSources PRIVATE
|
|||
${GEODE_LOADER_PATH}/include/Geode/cocos/extensions
|
||||
${GEODE_LOADER_PATH}/include/Geode/fmod
|
||||
)
|
||||
set_target_properties(GeodeCodegenSources PROPERTIES CXX_VISIBILITY_PRESET hidden)
|
||||
target_compile_features(GeodeCodegenSources PUBLIC cxx_std_20)
|
||||
|
||||
if (APPLE)
|
||||
target_compile_options(GeodeCodegenSources PUBLIC -ffunction-sections -fdata-sections)
|
||||
target_link_options(GeodeCodegenSources PUBLIC -dead_strip)
|
||||
endif()
|
||||
|
||||
if (NOT GEODE_DISABLE_PRECOMPILED_HEADERS)
|
||||
target_precompile_headers(GeodeCodegenSources INTERFACE
|
||||
"${GEODE_LOADER_PATH}/include/Geode/Bindings.hpp"
|
||||
|
@ -218,6 +225,11 @@ else()
|
|||
set(GEODE_PLATFORM_BIN_PATH ${GEODE_BIN_PATH}/${PROJECT_VERSION}/${GEODE_PLATFORM_BINARY})
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
# This allows you to compile in debug mode
|
||||
add_compile_definitions(_HAS_ITERATOR_DEBUGGING=0)
|
||||
endif()
|
||||
|
||||
|
||||
if (PROJECT_IS_TOP_LEVEL)
|
||||
add_subdirectory(loader)
|
||||
|
|
|
@ -121,6 +121,11 @@ class cocos2d::CCClippingNode {
|
|||
// void updateConnected() = win 0xc7fb0;
|
||||
//}
|
||||
|
||||
[[link(win)]]
|
||||
class cocos2d::CCConfiguration {
|
||||
void gatherGPUInfo() = mac 0x2a6e10;
|
||||
}
|
||||
|
||||
[[link(win)]]
|
||||
class cocos2d::CCDelayTime {
|
||||
static cocos2d::CCDelayTime* create(float) = mac 0x1f4380;
|
||||
|
@ -318,7 +323,7 @@ class cocos2d::CCFileUtils : cocos2d::TypeInfo {
|
|||
class cocos2d::CCGLProgram {
|
||||
auto setUniformsForBuiltins() = mac 0x232c70;
|
||||
auto use() = mac 0x231d70;
|
||||
bool compileShader(unsigned int* shader, unsigned int type, const char* source);
|
||||
bool compileShader(unsigned int* shader, unsigned int type, const char* source) = mac 0x231a30;
|
||||
}
|
||||
|
||||
[[link(win)]]
|
||||
|
@ -360,6 +365,7 @@ class cocos2d::CCImage {
|
|||
class cocos2d::CCKeyboardDispatcher {
|
||||
bool dispatchKeyboardMSG(cocos2d::enumKeyCodes, bool) = mac 0xe8190;
|
||||
const char* keyToString(cocos2d::enumKeyCodes) = mac 0xe8450;
|
||||
void updateModifierKeys(bool shft, bool ctrl, bool alt, bool cmd) = mac 0xe8430;
|
||||
}
|
||||
|
||||
[[link(win)]]
|
||||
|
@ -380,6 +386,7 @@ class cocos2d::CCKeypadHandler {
|
|||
|
||||
[[link(win)]]
|
||||
class cocos2d::CCLabelBMFont {
|
||||
CCLabelBMFont() = mac 0x347b60;
|
||||
static cocos2d::CCLabelBMFont* create(char const*, char const*) = mac 0x347660;
|
||||
auto limitLabelWidth(float, float, float) = mac 0x34a6e0, ios 0x21b740;
|
||||
auto setFntFile(char const*) = mac 0x34a5f0;
|
||||
|
@ -387,7 +394,7 @@ class cocos2d::CCLabelBMFont {
|
|||
static auto create() = mac 0x3473f0;
|
||||
|
||||
virtual auto init() = mac 0x347b10, ios 0x2198e0;
|
||||
bool initWithString(const char* str, const char* fnt, float width, cocos2d::CCTextAlignment align, cocos2d::CCPoint offset);
|
||||
bool initWithString(const char* str, const char* fnt, float width, cocos2d::CCTextAlignment align, cocos2d::CCPoint offset) = mac 0x347710;
|
||||
virtual auto setScaleX(float) = mac 0x34a5b0, ios 0x21b6e8;
|
||||
virtual auto setScaleY(float) = mac 0x34a5d0, ios 0x21b714;
|
||||
virtual auto setScale(float) = mac 0x34a590, ios 0x21b6bc;
|
||||
|
@ -631,6 +638,12 @@ class cocos2d::CCNode {
|
|||
virtual auto cleanup() = mac 0x123100, ios 0x15e3a4;
|
||||
auto convertToNodeSpace(cocos2d::CCPoint const&) = mac 0x124750, ios 0x15f55c;
|
||||
auto convertToWorldSpace(cocos2d::CCPoint const&) = mac 0x124790;
|
||||
cocos2d::CCPoint convertToNodeSpaceAR(cocos2d::CCPoint const& worldPoint) {
|
||||
return convertToNodeSpace(worldPoint) - getAnchorPointInPoints();
|
||||
}
|
||||
cocos2d::CCPoint convertToWorldSpaceAR(cocos2d::CCPoint const& nodePoint) {
|
||||
return convertToWorldSpace(nodePoint + getAnchorPointInPoints());
|
||||
}
|
||||
static cocos2d::CCNode* create() = mac 0x1230a0;
|
||||
virtual auto draw() = mac 0x123840, ios 0x15e974;
|
||||
auto getActionByTag(int) = mac 0x123ee0;
|
||||
|
@ -1129,6 +1142,7 @@ class cocos2d::CCTouchHandler {
|
|||
[[link(win)]]
|
||||
class cocos2d::CCTransitionFade {
|
||||
static cocos2d::CCTransitionFade* create(float, cocos2d::CCScene*) = mac 0x8ea30, ios 0x12c244;
|
||||
virtual bool initWithDuration(float t, cocos2d::CCScene* scene, cocos2d::ccColor3B const& color) = mac 0x8e930;
|
||||
}
|
||||
|
||||
[[link(win)]]
|
||||
|
@ -1251,16 +1265,30 @@ class cocos2d::extension::CCScrollView {
|
|||
[[link(win)]]
|
||||
class cocos2d {
|
||||
static auto FNTConfigLoadFile(char const*) = mac 0x344f10;
|
||||
static auto ccGLUseProgram(GLuint) = mac 0x1ae540;
|
||||
static auto ccGLBlendFunc(GLenum, GLenum) = mac 0x1ae560;
|
||||
static auto ccDrawSolidRect(cocos2d::CCPoint, cocos2d::CCPoint, cocos2d::_ccColor4F) = mac 0xecf00;
|
||||
static auto ccGLEnableVertexAttribs(unsigned int) = mac 0x1ae740;
|
||||
static auto ccGLBindTexture2D(GLuint) = mac 0x1ae610;
|
||||
static auto ccGLBindTexture2DN(GLuint, GLuint) = mac 0x1ae650;
|
||||
static float ccpDistance(cocos2d::CCPoint const&, cocos2d::CCPoint const&) = mac 0x1aaf90;
|
||||
static auto ccDrawLine(cocos2d::CCPoint const&, cocos2d::CCPoint const&) = mac 0xeccc0;
|
||||
static void ccDrawPoly(cocos2d::CCPoint const*, unsigned int, bool) = mac 0xed0a0;
|
||||
static void ccDrawColor4B(GLubyte, GLubyte, GLubyte, GLubyte) = mac 0xeddd0;
|
||||
static void CCMessageBox(const char* msg, const char* title) = mac 0xbabc0;
|
||||
}
|
||||
|
||||
//uintptr_t macNumberOfDraws() {
|
||||
// return geode::base::get() + 0x69ae90;
|
||||
//}
|
||||
//void ccIncrementGLDraws(int n) {
|
||||
//#ifdef GEODE_IS_MACOS
|
||||
// *reinterpret_cast<int*>(macNumberOfDraws()) += n;
|
||||
//#else
|
||||
// CC_INCREMENT_GL_DRAWS(n);
|
||||
//#endif
|
||||
//}
|
||||
|
||||
[[link(win)]]
|
||||
class DS_Dictionary {
|
||||
DS_Dictionary() = mac 0xbe9a0;
|
||||
|
|
|
@ -280,6 +280,10 @@ class CCAnimatedSprite : cocos2d::CCSprite {
|
|||
class CCAnimateFrameCache : cocos2d::CCObject {
|
||||
static CCAnimateFrameCache* sharedSpriteFrameCache() = mac 0x2e4df0, win 0x158f0;
|
||||
void addSpriteFramesWithFile(const char* file) = win 0x159b0;
|
||||
|
||||
cocos2d::CCDictionary* m_unknown1;
|
||||
cocos2d::CCDictionary* m_unknown2;
|
||||
cocos2d::CCDictionary* m_unknown3;
|
||||
}
|
||||
|
||||
class CCBlockLayer : cocos2d::CCLayerColor {
|
||||
|
@ -905,6 +909,8 @@ class CommentUploadDelegate {
|
|||
}
|
||||
|
||||
class ConfigureHSVWidget : cocos2d::CCNode {
|
||||
bool init(int abs, cocos2d::ccHSVValue val) = win 0x4a3f0, mac 0x237310;
|
||||
void updateLabels() = win 0x4adf0, mac 0x237df0;
|
||||
cocos2d::CCLabelBMFont* m_hueLabel;
|
||||
cocos2d::CCLabelBMFont* m_saturationLabel;
|
||||
cocos2d::CCLabelBMFont* m_brightnessLabel;
|
||||
|
@ -945,15 +951,15 @@ class CreateMenuItem : CCMenuItemSpriteExtra {
|
|||
class CreatorLayer : cocos2d::CCLayer, cocos2d::CCSceneTransitionDelegate, DialogDelegate {
|
||||
void onBack(cocos2d::CCObject*) = win 0x4fae0;
|
||||
void onChallenge(cocos2d::CCObject*) = mac 0x142960, win 0x4f1b0;
|
||||
void onLeaderboards(cocos2d::CCObject*) = win 0x4ed20;
|
||||
void onLeaderboards(cocos2d::CCObject*) = mac 0x142920, win 0x4ed20;
|
||||
void onMyLevels(cocos2d::CCObject*) = mac 0x142b70, win 0x4eaa0;
|
||||
void onSavedLevels(cocos2d::CCObject*) = mac 0x142860, win 0x4ebe0;
|
||||
void onDailyLevel(cocos2d::CCObject*) = win 0x4f170;
|
||||
void onWeeklyLevel(cocos2d::CCObject*) = win 0x4f190;
|
||||
void onFeaturedLevels(cocos2d::CCObject*) = win 0x4edf0;
|
||||
void onFameLevels(cocos2d::CCObject*) = win 0x4ee70;
|
||||
void onMapPacks(cocos2d::CCObject*) = win 0x4efb0;
|
||||
void onOnlineLevels(cocos2d::CCObject*) = win 0x4ef60;
|
||||
void onDailyLevel(cocos2d::CCObject*) = mac 0x142980, win 0x4f170;
|
||||
void onWeeklyLevel(cocos2d::CCObject*) = mac 0x1429a0, win 0x4f190;
|
||||
void onFeaturedLevels(cocos2d::CCObject*) = mac 0x142a20, win 0x4edf0;
|
||||
void onFameLevels(cocos2d::CCObject*) = mac 0x142a80, win 0x4ee70;
|
||||
void onMapPacks(cocos2d::CCObject*) = mac 0x1429c0, win 0x4efb0;
|
||||
void onOnlineLevels(cocos2d::CCObject*) = mac 0x142ae0, win 0x4ef60;
|
||||
void onGauntlets(cocos2d::CCObject*) = mac 0x142b20, win 0x4f0a0;
|
||||
void onSecretVault(cocos2d::CCObject*) = win 0x4f1d0;
|
||||
void onTreasureRoom(cocos2d::CCObject*) = win 0x4f540;
|
||||
|
@ -1026,7 +1032,7 @@ class CustomizeObjectLayer : FLAlertLayer, TextInputDelegate, HSVWidgetPopupDele
|
|||
void onClose(cocos2d::CCObject*) = mac 0xdf660, win 0x57ac0;
|
||||
void updateSelected(int channelID) = mac 0xe0970, win 0x57850;
|
||||
bool init(GameObject* target, cocos2d::CCArray* targets) = mac 0xdd560, win 0x53e00;
|
||||
void onHSV(cocos2d::CCObject* sender) = win 0x567c0;
|
||||
void onHSV(cocos2d::CCObject* sender) = win 0x567c0, mac 0xdfa00;
|
||||
void toggleVisible() = mac 0xe1140, win 0x56fb0;
|
||||
void highlightSelected(ButtonSprite* target) = mac 0xe0aa0, win 0x579d0;
|
||||
void updateCustomColorLabels() = mac 0xdff40, win 0x576d0;
|
||||
|
@ -1035,8 +1041,8 @@ class CustomizeObjectLayer : FLAlertLayer, TextInputDelegate, HSVWidgetPopupDele
|
|||
// inlined in most places
|
||||
void updateChannelLabel(int channel) = mac 0xe06e0, win 0x56f50;
|
||||
virtual void hsvPopupClosed(HSVWidgetPopup* popup, cocos2d::ccHSVValue value) = win 0x56990;
|
||||
virtual void colorSelectClosed(cocos2d::CCNode*) = mac 0xe0c70, win 0x564a0;
|
||||
virtual void textChanged(CCTextInputNode* input) = mac 0xe16a0, win 0x574d0;
|
||||
virtual void colorSelectClosed(cocos2d::CCNode*) = mac 0xe0610, win 0x564a0;
|
||||
virtual void textChanged(CCTextInputNode* input) = mac 0xe1470, win 0x574d0;
|
||||
inline CustomizeObjectLayer() {}
|
||||
~CustomizeObjectLayer() = win 0x53c30;
|
||||
|
||||
|
@ -1073,7 +1079,7 @@ class CustomizeObjectLayer : FLAlertLayer, TextInputDelegate, HSVWidgetPopupDele
|
|||
}
|
||||
|
||||
class DailyLevelPage : FLAlertLayer, FLAlertLayerProtocol, GJDailyLevelDelegate, LevelDownloadDelegate {
|
||||
static DailyLevelPage* create(bool weekly) = win 0x6a860;
|
||||
static DailyLevelPage* create(bool weekly) = mac 0x108ac0, win 0x6a860;
|
||||
bool init(bool weekly) = mac 0x108C90, win 0x6a900;
|
||||
virtual void updateTimers(float) = mac 0x109780, win 0x6bef0;
|
||||
virtual void show() = mac 0x10a4b0, win 0x3f360;
|
||||
|
@ -1136,7 +1142,7 @@ class DrawGridLayer : cocos2d::CCLayer {
|
|||
}
|
||||
|
||||
bool init(cocos2d::CCNode* grid, LevelEditorLayer* editor) = win 0x16c4d0;
|
||||
void draw() = win 0x16ce90;
|
||||
virtual void draw() = win 0x16ce90, mac 0xa3c40;
|
||||
virtual void update(float) = win 0x16cd80;
|
||||
void clearPlayerPoints() {
|
||||
m_playerNodePoints->removeAllObjects();
|
||||
|
@ -1272,7 +1278,7 @@ class EditorPauseLayer : CCBlockLayer, FLAlertLayerProtocol {
|
|||
bool init(LevelEditorLayer*) = mac 0x13c7a0, win 0x730e0, ios 0x280cb8;
|
||||
void onExitEditor(cocos2d::CCObject* sender) = mac 0x13f180, win 0x75660;
|
||||
void playStep2() = mac 0x13f040, win 0x75440;
|
||||
void onResume(cocos2d::CCObject* sender) = win 0x74fe0;
|
||||
void onResume(cocos2d::CCObject* sender) = mac 0x13e170, win 0x74fe0;
|
||||
void onSaveAndPlay(cocos2d::CCObject* sender) = mac 0x13e1b0, win 0x753d0;
|
||||
void onSaveAndExit(cocos2d::CCObject* sender) = mac 0x13e230, win 0x75620;
|
||||
void onSave(cocos2d::CCObject* sender) = mac 0x13e290, win 0x755a0;
|
||||
|
@ -1303,6 +1309,8 @@ class EditorUI : cocos2d::CCLayer, FLAlertLayerProtocol, ColorSelectDelegate, GJ
|
|||
|
||||
void create(LevelEditorLayer*) = mac 0x8a80, win 0x76270;
|
||||
cocos2d::CCArray* createCustomItems() = mac 0x1ddf0, win 0x7a370;
|
||||
void onDeleteCustomItem(cocos2d::CCObject* pSender) = win 0x7a280, mac 0x29860;
|
||||
void onNewCustomItem(cocos2d::CCObject* pSender) = win 0x79fd0, mac 0x24480;
|
||||
void deselectAll() = mac 0x1f300, win 0x86af0;
|
||||
void onDeselectAll(cocos2d::CCObject*) = mac 0x19cd0, win 0x86ac0;
|
||||
void disableButton(CreateMenuItem*) = mac 0x1c0f0, win 0x78af0;
|
||||
|
@ -1352,8 +1360,8 @@ class EditorUI : cocos2d::CCLayer, FLAlertLayerProtocol, ColorSelectDelegate, GJ
|
|||
void onCreateButton(cocos2d::CCObject* sender) = mac 0x1fd70, win 0x854f0;
|
||||
CCMenuItemSpriteExtra* getSpriteButton(const char* sprite, cocos2d::SEL_MenuHandler callback, cocos2d::CCMenu* menu, float scale) = mac 0xb500, win 0x78bf0;
|
||||
cocos2d::CCPoint offsetForKey(int objID) = win 0x92310;
|
||||
void updateDeleteMenu() = win 0x7c5d0;
|
||||
void updateCreateMenu(bool updateTab) = mac 0x1e960, win 0x85530;
|
||||
void updateDeleteMenu() = win 0x7c5d0, mac 0x1e960;
|
||||
void updateCreateMenu(bool updateTab) = mac 0x1ba80, win 0x85530;
|
||||
void toggleMode(cocos2d::CCObject* sender) = mac 0x187b0, win 0x7ad20;
|
||||
void zoomIn(cocos2d::CCObject* sender) = mac 0xc0c0, win 0x877c0;
|
||||
void zoomOut(cocos2d::CCObject* sender) = mac 0xc120, win 0x87830;
|
||||
|
@ -1421,6 +1429,7 @@ class EditorUI : cocos2d::CCLayer, FLAlertLayerProtocol, ColorSelectDelegate, GJ
|
|||
void sliderChanged(cocos2d::CCObject* slider) = mac 0xaed0, win 0x78cc0;
|
||||
void repositionObjectsToCenter(cocos2d::CCArray* objs, cocos2d::CCPoint center, bool ignoreGroupParent) = mac 0x1fcd0, win 0x88410;
|
||||
virtual void draw() = win 0x8fbe0;
|
||||
float valueFromXPos(float val) = win 0x78e30, mac 0x1c810;
|
||||
|
||||
bool m_isPlayingMusic;
|
||||
EditButtonBar* m_buttonBar;
|
||||
|
@ -1628,9 +1637,12 @@ class EffectGameObject : GameObject {
|
|||
PAD = mac 0x28, win 0x24;
|
||||
}
|
||||
|
||||
class EndLevelLayer {
|
||||
class EndLevelLayer : cocos2d::CCLayer {
|
||||
static EndLevelLayer* create() = mac 0x2787d0, win 0x94b50;
|
||||
|
||||
void customSetup() = win 0x94cb0;
|
||||
const char* getCoinString(void* p0) = win 0x96270;
|
||||
const char* getEndText() = win 0x964A0;
|
||||
void onMenu(cocos2d::CCObject* sender) = mac 0x27a500, win 0x96c10;
|
||||
void onEdit(cocos2d::CCObject* sender) = mac 0x27a640, win 0x96d30;
|
||||
}
|
||||
|
@ -1755,8 +1767,8 @@ class FMODSound : cocos2d::CCNode {
|
|||
class FriendRequestDelegate {}
|
||||
|
||||
class FriendsProfilePage : FLAlertLayer, FLAlertLayerProtocol, UploadActionDelegate, UploadPopupDelegate, UserListDelegate {
|
||||
static FriendsProfilePage* create(UserListType) = win 0x9ce80;
|
||||
bool init(UserListType) = win 0x9cf30;
|
||||
static FriendsProfilePage* create(UserListType) = win 0x9ce80, mac 0x3a9570;
|
||||
bool init(UserListType) = win 0x9cf30, mac 0x3a9770;
|
||||
}
|
||||
|
||||
class GJAccountBackupDelegate {
|
||||
|
@ -1785,11 +1797,16 @@ class GJAccountLoginDelegate {
|
|||
|
||||
class GJAccountManager : cocos2d::CCNode {
|
||||
static GJAccountManager* sharedState() = mac 0x85070, win 0x107d50;
|
||||
static GJAccountManager* get() {
|
||||
return GJAccountManager::sharedState();
|
||||
}
|
||||
gd::string getGJP() = mac 0x89520, win 0x10abb0;
|
||||
|
||||
PAD = mac 0x8, win 0x4;
|
||||
gd::string m_password;
|
||||
gd::string m_username;
|
||||
int m_accountID;
|
||||
int m_playerID;
|
||||
}
|
||||
|
||||
class GJAccountSyncDelegate {
|
||||
|
@ -2281,7 +2298,7 @@ class GJGameLevel : cocos2d::CCNode {
|
|||
void getLengthKey(int) = mac 0x2dbba0;
|
||||
void getNormalPercent() = mac 0x2b8b20;
|
||||
void levelWasAltered() = mac 0x2db530, win 0xbd550;
|
||||
void savePercentage(int, bool, int, int, bool) = mac 0x2db700;
|
||||
void savePercentage(int, bool, int, int, bool) = mac 0x2db700, win 0xbd5c0;
|
||||
void dataLoaded(DS_Dictionary* dict) = mac 0x2dc0e0, win 0xbded0, ios 0x6fca4;
|
||||
GJDifficulty getAverageDifficulty() = win 0xbd9b0;
|
||||
gd::string getUnpackedLevelDescription() = mac 0x2DDB50, win 0xbf890;
|
||||
|
@ -2581,21 +2598,21 @@ class GJScaleControl : cocos2d::CCLayer {
|
|||
virtual void ccTouchMoved(cocos2d::CCTouch*, cocos2d::CCEvent*) = mac 0x31e60, win 0x94840;
|
||||
virtual void ccTouchEnded(cocos2d::CCTouch*, cocos2d::CCEvent*) = mac 0x31fb0, win 0x94940;
|
||||
virtual void ccTouchCancelled(cocos2d::CCTouch*, cocos2d::CCEvent*) = mac 0x32060, win 0x2dea0; // shared with many others
|
||||
void updateLabel(float value) = win 0x94990;
|
||||
void updateLabel(float value) = win 0x94990, mac 0x31c90;
|
||||
void loadValues(GameObject* obj, cocos2d::CCArray* objs) = win 0x94590, mac 0x24f40;
|
||||
|
||||
Slider* m_slider;
|
||||
unsigned int m_touchID;
|
||||
float m_value;
|
||||
PAD = mac 0x8, win 0x4;
|
||||
bool m_shouldSnapAt1;
|
||||
cocos2d::CCLabelBMFont* m_label;
|
||||
GJScaleControlDelegate* m_delegate;
|
||||
}
|
||||
|
||||
class GJScaleControlDelegate {
|
||||
virtual void scaleChanged(float) {}
|
||||
virtual void scaleChangeBegin() {}
|
||||
virtual void scaleChangeEnded() {}
|
||||
virtual void scaleChanged(float) {}
|
||||
}
|
||||
|
||||
class GJScoreCell : TableViewCell, FLAlertLayerProtocol {
|
||||
|
@ -3547,7 +3564,8 @@ class GameStatsManager : cocos2d::CCNode {
|
|||
int getBaseCurrencyForLevel(GJGameLevel*) = mac 0x43470, win 0xf8530;
|
||||
GJChallengeItem* getChallenge(int id) = mac 0x451f0, win 0xa2fb0;
|
||||
void getSecretCoinKey(char const*) = mac 0x429f0;
|
||||
int getStat(char const*) = mac 0x3d310, win 0xf3580;
|
||||
int getStat(char const* type) = mac 0x3d310, win 0xf3580;
|
||||
void setStat(char const* type, int amount) = win 0xf3690;
|
||||
void hasPendingUserCoin(char const*) = mac 0x42730, win 0xf7c50;
|
||||
void hasSecretCoin(char const*) = mac 0x40730, win 0xf7dc0;
|
||||
void hasUserCoin(char const*) = mac 0x427e0, win 0xf7ae0;
|
||||
|
@ -3559,6 +3577,7 @@ class GameStatsManager : cocos2d::CCNode {
|
|||
void storeSecretCoin(char const*) = mac 0x42a10;
|
||||
void storeUserCoin(char const*) = mac 0x42890;
|
||||
bool isItemUnlocked(UnlockType type, int id) = win 0xfbb80;
|
||||
void checkAchievement(char const* type) = win 0xf37c0;
|
||||
|
||||
PAD = mac 0x50, win 0x28;
|
||||
cocos2d::CCDictionary* m_dailyChests;
|
||||
|
@ -3595,7 +3614,7 @@ class GameToolbox {
|
|||
static cocos2d::CCDictionary* stringSetupToDict(gd::string text, char const* delimeter) = mac 0x28d700, win 0x272a0;
|
||||
static CCMenuItemToggler* createToggleButton(gd::string text, cocos2d::SEL_MenuHandler onToggled, bool isToggled, cocos2d::CCMenu* toggleMenu, cocos2d::CCPoint position, cocos2d::CCNode* callbackTarget, cocos2d::CCNode* labelParent, cocos2d::CCArray* toggleArray) = mac 0x28bc90, win 0x25fe0;
|
||||
static CCMenuItemToggler* createToggleButton(gd::string text, cocos2d::SEL_MenuHandler onToggled, bool isToggled, cocos2d::CCMenu* toggleMenu, cocos2d::CCPoint position, cocos2d::CCNode* callbackTarget, cocos2d::CCNode* labelParent, float checkboxScale, float labelSize, float maxWidth, cocos2d::CCPoint labelOffset, const char* unknown, bool anchorHorizontally, int toggleTag, cocos2d::CCArray* toggleArray) = mac 0x28bdd0, win 0x25fe0;
|
||||
static cocos2d::ccColor3B transformColor(cocos2d::ccColor3B const& src, cocos2d::ccHSVValue hsv) = win 0x26a60;
|
||||
static cocos2d::ccColor3B transformColor(cocos2d::ccColor3B const& src, cocos2d::ccHSVValue hsv) = win 0x26a60, mac 0x28c950;
|
||||
static void alignItemsHorisontally(cocos2d::CCArray* array, float pad, cocos2d::CCPoint start, bool idk) = win 0x25b20;
|
||||
static gd::map<gd::string, gd::string> stringSetupToMap(gd::string, char const*) = mac 0x28d4c0;
|
||||
static cocos2d::ccColor3B multipliedColorValue(cocos2d::ccColor3B color1, cocos2d::ccColor3B color2, float factor) = win 0x26CE0;
|
||||
|
@ -3634,7 +3653,7 @@ class GauntletSelectLayer {
|
|||
class GhostTrailEffect {}
|
||||
|
||||
class HSVWidgetPopup : FLAlertLayer {
|
||||
bool init(cocos2d::_ccHSVValue value, HSVWidgetPopupDelegate* delegate, gd::string title);
|
||||
bool init(cocos2d::_ccHSVValue value, HSVWidgetPopupDelegate* delegate, gd::string title) = win 0x49f10, mac 0x236d30;
|
||||
void onClose(cocos2d::CCObject* sender) = win 0x4a280;
|
||||
|
||||
ConfigureHSVWidget* m_configureWidget;
|
||||
|
@ -3657,7 +3676,7 @@ class HardStreak : cocos2d::CCDrawNode {
|
|||
void reset() = mac 0x5c930;
|
||||
void resumeStroke() = mac 0x5c210;
|
||||
void stopStroke() = mac 0x5c8f0, win 0x14e460;
|
||||
void updateStroke(float) = mac 0x5c240, win 0x14e530;
|
||||
callback void updateStroke(float) = mac 0x5c240, win 0x14e530;
|
||||
|
||||
cocos2d::CCArray* m_pointsArr;
|
||||
cocos2d::CCPoint m_currentPoint;
|
||||
|
@ -3753,6 +3772,7 @@ class LevelBrowserLayer : cocos2d::CCLayer, LevelManagerDelegate, FLAlertLayerPr
|
|||
void updateLevelsLabel() = mac 0x255450, win 0x15c350;
|
||||
void onRefresh(cocos2d::CCObject* sender) = mac 0x253090;
|
||||
void onInfo(cocos2d::CCObject* sender) = mac 0x253170, win 0x15cb00;
|
||||
void onNew(cocos2d::CCObject* sender) = win 0x15cbf0, mac 0x252ac0;
|
||||
static LevelBrowserLayer* create(GJSearchObject* search) = mac 0x251210, win 0x159fa0, ios 0x2d0a00;
|
||||
|
||||
PAD = win 0x4, mac 0x8;
|
||||
|
@ -4012,16 +4032,17 @@ class LevelEditorLayer : GJBaseGameLayer, LevelSettingsDelegate {
|
|||
class LevelInfoLayer : cocos2d::CCLayer, LevelDownloadDelegate, LevelUpdateDelegate, RateLevelDelegate, LikeItemDelegate, FLAlertLayerProtocol, LevelDeleteDelegate, NumberInputDelegate, SetIDPopupDelegate {
|
||||
static LevelInfoLayer* create(GJGameLevel* level) = mac 0x15f290, win 0x175d50;
|
||||
bool init(GJGameLevel* level) = win 0x175df0, mac 0x15f520;
|
||||
void onGarage(cocos2d::CCObject* sender) = win 0x177c10;
|
||||
void onGarage(cocos2d::CCObject* sender) = win 0x177c10, mac 0x163ac0;
|
||||
void onViewProfile(cocos2d::CCObject* sender) = mac 0x1617d0, win 0x17ac90;
|
||||
void onLevelInfo(cocos2d::CCObject* sender) = mac 0x163880, win 0x17acf0;
|
||||
void setupProgressBars() = win 0x177fc0;
|
||||
void setupProgressBars() = win 0x177fc0, mac 0x1627e0;
|
||||
void setupLevelInfo() = mac 0x161C80, win 0x178680;
|
||||
void downloadLevel() = win 0x177d90;
|
||||
void downloadLevel() = win 0x177d90, mac 0x161b90;
|
||||
void onPlay(cocos2d::CCObject* sender) = mac 0x161840, win 0x179730;
|
||||
virtual void levelDownloadFinished(GJGameLevel*) = mac 0x164C00, win 0x1790C0;
|
||||
virtual void levelUpdateFinished(GJGameLevel*, UpdateResponse) = mac 0x164E60, win 0x1792B0;
|
||||
void showUpdateAlert(UpdateResponse) = mac 0x164ED0, win 0x179300;
|
||||
void updateLabelValues() = mac 0x164090, win 0x17b170;
|
||||
|
||||
PAD = win 0x4, mac 0x8;
|
||||
cocos2d::CCMenu* m_playBtnMenu;
|
||||
|
@ -4031,13 +4052,13 @@ class LevelInfoLayer : cocos2d::CCLayer, LevelDownloadDelegate, LevelUpdateDeleg
|
|||
CCMenuItemSpriteExtra* m_starRateBtn;
|
||||
CCMenuItemSpriteExtra* m_demonRateBtn;
|
||||
PAD = win 0x4, mac 0x8;
|
||||
CCMenuItemToggler* m_toggler;
|
||||
cocos2d::CCLabelBMFont* m_label0;
|
||||
cocos2d::CCLabelBMFont* m_label1;
|
||||
cocos2d::CCLabelBMFont* m_label2;
|
||||
cocos2d::CCLabelBMFont* m_label3;
|
||||
cocos2d::CCLabelBMFont* m_label4;
|
||||
cocos2d::CCLabelBMFont* m_label5;
|
||||
CCMenuItemToggler* m_ldmToggler;
|
||||
cocos2d::CCLabelBMFont* m_ldmLabel;
|
||||
cocos2d::CCLabelBMFont* m_lengthLabel;
|
||||
cocos2d::CCLabelBMFont* m_downloadsLabel;
|
||||
cocos2d::CCLabelBMFont* m_likesLabel;
|
||||
cocos2d::CCLabelBMFont* m_orbsLabel;
|
||||
cocos2d::CCLabelBMFont* m_folderLabel;
|
||||
CCMenuItemSpriteExtra* m_cloneBtn;
|
||||
PAD = win 0x4, mac 0x8;
|
||||
}
|
||||
|
@ -4089,6 +4110,15 @@ class LevelSettingsDelegate {
|
|||
virtual void levelSettingsUpdated() {}
|
||||
}
|
||||
|
||||
class SecretLayer2 : cocos2d::CCLayer, TextInputDelegate, FLAlertLayerProtocol, DialogDelegate {
|
||||
static SecretLayer2* create() = win 0x21FD70;
|
||||
|
||||
bool init() = win 0x21FE10, mac 0x25fe70;
|
||||
bool onSubmit(cocos2d::CCObject*) = win 0x221ac0, mac 0x2611a0;
|
||||
void updateSearchLabel(const char* text) = win 0x222FC0, mac 0x260e10;
|
||||
void showCompletedLevel() = win 0x220C10;
|
||||
}
|
||||
|
||||
class SecretLayer4 : cocos2d::CCLayer, TextInputDelegate, FLAlertLayerProtocol, DialogDelegate {
|
||||
static SecretLayer4* create() = mac 0x1ed500;
|
||||
static cocos2d::CCScene* scene() = mac 0x1ed4c0;
|
||||
|
@ -4258,7 +4288,6 @@ class LocalLevelManager : GManager {
|
|||
|
||||
cocos2d::CCDictionary* getAllLevelsInDict() = mac 0x35e3d0, win 0x18d7c0;
|
||||
|
||||
PAD = mac 0x4, win 0x1C;
|
||||
cocos2d::CCDictionary* m_loadData;
|
||||
cocos2d::CCDictionary* m_levelData;
|
||||
cocos2d::CCArray* m_localLevels;
|
||||
|
@ -4320,7 +4349,7 @@ class MoreOptionsLayer : FLAlertLayer, TextInputDelegate, GooglePlayDelegate {
|
|||
static MoreOptionsLayer* create() = win 0x1de850;
|
||||
virtual bool init() = mac 0x43f470, win 0x1DE8F0;
|
||||
void addToggle(const char* name, const char* key, const char* info) = mac 0x440430, win 0x1df6b0;
|
||||
void onKeybindings(cocos2d::CCObject* sender) = win 0x749d0;
|
||||
void onKeybindings(cocos2d::CCObject* sender) = mac 0x4410e0, win 0x749d0;
|
||||
void onToggle(cocos2d::CCObject* sender) = mac 0x441370;
|
||||
}
|
||||
|
||||
|
@ -4468,11 +4497,14 @@ class PauseLayer : CCBlockLayer {
|
|||
void createToggleButton(gd::string caption, cocos2d::SEL_MenuHandler callback, bool on, cocos2d::CCMenu* menu, cocos2d::CCPoint pos) = mac 0x20c890, win 0x1e5570;
|
||||
virtual void customSetup() = mac 0x20b300, win 0x1e4620;
|
||||
|
||||
void onRestart(cocos2d::CCObject* sender) = win 0x1e6040;
|
||||
void onRestart(cocos2d::CCObject* sender) = mac 0x20c860, win 0x1e6040;
|
||||
void onPracticeMode(cocos2d::CCObject* sender) = mac 0x20c6d0, win 0x1e5f30;
|
||||
void onNormalMode(cocos2d::CCObject* sender) = mac 0x20c720, win 0x1e5f60;
|
||||
void onResume(cocos2d::CCObject* sender) = mac 0x20c760, win 0x1e5fa0;
|
||||
virtual void keyDown(cocos2d::enumKeyCodes) = mac 0x20cc80, win 0x1E6580;
|
||||
|
||||
void musicSliderChanged(cocos2d::CCObject* sender) = win 0x1e5ce0;
|
||||
void sfxSliderChanged(cocos2d::CCObject* sender) = win 0x1ddfa0;
|
||||
void musicSliderChanged(cocos2d::CCObject* sender) = win 0x1e5ce0, mac 0x20cb00;
|
||||
void sfxSliderChanged(cocos2d::CCObject* sender) = win 0x1ddfa0, mac 0x20cb40;
|
||||
|
||||
bool m_unknown;
|
||||
bool m_unknown2;
|
||||
|
@ -4625,7 +4657,7 @@ class PlayLayer : GJBaseGameLayer, CCCircleWaveDelegate, CurrencyRewardDelegate,
|
|||
void spawnFirework() = mac 0x74200;
|
||||
void spawnParticle(char const*, int, cocos2d::tCCPositionType, cocos2d::CCPoint) = mac 0x76330;
|
||||
void spawnPlayer2() = mac 0x7d170, win 0x2089e0;
|
||||
void startGame() = mac 0x726b0;
|
||||
void startGame() = mac 0x726b0, win 0x1fd390;
|
||||
void startMusic() = mac 0x72910, win 0x20C8F0;
|
||||
void startRecording() = mac 0x7fec0;
|
||||
void startRecordingDelayed() = mac 0x7fed0;
|
||||
|
@ -4641,7 +4673,7 @@ class PlayLayer : GJBaseGameLayer, CCCircleWaveDelegate, CurrencyRewardDelegate,
|
|||
void toggleBGEffectVisibility(bool) = mac 0x7fe80;
|
||||
void toggleDualMode(GameObject*, bool, PlayerObject*, bool) = mac 0x7bf90, win 0x208880;
|
||||
void toggleFlipped(bool, bool) = mac 0x7bdc0, win 0x20ab20;
|
||||
void toggleGhostEffect(int) = mac 0x7fe40;
|
||||
void toggleGhostEffect(int) = mac 0x7fe40, win 0x1f8930;
|
||||
void toggleGlitter(bool) = mac 0x70e00, win 0x20a0d0;
|
||||
void togglePracticeMode(bool) = mac 0x7f9e0, win 0x20d0d0;
|
||||
void toggleProgressbar() = mac 0x6eeb0, win 0x208160;
|
||||
|
@ -5240,6 +5272,9 @@ class SetGroupIDLayer : FLAlertLayer, TextInputDelegate {
|
|||
void updateZOrder() = win 0x22e3d0;
|
||||
void onAddGroup(cocos2d::CCObject* sender) = mac 0x1967d0, win 0x22de20;
|
||||
void onClose(cocos2d::CCObject* sender) = mac 0x1966a0, win 0x22e830;
|
||||
void onEditorLayer(cocos2d::CCObject* sender) = win 0x22d690, mac 0x196800;
|
||||
void onEditorLayer2(cocos2d::CCObject* sender) = win 0x22d710, mac 0x196a40;
|
||||
void onZOrder(cocos2d::CCObject* sender) = win 0x22de80, mac 0x196920;
|
||||
|
||||
GameObject* m_targetObject;
|
||||
cocos2d::CCArray* m_targetObjects;
|
||||
|
@ -5350,12 +5385,14 @@ class SetupOpacityPopup : FLAlertLayer {
|
|||
|
||||
class SetupPickupTriggerPopup : FLAlertLayer {
|
||||
static SetupPickupTriggerPopup* create(EffectGameObject*, cocos2d::CCArray*) = mac 0x35e70, win 0x23d4a0;
|
||||
bool init(EffectGameObject* obj, cocos2d::CCArray* arr) = win 0x23d550, mac 0x36070;
|
||||
void onItemIDArrow(cocos2d::CCObject*) = mac 0x37100;
|
||||
void onNextItemID(cocos2d::CCObject*) = mac 0x37260;
|
||||
void textChanged(CCTextInputNode*) = mac 0x37ca0;
|
||||
void updateItemID() = mac 0x37ab0, win 0x23e4f0;
|
||||
|
||||
PAD = win 0xc;
|
||||
PAD = win 0xc, mac 0x18;
|
||||
CCTextInputNode* m_itemIDInput;
|
||||
CCTextInputNode* m_countInput;
|
||||
}
|
||||
|
||||
|
@ -5432,9 +5469,9 @@ class SimplePlayer : cocos2d::CCSprite {
|
|||
static SimplePlayer* create(int iconID) = mac 0x1b6140, win 0x12bd80;
|
||||
void updatePlayerFrame(int iconID, IconType iconType) = mac 0x1b62f0, win 0x12c650;
|
||||
void updateColors() = mac 0x1ba1f0, win 0x12c440, ios 0x224f2c;
|
||||
void setFrames(const char* firstLayer, const char* secondLayer, const char* birdDome, const char* outlineSprite, const char* detailSprite) = win 0x12c9e0;
|
||||
void setFrames(const char* firstLayer, const char* secondLayer, const char* birdDome, const char* outlineSprite, const char* detailSprite) = mac 0x1bca10, win 0x12c9e0;
|
||||
virtual void setColor(const cocos2d::ccColor3B& color) = mac 0x1bc9b0, win 0x12c410;
|
||||
virtual void setOpacity(unsigned char opacity) = win 0x12cb90;
|
||||
virtual void setOpacity(unsigned char opacity) = mac 0x135370, win 0x12cb90;
|
||||
|
||||
cocos2d::CCSprite* m_firstLayer;
|
||||
cocos2d::CCSprite* m_secondLayer;
|
||||
|
@ -5465,7 +5502,7 @@ class Slider : cocos2d::CCLayer {
|
|||
SliderTouchLogic* m_touchLogic;
|
||||
cocos2d::CCSprite* m_sliderBar;
|
||||
cocos2d::CCSprite* m_groove;
|
||||
float m_unknown;
|
||||
float m_width;
|
||||
float m_height;
|
||||
}
|
||||
|
||||
|
@ -5542,6 +5579,8 @@ class SpeedObject : cocos2d::CCNode {
|
|||
float m_somethingToCompare;
|
||||
float m_idk3;
|
||||
float m_idk4;
|
||||
|
||||
static SpeedObject* create(GameObject*, int, float) = win 0x20DE70;
|
||||
}
|
||||
|
||||
class SpritePartDelegate {}
|
||||
|
@ -5741,7 +5780,7 @@ class UILayer : cocos2d::CCLayerColor {
|
|||
virtual void keyDown(cocos2d::enumKeyCodes key) = mac 0x280470, win 0x25f890;
|
||||
virtual void keyUp(cocos2d::enumKeyCodes key) = mac 0x280600, win 0x25fa10;
|
||||
UILayer() = win 0x25f230;
|
||||
~UILayer() = win 0x25fef0;
|
||||
~UILayer() = win 0x25fef0, mac 0x280c90;
|
||||
|
||||
PAD = mac 0x16, win 0x8, android 0x8;
|
||||
cocos2d::CCMenu* m_checkPointMenu;
|
||||
|
|
|
@ -307,6 +307,8 @@ function(package_geode_resources_now proname src dest header_dest)
|
|||
if (NOT FILE_NAME STREQUAL ".geode_cache" AND NOT FILE_SHOULD_HASH EQUAL -1)
|
||||
|
||||
file(SHA256 ${file} COMPUTED_HASH)
|
||||
file(SIZE ${file} FILE_SIZE)
|
||||
message(STATUS "Hashed ${file} to ${COMPUTED_HASH} (${FILE_SIZE} bytes)")
|
||||
list(APPEND HEADER_FILE "\t{ \"${FILE_NAME}\", \"${COMPUTED_HASH}\" },\n")
|
||||
|
||||
# list(APPEND HEADER_FILE "\t\"${FILE_NAME}\",\n")
|
||||
|
|
|
@ -185,7 +185,8 @@ std::string generateBindingHeader(Root const& root, ghc::filesystem::path const&
|
|||
|
||||
single_output += fmt::format(::format_strings::class_start,
|
||||
fmt::arg("class_name", cls.name),
|
||||
fmt::arg("base_classes", supers)
|
||||
fmt::arg("base_classes", supers)//,
|
||||
// fmt::arg("hidden", str_if("GEODE_HIDDEN ", (codegen::platform & (Platform::Mac | Platform::iOS)) != Platform::None))
|
||||
);
|
||||
|
||||
// what.
|
||||
|
|
|
@ -27,10 +27,13 @@ execute_process(
|
|||
)
|
||||
|
||||
# Package info file for internal representation
|
||||
set(GEODE_RESOURCES_PATH ${CMAKE_CURRENT_SOURCE_DIR}/resources)
|
||||
configure_file(resources/mod.json.in ${CMAKE_CURRENT_SOURCE_DIR}/resources/mod.json)
|
||||
file(READ resources/mod.json LOADER_MOD_JSON)
|
||||
configure_file(${GEODE_ROOT_PATH}/VERSION ${CMAKE_CURRENT_SOURCE_DIR}/resources/version COPYONLY)
|
||||
configure_file(${GEODE_ROOT_PATH}/CHANGELOG.md ${CMAKE_CURRENT_SOURCE_DIR}/resources/changelog.md COPYONLY)
|
||||
configure_file(${GEODE_ROOT_PATH}/VERSION ${GEODE_RESOURCES_PATH}/version COPYONLY)
|
||||
configure_file(${GEODE_RESOURCES_PATH}/about.md.in ${GEODE_RESOURCES_PATH}/about.md NEWLINE_STYLE LF)
|
||||
configure_file(${GEODE_ROOT_PATH}/CHANGELOG.md ${GEODE_RESOURCES_PATH}/changelog.md NEWLINE_STYLE LF)
|
||||
configure_file(${GEODE_RESOURCES_PATH}/support.md.in ${GEODE_RESOURCES_PATH}/support.md NEWLINE_STYLE LF)
|
||||
configure_file(src/internal/about.hpp.in ${CMAKE_CURRENT_SOURCE_DIR}/src/internal/about.hpp)
|
||||
|
||||
# Source files
|
||||
|
|
13
loader/include/Geode/cocos/base_nodes/CCNode.h
vendored
13
loader/include/Geode/cocos/base_nodes/CCNode.h
vendored
|
@ -700,12 +700,6 @@ public:
|
|||
* @param cleanup true if all running actions and callbacks on the child node will be cleanup, false otherwise.
|
||||
*/
|
||||
virtual void removeChildByTag(int tag, bool cleanup);
|
||||
/**
|
||||
* Removes a child from the container by its ID.
|
||||
* @param id The ID of the node
|
||||
* @note Geode addition
|
||||
*/
|
||||
void removeChildByID(std::string const& id);
|
||||
/**
|
||||
* Removes all children from the container with a cleanup.
|
||||
*
|
||||
|
@ -890,6 +884,13 @@ public:
|
|||
*/
|
||||
GEODE_DLL CCNode* getChildByIDRecursive(std::string const& id);
|
||||
|
||||
/**
|
||||
* Removes a child from the container by its ID.
|
||||
* @param id The ID of the node
|
||||
* @note Geode addition
|
||||
*/
|
||||
GEODE_DLL void removeChildByID(std::string const& id);
|
||||
|
||||
/**
|
||||
* Add a child before a specified existing child
|
||||
* @param child The node to add. The node may not be a child of another
|
||||
|
|
|
@ -90,6 +90,7 @@ protected:
|
|||
bool m_bIsSendCleanupToScene;
|
||||
|
||||
public:
|
||||
GEODE_CUSTOM_CONSTRUCTOR_COCOS(CCTransitionScene, CCScene)
|
||||
/**
|
||||
* @js ctor
|
||||
*/
|
||||
|
@ -147,6 +148,7 @@ public:
|
|||
* @js ctor
|
||||
*/
|
||||
CCTransitionSceneOriented();
|
||||
GEODE_CUSTOM_CONSTRUCTOR_COCOS(CCTransitionSceneOriented, CCTransitionScene)
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
|
@ -171,6 +173,7 @@ public:
|
|||
* @js ctor
|
||||
*/
|
||||
CCTransitionRotoZoom();
|
||||
GEODE_CUSTOM_CONSTRUCTOR_COCOS(CCTransitionRotoZoom, CCTransitionScene)
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
|
@ -623,6 +626,7 @@ public:
|
|||
* @js ctor
|
||||
*/
|
||||
CCTransitionFade();
|
||||
GEODE_CUSTOM_CONSTRUCTOR_COCOS(CCTransitionFade, CCTransitionScene)
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
|
|
|
@ -3,12 +3,8 @@
|
|||
|
||||
#include <android/log.h>
|
||||
|
||||
#ifdef GEODE_EXPORTING
|
||||
#define CC_DLL __attribute__((visibility("default")))
|
||||
#else
|
||||
#define CC_DLL
|
||||
#endif
|
||||
#define ACTUAL_CC_DLL CC_DLL
|
||||
#define ACTUAL_CC_DLL
|
||||
|
||||
#define CC_NO_MESSAGE_PSEUDOASSERT(cond) \
|
||||
if (!(cond)) { \
|
||||
|
|
|
@ -3,12 +3,8 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef GEODE_EXPORTING
|
||||
#define CC_DLL __attribute__((visibility("default")))
|
||||
#else
|
||||
#define CC_DLL
|
||||
#endif
|
||||
#define ACTUAL_CC_DLL CC_DLL
|
||||
#define CC_DLL //__attribute__((visibility("hidden")))
|
||||
#define ACTUAL_CC_DLL
|
||||
|
||||
#define CC_ASSERT(cond) assert(cond)
|
||||
|
||||
|
|
|
@ -3,12 +3,8 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef GEODE_EXPORTING
|
||||
#define CC_DLL __attribute__((visibility("default")))
|
||||
#else
|
||||
#define CC_DLL
|
||||
#endif
|
||||
#define ACTUAL_CC_DLL CC_DLL
|
||||
#define CC_DLL //__attribute__((visibility("hidden")))
|
||||
#define ACTUAL_CC_DLL
|
||||
|
||||
|
||||
#if CC_DISABLE_ASSERT > 0
|
||||
|
|
2
loader/include/Geode/fmod/fmod.h
vendored
2
loader/include/Geode/fmod/fmod.h
vendored
|
@ -31,7 +31,7 @@ FMOD_RESULT F_API FMOD_File_GetDiskBusy (int *busy);
|
|||
/*
|
||||
FMOD System factory functions. Use this to create an FMOD System Instance. below you will see FMOD_System_Init/Close to get started.
|
||||
*/
|
||||
FMOD_RESULT F_API FMOD_System_Create (FMOD_SYSTEM **system);
|
||||
FMOD_RESULT /*F_API*/ FMOD_System_Create (FMOD_SYSTEM **system);
|
||||
FMOD_RESULT F_API FMOD_System_Release (FMOD_SYSTEM *system);
|
||||
|
||||
/*
|
||||
|
|
|
@ -406,10 +406,12 @@ namespace geode {
|
|||
bool isLoggingEnabled() const;
|
||||
void setLoggingEnabled(bool enabled);
|
||||
|
||||
bool shouldLoad() const;
|
||||
|
||||
friend class ModImpl;
|
||||
};
|
||||
}
|
||||
|
||||
inline char const* operator"" _spr(char const* str, size_t) {
|
||||
GEODE_HIDDEN inline char const* operator"" _spr(char const* str, size_t) {
|
||||
return geode::Mod::get()->expandSpriteName(str);
|
||||
}
|
||||
|
|
|
@ -96,6 +96,11 @@ namespace geode {
|
|||
*/
|
||||
std::optional<std::string> match;
|
||||
|
||||
/**
|
||||
* The CCTextInputNode's allowed character filter
|
||||
*/
|
||||
std::optional<std::string> filter;
|
||||
|
||||
static Result<StringSetting> parse(JsonMaybeObject& obj);
|
||||
};
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
namespace geode::modifier {
|
||||
template <uint32_t Id>
|
||||
uintptr_t address();
|
||||
GEODE_HIDDEN uintptr_t address();
|
||||
|
||||
Result<tulip::hook::HandlerMetadata> handlerMetadataForAddress(uintptr_t address);
|
||||
}
|
||||
|
|
77
loader/include/Geode/ui/TextArea.hpp
Normal file
77
loader/include/Geode/ui/TextArea.hpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
#pragma once
|
||||
|
||||
#include <Geode/DefaultInclude.hpp>
|
||||
#include <cocos2d.h>
|
||||
|
||||
namespace geode {
|
||||
enum WrappingMode {
|
||||
NO_WRAP,
|
||||
WORD_WRAP,
|
||||
CUTOFF_WRAP
|
||||
};
|
||||
|
||||
/**
|
||||
* A class which provides a textarea with proper alignment and some extra features like:
|
||||
*
|
||||
* - Max lines
|
||||
* - Changing all aspects after creation
|
||||
* - Custom text alignment
|
||||
* - Configurable and automatic word wrapping
|
||||
* - Line padding
|
||||
*
|
||||
* Contact me on Discord (\@smjs) if you have any questions, suggestions or bugs.
|
||||
*/
|
||||
class GEODE_DLL SimpleTextArea : public cocos2d::CCNode {
|
||||
static SimpleTextArea* create(const std::string& text, const std::string& font = "chatFont.fnt", const float scale = 1);
|
||||
static SimpleTextArea* create(const std::string& text, const std::string& font, const float scale, const float width);
|
||||
|
||||
cocos2d::CCMenu* m_container;
|
||||
std::string m_font;
|
||||
std::string m_text;
|
||||
std::vector<cocos2d::CCLabelBMFont*> m_lines;
|
||||
cocos2d::ccColor4B m_color;
|
||||
cocos2d::CCTextAlignment m_alignment;
|
||||
WrappingMode m_wrappingMode;
|
||||
size_t m_maxLines;
|
||||
float m_scale;
|
||||
float m_lineHeight;
|
||||
float m_linePadding;
|
||||
|
||||
void setFont(const std::string& font);
|
||||
std::string getFont();
|
||||
void setColor(const cocos2d::ccColor4B& color);
|
||||
cocos2d::ccColor4B getColor();
|
||||
void setAlignment(const cocos2d::CCTextAlignment alignment);
|
||||
cocos2d::CCTextAlignment getAlignment();
|
||||
void setWrappingMode(const WrappingMode mode);
|
||||
WrappingMode getWrappingMode();
|
||||
void setText(const std::string& text);
|
||||
std::string getText();
|
||||
void setMaxLines(const size_t maxLines);
|
||||
size_t getMaxLines();
|
||||
void setWidth(const float width);
|
||||
float getWidth();
|
||||
void setScale(const float scale);
|
||||
float getScale();
|
||||
void setLinePadding(const float padding);
|
||||
float getLinePadding();
|
||||
std::vector<cocos2d::CCLabelBMFont*> getLines();
|
||||
float getHeight();
|
||||
float getLineHeight();
|
||||
private:
|
||||
static SimpleTextArea* create(const std::string& font, const std::string& text, const float scale, const float width, const bool artificialWidth);
|
||||
|
||||
bool m_shouldUpdate;
|
||||
bool m_artificialWidth;
|
||||
|
||||
SimpleTextArea(const std::string& font, const std::string& text, const float scale, const float width, const bool artificialWidth);
|
||||
cocos2d::CCLabelBMFont* createLabel(const std::string& text, const float top);
|
||||
float calculateOffset(cocos2d::CCLabelBMFont* label);
|
||||
void charIteration(const std::function<cocos2d::CCLabelBMFont*(cocos2d::CCLabelBMFont* line, const char c, const float top)>& overflowHandling);
|
||||
void updateLinesNoWrap();
|
||||
void updateLinesWordWrap();
|
||||
void updateLinesCutoffWrap();
|
||||
void updateContainer();
|
||||
virtual void draw() override;
|
||||
};
|
||||
}
|
|
@ -953,7 +953,7 @@ namespace geode::cocos {
|
|||
return m_arr ? m_arr->count() : 0;
|
||||
}
|
||||
|
||||
T operator[](size_t index) {
|
||||
T* operator[](size_t index) {
|
||||
return static_cast<T*>(m_arr->objectAtIndex(index));
|
||||
}
|
||||
|
||||
|
|
|
@ -8,68 +8,77 @@
|
|||
using namespace geode::prelude;
|
||||
|
||||
struct CustomLoadingLayer : Modify<CustomLoadingLayer, LoadingLayer> {
|
||||
CCLabelBMFont* m_loadedModsLabel;
|
||||
bool m_updatingResources;
|
||||
|
||||
CustomLoadingLayer() : m_loadedModsLabel(nullptr), m_updatingResources(false) {}
|
||||
CCLabelBMFont* m_smallLabel = nullptr;
|
||||
int m_geodeLoadStep = 0;
|
||||
|
||||
void updateLoadedModsLabel() {
|
||||
auto allMods = Loader::get()->getAllMods();
|
||||
auto count = std::count_if(allMods.begin(), allMods.end(), [&](auto& item) {
|
||||
return item->isEnabled();
|
||||
});
|
||||
auto str = fmt::format("Geode: Loaded {}/{} mods", count, allMods.size());
|
||||
m_fields->m_loadedModsLabel->setCString(str.c_str());
|
||||
auto totalCount = std::count_if(allMods.begin(), allMods.end(), [&](auto& item) {
|
||||
return item->shouldLoad();
|
||||
});
|
||||
auto str = fmt::format("Geode: Loaded {}/{} mods", count, totalCount);
|
||||
this->setSmallText(str);
|
||||
}
|
||||
|
||||
void setSmallText(std::string const& text) {
|
||||
m_fields->m_smallLabel->setString(text.c_str());
|
||||
}
|
||||
|
||||
// hook
|
||||
bool init(bool fromReload) {
|
||||
CCFileUtils::get()->updatePaths();
|
||||
|
||||
if (!LoadingLayer::init(fromReload)) return false;
|
||||
|
||||
if (fromReload) return true;
|
||||
|
||||
auto winSize = CCDirector::sharedDirector()->getWinSize();
|
||||
|
||||
m_fields->m_loadedModsLabel = CCLabelBMFont::create("Geode: Loaded 0/0 mods", "goldFont.fnt");
|
||||
m_fields->m_loadedModsLabel->setPosition(winSize.width / 2, 30.f);
|
||||
m_fields->m_loadedModsLabel->setScale(.45f);
|
||||
m_fields->m_loadedModsLabel->setID("geode-loaded-info");
|
||||
this->addChild(m_fields->m_loadedModsLabel);
|
||||
this->updateLoadedModsLabel();
|
||||
|
||||
// fields have unpredictable destructors
|
||||
this->addChild(EventListenerNode<ResourceDownloadFilter>::create(
|
||||
this, &CustomLoadingLayer::updateResourcesProgress
|
||||
));
|
||||
|
||||
// verify loader resources
|
||||
if (!LoaderImpl::get()->verifyLoaderResources()) {
|
||||
m_fields->m_updatingResources = true;
|
||||
this->setUpdateText("Downloading Resources");
|
||||
}
|
||||
else {
|
||||
LoaderImpl::get()->updateSpecialFiles();
|
||||
}
|
||||
m_fields->m_smallLabel = CCLabelBMFont::create("", "goldFont.fnt");
|
||||
m_fields->m_smallLabel->setPosition(winSize.width / 2, 30.f);
|
||||
m_fields->m_smallLabel->setScale(.45f);
|
||||
m_fields->m_smallLabel->setID("geode-small-label");
|
||||
this->addChild(m_fields->m_smallLabel);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void setUpdateText(std::string const& text) {
|
||||
m_textArea->setString(text.c_str());
|
||||
void setupLoadingMods() {
|
||||
if (Loader::get()->getLoadingState() != Loader::LoadingState::Done) {
|
||||
this->updateLoadedModsLabel();
|
||||
this->waitLoadAssets();
|
||||
}
|
||||
else {
|
||||
this->continueLoadAssets();
|
||||
}
|
||||
}
|
||||
|
||||
void setupLoaderResources() {
|
||||
// verify loader resources
|
||||
if (!LoaderImpl::get()->verifyLoaderResources()) {
|
||||
this->setSmallText("Downloading Loader Resources");
|
||||
this->addChild(EventListenerNode<ResourceDownloadFilter>::create(
|
||||
this, &CustomLoadingLayer::updateResourcesProgress
|
||||
));
|
||||
}
|
||||
else {
|
||||
this->setSmallText("Loading Loader Resources");
|
||||
LoaderImpl::get()->updateSpecialFiles();
|
||||
this->continueLoadAssets();
|
||||
}
|
||||
}
|
||||
|
||||
void updateResourcesProgress(ResourceDownloadEvent* event) {
|
||||
std::visit(makeVisitor {
|
||||
[&](UpdateProgress const& progress) {
|
||||
this->setUpdateText(fmt::format(
|
||||
"Downloading Resources: {}%", progress.first
|
||||
this->setSmallText(fmt::format(
|
||||
"Downloading Loader Resources: {}%", progress.first
|
||||
));
|
||||
},
|
||||
[&](UpdateFinished) {
|
||||
this->setUpdateText("Resources Downloaded");
|
||||
m_fields->m_updatingResources = false;
|
||||
this->loadAssets();
|
||||
this->setSmallText("Downloaded Loader Resources");
|
||||
this->continueLoadAssets();
|
||||
},
|
||||
[&](UpdateFailed const& error) {
|
||||
LoaderImpl::get()->platformMessageBox(
|
||||
|
@ -81,24 +90,70 @@ struct CustomLoadingLayer : Modify<CustomLoadingLayer, LoadingLayer> {
|
|||
"The game will be loaded as normal, but please be aware "
|
||||
"that it is very likely to crash. "
|
||||
);
|
||||
this->setUpdateText("Resource Download Failed");
|
||||
m_fields->m_updatingResources = false;
|
||||
this->loadAssets();
|
||||
this->setSmallText("Failed Loader Resources");
|
||||
this->continueLoadAssets();
|
||||
}
|
||||
}, event->status);
|
||||
}
|
||||
|
||||
void loadAssets() {
|
||||
if (Loader::get()->getLoadingState() != Loader::LoadingState::Done) {
|
||||
this->updateLoadedModsLabel();
|
||||
void setupModResources() {
|
||||
log::debug("Loading mod resources");
|
||||
this->setSmallText("Loading mod resources");
|
||||
Loader::get()->updateResources(true);
|
||||
this->continueLoadAssets();
|
||||
}
|
||||
|
||||
int getCurrentStep() {
|
||||
return m_fields->m_geodeLoadStep + m_loadStep + 1;
|
||||
}
|
||||
|
||||
int getTotalStep() {
|
||||
return 18;
|
||||
}
|
||||
|
||||
void updateLoadingBar() {
|
||||
auto length = m_sliderGrooveXPos * this->getCurrentStep() / this->getTotalStep();
|
||||
m_sliderBar->setTextureRect({0, 0, length, m_sliderGrooveHeight});
|
||||
}
|
||||
|
||||
void waitLoadAssets() {
|
||||
Loader::get()->queueInMainThread([this]() {
|
||||
this->loadAssets();
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (m_fields->m_updatingResources) {
|
||||
return;
|
||||
|
||||
void continueLoadAssets() {
|
||||
++m_fields->m_geodeLoadStep;
|
||||
Loader::get()->queueInMainThread([this]() {
|
||||
this->loadAssets();
|
||||
});
|
||||
}
|
||||
|
||||
bool skipOnRefresh() {
|
||||
if (m_fromRefresh) {
|
||||
this->continueLoadAssets();
|
||||
}
|
||||
return !m_fromRefresh;
|
||||
}
|
||||
|
||||
// hook
|
||||
void loadAssets() {
|
||||
switch (m_fields->m_geodeLoadStep) {
|
||||
case 0:
|
||||
if (this->skipOnRefresh()) this->setupLoadingMods();
|
||||
break;
|
||||
case 1:
|
||||
if (this->skipOnRefresh()) this->setupLoaderResources();
|
||||
break;
|
||||
case 2:
|
||||
this->setupModResources();
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
this->setSmallText("Loading game resources");
|
||||
LoadingLayer::loadAssets();
|
||||
break;
|
||||
}
|
||||
this->updateLoadingBar();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
#include <Geode/loader/Loader.hpp>
|
||||
#include <Geode/modify/LoadingLayer.hpp>
|
||||
#include <Geode/modify/GameManager.hpp>
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
||||
struct ResourcesUpdate : Modify<ResourcesUpdate, LoadingLayer> {
|
||||
void loadAssets() {
|
||||
LoadingLayer::loadAssets();
|
||||
// this is in case the user refreshes texture quality at runtime
|
||||
if (m_loadStep == 10) {
|
||||
Loader::get()->updateResources(true);
|
||||
}
|
||||
}
|
||||
};
|
|
@ -7,8 +7,11 @@
|
|||
using namespace geode::prelude;
|
||||
|
||||
$register_ids(GJGarageLayer) {
|
||||
// the lock does not exist for not logged in users
|
||||
auto loggedInOffset = GJAccountManager::get()->m_accountID == GJAccountManager::get()->m_playerID ? -1 : 0;
|
||||
|
||||
setIDSafe(this, 2, "username-label");
|
||||
setIDSafe(this, 6, "player-icon");
|
||||
setIDSafe(this, 6 + loggedInOffset, "player-icon");
|
||||
|
||||
auto winSize = CCDirector::get()->getWinSize();
|
||||
|
||||
|
@ -39,7 +42,7 @@ $register_ids(GJGarageLayer) {
|
|||
|
||||
setIDs(
|
||||
this,
|
||||
10,
|
||||
10 + loggedInOffset,
|
||||
"cube-selection-menu",
|
||||
"ship-selection-menu",
|
||||
"ball-selection-menu",
|
||||
|
|
|
@ -408,7 +408,7 @@ void Loader::Impl::loadModGraph(Mod* node, bool early) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (Mod::get()->getSavedValue<bool>("should-load-" + node->getID(), true)) {
|
||||
if (node->shouldLoad()) {
|
||||
log::debug("Load");
|
||||
auto res = node->m_impl->loadBinary();
|
||||
if (!res) {
|
||||
|
@ -432,6 +432,10 @@ void Loader::Impl::loadModGraph(Mod* node, bool early) {
|
|||
|
||||
void Loader::Impl::findProblems() {
|
||||
for (auto const& [id, mod] : m_mods) {
|
||||
if (!mod->shouldLoad()) {
|
||||
log::debug("{} is not enabled", id);
|
||||
continue;
|
||||
}
|
||||
log::debug(id);
|
||||
log::pushNest();
|
||||
|
||||
|
@ -492,7 +496,7 @@ void Loader::Impl::findProblems() {
|
|||
Mod* myEpicMod = mod; // clang fix
|
||||
// if the mod is not loaded but there are no problems related to it
|
||||
if (!mod->isEnabled() &&
|
||||
Mod::get()->getSavedValue<bool>("should-load-" + mod->getID(), true) &&
|
||||
mod->shouldLoad() &&
|
||||
!std::any_of(m_problems.begin(), m_problems.end(), [myEpicMod](auto& item) {
|
||||
return std::holds_alternative<ModMetadata>(item.cause) &&
|
||||
std::get<ModMetadata>(item.cause).getID() == myEpicMod->getID() ||
|
||||
|
@ -777,7 +781,7 @@ void Loader::Impl::downloadLoaderResources(bool useLatestRelease) {
|
|||
.json()
|
||||
.then([this](json::Value const& json) {
|
||||
this->tryDownloadLoaderResources(fmt::format(
|
||||
"https://github.com/geode-sdk/geode/releases/download/{}/resources-" GEODE_PLATFORM_SHORT_IDENTIFIER ".zip",
|
||||
"https://github.com/geode-sdk/geode/releases/download/{}/resources.zip",
|
||||
this->getVersion().toString()
|
||||
), true);
|
||||
})
|
||||
|
@ -805,7 +809,7 @@ void Loader::Impl::downloadLoaderResources(bool useLatestRelease) {
|
|||
// find release asset
|
||||
for (auto asset : root.needs("assets").iterate()) {
|
||||
auto obj = asset.obj();
|
||||
if (obj.needs("name").template get<std::string>() == "resources-" GEODE_PLATFORM_SHORT_IDENTIFIER ".zip") {
|
||||
if (obj.needs("name").template get<std::string>() == "resources.zip") {
|
||||
this->tryDownloadLoaderResources(
|
||||
obj.needs("browser_download_url").template get<std::string>(),
|
||||
false
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <Geode/utils/ranges.hpp>
|
||||
#include <Geode/utils/MiniFunction.hpp>
|
||||
#include "ModImpl.hpp"
|
||||
#include <about.hpp>
|
||||
#include <crashlog.hpp>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
|
|
|
@ -245,3 +245,7 @@ void Mod::setLoggingEnabled(bool enabled) {
|
|||
bool Mod::hasSavedValue(std::string const& key) {
|
||||
return this->getSaveContainer().contains(key);
|
||||
}
|
||||
|
||||
bool Mod::shouldLoad() const {
|
||||
return m_impl->shouldLoad();
|
||||
}
|
|
@ -43,7 +43,9 @@ Result<> Mod::Impl::setup() {
|
|||
log::warn("Unable to load data for \"{}\": {}", m_metadata.getID(), loadRes.unwrapErr());
|
||||
}
|
||||
if (!m_resourcesLoaded) {
|
||||
LoaderImpl::get()->updateModResources(m_self);
|
||||
auto searchPathRoot = dirs::getModRuntimeDir() / m_metadata.getID() / "resources";
|
||||
CCFileUtils::get()->addSearchPath(searchPathRoot.string().c_str());
|
||||
|
||||
m_resourcesLoaded = true;
|
||||
}
|
||||
|
||||
|
@ -590,14 +592,13 @@ ghc::filesystem::path Mod::Impl::getConfigDir(bool create) const {
|
|||
}
|
||||
|
||||
char const* Mod::Impl::expandSpriteName(char const* name) {
|
||||
static std::unordered_map<std::string, char const*> expanded = {};
|
||||
if (expanded.count(name)) return expanded[name];
|
||||
if (m_expandedSprites.count(name)) return m_expandedSprites[name];
|
||||
|
||||
auto exp = new char[strlen(name) + 2 + m_metadata.getID().size()];
|
||||
auto exps = m_metadata.getID() + "/" + name;
|
||||
memcpy(exp, exps.c_str(), exps.size() + 1);
|
||||
|
||||
expanded[name] = exp;
|
||||
m_expandedSprites[name] = exp;
|
||||
|
||||
return exp;
|
||||
}
|
||||
|
@ -633,6 +634,10 @@ void Mod::Impl::setLoggingEnabled(bool enabled) {
|
|||
m_loggingEnabled = enabled;
|
||||
}
|
||||
|
||||
bool Mod::Impl::shouldLoad() const {
|
||||
return Mod::get()->getSavedValue<bool>("should-load-" + m_metadata.getID(), true);
|
||||
}
|
||||
|
||||
static Result<ModMetadata> getModImplInfo() {
|
||||
std::string err;
|
||||
json::Value json;
|
||||
|
|
|
@ -61,6 +61,8 @@ namespace geode {
|
|||
*/
|
||||
bool m_loggingEnabled = true;
|
||||
|
||||
std::unordered_map<std::string, char const*> m_expandedSprites;
|
||||
|
||||
|
||||
ModRequestedAction m_requestedAction = ModRequestedAction::None;
|
||||
|
||||
|
@ -137,6 +139,8 @@ namespace geode {
|
|||
|
||||
bool isLoggingEnabled() const;
|
||||
void setLoggingEnabled(bool enabled);
|
||||
|
||||
bool shouldLoad() const;
|
||||
};
|
||||
|
||||
class ModImpl : public Mod::Impl {
|
||||
|
|
|
@ -62,6 +62,7 @@ Result<StringSetting> StringSetting::parse(JsonMaybeObject& obj) {
|
|||
StringSetting sett;
|
||||
parseCommon(sett, obj);
|
||||
obj.has("match").into(sett.match);
|
||||
obj.has("filter").into(sett.filter);
|
||||
return Ok(sett);
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ CCNode* geode::createDefaultLogo(CCSize const& size) {
|
|||
if (!spr) {
|
||||
spr = CCLabelBMFont::create("OwO", "goldFont.fnt");
|
||||
}
|
||||
limitNodeSize(spr, size, 1.f, .1f);
|
||||
limitNodeSize(spr, size, 1.f, .01f);
|
||||
return spr;
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ CCNode* geode::createModLogo(Mod* mod, CCSize const& size) {
|
|||
CCSprite::create(fmt::format("{}/logo.png", mod->getID()).c_str());
|
||||
if (!spr) spr = CCSprite::createWithSpriteFrameName("no-logo.png"_spr);
|
||||
if (!spr) spr = CCLabelBMFont::create("N/A", "goldFont.fnt");
|
||||
limitNodeSize(spr, size, 1.f, .1f);
|
||||
limitNodeSize(spr, size, 1.f, .01f);
|
||||
spr->setPosition(size/2);
|
||||
spr->setAnchorPoint({.5f, .5f});
|
||||
|
||||
|
@ -116,7 +116,7 @@ CCNode* geode::createIndexItemLogo(IndexItemHandle item, CCSize const& size) {
|
|||
spr = logoGlow;
|
||||
}
|
||||
else {
|
||||
limitNodeSize(spr, size, 1.f, .1f);
|
||||
limitNodeSize(spr, size, 1.f, .01f);
|
||||
}
|
||||
spr->setPosition(size/2);
|
||||
spr->setAnchorPoint({.5f, .5f});
|
||||
|
|
|
@ -5,8 +5,9 @@
|
|||
#include "../list/ModListCell.hpp"
|
||||
#include "../list/ModListLayer.hpp"
|
||||
|
||||
bool DevProfilePopup::setup(std::string const& developer) {
|
||||
bool DevProfilePopup::setup(std::string const& developer, ModListLayer* list) {
|
||||
m_noElasticity = true;
|
||||
m_layer = list;
|
||||
|
||||
this->setTitle("Mods by " + developer);
|
||||
|
||||
|
@ -18,7 +19,7 @@ bool DevProfilePopup::setup(std::string const& developer) {
|
|||
for (auto& mod : Loader::get()->getAllMods()) {
|
||||
if (mod->getDeveloper() == developer) {
|
||||
auto cell = ModCell::create(
|
||||
mod, nullptr, ModListDisplay::Concise, { 358.f, 40.f }
|
||||
mod, m_layer, ModListDisplay::Concise, { 358.f, 40.f }
|
||||
);
|
||||
cell->disableDeveloperButton();
|
||||
items->addObject(cell);
|
||||
|
@ -31,7 +32,7 @@ bool DevProfilePopup::setup(std::string const& developer) {
|
|||
continue;
|
||||
}
|
||||
auto cell = IndexItemCell::create(
|
||||
item, nullptr, ModListDisplay::Concise, { 358.f, 40.f }
|
||||
item, m_layer, ModListDisplay::Concise, { 358.f, 40.f }
|
||||
);
|
||||
cell->disableDeveloperButton();
|
||||
items->addObject(cell);
|
||||
|
@ -39,18 +40,18 @@ bool DevProfilePopup::setup(std::string const& developer) {
|
|||
|
||||
// mods list
|
||||
auto listSize = CCSize { 358.f, 160.f };
|
||||
auto list = ListView::create(items, 40.f, listSize.width, listSize.height);
|
||||
list->setPosition(winSize / 2 - listSize / 2);
|
||||
m_mainLayer->addChild(list);
|
||||
auto cellList = ListView::create(items, 40.f, listSize.width, listSize.height);
|
||||
cellList->setPosition(winSize / 2 - listSize / 2);
|
||||
m_mainLayer->addChild(cellList);
|
||||
|
||||
addListBorders(m_mainLayer, winSize / 2, listSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DevProfilePopup* DevProfilePopup::create(std::string const& developer) {
|
||||
DevProfilePopup* DevProfilePopup::create(std::string const& developer, ModListLayer* list) {
|
||||
auto ret = new DevProfilePopup();
|
||||
if (ret && ret->init(420.f, 260.f, developer)) {
|
||||
if (ret && ret->init(420.f, 260.f, developer, list)) {
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -4,10 +4,14 @@
|
|||
|
||||
using namespace geode::prelude;
|
||||
|
||||
class DevProfilePopup : public Popup<std::string const&> {
|
||||
class ModListLayer;
|
||||
|
||||
class DevProfilePopup : public Popup<std::string const&, ModListLayer*> {
|
||||
protected:
|
||||
bool setup(std::string const& developer) override;
|
||||
ModListLayer* m_layer;
|
||||
|
||||
bool setup(std::string const& developer, ModListLayer* list) override;
|
||||
|
||||
public:
|
||||
static DevProfilePopup* create(std::string const& developer);
|
||||
static DevProfilePopup* create(std::string const& developer, ModListLayer* list);
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "../list/ModListLayer.hpp"
|
||||
#include "../settings/ModSettingsPopup.hpp"
|
||||
#include <Geode/loader/Dirs.hpp>
|
||||
#include <about.hpp>
|
||||
|
||||
#include <Geode/binding/ButtonSprite.hpp>
|
||||
#include <Geode/binding/CCTextInputNode.hpp>
|
||||
|
@ -49,45 +50,51 @@ bool ModInfoPopup::init(ModMetadata const& metadata, ModListLayer* list) {
|
|||
constexpr float logoSize = 40.f;
|
||||
constexpr float logoOffset = 10.f;
|
||||
|
||||
auto nameLabel = CCLabelBMFont::create(metadata.getName().c_str(), "bigFont.fnt");
|
||||
nameLabel->setAnchorPoint({ .0f, .5f });
|
||||
nameLabel->limitLabelWidth(200.f, .7f, .1f);
|
||||
m_mainLayer->addChild(nameLabel, 2);
|
||||
auto topNode = CCNode::create();
|
||||
topNode->setContentSize({350.f, 80.f});
|
||||
topNode->setLayout(
|
||||
RowLayout::create()
|
||||
->setAxisAlignment(AxisAlignment::Center)
|
||||
->setAutoScale(false)
|
||||
->setCrossAxisOverflow(true)
|
||||
);
|
||||
m_mainLayer->addChild(topNode);
|
||||
topNode->setAnchorPoint({.5f, .5f});
|
||||
topNode->setPosition(winSize.width / 2, winSize.height / 2 + 115.f);
|
||||
|
||||
auto logoSpr = this->createLogo({logoSize, logoSize});
|
||||
m_mainLayer->addChild(logoSpr);
|
||||
topNode->addChild(logoSpr);
|
||||
|
||||
auto labelNode = CCNode::create();
|
||||
labelNode->setLayout(
|
||||
ColumnLayout::create()
|
||||
->setAxisAlignment(AxisAlignment::Center)
|
||||
->setCrossAxisLineAlignment(AxisAlignment::Start)
|
||||
->setGap(0.f)
|
||||
->setAutoScale(false)
|
||||
->setCrossAxisOverflow(true)
|
||||
);
|
||||
labelNode->setContentSize({200.f, 80.f});
|
||||
topNode->addChild(labelNode);
|
||||
|
||||
auto nameLabel = CCLabelBMFont::create(metadata.getName().c_str(), "bigFont.fnt");
|
||||
nameLabel->limitLabelWidth(200.f, .7f, .1f);
|
||||
labelNode->addChild(nameLabel, 2);
|
||||
|
||||
auto developerStr = "by " + metadata.getDeveloper();
|
||||
auto developerLabel = CCLabelBMFont::create(developerStr.c_str(), "goldFont.fnt");
|
||||
developerLabel->setScale(.5f);
|
||||
developerLabel->setAnchorPoint({.0f, .5f});
|
||||
m_mainLayer->addChild(developerLabel);
|
||||
|
||||
auto logoTitleWidth =
|
||||
std::max(nameLabel->getScaledContentSize().width, developerLabel->getScaledContentSize().width) +
|
||||
logoSize + logoOffset;
|
||||
|
||||
nameLabel->setPosition(
|
||||
winSize.width / 2 - logoTitleWidth / 2 + logoSize + logoOffset, winSize.height / 2 + 125.f
|
||||
);
|
||||
logoSpr->setPosition(
|
||||
{winSize.width / 2 - logoTitleWidth / 2 + logoSize / 2, winSize.height / 2 + 115.f}
|
||||
);
|
||||
developerLabel->setPosition(
|
||||
winSize.width / 2 - logoTitleWidth / 2 + logoSize + logoOffset, winSize.height / 2 + 105.f
|
||||
);
|
||||
labelNode->addChild(developerLabel);
|
||||
|
||||
auto versionLabel = CCLabelBMFont::create(metadata.getVersion().toString().c_str(),
|
||||
"bigFont.fnt"
|
||||
);
|
||||
versionLabel->setAnchorPoint({ .0f, .5f });
|
||||
versionLabel->setScale(.4f);
|
||||
versionLabel->setPosition(
|
||||
nameLabel->getPositionX() + nameLabel->getScaledContentSize().width + 5.f,
|
||||
winSize.height / 2 + 125.f
|
||||
);
|
||||
versionLabel->setColor({0, 255, 0});
|
||||
m_mainLayer->addChild(versionLabel);
|
||||
topNode->addChild(versionLabel);
|
||||
|
||||
labelNode->updateLayout();
|
||||
topNode->updateLayout();
|
||||
|
||||
this->setTouchEnabled(true);
|
||||
|
||||
|
@ -425,7 +432,7 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
|
|||
disableBtnSpr, enableBtnSpr, this, menu_selector(LocalModInfoPopup::onEnableMod)
|
||||
);
|
||||
enableBtn->setPosition(-155.f, 75.f);
|
||||
enableBtn->toggle(!mod->isEnabled());
|
||||
enableBtn->toggle(!mod->shouldLoad());
|
||||
m_buttonMenu->addChild(enableBtn);
|
||||
|
||||
if (!mod->supportsDisabling()) {
|
||||
|
@ -629,9 +636,9 @@ void LocalModInfoPopup::onEnableMod(CCObject* sender) {
|
|||
}
|
||||
}
|
||||
if (m_layer) {
|
||||
m_layer->updateAllStates();
|
||||
m_layer->reloadList();
|
||||
}
|
||||
as<CCMenuItemToggler*>(sender)->toggle(m_mod->isEnabled());
|
||||
as<CCMenuItemToggler*>(sender)->toggle(m_mod->shouldLoad());
|
||||
}
|
||||
|
||||
void LocalModInfoPopup::onOpenConfigDir(CCObject*) {
|
||||
|
@ -640,7 +647,7 @@ void LocalModInfoPopup::onOpenConfigDir(CCObject*) {
|
|||
|
||||
void LocalModInfoPopup::onDisablingNotSupported(CCObject* pSender) {
|
||||
FLAlertLayer::create("Unsupported", "<cr>Disabling</c> is not supported for this mod.", "OK")->show();
|
||||
as<CCMenuItemToggler*>(pSender)->toggle(m_mod->isEnabled());
|
||||
as<CCMenuItemToggler*>(pSender)->toggle(m_mod->shouldLoad());
|
||||
}
|
||||
|
||||
void LocalModInfoPopup::onSettings(CCObject*) {
|
||||
|
|
|
@ -53,24 +53,21 @@ void InstallListCell::setupInfo(
|
|||
}
|
||||
this->addChild(m_titleLabel);
|
||||
|
||||
m_developerBtn = nullptr;
|
||||
m_creatorLabel = nullptr;
|
||||
if (developer) {
|
||||
auto creatorStr = "by " + *developer;
|
||||
auto creatorLabel = CCLabelBMFont::create(creatorStr.c_str(), "goldFont.fnt");
|
||||
creatorLabel->setScale(.34f);
|
||||
m_creatorLabel = CCLabelBMFont::create(creatorStr.c_str(), "goldFont.fnt");
|
||||
m_creatorLabel->setScale(.34f);
|
||||
if (inactive) {
|
||||
creatorLabel->setColor({ 163, 163, 163 });
|
||||
m_creatorLabel->setColor({ 163, 163, 163 });
|
||||
}
|
||||
|
||||
m_developerBtn = CCMenuItemSpriteExtra::create(
|
||||
creatorLabel, this, menu_selector(InstallListCell::onViewDev)
|
||||
);
|
||||
m_developerBtn->setPosition(
|
||||
m_creatorLabel->setPosition(
|
||||
m_titleLabel->getPositionX() + m_titleLabel->getScaledContentSize().width + 3.f +
|
||||
creatorLabel->getScaledContentSize().width / 2,
|
||||
m_creatorLabel->getScaledContentSize().width / 2,
|
||||
m_height / 2
|
||||
);
|
||||
m_menu->addChild(m_developerBtn);
|
||||
m_menu->addChild(m_creatorLabel);
|
||||
}
|
||||
|
||||
this->setupVersion(version);
|
||||
|
@ -96,7 +93,7 @@ void InstallListCell::setupVersion(std::variant<VersionInfo, ComparableVersionIn
|
|||
m_versionLabel->setScale(.2f);
|
||||
m_versionLabel->setPosition(
|
||||
m_titleLabel->getPositionX() + m_titleLabel->getScaledContentSize().width + 3.f +
|
||||
(m_developerBtn ? m_developerBtn->getScaledContentSize().width + 3.f : 0.f),
|
||||
(m_creatorLabel ? m_creatorLabel->getScaledContentSize().width + 3.f : 0.f),
|
||||
m_titleLabel->getPositionY() - 1.f
|
||||
);
|
||||
m_versionLabel->setColor({ 0, 255, 0 });
|
||||
|
@ -123,7 +120,7 @@ void InstallListCell::setupInfo(ModMetadata const& metadata, bool inactive) {
|
|||
}
|
||||
|
||||
void InstallListCell::onViewDev(CCObject*) {
|
||||
DevProfilePopup::create(getDeveloper())->show();
|
||||
// DevProfilePopup::create(getDeveloper(), m_layer)->show();
|
||||
}
|
||||
|
||||
bool InstallListCell::init(InstallListPopup* list, CCSize const& size) {
|
||||
|
|
|
@ -21,7 +21,7 @@ protected:
|
|||
float m_height;
|
||||
InstallListPopup* m_layer = nullptr;
|
||||
CCMenu* m_menu = nullptr;
|
||||
CCMenuItemSpriteExtra* m_developerBtn = nullptr;
|
||||
CCLabelBMFont* m_creatorLabel = nullptr;
|
||||
CCLabelBMFont* m_titleLabel = nullptr;
|
||||
CCLabelBMFont* m_versionLabel = nullptr;
|
||||
TagNode* m_tagLabel = nullptr;
|
||||
|
|
|
@ -113,7 +113,7 @@ CCArray* InstallListPopup::createCells(std::unordered_map<std::string, InstallLi
|
|||
|
||||
// installed
|
||||
// TODO: we should be able to select a different version even if its installed
|
||||
if (/*item.mod && !item.mod->isUninstalled()*/item.mod->getMetadata().getID() == "geode.loader") {
|
||||
if (item.mod && /*!item.mod->isUninstalled()*/item.mod->getMetadata().getID() == "geode.loader") {
|
||||
bottom.push_back(ModInstallListCell::create(item.mod, this, this->getCellSize()));
|
||||
for (auto const& dep : item.mod->getMetadata().getDependencies()) {
|
||||
queue.push(dep);
|
||||
|
|
|
@ -186,7 +186,7 @@ void ModListCell::updateCellLayout() {
|
|||
}
|
||||
|
||||
void ModListCell::onViewDev(CCObject*) {
|
||||
DevProfilePopup::create(this->getDeveloper())->show();
|
||||
DevProfilePopup::create(this->getDeveloper(), m_layer)->show();
|
||||
}
|
||||
|
||||
bool ModListCell::init(ModListLayer* list, CCSize const& size) {
|
||||
|
@ -233,8 +233,10 @@ void ModCell::onEnable(CCObject* sender) {
|
|||
else {
|
||||
tryOrAlert(m_mod->disable(), "Error disabling mod");
|
||||
}
|
||||
if (m_layer) {
|
||||
m_layer->reloadList();
|
||||
}
|
||||
}
|
||||
|
||||
void ModCell::onUnresolvedInfo(CCObject*) {
|
||||
ProblemsListPopup::create(m_mod)->show();
|
||||
|
@ -250,13 +252,15 @@ void ModCell::onRestart(CCObject*) {
|
|||
|
||||
void ModCell::updateState() {
|
||||
bool unresolved = m_mod->hasUnresolvedDependencies();
|
||||
bool shouldLoad = m_mod->shouldLoad();
|
||||
auto toggleable = !unresolved || !shouldLoad;
|
||||
if (m_enableToggle) {
|
||||
m_enableToggle->toggle(m_mod->isEnabled());
|
||||
m_enableToggle->setEnabled(!unresolved);
|
||||
m_enableToggle->m_offButton->setOpacity(unresolved ? 100 : 255);
|
||||
m_enableToggle->m_offButton->setColor(unresolved ? cc3x(155) : cc3x(255));
|
||||
m_enableToggle->m_onButton->setOpacity(unresolved ? 100 : 255);
|
||||
m_enableToggle->m_onButton->setColor(unresolved ? cc3x(155) : cc3x(255));
|
||||
m_enableToggle->setEnabled(toggleable);
|
||||
m_enableToggle->m_offButton->setOpacity(!toggleable ? 100 : 255);
|
||||
m_enableToggle->m_offButton->setColor(!toggleable ? cc3x(155) : cc3x(255));
|
||||
m_enableToggle->m_onButton->setOpacity(!toggleable ? 100 : 255);
|
||||
m_enableToggle->m_onButton->setColor(!toggleable ? cc3x(155) : cc3x(255));
|
||||
}
|
||||
bool hasProblems = false;
|
||||
for (auto const& item : Loader::get()->getProblems()) {
|
||||
|
@ -309,9 +313,6 @@ bool ModCell::init(
|
|||
auto viewSpr = ButtonSprite::create("View", "bigFont.fnt", "GJ_button_01.png", .8f);
|
||||
viewSpr->setScale(.65f);
|
||||
|
||||
auto viewBtn = CCMenuItemSpriteExtra::create(viewSpr, this, menu_selector(ModCell::onInfo));
|
||||
m_menu->addChild(viewBtn);
|
||||
|
||||
if (m_mod->isEnabled()) {
|
||||
auto latestIndexItem = Index::get()->getMajorItem(
|
||||
mod->getMetadata().getID()
|
||||
|
@ -333,6 +334,9 @@ bool ModCell::init(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto viewBtn = CCMenuItemSpriteExtra::create(viewSpr, this, menu_selector(ModCell::onInfo));
|
||||
m_menu->addChild(viewBtn);
|
||||
}
|
||||
|
||||
this->updateState();
|
||||
|
|
|
@ -324,6 +324,11 @@ bool StringSettingNode::setup(StringSettingValue* setting, float width) {
|
|||
m_input = InputNode::create(width / 2 - 10.f, "Text", "chatFont.fnt");
|
||||
m_input->setPosition({ -(width / 2 - 70.f) / 2, .0f });
|
||||
m_input->setScale(.65f);
|
||||
|
||||
if (setting->castDefinition().filter.has_value()) {
|
||||
m_input->getInput()->setAllowedChars(setting->castDefinition().filter.value());
|
||||
}
|
||||
|
||||
m_input->getInput()->setDelegate(this);
|
||||
m_menu->addChild(m_input);
|
||||
|
||||
|
|
|
@ -109,8 +109,8 @@ bool MDTextArea::init(std::string const& str, CCSize const& size) {
|
|||
if (!CCLayer::init()) return false;
|
||||
|
||||
m_text = str;
|
||||
m_size = size;
|
||||
this->setContentSize(size);
|
||||
m_size = size - CCSize { 15.f, 0.f };
|
||||
this->setContentSize(m_size);
|
||||
m_renderer = TextRenderer::create();
|
||||
CC_SAFE_RETAIN(m_renderer);
|
||||
|
||||
|
@ -118,8 +118,8 @@ bool MDTextArea::init(std::string const& str, CCSize const& size) {
|
|||
m_bgSprite->setScale(.5f);
|
||||
m_bgSprite->setColor({ 0, 0, 0 });
|
||||
m_bgSprite->setOpacity(75);
|
||||
m_bgSprite->setContentSize(size * 2 + CCSize { 25.f, 25.f });
|
||||
m_bgSprite->setPosition(size / 2);
|
||||
m_bgSprite->setContentSize(size * 2);
|
||||
m_bgSprite->setPosition(m_size / 2);
|
||||
this->addChild(m_bgSprite);
|
||||
|
||||
m_scrollLayer = ScrollLayer::create({ 0, 0, m_size.width, m_size.height }, true);
|
||||
|
@ -209,6 +209,7 @@ struct MDParser {
|
|||
static float s_codeStart;
|
||||
static size_t s_orderedListNum;
|
||||
static std::vector<TextRenderer::Label> s_codeSpans;
|
||||
static bool s_breakListLine;
|
||||
|
||||
static int parseText(MD_TEXTTYPE type, MD_CHAR const* rawText, MD_SIZE size, void* mdtextarea) {
|
||||
auto textarea = static_cast<MDTextArea*>(mdtextarea);
|
||||
|
@ -364,6 +365,10 @@ struct MDParser {
|
|||
renderer->pushIndent(g_indent);
|
||||
s_isOrderedList = type == MD_BLOCKTYPE::MD_BLOCK_OL;
|
||||
s_orderedListNum = 0;
|
||||
if (s_breakListLine) {
|
||||
renderer->breakLine();
|
||||
s_breakListLine = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -377,6 +382,10 @@ struct MDParser {
|
|||
|
||||
case MD_BLOCKTYPE::MD_BLOCK_LI:
|
||||
{
|
||||
if (s_breakListLine) {
|
||||
renderer->breakLine();
|
||||
s_breakListLine = false;
|
||||
}
|
||||
renderer->pushOpacity(renderer->getCurrentOpacity() / 2);
|
||||
auto lidetail = static_cast<MD_BLOCK_LI_DETAIL*>(detail);
|
||||
if (s_isOrderedList) {
|
||||
|
@ -387,6 +396,7 @@ struct MDParser {
|
|||
renderer->renderString("• ");
|
||||
}
|
||||
renderer->popOpacity();
|
||||
s_breakListLine = true;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -446,7 +456,13 @@ struct MDParser {
|
|||
case MD_BLOCKTYPE::MD_BLOCK_UL:
|
||||
{
|
||||
renderer->popIndent();
|
||||
if (s_breakListLine) {
|
||||
renderer->breakLine();
|
||||
s_breakListLine = false;
|
||||
}
|
||||
if (renderer->getCurrentIndent() == 0) {
|
||||
renderer->breakLine();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -489,7 +505,6 @@ struct MDParser {
|
|||
|
||||
case MD_BLOCKTYPE::MD_BLOCK_LI:
|
||||
{
|
||||
renderer->breakLine();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -626,6 +641,7 @@ size_t MDParser::s_orderedListNum = 0;
|
|||
bool MDParser::s_isCodeBlock = false;
|
||||
float MDParser::s_codeStart = 0;
|
||||
decltype(MDParser::s_codeSpans) MDParser::s_codeSpans = {};
|
||||
bool MDParser::s_breakListLine = false;
|
||||
|
||||
void MDTextArea::updateLabel() {
|
||||
m_renderer->begin(m_content, CCPointZero, m_size);
|
||||
|
@ -679,7 +695,16 @@ void MDTextArea::updateLabel() {
|
|||
|
||||
m_renderer->end();
|
||||
|
||||
if (m_content->getContentSize().height > m_size.height) {
|
||||
// Generate bottom padding
|
||||
m_scrollLayer->m_contentLayer->setContentSize(m_content->getContentSize() + CCSize { 0.f, 12.5 });
|
||||
m_content->setPositionY(10.f);
|
||||
} else {
|
||||
m_scrollLayer->m_contentLayer->setContentSize(m_content->getContentSize());
|
||||
m_content->setPositionY(-2.5f);
|
||||
}
|
||||
|
||||
|
||||
m_scrollLayer->moveToTop();
|
||||
}
|
||||
|
||||
|
|
300
loader/src/ui/nodes/TextArea.cpp
Normal file
300
loader/src/ui/nodes/TextArea.cpp
Normal file
|
@ -0,0 +1,300 @@
|
|||
#include <Geode/ui/TextArea.hpp>
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
||||
SimpleTextArea* SimpleTextArea::create(const std::string& text, const std::string& font, const float scale) {
|
||||
return SimpleTextArea::create(font, text, scale, CCDirector::sharedDirector()->getWinSize().width / 2, false);
|
||||
}
|
||||
|
||||
SimpleTextArea* SimpleTextArea::create(const std::string& text, const std::string& font, const float scale, const float width) {
|
||||
return SimpleTextArea::create(font, text, scale, width, true);
|
||||
}
|
||||
|
||||
SimpleTextArea* SimpleTextArea::create(const std::string& font, const std::string& text, const float scale, const float width, const bool artificialWidth) {
|
||||
SimpleTextArea* instance = new SimpleTextArea(font, text, scale, width, artificialWidth);
|
||||
|
||||
if (instance && instance->init()) {
|
||||
instance->autorelease();
|
||||
|
||||
return instance;
|
||||
} else {
|
||||
CC_SAFE_DELETE(instance);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTextArea::SimpleTextArea(const std::string& font, const std::string& text, const float scale, const float width, const bool artificialWidth) {
|
||||
m_font = font;
|
||||
m_text = text;
|
||||
m_maxLines = 0;
|
||||
m_scale = scale;
|
||||
m_linePadding = 0;
|
||||
m_color = { 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
m_alignment = kCCTextAlignmentLeft;
|
||||
m_wrappingMode = WORD_WRAP;
|
||||
m_artificialWidth = artificialWidth;
|
||||
m_container = CCMenu::create();
|
||||
m_shouldUpdate = true;
|
||||
|
||||
this->setAnchorPoint({ 0.5f, 0.5f });
|
||||
m_container->setPosition({ 0, 0 });
|
||||
m_container->setAnchorPoint({ 0, 1 });
|
||||
m_container->setContentSize({ width, 0 });
|
||||
|
||||
this->addChild(m_container);
|
||||
}
|
||||
|
||||
void SimpleTextArea::setFont(const std::string& font) {
|
||||
m_font = font;
|
||||
m_shouldUpdate = true;
|
||||
}
|
||||
|
||||
std::string SimpleTextArea::getFont() {
|
||||
return m_font;
|
||||
}
|
||||
|
||||
void SimpleTextArea::setColor(const ccColor4B& color) {
|
||||
m_color = color;
|
||||
m_shouldUpdate = true;
|
||||
}
|
||||
|
||||
ccColor4B SimpleTextArea::getColor() {
|
||||
return m_color;
|
||||
}
|
||||
|
||||
void SimpleTextArea::setAlignment(const CCTextAlignment alignment) {
|
||||
m_alignment = alignment;
|
||||
m_shouldUpdate = true;
|
||||
}
|
||||
|
||||
CCTextAlignment SimpleTextArea::getAlignment() {
|
||||
return m_alignment;
|
||||
}
|
||||
|
||||
void SimpleTextArea::setWrappingMode(const WrappingMode mode) {
|
||||
m_wrappingMode = mode;
|
||||
m_shouldUpdate = true;
|
||||
}
|
||||
|
||||
WrappingMode SimpleTextArea::getWrappingMode() {
|
||||
return m_wrappingMode;
|
||||
}
|
||||
|
||||
void SimpleTextArea::setText(const std::string& text) {
|
||||
m_text = text;
|
||||
m_shouldUpdate = true;
|
||||
}
|
||||
|
||||
std::string SimpleTextArea::getText() {
|
||||
return m_text;
|
||||
}
|
||||
|
||||
void SimpleTextArea::setMaxLines(const size_t maxLines) {
|
||||
m_maxLines = maxLines;
|
||||
m_shouldUpdate = true;
|
||||
}
|
||||
|
||||
size_t SimpleTextArea::getMaxLines() {
|
||||
return m_maxLines;
|
||||
}
|
||||
|
||||
void SimpleTextArea::setWidth(const float width) {
|
||||
m_artificialWidth = true;
|
||||
m_shouldUpdate = true;
|
||||
|
||||
this->setContentSize({ width, this->getContentSize().height });
|
||||
m_container->setContentSize(this->getContentSize());
|
||||
}
|
||||
|
||||
float SimpleTextArea::getWidth() {
|
||||
return m_container->getContentSize().width;
|
||||
}
|
||||
|
||||
void SimpleTextArea::setScale(const float scale) {
|
||||
m_scale = scale;
|
||||
m_shouldUpdate = true;
|
||||
}
|
||||
|
||||
float SimpleTextArea::getScale() {
|
||||
return m_scale;
|
||||
}
|
||||
|
||||
void SimpleTextArea::setLinePadding(const float padding) {
|
||||
m_linePadding = padding;
|
||||
m_shouldUpdate = true;
|
||||
}
|
||||
|
||||
float SimpleTextArea::getLinePadding() {
|
||||
return m_linePadding;
|
||||
}
|
||||
|
||||
std::vector<CCLabelBMFont*> SimpleTextArea::getLines() {
|
||||
return m_lines;
|
||||
}
|
||||
|
||||
float SimpleTextArea::getHeight() {
|
||||
return m_container->getContentSize().height;
|
||||
}
|
||||
|
||||
float SimpleTextArea::getLineHeight() {
|
||||
return m_lineHeight;
|
||||
}
|
||||
|
||||
CCLabelBMFont* SimpleTextArea::createLabel(const std::string& text, const float top) {
|
||||
CCLabelBMFont* label = CCLabelBMFont::create(text.c_str(), m_font.c_str());
|
||||
|
||||
label->setScale(m_scale);
|
||||
label->setPosition({ 0, top });
|
||||
label->setColor({ m_color.r, m_color.g, m_color.b });
|
||||
label->setOpacity(m_color.a);
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
float SimpleTextArea::calculateOffset(CCLabelBMFont* label) {
|
||||
return m_linePadding + label->getContentSize().height * m_scale;
|
||||
}
|
||||
|
||||
void SimpleTextArea::charIteration(const std::function<CCLabelBMFont*(CCLabelBMFont* line, const char c, const float top)>& overflowHandling) {
|
||||
float top = 0;
|
||||
CCLabelBMFont* line = this->createLabel("", top);
|
||||
m_lines = { line };
|
||||
|
||||
for (const char c : m_text) {
|
||||
if (m_maxLines && m_lines.size() > m_maxLines) {
|
||||
CCLabelBMFont* last = m_lines.at(m_maxLines - 1);
|
||||
const std::string text = last->getString();
|
||||
|
||||
m_lines.pop_back();
|
||||
last->setString(text.substr(0, text.size() - 3).append("...").c_str());
|
||||
|
||||
break;
|
||||
} else if (c == '\n') {
|
||||
m_lines.push_back(line = this->createLabel("", top -= this->calculateOffset(line)));
|
||||
} else if (m_artificialWidth && line->getContentSize().width * m_scale >= this->getWidth()) {
|
||||
m_lines.push_back(line = overflowHandling(line, c, top -= this->calculateOffset(line)));
|
||||
} else {
|
||||
line->setString((std::string(line->getString()) + c).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleTextArea::updateLinesNoWrap() {
|
||||
std::stringstream stream(m_text);
|
||||
std::string part;
|
||||
float top = 0;
|
||||
|
||||
while (std::getline(stream, part)) {
|
||||
if (m_maxLines && m_lines.size() >= m_maxLines) {
|
||||
CCLabelBMFont* last = m_lines.at(m_maxLines - 1);
|
||||
const std::string text = last->getString();
|
||||
|
||||
last->setString(text.substr(0, text.size() - 3).append("...").c_str());
|
||||
|
||||
break;
|
||||
} else {
|
||||
CCLabelBMFont* line = this->createLabel(part, 0);
|
||||
|
||||
top -= this->calculateOffset(line);
|
||||
|
||||
m_lines.push_back(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleTextArea::updateLinesWordWrap() {
|
||||
this->charIteration([this](CCLabelBMFont* line, const char c, const float top) {
|
||||
static std::string delimiters(" `~!@#$%^&*()-_=+[{}];:'\",<.>/?\\|");
|
||||
|
||||
if (delimiters.find(c) == std::string_view::npos) {
|
||||
const std::string text = line->getString();
|
||||
const size_t position = text.find_last_of(delimiters) + 1;
|
||||
|
||||
line->setString(text.substr(0, position).c_str());
|
||||
|
||||
return this->createLabel(text.substr(position) + c, top);
|
||||
} else {
|
||||
return this->createLabel(std::string(c, c != ' '), top);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void SimpleTextArea::updateLinesCutoffWrap() {
|
||||
this->charIteration([this](CCLabelBMFont* line, const char c, const float top) {
|
||||
const std::string text = line->getString();
|
||||
const char back = text.back();
|
||||
const bool lastIsSpace = back == ' ';
|
||||
CCLabelBMFont* newLine = this->createLabel(std::string(!lastIsSpace, back).append(std::string(c != ' ', c)), top);
|
||||
|
||||
if (!lastIsSpace) {
|
||||
if (text[text.size() - 2] == ' ') {
|
||||
line->setString(text.substr(0, text.size() - 1).c_str());
|
||||
} else {
|
||||
line->setString((text.substr(0, text.size() - 1) + '-').c_str());
|
||||
}
|
||||
}
|
||||
|
||||
return newLine;
|
||||
});
|
||||
}
|
||||
|
||||
void SimpleTextArea::updateContainer() {
|
||||
switch (m_wrappingMode) {
|
||||
case NO_WRAP: {
|
||||
this->updateLinesNoWrap();
|
||||
} break;
|
||||
case WORD_WRAP: {
|
||||
this->updateLinesWordWrap();
|
||||
} break;
|
||||
case CUTOFF_WRAP: {
|
||||
this->updateLinesCutoffWrap();
|
||||
} break;
|
||||
}
|
||||
|
||||
const size_t lineCount = m_lines.size();
|
||||
const float width = this->getWidth();
|
||||
|
||||
if (lineCount > 0) {
|
||||
m_lineHeight = m_lines.back()->getContentSize().height * m_scale;
|
||||
} else {
|
||||
m_lineHeight = 0;
|
||||
}
|
||||
|
||||
float height = m_lineHeight * lineCount + m_linePadding * (lineCount - 1);
|
||||
|
||||
this->setContentSize({ width, height });
|
||||
m_container->setContentSize(this->getContentSize());
|
||||
m_container->removeAllChildren();
|
||||
|
||||
for (CCLabelBMFont* line : m_lines) {
|
||||
const float y = height + line->getPositionY();
|
||||
|
||||
switch (m_alignment) {
|
||||
case kCCTextAlignmentLeft: {
|
||||
line->setAnchorPoint({ 0, 1 });
|
||||
line->setPosition({ 0, y });
|
||||
} break;
|
||||
case kCCTextAlignmentCenter: {
|
||||
line->setAnchorPoint({ 0, 1 });
|
||||
line->setPosition({ width / 2, y });
|
||||
} break;
|
||||
case kCCTextAlignmentRight: {
|
||||
line->setAnchorPoint({ 1, 1 });
|
||||
line->setPosition({ width, y });
|
||||
} break;
|
||||
}
|
||||
|
||||
m_container->addChild(line);
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleTextArea::draw() {
|
||||
CCNode::draw();
|
||||
|
||||
if (m_shouldUpdate) {
|
||||
this->updateContainer();
|
||||
|
||||
m_shouldUpdate = false;
|
||||
}
|
||||
}
|
|
@ -341,8 +341,8 @@ std::vector<TextRenderer::Label> TextRenderer::renderStringEx(
|
|||
auto lastIndent =
|
||||
m_indentationStack.size() > 1 ? m_indentationStack.at(m_indentationStack.size() - 1) : .0f;
|
||||
|
||||
if (m_cursor.x == m_origin.x + lastIndent && this->getCurrentIndent() > .0f) {
|
||||
m_cursor.x += this->getCurrentIndent();
|
||||
if (m_cursor.x < m_origin.x + this->getCurrentIndent()) {
|
||||
m_cursor.x = this->getCurrentIndent();
|
||||
}
|
||||
|
||||
auto createLabel = [&]() -> bool {
|
||||
|
@ -487,7 +487,7 @@ void TextRenderer::breakLine(float incY) {
|
|||
}
|
||||
if (h > y) y = h;
|
||||
m_cursor.y -= y;
|
||||
m_cursor.x = m_origin.x + getCurrentIndent();
|
||||
m_cursor.x = m_origin.x;
|
||||
}
|
||||
|
||||
float TextRenderer::adjustLineAlignment() {
|
||||
|
|
|
@ -21,12 +21,17 @@ using namespace geode::prelude;
|
|||
using namespace geode::utils::file;
|
||||
|
||||
Result<std::string> utils::file::readString(ghc::filesystem::path const& path) {
|
||||
if (!ghc::filesystem::exists(path))
|
||||
return Err("File does not exist");
|
||||
|
||||
#if _WIN32
|
||||
std::ifstream in(path.wstring(), std::ios::in | std::ios::binary);
|
||||
#else
|
||||
std::ifstream in(path.string(), std::ios::in | std::ios::binary);
|
||||
#endif
|
||||
if (in) {
|
||||
if (!in)
|
||||
return Err("Unable to open file");
|
||||
|
||||
std::string contents;
|
||||
in.seekg(0, std::ios::end);
|
||||
contents.resize((const size_t)in.tellg());
|
||||
|
@ -35,34 +40,32 @@ Result<std::string> utils::file::readString(ghc::filesystem::path const& path) {
|
|||
in.close();
|
||||
return Ok(contents);
|
||||
}
|
||||
return Err("Unable to open file");
|
||||
}
|
||||
|
||||
Result<json::Value> utils::file::readJson(ghc::filesystem::path const& path) {
|
||||
|
||||
auto str = utils::file::readString(path);
|
||||
|
||||
if (str) {
|
||||
if (!str)
|
||||
return Err(str.unwrapErr());
|
||||
try {
|
||||
return Ok(json::parse(str.value()));
|
||||
} catch(std::exception const& e) {
|
||||
return Err("Unable to parse JSON: " + std::string(e.what()));
|
||||
}
|
||||
} else {
|
||||
return Err("Unable to open file");
|
||||
catch(std::exception const& e) {
|
||||
return Err("Unable to parse JSON: " + std::string(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
Result<ByteVector> utils::file::readBinary(ghc::filesystem::path const& path) {
|
||||
if (!ghc::filesystem::exists(path))
|
||||
return Err("File does not exist");
|
||||
|
||||
#if _WIN32
|
||||
std::ifstream in(path.wstring(), std::ios::in | std::ios::binary);
|
||||
#else
|
||||
std::ifstream in(path.string(), std::ios::in | std::ios::binary);
|
||||
#endif
|
||||
if (in) {
|
||||
return Ok(ByteVector(std::istreambuf_iterator<char>(in), {}));
|
||||
}
|
||||
if (!in)
|
||||
return Err("Unable to open file");
|
||||
|
||||
return Ok(ByteVector(std::istreambuf_iterator<char>(in), {}));
|
||||
}
|
||||
|
||||
Result<> utils::file::writeString(ghc::filesystem::path const& path, std::string const& data) {
|
||||
|
@ -72,16 +75,16 @@ Result<> utils::file::writeString(ghc::filesystem::path const& path, std::string
|
|||
#else
|
||||
file.open(path.string());
|
||||
#endif
|
||||
if (file.is_open()) {
|
||||
file << data;
|
||||
file.close();
|
||||
|
||||
return Ok();
|
||||
}
|
||||
if (!file.is_open()) {
|
||||
file.close();
|
||||
return Err("Unable to open file");
|
||||
}
|
||||
|
||||
file << data;
|
||||
file.close();
|
||||
return Ok();
|
||||
}
|
||||
|
||||
Result<> utils::file::writeBinary(ghc::filesystem::path const& path, ByteVector const& data) {
|
||||
std::ofstream file;
|
||||
#if _WIN32
|
||||
|
@ -89,16 +92,16 @@ Result<> utils::file::writeBinary(ghc::filesystem::path const& path, ByteVector
|
|||
#else
|
||||
file.open(path.string(), std::ios::out | std::ios::binary);
|
||||
#endif
|
||||
if (file.is_open()) {
|
||||
file.write(reinterpret_cast<char const*>(data.data()), data.size());
|
||||
file.close();
|
||||
|
||||
return Ok();
|
||||
}
|
||||
if (!file.is_open()) {
|
||||
file.close();
|
||||
return Err("Unable to open file");
|
||||
}
|
||||
|
||||
file.write(reinterpret_cast<char const*>(data.data()), data.size());
|
||||
file.close();
|
||||
return Ok();
|
||||
}
|
||||
|
||||
Result<> utils::file::createDirectory(ghc::filesystem::path const& path) {
|
||||
try {
|
||||
#ifdef GEODE_IS_WINDOWS
|
||||
|
|
|
@ -79,6 +79,7 @@ Result<ByteVector> web::fetchBytes(std::string const& url) {
|
|||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ret);
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, utils::fetch::writeBytes);
|
||||
auto res = curl_easy_perform(curl);
|
||||
if (res != CURLE_OK) {
|
||||
|
@ -118,6 +119,7 @@ Result<std::string> web::fetch(std::string const& url) {
|
|||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ret);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, utils::fetch::writeString);
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
|
||||
auto res = curl_easy_perform(curl);
|
||||
if (res != CURLE_OK) {
|
||||
curl_easy_cleanup(curl);
|
||||
|
|
Loading…
Reference in a new issue