diff --git a/.gitignore b/.gitignore index c3cc666..58ebd5f 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,6 @@ build-linux-deb/ svgs/ compile_commands.json resources/fontvers/ + +notas.h +resources/gatos/ diff --git a/README.md b/README.md index 9ee1f51..9560d9f 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,16 @@ A mod menu made in Geode for Geometry Dash # TODOs (Based on whats next) -- Fix bug with info text being off screen +- Add a keyback function for those that use keyback on android +- Fix bug with the menu buttons not working + STEPS: + +- Fix bug with input button not working for button position on android - Add credits screen for cocos2d ui - Allow for dragging the button - Add "Render Hitbox" (Basically enables hitbox even if not in practice mode) - Add menu scale for the cocos ui +- Add "Transparent Lists" (look in https://discord.com/channels/911701438269386882/911702353546215524/1205501190025117779) - Add "No Shaders" - Add "uncomplete level" hack - Add "Custom Object Bypass" (basically allows you to store more than 1000 objects in custom object) diff --git a/changelog.md b/changelog.md index 8f77db9..a268a2e 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,10 @@ +# v1.4.2 + - Fixed bug with No Mirror Transition & Instant Mirror Portal if "No Effect" is applied. + - Fixed speedhack not syncing with gameplay correctly + - Fixed Platformer Mode buttons not showing if you use Force Platformer Mode on Android + - Fixed bug with camera effects affecting Cheat Indicator and Noclip Accuracy + - (Hopefully) Fixed issue with info text being off screen + - Removed Text Length and Character Filter functionality # v1.4.1 - Fixed Mac OS issue with not being able to open menu. # v1.4.0 diff --git a/resources/gato.jpg b/resources/gato.jpg deleted file mode 100644 index d403338..0000000 Binary files a/resources/gato.jpg and /dev/null differ diff --git a/resources/gato2.png b/resources/gato2.png deleted file mode 100644 index 11983cf..0000000 Binary files a/resources/gato2.png and /dev/null differ diff --git a/resources/hacks/settings.json b/resources/hacks/settings.json index 0b998b6..2fbc190 100644 --- a/resources/hacks/settings.json +++ b/resources/hacks/settings.json @@ -30,7 +30,7 @@ "opcodes": [], "type": "dropdown", "default": 0, - "values": ["English [100%]", "Français [90%]", "Português (Brasil) [100%]", "Deutsch [90%]", "Русский [90%]", "Čeština [90%]", "Indonesia [90%]", "Español [90%]", "Polskie [90%]", "Melayu [90%]"] + "values": ["English [100%]", "Français [88%]", "Português (Brasil) [100%]", "Deutsch [88%]", "Русский [100%]", "Čeština [88%]", "Indonesia [88%]", "Español [88%]", "Polskie [88%]", "Melayu [88%]"] }, { "name": "Theme", diff --git a/server/src/components/Macro.ts b/server/src/components/Macro.ts new file mode 100644 index 0000000..4705bb1 --- /dev/null +++ b/server/src/components/Macro.ts @@ -0,0 +1,7 @@ +export interface MacroData { + timestamp: string; + userID: number; + name: string; + levelID: string; + data: string; +}; diff --git a/server/src/components/Theme.ts b/server/src/components/Theme.ts new file mode 100644 index 0000000..cc23b5f --- /dev/null +++ b/server/src/components/Theme.ts @@ -0,0 +1,8 @@ +export interface ThemeData { + timestamp: string; + userID: number; + name: string; + desc: string; + screenshots?: Array; + data: string; +}; diff --git a/server/src/components/User.ts b/server/src/components/User.ts new file mode 100644 index 0000000..4f1aade --- /dev/null +++ b/server/src/components/User.ts @@ -0,0 +1,6 @@ +export default interface UserData { + userID: number; + userName: string; + token: string; // based on a hashed ip addr + timestamp: string; +}; diff --git a/server/src/controllers/auth.ts b/server/src/controllers/auth.ts new file mode 100644 index 0000000..62cc15f --- /dev/null +++ b/server/src/controllers/auth.ts @@ -0,0 +1,31 @@ +import redis from 'redis' +import crypto from 'crypto'; +import User from '../components/User'; + +const client = redis.createClient(); // switch to cache + +export function hashIP(ip: string): string { + const hash = crypto.createHash('sha256'); + hash.update(ip); + return hash.digest('hex'); +} + +export async function getUser(hashIP: string): Promise { + try { + const userData = (await client.hGetAll(`users:${hashIP}`) as unknown) as User; + if (userData) return userData; + return null; + } catch (e) { + console.error(e); + return null; + } +} + +export async function createUser(name: string, hashIP: string): Promise { + return new Promise((resolve, reject) => { + return getUser(hashIP).then(user => { + if (user != null) return reject("Already created an account."); + resolve(); + }).catch(reject); + }) +} diff --git a/server/src/controllers/theme.ts b/server/src/controllers/theme.ts new file mode 100644 index 0000000..7ba2574 --- /dev/null +++ b/server/src/controllers/theme.ts @@ -0,0 +1,12 @@ +import { Router, Request, Response } from 'express' +import crypto from 'crypto' +import multer from 'multer' + +const router = Router(); + +router.post('/api/themes', (req: Request, res: Response) => { + const { token, data } = req.body; + +}) + +export default router; diff --git a/server/src/controllers/user.ts b/server/src/controllers/user.ts new file mode 100644 index 0000000..e69de29 diff --git a/server/src/redis.ts b/server/src/redis.ts new file mode 100644 index 0000000..63f0746 --- /dev/null +++ b/server/src/redis.ts @@ -0,0 +1,30 @@ +// taken from my discord bot + +// https://stackoverflow.com/a/74535407 +import type { RedisClientType } from 'redis' +import { createClient } from 'redis' + +let redisClient: RedisClientType +let isReady: boolean +async function getCache(): Promise { + if (!isReady) { + redisClient = createClient({ + url: 'redis://127.0.0.1:6379', + }) + redisClient.on('error', err => console.error(`[Redis] Error: ${err}`)) + redisClient.on('connect', () => console.log('[Redis] Connected!')) + redisClient.on('reconnecting', () => console.log('[Redis] Reconnecting...')) + redisClient.on('ready', () => { + isReady = true + console.log('[Redis] Ready!') + }) + await redisClient.connect(); + } + return redisClient +} +getCache().then(connection => { + redisClient = connection +}).catch(err => { + console.error('Failed to connect to Redis', err) +}) +export { getCache } diff --git a/server/src/typings/Theme.ts b/server/src/typings/Theme.ts deleted file mode 100644 index 1645621..0000000 --- a/server/src/typings/Theme.ts +++ /dev/null @@ -1,23 +0,0 @@ -export interface UserData { - userID: number; - userName: string; - token: string; // based on a hashed ip addr - timestamp: string; -}; - -export interface ThemeData { - timestamp: string; - userID: number; - name: string; - desc: string; - screenshots?: Array; - data: string; -}; - -export interface MacroData { - timestamp: string; - userID: number; - name: string; - levelID: string; - data: string; -}; diff --git a/src/GatoSim.cpp b/src/GatoSim.cpp index 1d83d46..96832ee 100644 --- a/src/GatoSim.cpp +++ b/src/GatoSim.cpp @@ -3,6 +3,24 @@ // TODO: add a popup asking for name, and what sprite +/* + std::string name; + std::string desc; + int price; + int tier; + int amount; +*/ + +std::vector items = { + { + "", + "", + 2, + 2, + 2 + } +}; + // definitely not copied off a mod that i was working on with someone *cough cough* bool GatoSim::init() { auto size = cocos2d::CCDirector::sharedDirector()->getWinSize(); diff --git a/src/GatoSim.hpp b/src/GatoSim.hpp index aeea0d9..b73e209 100644 --- a/src/GatoSim.hpp +++ b/src/GatoSim.hpp @@ -2,23 +2,25 @@ // this is all a spoiler! #include -struct ShopItem { + +struct PetItem { std::string name; std::string desc; int price; + int tier = 1; + int amount; }; + + using namespace geode::prelude; class GatoSim : public CCLayer, public FLAlertLayerProtocol { // TODO: add some json file // maybe turn this into some sort of "cookie clicker" because why not std::string name; - int fod = 0; - int drank = 0; + int pet = 0; std::vector toi; bool hasDoneDaily = false; - int bal = 250; - int satis = 0; protected: CCMenu* m_buttonMenu; diff --git a/src/Hacks/Bypass.cpp b/src/Hacks/Bypass.cpp index d981209..bad7e95 100644 --- a/src/Hacks/Bypass.cpp +++ b/src/Hacks/Bypass.cpp @@ -19,6 +19,7 @@ class $modify(GameManager) { }; // Text Length, Character Filter +#if 0 class $modify(CCTextInputNode) { void updateLabel(gd::string p0) { if (Hacks::isHackEnabled("Character Filter") && !Hacks::isHackEnabled("Enable Patching")) this->setAllowedChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,-!?:;)(/\\\"\'`*= +-_%[]<>|@&^#{}%$~"); @@ -26,7 +27,7 @@ class $modify(CCTextInputNode) { CCTextInputNode::updateLabel(p0); } }; - +#endif /* class $modify(GameStatsManager) { // Almost all bypass diff --git a/src/Hacks/Global.cpp b/src/Hacks/Global.cpp index d2841bc..fc7b362 100644 --- a/src/Hacks/Global.cpp +++ b/src/Hacks/Global.cpp @@ -3,12 +3,14 @@ using namespace geode::prelude; #include +#include #include #include #include #include #include #include +#include // Practice Music class $modify(GameStatsManager) { @@ -34,19 +36,26 @@ class $modify(CCScheduler) { }; #ifndef GEODE_IS_MACOS +class $modify(PlayLayer) { + // No Glow, Show Hidden Objects + void addObject(GameObject* obj) { + // "Optimization" + if (Hacks::isHackEnabled("Show Hidden Objects")) { + obj->m_activeMainColorID = -1; + obj->m_isHide = false; + if (obj->m_objectID == 1007) return; + } + if (Hacks::isHackEnabled("No Glow")) { + obj->m_hasNoGlow = true; + } + PlayLayer::addObject(obj); + } +}; + + // Layout Mode class $modify(GameObject) { - // Layout Mode, No Glow void setVisible(bool v) { - if (Hacks::isHackEnabled("No Glow")) { // easier than having to check for glow sprite lol - this->m_hasNoGlow = true; - } - if (Hacks::isHackEnabled("Show Hidden Objects")) { - m_activeMainColorID = -1; - if (m_isHide) v = true; - m_isHide = false; - // ok but why doesnt this work - } if (!Hacks::isHackEnabled("Layout Mode")) return GameObject::setVisible(v); //m_hasGroupParent == 0 std::vector outerPortal = {}; @@ -57,19 +66,6 @@ class $modify(GameObject) { GameObject::setVisible(v); } } - /* - void makeInvisible() { // 0x13bf20 - std::cout << "make it invisible" << std::endl; - if (!Hacks::isHackEnabled("Show Hidden Objects")) return GameObject::makeInvisible(); - } - */ - static GameObject* createWithKey(int p0) { - auto gameObject = GameObject::createWithKey(p0); - if (Hacks::isHackEnabled("Show Hidden Objects")) { - if (p0 == 1007 && PlayLayer::get() != nullptr) return nullptr; - } - return gameObject; - } }; #endif @@ -111,3 +107,14 @@ class $modify(CCSprite) { } } }; + +// Physics Bypass (TPS) +// dVar3 = 0.004166666883975267; +// which (dVar3 * 240 = 1) lol, so 1.F / TPS? +/* +class $modify(GJBaseGameLayer) { + float getModifiedDelta(float p0) { + std::cout << "yAEY" << std::endl; + return GJBaseGameLayer::getModifiedDelta(p0); + } +};*/ diff --git a/src/Hacks/Player.cpp b/src/Hacks/Player.cpp index 0ea28af..c533470 100644 --- a/src/Hacks/Player.cpp +++ b/src/Hacks/Player.cpp @@ -31,11 +31,14 @@ class $modify(PlayerObject) { if (!m_fields->was_platformer) { m_fields->was_platformer = this->m_isPlatformer; } - if (Hacks::isHackEnabled("Force Platformer Mode")) { - togglePlatformerMode(true); - } else { - togglePlatformerMode(m_fields->was_platformer); + #ifndef GEODE_IS_DESKTOP + if (PlayLayer::get() != nullptr) { + auto playLayer = PlayLayer::get(); //shut! + playLayer->m_uiLayer->togglePlatformerMode(Hacks::isHackEnabled("Force Platformer Mode") ? true : m_fields->was_platformer); + // for some reason i was trying to look for togglePlatformerMode when I realized that i couldve just literally used the func as its android, im so mad } + #endif + togglePlatformerMode(Hacks::isHackEnabled("Force Platformer Mode") ? true : m_fields->was_platformer); auto gravityHack = Hacks::getHack("Gravity Value"); if (Hacks::isHackEnabled("Change Gravity")) { // assume its enabled m_gravityMod = gravityHack->value.floatValue; @@ -75,10 +78,42 @@ class $modify(GJBaseGameLayer) { #ifndef GEODE_IS_MACOS // No Mirror Transition, Instant Mirror Portal void toggleFlipped(bool p0, bool p1) { // i spent a lot of time figuring out why CCActionTween wont hook, only to realize that p1 instantly transitions it - if (Hacks::isHackEnabled("Enable Patching")) return GJBaseGameLayer::toggleFlipped(p0, p1); - if (!Hacks::isHackEnabled("No Mirror Transition")) GJBaseGameLayer::toggleFlipped(p0, Hacks::isHackEnabled("Instant Mirror Portal")); + //std::cout << this->m_gameState.m_unk188 << std::endl; + if (!Hacks::isHackEnabled("No Mirror Transition")) return GJBaseGameLayer::toggleFlipped(p0, (p1) ? p1 : Hacks::isHackEnabled("Instant Mirror Portal")); } #endif + void update(float dt) { + /* + fVar30 = (float)((double)dt + *(double *)&this[4].GJBaseGameLayer_data.m_gameState.field_0xf0); + fVar25 = *(float *)&(this->GJBaseGameLayer_data).m_gameState.field_0x188; + if (1.0 < fVar25) { + fVar25 = 1.0; + } + fVar24 = (float10)roundf(fVar30 / (fVar25 * 0.004166667)); + fStack_64 = (float)fVar24; + dVar28 = (double)(int)fVar24 * (double)(fVar25 * 0.004166667); + dVar26 = (double)fVar30 - dVar28; + dt = (float)dVar28; + */ + // we love ghidra + /*float fVar30 = (float)((double)dt + 0.0); + float fVar25 = m_gameState.m_unk188; + if (1.0 < fVar25) { + fVar25 = 1.0; + } + float physicsTPS = (1.F / 360.F); + float fVar24 = (float)roundf(fVar30 / (fVar25 * physicsTPS)); + double dVar28 = (int)fVar24 * (double)(fVar25 * physicsTPS); + double dVar26 = (double)fVar30 - dVar28; + auto beforeDt = dt; + dt = (float)dVar28; + std::cout << dt << "," << beforeDt << std::endl;*/ + //this->m_gameState.m_unk188 = 0.7F; + //std::cout << (float)((double)dt + (double)m_gameState.m_unkf0) << "," << dt << std::endl; + //std::cout << m_gameState.m_unkf0 << std::endl; + //m_gameState.m_unkf0 = 0.00001; + GJBaseGameLayer::update(dt); + } }; #ifndef GEODE_IS_MACOS diff --git a/src/ImGui.cpp b/src/ImGui.cpp index b5447f5..ac99ff0 100644 --- a/src/ImGui.cpp +++ b/src/ImGui.cpp @@ -245,7 +245,6 @@ class $modify(MenuLayer) { if (name == "Speedhack") { if (hack->value.floatValue < 0.0F) return; Hacks::setPitch(hack->value.floatValue); - CCDirector::sharedDirector()->getScheduler()->setTimeScale(hack->value.floatValue); } else { if (name == "Menu Opacity") { changedOpacity = true; diff --git a/src/PrismUI.cpp b/src/PrismUI.cpp index 22c21d6..2a83c98 100644 --- a/src/PrismUI.cpp +++ b/src/PrismUI.cpp @@ -134,6 +134,7 @@ bool PrismUIButton::init(HackItem* hack) { } else if (hack->value.type == ValueType::Int && hack->type != "dropdown" && !name.starts_with("Button Position")) { auto min = obj.get("min"); auto max = obj.get("max"); + label->limitLabelWidth(120, 0.5F, .1F); // TODO: add + and - buttons because according to some, android keyboard is BAD! m_input = InputNode::create(150.f, "...", "PrismMenu.fnt"_spr); m_input->getInput()->setString(std::to_string(hack->value.intValue)); @@ -290,9 +291,6 @@ void PrismUIButton::onFloatBtn(CCObject* ret) { if (m_hack->value.floatValue < 0.0F) return; Hacks::setPitch(m_hack->value.floatValue); m_hack->value.floatValue = std::max(m_hack->value.floatValue, 0.01f); -#ifdef GEODE_IS_WINDOWS - CCDirector::sharedDirector()->getScheduler()->setTimeScale(m_hack->value.floatValue); -#endif } else { if (!name.starts_with("Button Position")) { Hacks::Settings::setSettingValue(&settings, *m_hack, m_hack->value.floatValue); @@ -699,24 +697,18 @@ void PrismUIButton::onInfoBtn(CCObject* ret) { desc.c_str(), "PrismMenu.fnt"_spr, 0.7F, //0.8 280.F, { 0.5, 0 }, 20.F, false);*/ //const std::string& font, const std::string& text, const float scale, const float width, - auto newLines = SimpleTextArea::create("A", "PrismMenu.fnt"_spr, 0.5F, 260.0F); + auto winSize = cocos2d::CCDirector::sharedDirector()->getWinSize(); + auto newLines = SimpleTextArea::create("A", "PrismMenu.fnt"_spr, 0.5F, winSize.width / 2.2F); // 260.0F newLines->setText(desc.c_str()); + newLines->setAlignment(CCTextAlignment::kCCTextAlignmentCenter); + std::cout << desc.c_str() << std::endl; newLines->setScale(calculateScale(desc, 25, .75F, .25F)); - auto newLinesMenu = static_cast(newLines->getChildren()->objectAtIndex(0)); - newLinesMenu->setPositionY(40); - newLinesMenu->setLayout( // solution for SimpleTextArea not being centered, ->setAlignment doesnt work properly - ColumnLayout::create() - ->setCrossAxisLineAlignment(AxisAlignment::Center) - ->setAxisAlignment(AxisAlignment::Center) - ->setAxisReverse(true) - ); - auto winSize = cocos2d::CCDirector::sharedDirector()->getWinSize(); + // ok geode broke AxisLayout, thats nice newLines->setPosition({(winSize.width / 2), (winSize.height / 2) + 10}); // 160 - 220 newLines->setZOrder(lines->getZOrder()); lines->removeFromParentAndCleanup(true); flAlert->m_mainLayer->addChild(newLines); flAlert->show(); - newLinesMenu->updateLayout(); // why this no work!? } } @@ -831,12 +823,15 @@ void PrismUI::keyDown(cocos2d::enumKeyCodes key) { return FLAlertLayer::keyDown(key); } +void PrismUI::keybackClicked() { + onClose(nullptr); +}; + void PrismUI::onClose(cocos2d::CCObject* pSender) { auto prismButton = CCScene::get()->getChildByID("prism-icon"); if (prismButton != nullptr) { static_cast(prismButton->getChildren()->objectAtIndex(0))->setEnabled(true); } - this->setKeyboardEnabled(false); this->removeFromParentAndCleanup(true); }; diff --git a/src/PrismUI.hpp b/src/PrismUI.hpp index 875587e..897730a 100644 --- a/src/PrismUI.hpp +++ b/src/PrismUI.hpp @@ -55,6 +55,7 @@ class PrismUI : public FLAlertLayer { float height ); virtual void keyDown(cocos2d::enumKeyCodes) override; + virtual void keybackClicked(); void CreateHackItem(HackItem*); void RegenCategory(); void CreateButton(const char* name, int menuIndex); diff --git a/src/main.cpp b/src/main.cpp index 97b387a..fe6163a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -282,6 +282,7 @@ class $modify(PlayLayer) { auto winSize = CCDirector::sharedDirector()->getWinSize(); m_fields->prismNode = CCNode::create(); m_fields->prismNode->setTag(10420); + m_fields->prismNode->setZOrder(1); m_fields->cheatIndicator = createCheatIndicator(false); m_fields->cheatIndicator->setVisible(Hacks::isHackEnabled("Cheat Indicator")); m_fields->accuracyLabel = CCLabelBMFont::create("100.00%", "bigFont.fnt");