├── .github ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.MD ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── request-new-hack.md ├── fixedlogo.png ├── plainlogo.png ├── pull_request_template.md └── workflows │ └── codeql-analysis.yml ├── .gitignore ├── .vscode └── PMGH.code-snippets ├── LICENSE ├── PHEx ├── README.md ├── build.js ├── build │ ├── default │ ├── extension.crx │ ├── extension.xpi │ └── extension.zip ├── package-lock.json ├── package.json ├── src │ ├── assets │ │ ├── x128.png │ │ ├── x16.png │ │ └── x48.png │ ├── background.js │ ├── disableIntegrity.js │ ├── manifest.json │ ├── popup.html │ └── popup.js └── status.json ├── README.md ├── announcement.md ├── docs ├── README.md ├── classes │ ├── _player_d_.player.md │ └── _player_d_.playerdata.md ├── globals.md ├── interfaces │ ├── _game_d_.game.md │ ├── _pixi_d_.pixi.md │ ├── _player_d_.playername.md │ └── _prodigy_d_.prodigy.md └── modules │ ├── _game_d_.md │ ├── _item_d_.md │ ├── _pixi_d_.md │ ├── _player_d_.md │ ├── _prodigy_d_.md │ ├── _test_.md │ └── _util_d_.md ├── meta ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.MD ├── FAQ.md ├── YOUTUBE_ATTRIBUTION.md └── utility │ ├── push.bat │ └── updateCommitter.sh ├── oldguard ├── dist │ ├── bundle.css │ └── bundle.js ├── index.js ├── package-lock.json ├── package.json ├── src │ ├── app.css │ └── app.jsx └── testOldguard.html ├── typings ├── backpack.d.ts ├── debugMisc.d.ts ├── game.d.ts ├── gameContainer.d.ts ├── gameData.d.ts ├── item.d.ts ├── open.d.ts ├── package.json ├── pet.d.ts ├── pixi.d.ts ├── player.d.ts ├── prodigy.d.ts ├── test.ts ├── tsconfig.json └── util.d.ts └── willsCheatMenu ├── .eslintrc.json ├── README.md ├── babel.config.js ├── dist └── bundle.js ├── hot-reload.mjs ├── loader.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── src ├── assets │ ├── academy.png │ ├── archives.png │ ├── bonfire_spire.png │ ├── crystal_caverns.png │ ├── darktower.png │ ├── dyno.png │ ├── earthtower.png │ ├── elemental_guardian.png │ ├── forest.png │ ├── house.png │ ├── lamplight.png │ ├── shipwreck_shore.png │ ├── shiverchill.png │ ├── skywatch.png │ ├── tower_town.png │ └── toyzone.png ├── declarations.d.ts ├── hacks │ ├── battle.ts │ ├── inventory.ts │ ├── location.ts │ ├── minigame.ts │ ├── misc.ts │ ├── pets.ts │ ├── player.ts │ └── utility.ts ├── index.ts ├── style.scss ├── sweetalert2.d.ts └── utils │ ├── keybinds.ts │ ├── swal.ts │ └── util.ts ├── statusmessage.json ├── tsconfig.json └── webpack.config.js /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Citizen Code of Conduct 2 | 3 | Our goal was to improve Prodigy's security, not ruining the game for profit. We won't sell our hacks, or put ads. 4 | 5 | Our hacks will **always** be open-source, and free to use. 6 | 7 | --- 8 | 9 | You may ***never***: 10 | 11 | - sell our hacks in any way shape or form 12 | - hide our hacks behind a paywall/subscribewall of any kind 13 | - This includes adfly 😐 14 | - use our hacks to leak private information 15 | - use our hacks to steal user login information or tokens 16 | - claim ownership of our hacks (Just stop bragging about it 😠) 17 | - modify it slightly just to add your own ads 🤨 18 | 19 | If you're gonna talk about our hacks (on YouTube or other social media platforms), please please pretty please [credit us properly](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/blob/master/YOUTUBE_ATTRIBUTION.md). 20 | 21 | It hurts our souls when skids take credit for our hacks and don't even link us. 22 | 23 | --- 24 | 25 | Last reminder that we are **volunteers**, and do not profit from this. We do this for *fun*, not for evil. Please don't spoil our fun. 26 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.MD: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Hacking Prodigy used to be as easy as `PIXI.game.prodigy.player.gold=999`, but now we need a whole team! 4 | 5 | If you'd like to join as an official collaborator, you can message us on [our official Discord server](https://discord.gg/XQDfbfq)! 6 | 7 | Additionally, read our [Code of Conduct](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/blob/master/.github/CODE_OF_CONDUCT.md) before continuing. 8 | 9 | --- 10 | 11 | ## The Goal of [PMGH](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking) 12 | 13 | Our main goal in this repository is to bring Prodigy's attention to their game's architecture. 14 | 15 | Most of the data stuff is handled on the client side, so hacking is as easy as changing a variable. No pwn needed! 16 | 17 | Since we've started this repository, Prodigy's security has improved by leaps and bounds, but the main issue is still the same; 18 | once you get to the player variable, you can easily change anything you want. 19 | 20 | Ideally everything would be handled server side. For example, arena points are already handled properly. The only way to increment arena points is by sending a "win" event, which is rate limited to once per minute. 21 | 22 | ## Tasks 23 | 24 | There are lots of things to do! (Ranked from easiest to hardest) 25 | 26 | ### Research 27 | 28 | As the name indicates, research. Research includes: 29 | 30 | - looking for new endpoints to mess around with 31 | - reading the Prodigy source extensively 32 | - reporting broken hacks 33 | - suggesting new hack ideas 34 | 35 | Requirements: 36 | 37 | - basic coding skills 38 | - basic understanding of what an API is (the bar is super low huh) 39 | - reading skills 40 | 41 | Anybody can do this! If you want to help with any of these, you can post your findings in [Discussions](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/discussions), or [our official Discord](https://discord.gg/XQDfbfq). 42 | 43 | ### Typings 44 | 45 | Basically just typescript definitions for Prodigy objects. An understanding of how to implement the types is also necessary. 46 | 47 | Requirements: 48 | 49 | - lots of spare time 50 | 51 | If you make a PR with Typings, [Will](https://github.com/MelnCat) will will you into his Will will. <3 52 | 53 | ### [Will's Cheat Menu](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/tree/master/willsCheatMenu) 54 | 55 | [Will's Cheat Menu](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/tree/master/willsCheatMenu)! Written in Typescript, it gives a visual cheat menu, with tons of handy dandy hacks in one place. No more copy pasting required! 56 | 57 | Requirements: 58 | 59 | - Javascript/Typescript knowledge 60 | - Basic knowledge of how to use the command line 61 | - Basic knowledge of Node.js/npm syntax 62 | - A good personality 63 | 64 | you can build it from `./willsCheatMenu` with `webpack`. 65 | 66 | ### [Browser Extension](https://chrome.google.com/webstore/detail/prodigy-hacking-extension/gjabpajagbgoifbkflgojeojmnlmioea) 67 | 68 | We used to rely on the Chrome extension "Redirector", and "Anti-CSP", but due to some extra anti-cheats from Prodigy, we've decided to roll our own extension. 69 | 70 | The extension does a few things (only on Prodigy domains): 71 | 72 | - disable CSP, so we can inject our scripts 73 | - disable Prodigy's official game files, and inject our hacked files 74 | - hehehehehehe 75 | 76 | We usually don't need help with this, it almost never changes, When it does change, we usually need 77 | *extremely skilled* researchers to figure out the problem, and fix it. 78 | 79 | #### [P-NP](https://github.com/Prodigy-Hacking/P-NP) (aka Redirector) 80 | 81 | Redirector was made by [Will](https://github.com/MelnCat). Thanks, [Will](https://github.com/MelnCat)! 82 | 83 | It just edits the gamescript so we can bypass any clientside anti-cheats, and expose the special 84 | sauce objects we desire. 85 | 86 | [Redirector]((https://github.com/Prodigy-Hacking/P-NP)) is written in Typescript. It also comes in its own repository! 87 | 88 | To build: 89 | 90 | ```cmd 91 | npm tsc 92 | ``` 93 | 94 | We usually don't require help with [Redirector](https://github.com/Prodigy-Hacking/P-NP), but it's pretty important to know it exists. 95 | 96 | Because we can edit the game script, we can also import external scripts, such as [WCM](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/tree/master/willsCheatMenu). 97 | 98 | ## Your contributions are licensed under the [MPL 2.0 software license](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/blob/master/LICENSE) 99 | 100 | When you submit anything here, your contributions will be licensesd under [the MPL 2.0 license](https://www.mozilla.org/en-US/MPL/2.0/). Contact a collaborator if this is an issue to you. 101 | 102 | ## We Develop with [GitHub](https://github.com/) 103 | 104 | We use [GitHub](https://github.com/) to host code, track [issues](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/issues) and feature requests, and provide you with this work. 105 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: ["https://discord.gg/XQDfbfq"] 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Describe an issue 4 | title: "[BUG]" 5 | labels: Bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | ***Description***: 11 | 12 | 13 | ***Replication***: 14 | 15 | 16 | ***Images***: 17 | 18 | 19 | ***Additional Errors***: 20 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/request-new-hack.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Request New Hack 3 | about: Request a new hack! 4 | title: "[HR]" 5 | labels: 'enhancement,hack' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe your hack:** 11 | 12 | 13 | **(Optional) Additional information** 14 | 15 | **Have you made sure this hack isn't available yet?* (Yes/No)** 16 | -------------------------------------------------------------------------------- /.github/fixedlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/.github/fixedlogo.png -------------------------------------------------------------------------------- /.github/plainlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/.github/plainlogo.png -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 5 | 6 | ## Screenshots 7 | 10 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master, masterf ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | schedule: 21 | - cron: '18 12 * * 3' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | 28 | strategy: 29 | fail-fast: false 30 | matrix: 31 | language: [ 'javascript' ] 32 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 33 | # Learn more: 34 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 35 | 36 | steps: 37 | - name: Checkout repository 38 | uses: actions/checkout@v2 39 | 40 | # Initializes the CodeQL tools for scanning. 41 | - name: Initialize CodeQL 42 | uses: github/codeql-action/init@v1 43 | with: 44 | languages: ${{ matrix.language }} 45 | # If you wish to specify custom queries, you can do so here or in a config file. 46 | # By default, queries listed here will override any specified in a config file. 47 | # Prefix the list here with "+" to use these queries and those in the config file. 48 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 49 | 50 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 51 | # If this step fails, then you should remove it and run the build manually (see below) 52 | - name: Autobuild 53 | uses: github/codeql-action/autobuild@v1 54 | 55 | # ℹ️ Command-line programs to run using the OS shell. 56 | # 📚 https://git.io/JvXDl 57 | 58 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 59 | # and modify them (or add more) to build your code if your project 60 | # uses a compiled language 61 | 62 | #- run: | 63 | # make bootstrap 64 | # make release 65 | 66 | - name: Perform CodeQL Analysis 67 | uses: github/codeql-action/analyze@v1 68 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .git 2 | .gitignore 3 | config.json 4 | *.log 5 | node_modules/ 6 | 7 | *.pem 8 | PHEx/src/web-ext-artifacts/prodigy_hacking_extension_phex_-2.0.1.zip 9 | 10 | # macOS 11 | **/.DS_Store 12 | 13 | # IntelliJ IDEA 14 | /.idea/ 15 | -------------------------------------------------------------------------------- /.vscode/PMGH.code-snippets: -------------------------------------------------------------------------------- 1 | { 2 | "Create Hack": { 3 | "scope": "typescript", 4 | "prefix": "ch", 5 | "body": [ 6 | "new Hack(category.$1, \"\", \"\").setClick(async () => {", 7 | " ", 8 | "});" 9 | ], 10 | "description": "Create new hack", 11 | }, 12 | "Create Toggler": { 13 | "scope": "typescript", 14 | "prefix": "ct", 15 | "body": [ 16 | "new Toggler(category.$1, \"\", \"\").setEnabled(async () => {", 17 | " ", 18 | "}).setDisabled(async() => {", 19 | " ", 20 | "});" 21 | ] 22 | } 23 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | “Commons Clause” License Condition v1.0 2 | 3 | The Software is provided to you by the Licensor under the License, as defined below, subject to the following condition. 4 | 5 | Without limiting other conditions in the License, the grant of rights under the License will not include, and the License does not grant to you, the right to Sell the Software. 6 | 7 | For purposes of the foregoing, “Sell” means practicing any or all of the rights granted to you under the License to provide to third parties, for a fee or other consideration (including without limitation fees for hosting or consulting/ support services related to the Software), a product or service whose value derives, entirely or substantially, from the functionality of the Software. Any license notice or attribution required by the License must also include this Commons Clause License Condition notice. 8 | 9 | Software: ProdigyMathGameHacking (https://github.com/Prodigy-Hacking/ProdigyMathGameHacking) 10 | 11 | License: Mozilla Public License 2.0 12 | 13 | Licensor: Prodigy Hacking Orginization (https://github.com/Prodigy-Hacking) 14 | 15 | ---- 16 | 17 | Mozilla Public License Version 2.0 18 | ================================== 19 | 20 | 1. Definitions 21 | -------------- 22 | 23 | 1.1. "Contributor" 24 | means each individual or legal entity that creates, contributes to 25 | the creation of, or owns Covered Software. 26 | 27 | 1.2. "Contributor Version" 28 | means the combination of the Contributions of others (if any) used 29 | by a Contributor and that particular Contributor's Contribution. 30 | 31 | 1.3. "Contribution" 32 | means Covered Software of a particular Contributor. 33 | 34 | 1.4. "Covered Software" 35 | means Source Code Form to which the initial Contributor has attached 36 | the notice in Exhibit A, the Executable Form of such Source Code 37 | Form, and Modifications of such Source Code Form, in each case 38 | including portions thereof. 39 | 40 | 1.5. "Incompatible With Secondary Licenses" 41 | means 42 | 43 | (a) that the initial Contributor has attached the notice described 44 | in Exhibit B to the Covered Software; or 45 | 46 | (b) that the Covered Software was made available under the terms of 47 | version 1.1 or earlier of the License, but not also under the 48 | terms of a Secondary License. 49 | 50 | 1.6. "Executable Form" 51 | means any form of the work other than Source Code Form. 52 | 53 | 1.7. "Larger Work" 54 | means a work that combines Covered Software with other material, in 55 | a separate file or files, that is not Covered Software. 56 | 57 | 1.8. "License" 58 | means this document. 59 | 60 | 1.9. "Licensable" 61 | means having the right to grant, to the maximum extent possible, 62 | whether at the time of the initial grant or subsequently, any and 63 | all of the rights conveyed by this License. 64 | 65 | 1.10. "Modifications" 66 | means any of the following: 67 | 68 | (a) any file in Source Code Form that results from an addition to, 69 | deletion from, or modification of the contents of Covered 70 | Software; or 71 | 72 | (b) any new file in Source Code Form that contains any Covered 73 | Software. 74 | 75 | 1.11. "Patent Claims" of a Contributor 76 | means any patent claim(s), including without limitation, method, 77 | process, and apparatus claims, in any patent Licensable by such 78 | Contributor that would be infringed, but for the grant of the 79 | License, by the making, using, selling, offering for sale, having 80 | made, import, or transfer of either its Contributions or its 81 | Contributor Version. 82 | 83 | 1.12. "Secondary License" 84 | means either the GNU General Public License, Version 2.0, the GNU 85 | Lesser General Public License, Version 2.1, the GNU Affero General 86 | Public License, Version 3.0, or any later versions of those 87 | licenses. 88 | 89 | 1.13. "Source Code Form" 90 | means the form of the work preferred for making modifications. 91 | 92 | 1.14. "You" (or "Your") 93 | means an individual or a legal entity exercising rights under this 94 | License. For legal entities, "You" includes any entity that 95 | controls, is controlled by, or is under common control with You. For 96 | purposes of this definition, "control" means (a) the power, direct 97 | or indirect, to cause the direction or management of such entity, 98 | whether by contract or otherwise, or (b) ownership of more than 99 | fifty percent (50%) of the outstanding shares or beneficial 100 | ownership of such entity. 101 | 102 | 2. License Grants and Conditions 103 | -------------------------------- 104 | 105 | 2.1. Grants 106 | 107 | Each Contributor hereby grants You a world-wide, royalty-free, 108 | non-exclusive license: 109 | 110 | (a) under intellectual property rights (other than patent or trademark) 111 | Licensable by such Contributor to use, reproduce, make available, 112 | modify, display, perform, distribute, and otherwise exploit its 113 | Contributions, either on an unmodified basis, with Modifications, or 114 | as part of a Larger Work; and 115 | 116 | (b) under Patent Claims of such Contributor to make, use, sell, offer 117 | for sale, have made, import, and otherwise transfer either its 118 | Contributions or its Contributor Version. 119 | 120 | 2.2. Effective Date 121 | 122 | The licenses granted in Section 2.1 with respect to any Contribution 123 | become effective for each Contribution on the date the Contributor first 124 | distributes such Contribution. 125 | 126 | 2.3. Limitations on Grant Scope 127 | 128 | The licenses granted in this Section 2 are the only rights granted under 129 | this License. No additional rights or licenses will be implied from the 130 | distribution or licensing of Covered Software under this License. 131 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 132 | Contributor: 133 | 134 | (a) for any code that a Contributor has removed from Covered Software; 135 | or 136 | 137 | (b) for infringements caused by: (i) Your and any other third party's 138 | modifications of Covered Software, or (ii) the combination of its 139 | Contributions with other software (except as part of its Contributor 140 | Version); or 141 | 142 | (c) under Patent Claims infringed by Covered Software in the absence of 143 | its Contributions. 144 | 145 | This License does not grant any rights in the trademarks, service marks, 146 | or logos of any Contributor (except as may be necessary to comply with 147 | the notice requirements in Section 3.4). 148 | 149 | 2.4. Subsequent Licenses 150 | 151 | No Contributor makes additional grants as a result of Your choice to 152 | distribute the Covered Software under a subsequent version of this 153 | License (see Section 10.2) or under the terms of a Secondary License (if 154 | permitted under the terms of Section 3.3). 155 | 156 | 2.5. Representation 157 | 158 | Each Contributor represents that the Contributor believes its 159 | Contributions are its original creation(s) or it has sufficient rights 160 | to grant the rights to its Contributions conveyed by this License. 161 | 162 | 2.6. Fair Use 163 | 164 | This License is not intended to limit any rights You have under 165 | applicable copyright doctrines of fair use, fair dealing, or other 166 | equivalents. 167 | 168 | 2.7. Conditions 169 | 170 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 171 | in Section 2.1. 172 | 173 | 3. Responsibilities 174 | ------------------- 175 | 176 | 3.1. Distribution of Source Form 177 | 178 | All distribution of Covered Software in Source Code Form, including any 179 | Modifications that You create or to which You contribute, must be under 180 | the terms of this License. You must inform recipients that the Source 181 | Code Form of the Covered Software is governed by the terms of this 182 | License, and how they can obtain a copy of this License. You may not 183 | attempt to alter or restrict the recipients' rights in the Source Code 184 | Form. 185 | 186 | 3.2. Distribution of Executable Form 187 | 188 | If You distribute Covered Software in Executable Form then: 189 | 190 | (a) such Covered Software must also be made available in Source Code 191 | Form, as described in Section 3.1, and You must inform recipients of 192 | the Executable Form how they can obtain a copy of such Source Code 193 | Form by reasonable means in a timely manner, at a charge no more 194 | than the cost of distribution to the recipient; and 195 | 196 | (b) You may distribute such Executable Form under the terms of this 197 | License, or sublicense it under different terms, provided that the 198 | license for the Executable Form does not attempt to limit or alter 199 | the recipients' rights in the Source Code Form under this License. 200 | 201 | 3.3. Distribution of a Larger Work 202 | 203 | You may create and distribute a Larger Work under terms of Your choice, 204 | provided that You also comply with the requirements of this License for 205 | the Covered Software. If the Larger Work is a combination of Covered 206 | Software with a work governed by one or more Secondary Licenses, and the 207 | Covered Software is not Incompatible With Secondary Licenses, this 208 | License permits You to additionally distribute such Covered Software 209 | under the terms of such Secondary License(s), so that the recipient of 210 | the Larger Work may, at their option, further distribute the Covered 211 | Software under the terms of either this License or such Secondary 212 | License(s). 213 | 214 | 3.4. Notices 215 | 216 | You may not remove or alter the substance of any license notices 217 | (including copyright notices, patent notices, disclaimers of warranty, 218 | or limitations of liability) contained within the Source Code Form of 219 | the Covered Software, except that You may alter any license notices to 220 | the extent required to remedy known factual inaccuracies. 221 | 222 | 3.5. Application of Additional Terms 223 | 224 | You may choose to offer, and to charge a fee for, warranty, support, 225 | indemnity or liability obligations to one or more recipients of Covered 226 | Software. However, You may do so only on Your own behalf, and not on 227 | behalf of any Contributor. You must make it absolutely clear that any 228 | such warranty, support, indemnity, or liability obligation is offered by 229 | You alone, and You hereby agree to indemnify every Contributor for any 230 | liability incurred by such Contributor as a result of warranty, support, 231 | indemnity or liability terms You offer. You may include additional 232 | disclaimers of warranty and limitations of liability specific to any 233 | jurisdiction. 234 | 235 | 4. Inability to Comply Due to Statute or Regulation 236 | --------------------------------------------------- 237 | 238 | If it is impossible for You to comply with any of the terms of this 239 | License with respect to some or all of the Covered Software due to 240 | statute, judicial order, or regulation then You must: (a) comply with 241 | the terms of this License to the maximum extent possible; and (b) 242 | describe the limitations and the code they affect. Such description must 243 | be placed in a text file included with all distributions of the Covered 244 | Software under this License. Except to the extent prohibited by statute 245 | or regulation, such description must be sufficiently detailed for a 246 | recipient of ordinary skill to be able to understand it. 247 | 248 | 5. Termination 249 | -------------- 250 | 251 | 5.1. The rights granted under this License will terminate automatically 252 | if You fail to comply with any of its terms. However, if You become 253 | compliant, then the rights granted under this License from a particular 254 | Contributor are reinstated (a) provisionally, unless and until such 255 | Contributor explicitly and finally terminates Your grants, and (b) on an 256 | ongoing basis, if such Contributor fails to notify You of the 257 | non-compliance by some reasonable means prior to 60 days after You have 258 | come back into compliance. Moreover, Your grants from a particular 259 | Contributor are reinstated on an ongoing basis if such Contributor 260 | notifies You of the non-compliance by some reasonable means, this is the 261 | first time You have received notice of non-compliance with this License 262 | from such Contributor, and You become compliant prior to 30 days after 263 | Your receipt of the notice. 264 | 265 | 5.2. If You initiate litigation against any entity by asserting a patent 266 | infringement claim (excluding declaratory judgment actions, 267 | counter-claims, and cross-claims) alleging that a Contributor Version 268 | directly or indirectly infringes any patent, then the rights granted to 269 | You by any and all Contributors for the Covered Software under Section 270 | 2.1 of this License shall terminate. 271 | 272 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 273 | end user license agreements (excluding distributors and resellers) which 274 | have been validly granted by You or Your distributors under this License 275 | prior to termination shall survive termination. 276 | 277 | ************************************************************************ 278 | * * 279 | * 6. Disclaimer of Warranty * 280 | * ------------------------- * 281 | * * 282 | * Covered Software is provided under this License on an "as is" * 283 | * basis, without warranty of any kind, either expressed, implied, or * 284 | * statutory, including, without limitation, warranties that the * 285 | * Covered Software is free of defects, merchantable, fit for a * 286 | * particular purpose or non-infringing. The entire risk as to the * 287 | * quality and performance of the Covered Software is with You. * 288 | * Should any Covered Software prove defective in any respect, You * 289 | * (not any Contributor) assume the cost of any necessary servicing, * 290 | * repair, or correction. This disclaimer of warranty constitutes an * 291 | * essential part of this License. No use of any Covered Software is * 292 | * authorized under this License except under this disclaimer. * 293 | * * 294 | ************************************************************************ 295 | 296 | ************************************************************************ 297 | * * 298 | * 7. Limitation of Liability * 299 | * -------------------------- * 300 | * * 301 | * Under no circumstances and under no legal theory, whether tort * 302 | * (including negligence), contract, or otherwise, shall any * 303 | * Contributor, or anyone who distributes Covered Software as * 304 | * permitted above, be liable to You for any direct, indirect, * 305 | * special, incidental, or consequential damages of any character * 306 | * including, without limitation, damages for lost profits, loss of * 307 | * goodwill, work stoppage, computer failure or malfunction, or any * 308 | * and all other commercial damages or losses, even if such party * 309 | * shall have been informed of the possibility of such damages. This * 310 | * limitation of liability shall not apply to liability for death or * 311 | * personal injury resulting from such party's negligence to the * 312 | * extent applicable law prohibits such limitation. Some * 313 | * jurisdictions do not allow the exclusion or limitation of * 314 | * incidental or consequential damages, so this exclusion and * 315 | * limitation may not apply to You. * 316 | * * 317 | ************************************************************************ 318 | 319 | 8. Litigation 320 | ------------- 321 | 322 | Any litigation relating to this License may be brought only in the 323 | courts of a jurisdiction where the defendant maintains its principal 324 | place of business and such litigation shall be governed by laws of that 325 | jurisdiction, without reference to its conflict-of-law provisions. 326 | Nothing in this Section shall prevent a party's ability to bring 327 | cross-claims or counter-claims. 328 | 329 | 9. Miscellaneous 330 | ---------------- 331 | 332 | This License represents the complete agreement concerning the subject 333 | matter hereof. If any provision of this License is held to be 334 | unenforceable, such provision shall be reformed only to the extent 335 | necessary to make it enforceable. Any law or regulation which provides 336 | that the language of a contract shall be construed against the drafter 337 | shall not be used to construe this License against a Contributor. 338 | 339 | 10. Versions of the License 340 | --------------------------- 341 | 342 | 10.1. New Versions 343 | 344 | Mozilla Foundation is the license steward. Except as provided in Section 345 | 10.3, no one other than the license steward has the right to modify or 346 | publish new versions of this License. Each version will be given a 347 | distinguishing version number. 348 | 349 | 10.2. Effect of New Versions 350 | 351 | You may distribute the Covered Software under the terms of the version 352 | of the License under which You originally received the Covered Software, 353 | or under the terms of any subsequent version published by the license 354 | steward. 355 | 356 | 10.3. Modified Versions 357 | 358 | If you create software not governed by this License, and you want to 359 | create a new license for such software, you may create and use a 360 | modified version of this License if you rename the license and remove 361 | any references to the name of the license steward (except to note that 362 | such modified license differs from this License). 363 | 364 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 365 | Licenses 366 | 367 | If You choose to distribute Source Code Form that is Incompatible With 368 | Secondary Licenses under the terms of this version of the License, the 369 | notice described in Exhibit B of this License must be attached. 370 | 371 | Exhibit A - Source Code Form License Notice 372 | ------------------------------------------- 373 | 374 | This Source Code Form is subject to the terms of the Mozilla Public 375 | License, v. 2.0. If a copy of the MPL was not distributed with this 376 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 377 | 378 | If it is not possible or desirable to put the notice in a particular 379 | file, then You may include the notice in a location (such as a LICENSE 380 | file in a relevant directory) where a recipient would be likely to look 381 | for such a notice. 382 | 383 | You may add additional accurate notices of copyright ownership. 384 | 385 | Exhibit B - "Incompatible With Secondary Licenses" Notice 386 | --------------------------------------------------------- 387 | 388 | This Source Code Form is "Incompatible With Secondary Licenses", as 389 | defined by the Mozilla Public License, v. 2.0. 390 | -------------------------------------------------------------------------------- /PHEx/README.md: -------------------------------------------------------------------------------- 1 | # Prodigy Hacking Extension (PHEx) 2 | 3 | Combined with [P-NP](https://github.com/Prodigy-Hacking/P-NP) to inject modified game files into Prodigy. 4 | 5 | Made of the Redirector extension, no-csp, and a little extra spice ;) 6 | 7 | ## [Usage](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/wiki/How-to-install-hacks) 8 | 9 | ## Building 10 | 11 | Remember to run `npm i` first in the PHEx directory to download the required packages needed for the build command. You only need to do this once. 12 | 13 | ```cmd 14 | npm run build 15 | ``` 16 | 17 | ## Credit 18 | 19 | Originally created by [Rus](https://github.com/UntrustableRus/) 20 | 21 | Maintained by the PMGH organization. 22 | -------------------------------------------------------------------------------- /PHEx/build.js: -------------------------------------------------------------------------------- 1 | const zipdir = require("zip-dir"); 2 | const fs = require('fs'); 3 | 4 | console.log("Building..."); 5 | 6 | zipdir("./src", { saveTo: "./build/extension.zip" }, function (err, buffer) { 7 | if (err) return console.error(err); 8 | console.log(".ZIP file built"); 9 | 10 | console.log("Building .CRX"); 11 | 12 | fs.copyFile('./build/extension.zip', './build/extension.crx', (err) => { 13 | if (err) console.error(err); 14 | console.log('.CRX file built'); 15 | }); 16 | 17 | fs.copyFile('./build/extension.zip', './build/extension.xpi', (err) => { 18 | if (err) console.error(err); 19 | console.log('.XPI file built'); 20 | console.log('Build finished successfully'); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /PHEx/build/default: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /PHEx/build/extension.crx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/PHEx/build/extension.crx -------------------------------------------------------------------------------- /PHEx/build/extension.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/PHEx/build/extension.xpi -------------------------------------------------------------------------------- /PHEx/build/extension.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/PHEx/build/extension.zip -------------------------------------------------------------------------------- /PHEx/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pmgh-phex", 3 | "version": "2.0.0", 4 | "description": "", 5 | "main": "build.js", 6 | "scripts": { 7 | "build": "node build.js" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/UntrustableRus/PMGH-ext.git" 12 | }, 13 | "keywords": [], 14 | "author": "", 15 | "license": "ISC", 16 | "bugs": { 17 | "url": "https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/issues" 18 | }, 19 | "homepage": "https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/blob/master/PHEx/README.md", 20 | "dependencies": { 21 | "dir-archiver": "^1.1.2", 22 | "simple-archiver": "^1.0.1", 23 | "zip-dir": "^2.0.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /PHEx/src/assets/x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/PHEx/src/assets/x128.png -------------------------------------------------------------------------------- /PHEx/src/assets/x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/PHEx/src/assets/x16.png -------------------------------------------------------------------------------- /PHEx/src/assets/x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/PHEx/src/assets/x48.png -------------------------------------------------------------------------------- /PHEx/src/background.js: -------------------------------------------------------------------------------- 1 | const browser = chrome || browser; 2 | 3 | // Ignore X-Frame Headers 4 | const HEADERS_TO_STRIP_LOWERCASE = [ 5 | "content-security-policy", 6 | "x-frame-options", 7 | ]; 8 | 9 | browser.webRequest.onHeadersReceived.addListener( 10 | details => ({ 11 | responseHeaders: details.responseHeaders.filter(header => !HEADERS_TO_STRIP_LOWERCASE.includes(header.name.toLowerCase())) 12 | }), 13 | { urls: [""] }, 14 | ["blocking", "responseHeaders", "extraHeaders"] 15 | ); 16 | 17 | function get(key) { 18 | return new Promise(resolve => { 19 | browser.storage.local.get([key], result => { 20 | resolve(result[key]); 21 | }); 22 | }); 23 | }; 24 | 25 | // Redirect Requests 26 | browser.webRequest.onBeforeRequest.addListener(async details => { 27 | // get options from local 28 | const url = await get("url"); 29 | const checked = await get("checked"); 30 | const redirectorDomain = (url && checked) ? url : "https://hacks.prodigyhacking.com"; 31 | 32 | if (details.url.startsWith("https://code.prodigygame.com/code/") && details.url.includes("/game.min.js")) { 33 | fetch("https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/master/PHEx/status.json").then(response => response.json()).then(async data => { 34 | if (data.offline == true) { 35 | eval(await (await fetch("https://unpkg.com/sweetalert2")).text()) 36 | if (swal) { 37 | swal.fire({ 38 | title: "Oh no!", 39 | html: `Our hacks are currently having some issues, and we're working on it.`, 40 | icon: "error" 41 | }) 42 | } else { 43 | const res = confirm(`Uh Oh! Hacks look to be down. Hit OK to go to our discord to get updates on when they'll go back up!`); 44 | 45 | if (res) location = "https://discord.gg/XQDfbfq"; 46 | } 47 | } 48 | }); 49 | 50 | // Blocking gamemin 51 | browser.webRequest.onBeforeRequest.addListener( 52 | _ => ({ cancel: true }), 53 | { urls: ["*://code.prodigygame.com/code/*"] }, 54 | ["blocking"] 55 | ); 56 | 57 | // see disableIntegrity.js, we append the new game.min to the document 58 | return { cancel: true }; 59 | } else if (details.url.startsWith("https://code.prodigygame.com/js/public-game")) { 60 | return { 61 | redirectUrl: `${redirectorDomain}/public-game.min.js?hash=${details.url.split("public-game-")[1].split(".")[0]}&updated=${Date.now()}` 62 | }; 63 | } 64 | }, { 65 | urls: [ 66 | "https://code.prodigygame.com/code/*/game.min.js?v=*", 67 | "https://code.prodigygame.com/js/public-game-*.min.js" 68 | ], 69 | types: ["script", "xmlhttprequest"], 70 | }, ["blocking"]); -------------------------------------------------------------------------------- /PHEx/src/disableIntegrity.js: -------------------------------------------------------------------------------- 1 | (async () => { 2 | function get(key) { 3 | return new Promise(resolve => { 4 | chrome.storage.local.get([key], result => { 5 | resolve(result[key]); 6 | }); 7 | }); 8 | } 9 | 10 | if (!window.scriptIsInjected) { 11 | // get options from local 12 | const url = await get("url"); 13 | const checked = await get("checked"); 14 | const redirectorDomain = (url && checked) ? url : "https://hacks.prodigyhacking.com"; 15 | 16 | window.scriptIsInjected = true; 17 | 18 | function redirectorCheck() { 19 | fetch(`${redirectorDomain}/game.min.js?updated=${Date.now()}`) 20 | .then(res => res.text()) 21 | .then(response => { 22 | console.log("Connection to server was Successful!"); 23 | 24 | // 25 | // we cancel the real game.min, and just append ours 26 | // a messy solution for sure, but this should only be a bandaid on a bulletwound 27 | const injectedScript = document.createElement("script"); 28 | injectedScript.innerHTML = response; 29 | 30 | document.body.append(injectedScript); 31 | }) 32 | .catch(async (error) => { 33 | // If fetch spits out error, trigger dialog box 34 | eval(await (await fetch('https://unpkg.com/sweetalert2')).text()); 35 | if (swal) { 36 | swal.fire({ 37 | title: "Oh no!", 38 | html: `An error occurred when trying to fetch the hacks, this usually happens when your school blocks https://hacks.prodigyhacking.com.
More info:

 ${error} 

If this continues to happen, join our Discord server for support at https://discord.gg/XQDfbfq.`, 39 | icon: "error" 40 | }) 41 | } else { 42 | const res = confirm(`Oh No! Something went wrong while trying to connect to the server! Try reloading this page. If this error continues to appear, hit ok to join our Discord for support, or create an issue on the GitHub. More info ${error}. This is normally caused by your school or organization blocking the hacks.`); 43 | if (res) location = "https://discord.gg/XQDfbfq"; 44 | } 45 | }); 46 | } 47 | setTimeout(redirectorCheck, 1000); 48 | 49 | const pluginVersion = chrome.runtime.getManifest().version; 50 | const supportedVersion = (await (await fetch(`${redirectorDomain}/version`)).text()); 51 | // Checks for plugin version. If outdated, triggers dialog box. 52 | if (pluginVersion !== supportedVersion) { 53 | const res = confirm("The PMGH extension is outdated. If you expierence any errors, please update. If you are on the Chrome Webstore version or any webstore, please wait. Updates take some time."); 54 | 55 | if (res) location = "https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/wiki/How-to-Update"; 56 | } 57 | 58 | // Disable integrity 59 | console.groupCollapsed("integrity patches"); 60 | [...document.getElementsByTagName("script"), ...document.getElementsByTagName("link")].forEach(v => { 61 | if (v.integrity) { 62 | console.log(v.integrity); 63 | v.removeAttribute("integrity"); 64 | } 65 | }); 66 | console.groupEnd("integrity patches"); 67 | } 68 | })(); 69 | -------------------------------------------------------------------------------- /PHEx/src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Prodigy Hacking Extension (PHEx)", 3 | "version": "2.1.8", 4 | "description": "PHEx is an extension made to raise awareness of security issues for Prodigy", 5 | "permissions": [ 6 | "webRequest", 7 | "webRequestBlocking", 8 | "*://*.prodigygame.com/*", 9 | "https://raw.githubusercontent.com/*", 10 | "storage" 11 | ], 12 | "icons": { 13 | "16": "assets/x16.png", 14 | "48": "assets/x48.png", 15 | "128": "assets/x128.png" 16 | }, 17 | "background": { 18 | "scripts": ["background.js"], 19 | "persistent": true 20 | }, 21 | "content_scripts": [{ 22 | "matches": ["https://math.prodigygame.com/*"], 23 | "js": ["disableIntegrity.js"] 24 | }], 25 | "browser_action": { 26 | "default_popup": "popup.html" 27 | }, 28 | "manifest_version": 2 29 | } 30 | -------------------------------------------------------------------------------- /PHEx/src/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | PHEX 5 | 6 | 33 | 34 | 35 | 36 | 37 | 38 |
39 | 40 |

PHEX

41 | 42 |
43 | 44 |
45 | 46 |

47 | 48 |
49 | 50 |
51 | 52 | 53 |

54 | 55 |
56 | Developer Options 57 | 58 |

Developer Options

59 | 60 |

Only touch if you know what you're doing! To use the hack, just go to prodigy. If you need help, go to our discord server

61 | 62 |

Custom PNP URL

63 | 64 | 65 |

Use Custom URL

66 | 67 | 68 |

Save

69 |

Only touch if you know what you're doing! To save options, type in "nootnoot", and submit.

70 | 71 | 72 | 73 |

74 | 75 | 76 |
77 | 78 | 79 | 80 |
81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /PHEx/src/popup.js: -------------------------------------------------------------------------------- 1 | (async() => { 2 | function set(key, value) { 3 | chrome.storage.local.set({ [key]: value }) 4 | }; 5 | function get(key) { 6 | return new Promise(resolve => { 7 | chrome.storage.local.get([key], result => { 8 | resolve(result[key]) 9 | }) 10 | }) 11 | }; 12 | function validURL(str) { 13 | var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol 14 | '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name 15 | '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address 16 | '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path 17 | '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string 18 | '(\\#[-a-z\\d_]*)?$','i'); // fragment locator 19 | return !!pattern.test(str) || new URL(str).hostname === "localhost"; 20 | } 21 | 22 | const checkbox = document.querySelector(".check") 23 | const input = document.querySelector("input") 24 | 25 | input.value = await get("url") || ""; 26 | checkbox.checked = await get("checked") || false; 27 | 28 | input.onchange = () => { 29 | document.querySelector("p").innerHTML = "" 30 | } 31 | 32 | checkbox.addEventListener("click", async (event) => { 33 | if (await get("checked")) { 34 | // if already checked, no need to run checks 35 | // set checked to new value, which should be false 36 | set("checked", checkbox.checked); 37 | } else { 38 | // if we're turning on checked, we need to run a few checks 39 | if (validURL(input.value)) { 40 | // if the URL is valid, update url and checked to their latest values. 41 | set("url", input.value); 42 | set("checked", checkbox.checked); 43 | } else { 44 | // if the URL is invalid, scream at them until they burst into tears 45 | document.querySelector("p").innerHTML = "Invalid URL"; 46 | checkbox.checked = false; 47 | } 48 | } 49 | }) 50 | })() -------------------------------------------------------------------------------- /PHEx/status.json: -------------------------------------------------------------------------------- 1 | { 2 | "offline": false 3 | } 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Hacks are being shut down. Thanks for everything.

2 |

3 | 4 | Installation 8 | 9 |

10 | 11 | 12 | 13 | 14 |

15 | 16 | Website 17 | • 18 | Discord 19 | • 20 | Installation 21 | • 22 | Youtube 23 | 24 |

25 |

26 | 27 | Chrome Web Store Rating 28 | 29 | 30 | 31 | Extension Downloads 32 | 33 | 34 | 35 | Extension Downloads 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |

47 | 48 | 49 | 50 | ## How to install 51 | 52 | 1.) Install the [extension](https://chrome.google.com/webstore/detail/prodigyhacking/gjabpajagbgoifbkflgojeojmnlmioea) (also known as PHEx) from the Chrome Web Store. 53 |
54 | 2.) Visit https://prodigygame.com 55 |
56 | 3.) Make a second account and log in. DO NOT USE HACKS ON YOUR PRIMARY ACCOUNT. Hacks can damage your account if used improperly or excessively, and most hacks can't be undone. 57 |
58 | 4.) A dropdown arrow will appear after 15-20 seconds. 59 | 60 | ## Motivation 61 | 62 |
63 | We aren't evil. Everything is open source, forever free, and without ads. 64 |
65 | We're not trying to break the game because we're evil. We wanted to help Prodigy become more secure, but they've ignored our emails and our requests to talk. They've even gone as far as to ban a user from their official Zendesk. 66 | 67 | Because of that, we're publicly showing hacks! That, and it's also just fun :) 68 | 69 | All of our hacks are open source, and free. No paywalls, no ads, and no Patreon. If you really want to support us, you can Nitro boost our Discord server [here](https://discord.gg/XQDfbfq)! 70 |
71 | 72 |
73 | Can you hack for me? 74 | 75 | No. See [#170](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/discussions/170). 76 | 77 |
78 | 79 |
80 | How do I know you won't steal my account? 81 | Of course, with trusting any hacks, comes the risk that we're actually bad actors that will steal all your info. 82 | It's impossible to prove with absolute certainty to anyone reading this that we aren't bad faith, but we can open source our things, and try to be transparent. 83 | 84 | - We do not want your account. 85 | 86 | Not only do we not want your account, but we will actively ban you from our organization if you share your credentials online. It's bad security, and we really can't be bothered. 87 | 88 | - But what if you steal my personal info? 89 | 90 | We do not want your personal info. Please do not share it. Even if we wanted to, there's not much we could do with it. "Wow, John Doe is in 5th grade and has mastered fractions!" 91 | 92 | - How do I know what code is running in the hacks? 93 | 94 | Again, our code is open source, and you're always free to read any of it. If you have trouble understanding what a certain thing does, feel free to ask any of the administrators on our official Discord. 95 |
96 | 97 |
98 | Legal 99 | If you have any legal problems, please email support@prodigyhacking.com 100 |
101 | 102 | 103 | 104 | ## Disclaimer 105 | 106 |
107 | Always use an alt, just to be safe. 108 |
109 | While our hacks are completely safe, you should never use hacks on your main account. 110 | 111 | There's an extremely small chance your account will be hacker-tagged, reset, or banned. Luckily, it almost never happens. The only incidents PMGH knows of users being banned for hacking were contributors or staff of PMGH itself. 112 | 113 | We will never ask you for your password. If somebody asks you for personal/sensitive information, report it to the staff on our [Discord server](https://discord.gg/XQDfbfq). 114 | 115 | All of our hacks are *open-source*, and only located under our [Github Organization](https://github.com/Prodigy-Hacking). 116 | *If it's not an official repository or a fork, it may not be safe!* 117 |
118 | 119 | 120 | 121 |
122 | We're not liable for damage to your account. 123 |
124 | - All hacks, exploits, or other files hosted here may damage your account if used improperly or excessively. We can't stress enough, do not use any of these hacks on your primary account, as you risk your account becoming damaged beyond repair, preventing you from accessing Prodigy Math Game in that account. You have been warned. 125 |
126 | - We are not liable for any damages of any kind, as our license states: 127 | 128 | > Limitation of Liability 129 | > Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall any Contributor, or anyone who distributes Covered Software as permitted above, be liable to You for any direct, indirect, special, incidental, or consequential damages of any character including, without limitation, damages for lost profits, loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party’s negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You. 130 |
131 | 132 | 133 | 134 | 135 | 136 | ## Current Collaborators 137 | - [PatheticMustan](https://github.com/PatheticMustan) 138 | - [Arcerion](https://github.com/ArcerionDev) 139 | - [Yama](https://github.com/vibinyama) 140 | - [BoredFish](https://github.com/BoredFishRE) 141 | - [Hostedposted](https://github.com/hostedposted) 142 | - [Spacebar](https://github.com/00100000) 143 | - Noot (Anonymous User) 144 | 145 | 146 | 147 | 148 | 149 | ## Retired Collaborators 150 | 151 | - [MelnCat](https://github.com/MelnCat) 152 | - [Exoticc](https://github.com/Exoticc) 153 | - [Rus](https://github.com/UntrustableRus) 154 | - [Rubberduck55](https://github.com/Rubberduck55) 155 | - [Whimpers](https://github.com/KryptoCrash) 156 | 157 | 158 | 159 | 160 | ## Important Folders 161 | 162 | - [ProdigyMathGameHacking](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking) 163 | - Our main repo, used as an issue tracker, things we're working on, documentation, and central hub. You're currently on it. 164 | - [PHEx](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/tree/master/PHEx) 165 | - The Prodigy Hacking Extension, used to inject our modified gamefiles into Prodigy. 166 | 167 |
168 | 169 |

170 | Jokes Card 171 |

172 | 173 | 174 | ---- 175 | ***All hacks and software are licensed under the Mozilla Public License (MPL) V2.0, unless stated otherwise with a separate license. Any violation of the policy of this licence may result in a DMCA takedown.*** -------------------------------------------------------------------------------- /announcement.md: -------------------------------------------------------------------------------- 1 | First we'd like to thank everyone for being with us. For the past 2.5 years, we've maintained hacks for the math game Prodigy. 2 | 3 | Our original goal, which was raising awareness about the security of Prodigy has (mostly) been accomplished! 4 | While we would love to continue maintaining hacks, we collectively have had less and less time to focus on development. 5 | Server costs are also surprisingly expensive..! Who knew? 6 | 7 | For these reasons, As of April 10th, 2022, we will shut down our instance of P-NP. 8 | Hacks for the most part will no longer work. 9 | 10 | We will keep our source code on GitHub, where anyone can continue development by forking our repositories. 11 | We'll continue to review pull requests, but patched hacks most likely will remain patched. 12 | 13 | If you would like to run your own instance of the hacks, we'll soon release instructions on how to run P-NP. 14 | This discord server will move from a Prodigy Hacking server to a Coding focused server over the next month. 15 | 16 | Thank you all for understanding, and being with us for the past few years. 17 | So long, and thanks for all the fish. 18 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # ProdigyMathGameHacking 2 | 3 | ## Collaborators 4 | - [PatheticMustan](https://github.com/PatheticMustan) 5 | - [Arcerion](https://github.com/ArcerionDev) 6 | - [Yama](https://github.com/YamaHacks) 7 | - [Rus](https://github.com/UntrustableRus) 8 | - [BoredFish](https://github.com/BoredFishRE) 9 | - Noot (Anonymous User) 10 | 11 | # Hacking Prodigy Math Game 12 | 13 | I'm making this repository to try to get the developers to change how Prodigy handles player game data. Instead of handling everything server side, a lot of the heavy lifting is done on the player side. The server just manages multiplayer battles, and hosts data, messages, and events. 14 | 15 | Basically any changes you make to your user data via the API or via JS code - we exploit - are saved. Be warned, if you mess up the data TOO much, the server gets really confused, and your account is broken forever! Don't do this on your main account. I've already broken three accounts. ;) 16 | 17 | # Disclaimer 18 | - All hacks, exploits, or other files hosted here may damage your account if used improperly or excessively. Do not use any of these hacks on your primary account, as you risk your account becoming damaged beyond repair, preventing you from accessing Prodigy Math Game in that account. You have been warned. 19 | - We are not liable for any damages of any kind, as our license states: 20 | > 7. Limitation of Liability Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall any Contributor, or anyone who distributes Covered Software as permitted above, be liable to You for any direct, indirect, special, incidental, or consequential damages of any character including, without limitation, damages for lost profits, loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party’s negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You. 21 | 22 | 23 | # Usage 24 | For set-up information, see [this](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/wiki/How-to-install-hacks) page. 25 | 26 | 27 | Any questions? Join our [Discord](https://discord.gg/XQDfbfq)! 28 | 29 | Documentation: [Docs](./docs/interfaces/_pixi_d_.pixi.md) 30 | -------------------------------------------------------------------------------- /docs/classes/_player_d_.playerdata.md: -------------------------------------------------------------------------------- 1 | [ProdigyMathGameHackingTypings](../README.md) › [Globals](../globals.md) › ["player.d"](../modules/_player_d_.md) › [PlayerData](_player_d_.playerdata.md) 2 | 3 | # Class: PlayerData 4 | 5 | ## Hierarchy 6 | 7 | * **PlayerData** 8 | 9 | ## Index 10 | 11 | ### Properties 12 | 13 | * [allowsHouseVisitors](_player_d_.playerdata.md#allowshousevisitors) 14 | * [arena](_player_d_.playerdata.md#arena) 15 | * [atHomeTimestamp](_player_d_.playerdata.md#athometimestamp) 16 | * [atSchoolTimestamp](_player_d_.playerdata.md#atschooltimestamp) 17 | * [battleCounter](_player_d_.playerdata.md#battlecounter) 18 | * [bountyScore](_player_d_.playerdata.md#bountyscore) 19 | * [daily](_player_d_.playerdata.md#daily) 20 | * [deserter](_player_d_.playerdata.md#deserter) 21 | * [dungeonRunsTimeStamps](_player_d_.playerdata.md#dungeonrunstimestamps) 22 | * [energy](_player_d_.playerdata.md#energy) 23 | * [gold](_player_d_.playerdata.md#gold) 24 | * [hp](_player_d_.playerdata.md#hp) 25 | * [lastArchiveRun](_player_d_.playerdata.md#lastarchiverun) 26 | * [level](_player_d_.playerdata.md#level) 27 | * [memberStarsExpirationDate](_player_d_.playerdata.md#memberstarsexpirationdate) 28 | * [nm](_player_d_.playerdata.md#nm) 29 | * [numSpins1](_player_d_.playerdata.md#numspins1) 30 | * [numSpins2](_player_d_.playerdata.md#numspins2) 31 | * [school](_player_d_.playerdata.md#school) 32 | * [settings](_player_d_.playerdata.md#settings) 33 | * [spellbook](_player_d_.playerdata.md#spellbook) 34 | * [spells](_player_d_.playerdata.md#spells) 35 | * [spinDate1](_player_d_.playerdata.md#spindate1) 36 | * [spinDate2](_player_d_.playerdata.md#spindate2) 37 | * [stars](_player_d_.playerdata.md#stars) 38 | * [startDate](_player_d_.playerdata.md#startdate) 39 | * [storedMemberStars](_player_d_.playerdata.md#storedmemberstars) 40 | * [team](_player_d_.playerdata.md#team) 41 | * [titanID](_player_d_.playerdata.md#titanid) 42 | * [tower](_player_d_.playerdata.md#tower) 43 | * [trialSkipAvailable](_player_d_.playerdata.md#trialskipavailable) 44 | * [trialStartDate](_player_d_.playerdata.md#trialstartdate) 45 | * [versionID](_player_d_.playerdata.md#versionid) 46 | * [win](_player_d_.playerdata.md#win) 47 | * [zone](_player_d_.playerdata.md#zone) 48 | 49 | ## Properties 50 | 51 | ### allowsHouseVisitors 52 | 53 | • **allowsHouseVisitors**: *boolean* 54 | 55 | ___ 56 | 57 | ### arena 58 | 59 | • **arena**: *number* 60 | 61 | ___ 62 | 63 | ### atHomeTimestamp 64 | 65 | • **atHomeTimestamp**: *number* 66 | 67 | ___ 68 | 69 | ### atSchoolTimestamp 70 | 71 | • **atSchoolTimestamp**: *number* 72 | 73 | ___ 74 | 75 | ### battleCounter 76 | 77 | • **battleCounter**: *number* 78 | 79 | ___ 80 | 81 | ### bountyScore 82 | 83 | • **bountyScore**: *number* 84 | 85 | ___ 86 | 87 | ### daily 88 | 89 | • **daily**: *object* 90 | 91 | #### Type declaration: 92 | 93 | * **festivalName**: *string* 94 | 95 | * **isComplete**: *boolean* 96 | 97 | * **lastStarted**: *number* 98 | 99 | * **location**: *string* 100 | 101 | * **monsterID**: *number* 102 | 103 | ___ 104 | 105 | ### deserter 106 | 107 | • **deserter**: *number* 108 | 109 | ___ 110 | 111 | ### dungeonRunsTimeStamps 112 | 113 | • **dungeonRunsTimeStamps**: *object[]* 114 | 115 | ___ 116 | 117 | ### energy 118 | 119 | • **energy**: *number* 120 | 121 | ___ 122 | 123 | ### gold 124 | 125 | • **gold**: *number* 126 | 127 | ___ 128 | 129 | ### hp 130 | 131 | • **hp**: *number* 132 | 133 | ___ 134 | 135 | ### lastArchiveRun 136 | 137 | • **lastArchiveRun**: *number* 138 | 139 | ___ 140 | 141 | ### level 142 | 143 | • **level**: *number* 144 | 145 | ___ 146 | 147 | ### memberStarsExpirationDate 148 | 149 | • **memberStarsExpirationDate**: *number* 150 | 151 | ___ 152 | 153 | ### nm 154 | 155 | • **nm**: *number* 156 | 157 | ___ 158 | 159 | ### numSpins1 160 | 161 | • **numSpins1**: *number* 162 | 163 | ___ 164 | 165 | ### numSpins2 166 | 167 | • **numSpins2**: *number* 168 | 169 | ___ 170 | 171 | ### school 172 | 173 | • **school**: *string* 174 | 175 | ___ 176 | 177 | ### settings 178 | 179 | • **settings**: *object* 180 | 181 | #### Type declaration: 182 | 183 | * **bgmVolume**: *number* 184 | 185 | * **sfxVolume**: *number* 186 | 187 | * **voiceVolume**: *number* 188 | 189 | ___ 190 | 191 | ### spellbook 192 | 193 | • **spellbook**: *number[]* 194 | 195 | ___ 196 | 197 | ### spells 198 | 199 | • **spells**: *number[]* 200 | 201 | ___ 202 | 203 | ### spinDate1 204 | 205 | • **spinDate1**: *number* 206 | 207 | ___ 208 | 209 | ### spinDate2 210 | 211 | • **spinDate2**: *number* 212 | 213 | ___ 214 | 215 | ### stars 216 | 217 | • **stars**: *number* 218 | 219 | ___ 220 | 221 | ### startDate 222 | 223 | • **startDate**: *number* 224 | 225 | ___ 226 | 227 | ### storedMemberStars 228 | 229 | • **storedMemberStars**: *number* 230 | 231 | ___ 232 | 233 | ### team 234 | 235 | • **team**: *number* 236 | 237 | ___ 238 | 239 | ### titanID 240 | 241 | • **titanID**: *number* 242 | 243 | ___ 244 | 245 | ### tower 246 | 247 | • **tower**: *number* 248 | 249 | ___ 250 | 251 | ### trialSkipAvailable 252 | 253 | • **trialSkipAvailable**: *boolean* 254 | 255 | ___ 256 | 257 | ### trialStartDate 258 | 259 | • **trialStartDate**: *string* 260 | 261 | ___ 262 | 263 | ### versionID 264 | 265 | • **versionID**: *number* 266 | 267 | ___ 268 | 269 | ### win 270 | 271 | • **win**: *number* 272 | 273 | ___ 274 | 275 | ### zone 276 | 277 | • **zone**: *string* 278 | -------------------------------------------------------------------------------- /docs/globals.md: -------------------------------------------------------------------------------- 1 | [ProdigyMathGameHackingTypings](README.md) › [Globals](globals.md) 2 | 3 | # ProdigyMathGameHackingTypings 4 | 5 | ## Index 6 | 7 | ### Modules 8 | 9 | * ["game.d"](modules/_game_d_.md) 10 | * ["item.d"](modules/_item_d_.md) 11 | * ["pixi.d"](modules/_pixi_d_.md) 12 | * ["player.d"](modules/_player_d_.md) 13 | * ["prodigy.d"](modules/_prodigy_d_.md) 14 | * ["test"](modules/_test_.md) 15 | * ["util.d"](modules/_util_d_.md) 16 | -------------------------------------------------------------------------------- /docs/interfaces/_game_d_.game.md: -------------------------------------------------------------------------------- 1 | [ProdigyMathGameHackingTypings](../README.md) › [Globals](../globals.md) › ["game.d"](../modules/_game_d_.md) › [Game](_game_d_.game.md) 2 | 3 | # Interface: Game 4 | 5 | ## Hierarchy 6 | 7 | * **Game** 8 | 9 | ## Index 10 | 11 | ### Properties 12 | 13 | * [id](_game_d_.game.md#id) 14 | * [prodigy](_game_d_.game.md#prodigy) 15 | 16 | ## Properties 17 | 18 | ### id 19 | 20 | • **id**: *number* 21 | 22 | ___ 23 | 24 | ### prodigy 25 | 26 | • **prodigy**: *[Prodigy](_prodigy_d_.prodigy.md)* 27 | -------------------------------------------------------------------------------- /docs/interfaces/_pixi_d_.pixi.md: -------------------------------------------------------------------------------- 1 | [ProdigyMathGameHackingTypings](../README.md) › [Globals](../globals.md) › ["pixi.d"](../modules/_pixi_d_.md) › [PIXI](_pixi_d_.pixi.md) 2 | 3 | # Interface: PIXI 4 | 5 | ## Hierarchy 6 | 7 | * **PIXI** 8 | 9 | ## Index 10 | 11 | ### Properties 12 | 13 | * [game](_pixi_d_.pixi.md#game) 14 | 15 | ## Properties 16 | 17 | ### game 18 | 19 | • **game**: *[Game](_game_d_.game.md)* 20 | -------------------------------------------------------------------------------- /docs/interfaces/_player_d_.playername.md: -------------------------------------------------------------------------------- 1 | [ProdigyMathGameHackingTypings](../README.md) › [Globals](../globals.md) › ["player.d"](../modules/_player_d_.md) › [PlayerName](_player_d_.playername.md) 2 | 3 | # Interface: PlayerName 4 | 5 | ## Hierarchy 6 | 7 | * **PlayerName** 8 | 9 | ## Index 10 | 11 | ### Properties 12 | 13 | * [data](_player_d_.playername.md#data) 14 | * [gender](_player_d_.playername.md#gender) 15 | * [localizer](_player_d_.playername.md#localizer) 16 | 17 | ## Properties 18 | 19 | ### data 20 | 21 | • **data**: *object* 22 | 23 | #### Type declaration: 24 | 25 | * **firstName**: *number* 26 | 27 | * **lastName**: *number* 28 | 29 | * **middleName**: *number* 30 | 31 | * **nickname**: *unknown* 32 | 33 | ___ 34 | 35 | ### gender 36 | 37 | • **gender**: *"male" | "female"* 38 | 39 | ___ 40 | 41 | ### localizer 42 | 43 | • **localizer**: *object* 44 | 45 | #### Type declaration: 46 | 47 | * **dataSource**: *[TODO](../modules/_util_d_.md#todo)* 48 | -------------------------------------------------------------------------------- /docs/interfaces/_prodigy_d_.prodigy.md: -------------------------------------------------------------------------------- 1 | [ProdigyMathGameHackingTypings](../README.md) › [Globals](../globals.md) › ["prodigy.d"](../modules/_prodigy_d_.md) › [Prodigy](_prodigy_d_.prodigy.md) 2 | 3 | # Interface: Prodigy 4 | 5 | ## Hierarchy 6 | 7 | * **Prodigy** 8 | 9 | ## Index 10 | 11 | ### Properties 12 | 13 | * [game](_prodigy_d_.prodigy.md#game) 14 | * [player](_prodigy_d_.prodigy.md#player) 15 | * [version](_prodigy_d_.prodigy.md#version) 16 | 17 | ## Properties 18 | 19 | ### game 20 | 21 | • **game**: *[Game](_game_d_.game.md)* 22 | 23 | ___ 24 | 25 | ### player 26 | 27 | • **player**: *[Player](../classes/_player_d_.player.md)* 28 | 29 | ___ 30 | 31 | ### version 32 | 33 | • **version**: *string* 34 | -------------------------------------------------------------------------------- /docs/modules/_game_d_.md: -------------------------------------------------------------------------------- 1 | [ProdigyMathGameHackingTypings](../README.md) › [Globals](../globals.md) › ["game.d"](_game_d_.md) 2 | 3 | # Module: "game.d" 4 | 5 | ## Index 6 | 7 | ### Interfaces 8 | 9 | * [Game](../interfaces/_game_d_.game.md) 10 | -------------------------------------------------------------------------------- /docs/modules/_item_d_.md: -------------------------------------------------------------------------------- 1 | [ProdigyMathGameHackingTypings](../README.md) › [Globals](../globals.md) › ["item.d"](_item_d_.md) 2 | 3 | # Module: "item.d" 4 | 5 | ## Index 6 | 7 | ### Type aliases 8 | 9 | * [Item](_item_d_.md#item) 10 | 11 | ## Type aliases 12 | 13 | ### Item 14 | 15 | Ƭ **Item**: *[TODO](_util_d_.md#todo)* 16 | -------------------------------------------------------------------------------- /docs/modules/_pixi_d_.md: -------------------------------------------------------------------------------- 1 | [ProdigyMathGameHackingTypings](../README.md) › [Globals](../globals.md) › ["pixi.d"](_pixi_d_.md) 2 | 3 | # Module: "pixi.d" 4 | 5 | ## Index 6 | 7 | ### Namespaces 8 | 9 | * [__global](_pixi_d_.md#__global) 10 | 11 | ### Interfaces 12 | 13 | * [PIXI](../interfaces/_pixi_d_.pixi.md) 14 | 15 | ## Namespaces 16 | 17 | ### __global 18 | 19 | • **__global**: 20 | 21 | ### `Const` PIXI 22 | 23 | • **PIXI**: *[PIXI](../interfaces/_pixi_d_.pixi.md)* 24 | -------------------------------------------------------------------------------- /docs/modules/_player_d_.md: -------------------------------------------------------------------------------- 1 | [ProdigyMathGameHackingTypings](../README.md) › [Globals](../globals.md) › ["player.d"](_player_d_.md) 2 | 3 | # Module: "player.d" 4 | 5 | ## Index 6 | 7 | ### Classes 8 | 9 | * [Player](../classes/_player_d_.player.md) 10 | * [PlayerData](../classes/_player_d_.playerdata.md) 11 | 12 | ### Interfaces 13 | 14 | * [PlayerName](../interfaces/_player_d_.playername.md) 15 | 16 | ### Type aliases 17 | 18 | * [ItemType](_player_d_.md#itemtype) 19 | * [Zones](_player_d_.md#zones) 20 | 21 | ## Type aliases 22 | 23 | ### ItemType 24 | 25 | Ƭ **ItemType**: *"follow" | "hat" | "outfit" | "spellRelic" | "weapon" | "boots"* 26 | 27 | ___ 28 | 29 | ### Zones 30 | 31 | Ƭ **Zones**: *"tower_town"* 32 | -------------------------------------------------------------------------------- /docs/modules/_prodigy_d_.md: -------------------------------------------------------------------------------- 1 | [ProdigyMathGameHackingTypings](../README.md) › [Globals](../globals.md) › ["prodigy.d"](_prodigy_d_.md) 2 | 3 | # Module: "prodigy.d" 4 | 5 | ## Index 6 | 7 | ### Interfaces 8 | 9 | * [Prodigy](../interfaces/_prodigy_d_.prodigy.md) 10 | -------------------------------------------------------------------------------- /docs/modules/_test_.md: -------------------------------------------------------------------------------- 1 | [ProdigyMathGameHackingTypings](../README.md) › [Globals](../globals.md) › ["test"](_test_.md) 2 | 3 | # Module: "test" 4 | 5 | 6 | -------------------------------------------------------------------------------- /docs/modules/_util_d_.md: -------------------------------------------------------------------------------- 1 | [ProdigyMathGameHackingTypings](../README.md) › [Globals](../globals.md) › ["util.d"](_util_d_.md) 2 | 3 | # Module: "util.d" 4 | 5 | ## Index 6 | 7 | ### Type aliases 8 | 9 | * [TODO](_util_d_.md#todo) 10 | 11 | ## Type aliases 12 | 13 | ### TODO 14 | 15 | Ƭ **TODO**: *any* 16 | -------------------------------------------------------------------------------- /meta/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Timeline of PMGH 2 | 3 | - **PIXI Ages**: `9/21/19 - 3/25/20` 4 | - During these times, `PIXI.game` was a thing. However, Prodigy hacks were not well known. 5 | - **Phaser Day**: `3/25/20 - 3/26/20` 6 | - On this day, we used `Phaser.GAMES[0]`, only for it to be patched the day after. 7 | - **Login.gameObj** Day: `3/26/20 - 3/27/20` 8 | - An alternative method was found. However, it only supported the player object. It was also patched after a day. 9 | - **CanvasPool Days**: `3/27/20 - 3/30/20` 10 | - This method worked for longer. However, it was also quickly patched. 11 | - **Cheat Dashboard Day**: `3/30/20 - 3/30/20` 12 | - A cheat dashboard was developed. However, it was not very good, which caused it to be unsupported the day after. 13 | - **Dark Ages**: `4/1/20 - 4/7/20` 14 | - The first week of April was a sad week for Prodigy hacking. All known hacking methods were patched. 15 | - **EnableDebug Breakthrough**: `4/07/20 - 4/09/20` 16 | - A way to enable debug mode was found, and worked for two days. However, debug was removed by Prodigy quickly after. 17 | - **Prodigy Console Prevention**: `4/10/20` 18 | - On this day, Prodigy added the devtool disabler, which would cause a 404 on devtool open. 19 | - **Debugger Scope Ages**: `4/12/20 - 4/15/20` 20 | - On these days, multiple variables were used to obtain the Prodigy's scopes, and access the `instance` objects. 21 | - **Redirector Ages**: `4/15/20 - around 11/13/20` 22 | - After many days, the Redirector hack was created, which would use a modified version of prodigy's game files. This would not be patched for a very long time. It was suceeded by the extension 23 | - **Content Security Patch**: `6/10/20` 24 | - On June 10th, Prodigy added content security headers. This caused the addition of another extension to help with hacks. 25 | - **`hack.instance.prodigy.player` Patch**: `7/5/20 - 7/5/20` 26 | - On July 5th, Prodigy implemented a patch for `hack.instance.prodigy.player`. This was unpatched by ProdigyMathGameHacking about 3 hours later. 27 | - **Script based hacks return**: `8/25/20` 28 | - On August 20th, we found a way to access the Prodigy API, and use hacks without the Redirector extension. 29 | - **`_.instance.prodigy.player` Patch**: `9/17/20 - CURRENT` 30 | - On September 18th, Prodigy patched the `hack` variable by redirecting to a 404 page if the `hack` variable was detected. To unpatch this, we renamed the variable to `_`. Prodigy already uses `_`, so they can't delete it. 31 | - **Chrome Extension Releases**: `10/21/20 - 11/11/20` 32 | - On October 21st, Google accepted the ProdigyMathGameHacking extension submission to the Chrome Web Store. The extension works exacatly the same as the Redirector Hack, but is much easier as you only have to install our extension without importing the JSON file into Redirector. 33 | - **Chrome Extension Taken down**: `11/11/20` 34 | - On November 11th, Prodigy removed the PMGH Chrome extension via DMCA takedown. 35 | 36 | - **Prodigy adds SHA256 Integrity Checks**: `11/13/20 - CURRENT` 37 | - On November 13th, Prodigy added extra security via integrity checking with sha256. This broke the hacks. 38 | 39 | - **SHA256 Sumchecks bypassed**: `11/13/20 - 11/19/20` 40 | - On November 19th, Natsumi bypassed the SHA256 sumcheck, which fixed the hacks. 41 | -------------------------------------------------------------------------------- /meta/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Citizen Code of Conduct 2 | 3 | Our goal was to improve Prodigy's security, not ruining the game for profit. We won't sell our hacks, or put ads. 4 | 5 | Our hacks will **always** be open-source, and free to use. 6 | 7 | --- 8 | 9 | You may ***never***: 10 | 11 | - sell our hacks in any way shape or form 12 | - hide our hacks behind a paywall/subscribewall of any kind 13 | - This includes adfly 😐 14 | - use our hacks to leak private information 15 | - use our hacks to steal user login information or tokens 16 | - claim ownership of our hacks (Just stop bragging about it 😠) 17 | - modify it slightly just to add your own ads 🤨 18 | 19 | If you're gonna talk about our hacks (on YouTube or other social media platforms), please please pretty please [credit us properly](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/blob/master/YOUTUBE_ATTRIBUTION.md). 20 | 21 | It hurts our souls when skids take credit for our hacks and don't even link us. 22 | 23 | --- 24 | 25 | Last reminder that we are **volunteers**, and do not profit from this. We do this for *fun*, not for evil. Please don't spoil our fun. 26 | -------------------------------------------------------------------------------- /meta/CONTRIBUTING.MD: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Hacking Prodigy used to be as easy as `PIXI.game.prodigy.player.gold=999`, but now we need a whole team! 4 | 5 | If you'd like to join as an official collaborator, you can message us on [our official Discord server](https://discord.gg/XQDfbfq)! 6 | 7 | Additionally, read our [Code of Conduct](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/blob/master/.github/CODE_OF_CONDUCT.md) before continuing. 8 | 9 | --- 10 | 11 | ## The Goal of [PMGH](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking) 12 | 13 | Our main goal in this repository is to bring Prodigy's attention to their game's architecture. 14 | 15 | Most of the data stuff is handled on the client side, so hacking is as easy as changing a variable. No pwn needed! 16 | 17 | Since we've started this repository, Prodigy's security has improved by leaps and bounds, but the main issue is still the same; 18 | once you get to the player variable, you can easily change anything you want. 19 | 20 | Ideally everything would be handled server side. For example, arena points are already handled properly. The only way to increment arena points is by sending a "win" event, which is rate limited to once per minute. 21 | 22 | ## Tasks 23 | 24 | There are lots of things to do! (Ranked from easiest to hardest) 25 | 26 | ### Research 27 | 28 | As the name indicates, research. Research includes: 29 | 30 | - looking for new endpoints to mess around with 31 | - reading the Prodigy source extensively 32 | - reporting broken hacks 33 | - suggesting new hack ideas 34 | 35 | Requirements: 36 | 37 | - basic coding skills 38 | - basic understanding of what an API is (the bar is super low huh) 39 | - reading skills 40 | 41 | Anybody can do this! If you want to help with any of these, you can post your findings in [Discussions](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/discussions), or [our official Discord](https://discord.gg/XQDfbfq). 42 | 43 | ### Typings 44 | 45 | Basically just typescript definitions for Prodigy objects. An understanding of how to implement the types is also necessary. 46 | 47 | Requirements: 48 | 49 | - lots of spare time 50 | 51 | If you make a PR with Typings, [Will](https://github.com/MelnCat) will will you into his Will will. <3 52 | 53 | ### [Will's Cheat Menu](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/tree/master/willsCheatMenu) 54 | 55 | [Will's Cheat Menu](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/tree/master/willsCheatMenu)! Written in Typescript, it gives a visual cheat menu, with tons of handy dandy hacks in one place. No more copy pasting required! 56 | 57 | Requirements: 58 | 59 | - Javascript/Typescript knowledge 60 | - Basic knowledge of how to use the command line 61 | - Basic knowledge of Node.js/npm syntax 62 | - A good personality 63 | 64 | you can build it from `./willsCheatMenu` with `webpack`. 65 | 66 | ### [Browser Extension](https://chrome.google.com/webstore/detail/prodigy-hacking-extension/gjabpajagbgoifbkflgojeojmnlmioea) 67 | 68 | We used to rely on the Chrome extension "Redirector", and "Anti-CSP", but due to some extra anti-cheats from Prodigy, we've decided to roll our own extension. 69 | 70 | The extension does a few things (only on Prodigy domains): 71 | 72 | - disable CSP, so we can inject our scripts 73 | - disable Prodigy's official game files, and inject our hacked files 74 | - hehehehehehe 75 | 76 | We usually don't need help with this, it almost never changes, When it does change, we usually need 77 | *extremely skilled* researchers to figure out the problem, and fix it. 78 | 79 | #### [P-NP](https://github.com/Prodigy-Hacking/P-NP) (aka Redirector) 80 | 81 | Redirector was made by [Will](https://github.com/MelnCat). Thanks, [Will](https://github.com/MelnCat)! 82 | 83 | It just edits the gamescript so we can bypass any clientside anti-cheats, and expose the special 84 | sauce objects we desire. 85 | 86 | [Redirector]((https://github.com/Prodigy-Hacking/P-NP)) is written in Typescript. It also comes in its own repository! 87 | 88 | To build: 89 | 90 | ```cmd 91 | npm tsc 92 | ``` 93 | 94 | We usually don't require help with [Redirector](https://github.com/Prodigy-Hacking/P-NP), but it's pretty important to know it exists. 95 | 96 | Because we can edit the game script, we can also import external scripts, such as [WCM](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/tree/master/willsCheatMenu). 97 | 98 | ## Your contributions are licensed under the [MPL 2.0 software license](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/blob/master/LICENSE) 99 | 100 | When you submit anything here, your contributions will be licensesd under [the MPL 2.0 license](https://www.mozilla.org/en-US/MPL/2.0/). Contact a collaborator if this is an issue to you. 101 | 102 | ## We Develop with [GitHub](https://github.com/) 103 | 104 | We use [GitHub](https://github.com/) to host code, track [issues](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/issues) and feature requests, and provide you with this work. 105 | -------------------------------------------------------------------------------- /meta/FAQ.md: -------------------------------------------------------------------------------- 1 | # FAQ (Frequently Asked Questions) 2 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 3 | Q: "Are these hacks patched?" 4 | A: No, they currently are not patched, and probably won't be for a while. 5 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 6 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 7 | Q: "Why are you doing this?" 8 | A: By finding and reporting hacks, we want to improve Prodigy's security. Also, it's fun. 9 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 10 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11 | Q: "Are you still updating these hacks?" 12 | A: Yes. If something is broken, or not updated, just make an issue in the Github, or tell us on our official Discord! 13 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 14 | ## [Our Discord~](https://discord.gg/XQDfbfq) 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 16 | Q: "Do you have script based hacks?" 17 | A: Yes, you can check them out right below. 18 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 19 | ## [Script based hacks~](https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/tree/master/hacks/Script-Based%20Hacks) 20 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 21 | Q: "Can I make my own menu?" 22 | A: While you technically can, you would need to make a script to put in your menu, that also removes Will's menu, and put that into console. 23 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 24 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 25 | Q: "Do the hacks save?" 26 | A: While some do, others dont. Basic things such as levels 1-100 save, while going higher than that isnt meant to happen, 27 | therefore doesnt save. Basically; It depends. 28 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 29 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 30 | Q: "Can I be banned for this?" 31 | A: Technically, yes, although it's very rare. 32 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 33 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 34 | Q: "Why do my hacks not save, even the basic ones?" 35 | A: Just go into a fight and win the battle, or use the force save character hack in console below. 36 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | ## [Force save character hack~](https://github.com/ProdigyHacking/ProdigyMathGameHacking/blob/master/hacks/Misc/ForceSaveCharacter.js) 38 | #### If you have any more questions put a comment on this, create a issue, or ask in the discord server! (Our staff team are also always availible for questions) 39 | -------------------------------------------------------------------------------- /meta/YOUTUBE_ATTRIBUTION.md: -------------------------------------------------------------------------------- 1 | # To make a public video on our hacks, please copy the format below 2 | 3 | ```text 4 | Hacks belong to and were developed by the Prodigy-Hacking organization - https://github.com/Prodigy-Hacking/ProdigyMathGameHacking 5 | PMGH Discord - https://discord.gg/XQDfbfq 6 | PMGH Website - https://prodigyhacking.com 7 | ``` 8 | 9 | *If you'd like an exception, please contact us [on Discord](https://discord.gg/XQDfbfq). We're friendly, I promise!* 10 | -------------------------------------------------------------------------------- /meta/utility/push.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | git add -A 3 | echo Added files. 4 | git commit -am "%*" 5 | echo Committed. 6 | git pull 7 | echo Pulled. 8 | git push 9 | echo Pushed. 10 | -------------------------------------------------------------------------------- /meta/utility/updateCommitter.sh: -------------------------------------------------------------------------------- 1 | git filter-branch --env-filter ' 2 | OLD_EMAIL="redacted" 3 | CORRECT_NAME="Noot" 4 | CORRECT_EMAIL="noot" 5 | if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ] 6 | then 7 | export GIT_COMMITTER_NAME="$CORRECT_NAME" 8 | export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL" 9 | fi 10 | if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ] 11 | then 12 | export GIT_AUTHOR_NAME="$CORRECT_NAME" 13 | export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL" 14 | fi 15 | ' --tag-name-filter cat -- --branches --tags 16 | GITHASH=$(git rev-parse @~1) 17 | git filter-branch --commit-filter 'export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_DATE="$GIT 18 | _AUTHOR_DATE"; git commit-tree "$@"' -- $GITHASH..HEAD 19 | -------------------------------------------------------------------------------- /oldguard/dist/bundle.css: -------------------------------------------------------------------------------- 1 | body{background-color:lime} 2 | -------------------------------------------------------------------------------- /oldguard/index.js: -------------------------------------------------------------------------------- 1 | const readline = require("readline"); 2 | 3 | const esbuild = require("esbuild"); 4 | const cssModulesPlugin = require('esbuild-css-modules-plugin'); 5 | 6 | const express = require("express"); 7 | const app = express(); 8 | const port = 1005; 9 | 10 | app.use(express.static("dist")); 11 | app.get("/", (req, res) => { 12 | res.redirect("bundle.js"); 13 | }); 14 | 15 | app.listen(port, () => { 16 | readline.emitKeypressEvents(process.stdin); 17 | process.stdin.setRawMode(true); 18 | 19 | console.log( 20 | ` 21 | The old machine hums along... listen to the vibrations of the ancient one on :${port} 22 | 23 | Oldguard Dashboard! 24 | [b] - rebuild 25 | [ctrl c] - quit 26 | ` 27 | ); 28 | }); 29 | 30 | 31 | 32 | process.stdin.on("keypress", (str, key) => { 33 | const { name, ctrl } = key; 34 | 35 | // exit 36 | if (name === "c" && ctrl) { process.exit(); } 37 | 38 | // build 39 | if (name === "b") { 40 | esbuild.build({ 41 | entryPoints: ["./src/app.jsx"], 42 | bundle: true, 43 | minifyWhitespace: true, 44 | target: "chrome90", 45 | outfile: "dist/bundle.js", 46 | plugins: [cssModulesPlugin({inject: true})] 47 | }).catch(err => console.error(err)); // lol error handling 48 | 49 | console.log(`Built at ${Date.now()} (${Date()})`); 50 | return; 51 | } 52 | }); 53 | 54 | -------------------------------------------------------------------------------- /oldguard/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "oldguard", 3 | "version": "1.0.0", 4 | "description": "cheats anew", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node build.js && node server.js" 8 | }, 9 | "author": "PatheticMustan", 10 | "license": "ISC", 11 | "dependencies": { 12 | "esbuild": "^0.14.2", 13 | "esbuild-css-modules-plugin": "^2.0.9", 14 | "react": "^17.0.2", 15 | "react-dom": "^17.0.2", 16 | "sweetalert2": "^11.2.2" 17 | }, 18 | "devDependencies": { 19 | "express": "^4.17.1" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /oldguard/src/app.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: lime; 3 | } -------------------------------------------------------------------------------- /oldguard/src/app.jsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { useState } from "react"; 3 | 4 | import * as ReactDOM from "react-dom"; 5 | 6 | import "./app.css"; 7 | 8 | function App() { 9 | const [showing, setShowing] = useState(false); 10 | 11 | return
12 | reload at {Date.now()}
13 | 14 |
; 15 | } 16 | 17 | // let's inject our menu! 18 | window.onload = _ => { 19 | const container = window.document.getElementById("oldguard") || window.document.body; 20 | ReactDOM.render(, container); 21 | }; -------------------------------------------------------------------------------- /oldguard/testOldguard.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hell yeah, Oldguard 5 | 6 | 7 | 8 | 9 | 10 |

Oldguard!

11 |

Oldguard should pop up somewhere, I think

12 | 13 |
14 | 15 | -------------------------------------------------------------------------------- /typings/backpack.d.ts: -------------------------------------------------------------------------------- 1 | export declare type BackpackItemType = "item" | "mathTownFrame" | "relic" | "fossil" | "follow" | "mount" | "spellRelic" | "weapon" | "outfit" | "boots" | "hat" | "currency" | "mathTownInterior" | "key"; 2 | export declare interface Backpack { 3 | addKeyItem(ID: number, something: number): void; 4 | updated: boolean; 5 | data: BackpackData 6 | } 7 | export declare interface BackpackItem { 8 | /** Item count. */ 9 | ID: number; 10 | [index: string]: number; 11 | N?: number; 12 | } 13 | export declare type BackpackData = { 14 | [type in BackpackItemType]: BackpackItem[] 15 | } -------------------------------------------------------------------------------- /typings/debugMisc.d.ts: -------------------------------------------------------------------------------- 1 | import { Game } from "./game"; 2 | 3 | export declare interface DebugMisc { 4 | addPlayerTimer: null; 5 | attackDamageCache: unknown; 6 | bountyOverrides: unknown; 7 | fakePlayerActions: unknown[]; 8 | fakePlayers: Map; 9 | game: Game; 10 | generatedRandomPlayers: unknown[]; 11 | hatSwitchEvent: null; 12 | stressTests: { 13 | emitters: unknown[]; 14 | playerContainers: unknown[]; 15 | }; 16 | updatePlayerTimer: null; 17 | _joinDelay: unknown; 18 | _playerLimit: null; 19 | disableTimeoutDialogue(): void; 20 | [index: string]: TODO; 21 | } 22 | -------------------------------------------------------------------------------- /typings/game.d.ts: -------------------------------------------------------------------------------- 1 | import { Prodigy } from "./prodigy"; 2 | import { TODO } from "./util"; 3 | import { gameData } from "./gameData"; 4 | 5 | export declare interface Game { 6 | id: number; // Not sure what this does. Seems to be 0. 7 | state: GameState; 8 | input: TODO; 9 | spriteBatch: TODO; 10 | } 11 | export declare interface GameState { 12 | states: GameStates; 13 | current: GameStates[keyof GameStates]["key"]; 14 | callbackContext: { runAwayCallback(): void }; 15 | getCurrentState(): GameStates[keyof GameStates]; 16 | } 17 | export declare interface GameStates { 18 | Boot: BootState; 19 | Loading: GameStatesState; 20 | PVPLoading: GameStatesState; 21 | TileScreen: TileScreenState; 22 | Login: LoginState; 23 | Battle: BattleState; 24 | PVP: PVPState; 25 | Faint: GameStatesState; 26 | CharSelect: GameStatesState; 27 | CharCreate: GameStatesState; 28 | Museum: GameStatesState & any; 29 | DinoDig: GameStatesState; 30 | DanceDance: GameStatesState; 31 | CoOp: GameStatesState; 32 | TestScreen: GameStatesState; 33 | PrefabScene: GameStatesState; 34 | Battle: BattleState; 35 | Login: LoginState; 36 | } 37 | export declare interface GameStatesState { 38 | key: string; 39 | game: Game; 40 | add?: unknown; 41 | } 42 | export declare interface BootState extends GameStatesState { 43 | key: "Boot"; 44 | _gameData: gameData; 45 | _metricsManager: TODO; 46 | } 47 | export declare interface PVPState extends GameStatesState { 48 | key: "PVP"; 49 | endPVP(): void; 50 | } 51 | export declare interface BattleState extends GameStatesState { 52 | key: "Battle"; 53 | startVictory(): void; 54 | teams: TODO[]; 55 | } 56 | export declare interface LoginState extends GameStatesState { 57 | key: "Login"; 58 | _gameObj: Prodigy; 59 | } 60 | export declare interface TileScreenState extends GameStatesState { 61 | key: "TileScreen"; 62 | process(): void; 63 | } -------------------------------------------------------------------------------- /typings/gameContainer.d.ts: -------------------------------------------------------------------------------- 1 | import { Game } from "./game"; 2 | import { TODO } from "./util"; 3 | 4 | type Bindings = 5 | | "Game" 6 | | "LocalizationService" 7 | | "FeatureFlagProvider" 8 | | "EnvironmentProvider" 9 | | "URLProvider" 10 | | "Assets" 11 | | "Loader" 12 | | "IFSMController" 13 | | "FSMFactories" 14 | | "FSMService" 15 | | "FSMDataProvider" 16 | | "CacheExpirationStrategy" 17 | | "CacheStorageStrategy" 18 | | "StoreDataProvider" 19 | | "ChatManager" 20 | | "StoreService" 21 | | "TimeManager" 22 | | "TechnicalMetricsManager" 23 | | "VoucherDataProvider" 24 | | "VoucherService" 25 | | "JWTAuthProvider" 26 | | "SessionTokenAuthProvider" 27 | | "DungeonService" 28 | | "DungeonDataProvider" 29 | | "PVPNetworkHandler" 30 | | "NetworkManager" 31 | | "NicknameFactory" 32 | | "NicknameController" 33 | | "NicknameProvider" 34 | | "DeviceInfoProvider" 35 | | "SocketService" 36 | | "MultiplayerSocket" 37 | | "GameServerSocket" 38 | | "GameServerService" 39 | | "UUIDProvider" 40 | | "LoggedInPlayer" 41 | | "EventBuilder" 42 | | "SurveyController" 43 | | "OptimizelyWrapper" 44 | | "GameEventReceivers" 45 | | "GameEventBroadcaster" 46 | | "GameAvatarDataFactory" 47 | | "GameBattleDataFactory" 48 | | "GameCompleteDataFactory" 49 | | "GameDiscoveryDataFactory" 50 | | "GameQuestionDataFactory" 51 | | "GameSocialDataFactory" 52 | | "ArchivesDungeonGenerator" 53 | | "TowersDungeonGenerator" 54 | | "GameStartDataFactory" 55 | | "GameSinkDataFactory" 56 | | "GameSourceDataFactory" 57 | | "ExternalMethods" 58 | | "MailExtensionController" 59 | | "MailExtension" 60 | | "PlayerService" 61 | | "InputBlocker" 62 | | "FXController" 63 | | "RemoteLogger" 64 | | "PrefabService" 65 | | "PrefabDataProvider" 66 | | "PrefabLoader" 67 | | "SurveyDataProvider" 68 | | "SurveyService" 69 | | "FeatureRequirements" 70 | | "BreadcrumbManager" 71 | | "Items" 72 | | "HttpClient" 73 | | "DuelInviteService" 74 | | "PvPBattleSocketRoom" 75 | | "BattleApiSocket" 76 | | "GeolocationService" 77 | | "MatchmakingService" 78 | | "BattleRoomService" 79 | | "MathTower" 80 | | "FeatureFlags" 81 | | "Storage" 82 | | "StorageSerializer" 83 | | "StoreManager" 84 | | "TowerTownBreadcrumbManager" 85 | | "DefaultItems" 86 | | "Education" 87 | | "DialogueFactory" 88 | | "Events" 89 | | "Cache" 90 | | "AssetLoader" 91 | | "AppearanceFactory" 92 | | "AnalyticsService"; 93 | export declare interface InversifyContainer { 94 | applyCustomMetadataReader(arg0: unknown): unknown; 95 | applyMiddleware(): unknown; 96 | createChild(): unknown; 97 | get(binding: T): T extends keyof Mapping ? Mapping[T] : TODO; 98 | } 99 | export declare interface GameContainer { 100 | inversifyContainer: InversifyContainer; 101 | hasBinding(binding: T): T extends Bindings ? true : false; 102 | get: InversifyContainer["get"]; 103 | } 104 | export declare interface DialogueFactory { 105 | _game: Game; 106 | _hands: Map; 107 | addGuideHand(arg0: unknown, x: number, y: number): unknown; 108 | createBuilder(): InstanceType; 109 | removeGuideHand(hand: unknown): unknown; 110 | showAllDone(arg0: unknown): void; 111 | showCastSpells(arg0: unknown): void; 112 | showChooseLookOfEachFloor(arg0: unknown): void; 113 | showForceCorrectAnswer(arg0: unknown): void; 114 | showSpeedUpBlockPlacement(arg0: unknown): void; 115 | showSwoopyIntroduction(arg0: unknown, arg1: unknown, arg2: unknown): void; 116 | showTutorialCompleted(arg0: unknown): void; 117 | } 118 | export declare interface Dialogue { 119 | condition: null | (() => boolean); 120 | dialogueConfig: { 121 | blockInput: boolean; 122 | dialogueData: { 123 | audio: { 124 | d: number; 125 | s: number; 126 | tag: string; 127 | }; 128 | avatar: { 129 | animationMod: string; 130 | atlas: string; // The character. 131 | frameName: string; // The expression. 132 | spineAttachment: string; 133 | }; 134 | textKey: string; 135 | callback: () => unknown; 136 | 137 | }; 138 | }; 139 | } 140 | export declare class DialogueBuilder { 141 | _controller: TODO; 142 | _events: Dialogue[]; 143 | _showGuideHand: { 144 | _hands: Map; 145 | _game: Game; 146 | }; 147 | 148 | } 149 | f.createBuilder().addDialogue(20).start(true); 150 | export declare interface Mappings { 151 | DialogueFactory: DialogueFactory; 152 | } 153 | -------------------------------------------------------------------------------- /typings/item.d.ts: -------------------------------------------------------------------------------- 1 | import { TODO } from "./util"; 2 | 3 | export declare interface Item extends PartialItem { 4 | assetID: number; 5 | name: string; 6 | data: Partial 7 | gender: number; 8 | metadata: Partial 9 | } // should have ID, type 10 | export declare interface ItemData { 11 | isPurchaseable: boolean; 12 | items: unknown[]; 13 | name: string; 14 | questions: number; 15 | filename: string; 16 | element: string; 17 | damage: number; 18 | type: number; 19 | foreignSpellPools: number[][] 20 | } 21 | export declare interface ItemMetadata { 22 | vIcon: number; 23 | assets: { default: {v: number} } 24 | } 25 | export declare interface PartialItem { 26 | ID: number; 27 | type: T; 28 | } -------------------------------------------------------------------------------- /typings/open.d.ts: -------------------------------------------------------------------------------- 1 | import { PartialItem } from "./item"; 2 | 3 | export declare interface Open { 4 | PopUpModal(prop0: unknown): unknown; 5 | /** Opens the set last name menu, but does nothing. */ 6 | advancedNameChange(prop0: unknown, prop1: unknown, prop2: unknown): unknown; 7 | alert( 8 | prop0: unknown, 9 | prop1: unknown, 10 | prop2: unknown, 11 | prop3: unknown, 12 | prop4: unknown, 13 | prop5: unknown 14 | ): unknown; 15 | /** Opens a broken archive entrance menu. The buttons don't do anything. */ 16 | archiveEntranceMenu(prop0: unknown, prop1: unknown): void; 17 | /** Opens the inventory screen. */ 18 | backpack(): void; 19 | /** Opens a placeholder popup. */ 20 | bannerDialog(prop0: unknown): void; 21 | /** Opens the use item screen that appears in battle. Broken. */ 22 | battlePotionSelect(prop0: unknown): unknown[]; 23 | /** Opens a "choose your boost!" popup. There are no buttons, softlocking the game. */ 24 | boostSelect(prop0: unknown, prop1: unknown): void; 25 | /** Opens the bounty board. */ 26 | bountyBoard(): void; 27 | /** Opens the bounty store. */ 28 | bountyStore(): void; 29 | /** Unknown functionality. Softlocks the game without arguments. Seems to have something to do with players. */ 30 | card(prop0: unknown, prop1: unknown, prop2: unknown): void; 31 | /** Opens the unused spellbook popup. */ 32 | character(): void; 33 | /** Unknown usage. */ 34 | characterDialogue(prop0: unknown, prop1: unknown, prop2: unknown): void; 35 | /** Opens the chat popup. The arguments are not needed. */ 36 | chat(prop0?: unknown): void; 37 | /** Unknown functionality. */ 38 | choosePet(prop0: unknown, prop1: unknown): void; 39 | /** Opens an unknown popup. */ 40 | classModeMessage( 41 | prop0: unknown, 42 | prop1: unknown, 43 | prop2: unknown, 44 | prop3: unknown, 45 | prop4: unknown, 46 | prop5: unknown, 47 | prop6: unknown, 48 | prop7: unknown 49 | ): void; 50 | /** Unknown functionality. */ 51 | cleanup(): void; 52 | /** Closes a menu. */ 53 | close(index: number): void; 54 | /** Closes the chat menu. */ 55 | closeChat(): void; 56 | /** Softlocks the game. */ 57 | coOpModal(prop0: unknown): unknown; 58 | gotItem(item: PartialItem[], prop1: unknown, prop2: unknown, prop3: unknown, prop4: unknown): unknown; 59 | menus: TODO[]; 60 | map(...args: any[]): void; 61 | } 62 | -------------------------------------------------------------------------------- /typings/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ProdigyMathGameHackingTypings", 3 | "version": "1.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /typings/pet.d.ts: -------------------------------------------------------------------------------- 1 | export declare interface Pet { 2 | ID: number; 3 | catchDate?: number; 4 | foreignSpells: number[]; 5 | level: number; 6 | levelCaught?: number; 7 | stars: number; 8 | team?: number; 9 | nickname?: string; 10 | } 11 | -------------------------------------------------------------------------------- /typings/pixi.d.ts: -------------------------------------------------------------------------------- 1 | import { Game } from "./game"; 2 | import { Prodigy } from "./prodigy"; 3 | import { Hack } from "../redirect/global"; 4 | import { gameData } from "./gameData"; 5 | export declare interface PIXI {} 6 | export declare interface Phaser {} 7 | declare global { 8 | const PIXI: PIXI; 9 | const Phaser: Phaser; 10 | const _: Hack 11 | } 12 | -------------------------------------------------------------------------------- /typings/player.d.ts: -------------------------------------------------------------------------------- 1 | import { TODO } from "./util"; 2 | import { Game } from "./game"; 3 | import { Item } from "./item"; 4 | import { Backpack } from "./backpack"; 5 | import { Pet } from "./pet"; 6 | export declare type ItemType = 7 | | "follow" 8 | | "hat" 9 | | "outfit" 10 | | "spellRelic" 11 | | "weapon" 12 | | "boots"; 13 | export declare type Zones = "tower_town"; 14 | export declare class Player { 15 | static ACCOUNT_RESET_ZONE_KEEPERS: Zones[]; 16 | static HP_BONUS: { 17 | A: number; 18 | "A+": number; 19 | "A-": number; 20 | B: number; 21 | "B+": number; 22 | "B-": number; 23 | C: number; 24 | "C+": number; 25 | "C-": number; 26 | }; 27 | static LEVEL_CURVE: { lvl: number, a: number }[] 28 | static enemiesPerLevel(level: number): number; 29 | static getAoeEvolutions(): number[]; 30 | static getAttacksFromCurve(prop0: unknown[], prop1: number, prop2: number): unknown[] 31 | static getAttacksOfType(prop0: unknown, prop1: unknown): unknown[]; 32 | static getEvolutionsFromCurve(prop0: unknown[], prop1: number, prop2: number): unknown[] 33 | static getHeartsFromCurve(prop0: unknown[], prop1: number, prop2: number): number 34 | static getLevelPercent(stars: number): number; 35 | static getSingleShotEvolutions(): number[]; 36 | static levelFromStars(stars: number): number; 37 | static starsToLevel(stars: number): number 38 | static MAX_HEARTS: number 39 | achievements: TODO; 40 | appearance: TODO; 41 | backpack: Backpack; 42 | daily: TODO; 43 | dailyQuestions: TODO; 44 | encounters: TODO; 45 | equipment: TODO; 46 | house: TODO; 47 | kennel: { 48 | addPet(id: number): unknown 49 | data: Pet[]; 50 | petTeam: Pet[]; 51 | }; 52 | onHPChange: TODO; 53 | quests: TODO; 54 | state: TODO; 55 | _remoteLogger: TODO; 56 | tutorial: TODO; 57 | game: Game; 58 | immortal: boolean; 59 | inPVP: boolean; 60 | isClassCodeAttached: boolean; 61 | readonly isFocusModeEnabled: boolean; // Getter 62 | danceID?: unknown; 63 | emoteID?: unknown; 64 | appearanceChanged: boolean; 65 | broadcastId: number; 66 | catchAttempt: number; 67 | chatID: number; 68 | classIDs: number[]; 69 | coOpTeam?: unknown; 70 | currentVideoSkillId?: unknown; 71 | curriculumTreeID: number; 72 | earlyBirdLastChance: boolean; 73 | grade: number; 74 | isOpponent: boolean; 75 | hasUsedTicket: boolean; 76 | /** Membership */ 77 | P: boolean; 78 | justLeveled: boolean; 79 | /** A date ISOString */ 80 | lastVisited: string; 81 | locationSelectionType: string; // home 82 | memberEndDate?: unknown; // possibly Date? 83 | memberPrompt: boolean; 84 | memberShareDate?: unknown; // possibly Date? 85 | /** A date ISOString */ 86 | memberStartDate?: string; 87 | modifiers: { 88 | maxHearts: number; 89 | damage: number; 90 | miss: number; 91 | ignoreElement: number; 92 | potion?: unknown; 93 | }; 94 | overrideClassSelect: boolean; 95 | owners: { 96 | id: number; 97 | ownerID: number; 98 | startDate: number; 99 | }[]; 100 | parentEmail: string; 101 | parentalLink: boolean; 102 | password: string; 103 | playerParents: unknown[]; 104 | playerTeachers: { 105 | id: number; 106 | type: string; 107 | startDate: number; 108 | }[]; 109 | pvpHP: number; 110 | registerDate: Date; 111 | readonly saveEnabled: boolean; // Getter 112 | source?: unknown; 113 | spellStreak: number; 114 | starsEarned: number; 115 | starsReward: number; 116 | starsRewardBase: number; 117 | starsToProcess: number; 118 | data: PlayerData; 119 | team?: unknown; 120 | transformID?: unknown; // Possibly number? 121 | tutorialCompletedThisSession: boolean; 122 | type: string; // Possibly "A" | "B" | "C" | "D" | "F" 123 | updated: boolean; 124 | userID: number; 125 | username: string; 126 | world: { 127 | id: number; 128 | full: number; 129 | name: string; 130 | meta: unknown; // Seems to be {type: "hat", ID: 47} for me. 131 | count: number; 132 | }; 133 | _isFocusModeEnabled: false; 134 | _saveEnabled: true; 135 | name: PlayerName; 136 | addAsset(asset: unknown): void; 137 | addBattle(): void; 138 | addBountyScore(bountyScore: number): void; 139 | addLoss(): void; 140 | addSpell(spell: number): void; 141 | addStars(stars: number, prop1: boolean, prop2: boolean): boolean; 142 | addWin(): void; 143 | anyPetsAboveLevel(level: number): boolean; 144 | canCatch(): boolean; 145 | canSpin(): boolean; 146 | castSpell(prop0: boolean): void; 147 | changeCurrentHearts(prop0: number, prop1: number): void; 148 | changeCurrentHeartsPercent(percent: number): void; 149 | changeEnergy(energy: number): void; 150 | changeGold(gold: number, prop1: boolean): void; 151 | checkVersion(): void; 152 | completeDaily(daily: keyof PlayerData, completed: boolean): void; 153 | completeTower(tower: number): void; 154 | constructor(prop0: unknown); 155 | createDataClone(): Player; 156 | createRandom(): void; 157 | diffAttackSlots(level: number): void; 158 | equip(id: number, type: ItemType): boolean; 159 | evolve(unused0: never, unused1: never): never; 160 | forceSaveCharacter(): void; 161 | getAllAttacks(): number[]; 162 | getAllowsHouseVisitors(): boolean; 163 | getArenaPoints(): number; 164 | getAttacks(): number[]; 165 | getAvailableEvolutions(): unknown[]; // What does this return? 166 | getBaseMaxHearts(): number; 167 | getBattles(): number; 168 | getBountyScore(): number; 169 | getColiseum(): number; 170 | getCurrentBamSpells(): number[]; 171 | getCurrentHearts(): number; 172 | getDailyQuestions(): Player["dailyQuestions"]; 173 | getDamageBonus(): ReturnType; 174 | getDataAndClear(): Partial; 175 | getElement(): "wizard"; 176 | getEnergy(): number; 177 | getEquipmentSpell(): { ID: number; type: unknown; locked: boolean }; 178 | getFirstName(): string; 179 | getGold(): number; 180 | getHeartBonus(): number; 181 | getID(): Player["userID"]; 182 | getLatestClassIDLegacy(): number; 183 | getLevel(): number; 184 | getLevelingCurve(level: number): unknown[]; 185 | getLosses(): number; 186 | getMaxHearts(level: number): number; 187 | getMaxTimeForCurrentMorphMarbleEffect(): number; 188 | getName(): string; 189 | getNameWithoutNickname(): string; 190 | getNativeSpell( 191 | prop0: unknown, 192 | prop1: unknown[], 193 | prop2: unknown, 194 | prop3: unknown 195 | ): unknown; 196 | getNumAttacks(): number; 197 | getNumRelics(): number; 198 | getPercentToLevel(): number; 199 | getPlayerClass(): string; 200 | getPlayerData(): PlayerData; 201 | getRegisterDate(): Date | null; 202 | getSettings(): PlayerData["settings"]; 203 | getSpellAssets(): unknown[]; 204 | getSpellStreak(): Player["spellStreak"]; 205 | getStarReward(): number; 206 | getStarRewardByDamage(damage: number): number; 207 | getStars(): number | null; 208 | getStarsToLevel(): number; 209 | getStatHealth(): number; 210 | getStatPower(): number; 211 | getTeamScore(): number; 212 | getTowerProgress(): number; 213 | getUpdatedData(prop0: unknown, prop1: unknown): unknown; 214 | getWins(): number; 215 | hasCompletedTowerTownTutorial(): boolean; 216 | hasCompletedTutorial(): boolean; 217 | hasHouseItem(item: Item): boolean; 218 | hasMaxQuantityOfItem(type: unknown, item: unknown): boolean; 219 | hasMembership(): Player["it"]; 220 | hasValidatedParentEmail(): boolean; 221 | hasValidatedTeacherEmail(): boolean; 222 | heal(): void; 223 | healTeam(hearts: number): void; 224 | healTeamMember(hearts: number, prop1: unknown, prop2: unknown): void; 225 | init(prop0: unknown): unknown; 226 | initFromProtobuf(prop0: unknown): void; 227 | isBlockedByDarkTowerMemberGate(): boolean; 228 | isItemOwned(item: Item): boolean; 229 | isKnockedOut(): boolean; 230 | isPlayerTransformed(): boolean; 231 | onTutorialComplete(): void; 232 | processDeserter(): void; 233 | processStars(): void; 234 | processTrialMembership(): void; 235 | resetAccount(): void; 236 | resetModifiers(): void; 237 | rewardMembershipPrizes(prop0: unknown): void; 238 | setAllowsHouseVisitors(allow: boolean): void; 239 | setBGMVolume(volume: number): void; 240 | setColiseum(coliseum: number): void; 241 | setData(data: PlayerData): void; 242 | setDefault(gender: "male" | "female"): void; 243 | setEnergy(energy: number): void; 244 | setMemberDebug(): void; 245 | setMembership(player: Player, member: boolean): void; 246 | setParentEmail(email: string): void; 247 | setPlayerClass(playerClass: unknown): void; 248 | setSFXVolume(volume: number): void; 249 | setSpinDate(date: Date): void; 250 | setVoiceVolume(volume: number): void; 251 | setZone(zone: unknown): void; 252 | spinWheel(wheel: 1 | 2): void; 253 | swapSpells(prop0: unknown, prop1: unknown): unknown; 254 | transformPlayer(prop0: unknown, prop1: unknown, prop2: number): void; 255 | unequip(type: ItemType): boolean; 256 | updateMembershipVideoAdData(): void; 257 | updateModifier(type: "potion" | "barrier", modifier: number): void; 258 | validateLevel(): void; 259 | } 260 | export declare interface PlayerName { 261 | generateRandomName(): void; 262 | data: { 263 | firstName: number | null; 264 | lastName: number | null; 265 | middleName: number | null; 266 | nickname: number | null; 267 | }; 268 | gender: "male" | "female"; 269 | localizer: { dataSource: TODO }; 270 | } 271 | export declare class PlayerData { 272 | allowsHouseVisitors: boolean; 273 | arena: number; 274 | atHomeTimestamp: number; 275 | atSchoolTimestamp: number; 276 | battleCounter: number; 277 | bountyScore: number; 278 | daily: { 279 | festivalName: string; 280 | isComplete: boolean; 281 | lastStarted: number; 282 | location: string; 283 | monsterID: number; 284 | }; 285 | deserter: number; 286 | dungeonRunsTimeStamps: { 287 | dungeonName: string; 288 | lastRunTimeStamp: number; 289 | }[]; 290 | energy: number; 291 | gold: number; 292 | hp: number; 293 | lastArchiveRun: number; 294 | level: number; 295 | memberStarsExpirationDate: number; 296 | nm: number; 297 | numSpins1: number; 298 | numSpins2: number; 299 | school: string; 300 | settings: { 301 | bgmVolume: number; 302 | voiceVolume: number; 303 | sfxVolume: number; 304 | }; 305 | spellbook: number[]; 306 | spells: number[]; 307 | spinDate1: number; 308 | spinDate2: number; 309 | stars: number; 310 | startDate: number; 311 | storedMemberStars: number; 312 | team: number; 313 | titanID: number; 314 | tower: number; 315 | trialSkipAvailable: boolean; 316 | trialStartDate: string; 317 | versionID: number; 318 | win: number; 319 | zone: string; 320 | } 321 | // TODO: Get types for unknowns. 322 | -------------------------------------------------------------------------------- /typings/prodigy.d.ts: -------------------------------------------------------------------------------- 1 | import { Game } from "./game"; 2 | import { Player } from "./player"; 3 | import { DebugMisc } from "./debugMisc"; 4 | import { TODO } from "./util"; 5 | import { Open } from "./open"; 6 | import { GameContainer } from "./gameContainer"; 7 | 8 | export declare interface Prodigy { 9 | version: string; 10 | game: Game; 11 | // debugMisc: DebugMisc; 12 | world: TODO; 13 | giftBoxController: TODO; 14 | open: Open; 15 | // debugQuests: TODO; 16 | user: TODO; 17 | pvpNetworkHandler: TODO; 18 | // network: TODO; 19 | classModeController: TODO; 20 | gameContainer: GameContainer; 21 | dialogue: TODO; 22 | notifications: TODO; 23 | battle: TODO; 24 | } -------------------------------------------------------------------------------- /typings/test.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/typings/test.ts -------------------------------------------------------------------------------- /typings/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["./**/*"], 3 | "compilerOptions": { 4 | /* Basic Options */ 5 | // "incremental": true, /* Enable incremental compilation */ 6 | "target": "ES2020", 7 | /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ 8 | "module": "es2020", 9 | "skipLibCheck": true, 10 | /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ 11 | // "lib": [], /* Specify library files to be included in the compilation. */ 12 | // "allowJs": true, /* Allow javascript files to be compiled. */ 13 | // "checkJs": true, /* Report errors in .js files. */ 14 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 15 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 16 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 17 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 18 | // "outFile": "./", /* Concatenate and emit output to single file. */ 19 | // "outDir": "./", /* Redirect output structure to the directory. */ 20 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 21 | // "composite": true, /* Enable project compilation */ 22 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 23 | // "removeComments": true, /* Do not emit comments to output. */ 24 | // "noEmit": true, /* Do not emit outputs. */ 25 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 26 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 27 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 28 | 29 | /* Strict Type-Checking Options */ 30 | "strict": true, 31 | /* Enable all strict type-checking options. */ 32 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 33 | // "strictNullChecks": true, /* Enable strict null checks. */ 34 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 35 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 36 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 37 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 38 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 39 | 40 | /* Additional Checks */ 41 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 42 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 43 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 44 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 45 | 46 | /* Module Resolution Options */ 47 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 48 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 49 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 50 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 51 | // "typeRoots": [], /* List of folders to include type definitions from. */ 52 | // "types": [], /* Type declaration files to be included in compilation. */ 53 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 54 | "esModuleInterop": true, 55 | /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 56 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 57 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 58 | 59 | /* Source Map Options */ 60 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 61 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 62 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 63 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 64 | 65 | /* Experimental Options */ 66 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 67 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 68 | 69 | /* Advanced Options */ 70 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /typings/util.d.ts: -------------------------------------------------------------------------------- 1 | export type TODO = any; -------------------------------------------------------------------------------- /willsCheatMenu/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true 5 | }, 6 | "extends": [ 7 | "eslint:recommended", 8 | "plugin:@typescript-eslint/eslint-recommended", 9 | "standard" 10 | ], 11 | "globals": { 12 | "Atomics": "readonly", 13 | "SharedArrayBuffer": "readonly" 14 | }, 15 | "parser": "@typescript-eslint/parser", 16 | "parserOptions": { 17 | "ecmaVersion": 11, 18 | "sourceType": "module" 19 | }, 20 | "plugins": [ 21 | "@typescript-eslint" 22 | ], 23 | "rules": { 24 | "indent": [ 25 | "error", 26 | "tab" 27 | ], 28 | "linebreak-style": [ 29 | "error", 30 | "windows" 31 | ], 32 | "quotes": [ 33 | "error", 34 | "double" 35 | ], 36 | "semi": [ 37 | "error", 38 | "always" 39 | ], 40 | "no-tabs": "off" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /willsCheatMenu/README.md: -------------------------------------------------------------------------------- 1 | # Will's Cheat Menu 2 | 3 |
4 | 5 | This is the main cheat menu UI for ProdigyMathGameHacking. 6 | Originally made by [MelnDev](https://github.com/MelnDev), now maintained by [ArcerionDev](https://github.com/ArcerionDev) and [PatheticMustan](https://github.com/PatheticMustan). 7 | 8 |
9 | 10 | Usage: Install the hacks, the dropdown should appear in the top left corner after a moment. 11 | 12 | Build / Development: Install dependencies and run `webpack` in the command prompt to compile it. 13 | 14 | ``` 15 | npm i 16 | npm run build 17 | ``` 18 | 19 | We are always looking for new contributors to help maintain the hacks and menu! 20 | -------------------------------------------------------------------------------- /willsCheatMenu/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = api => { 2 | api.cache(true); 3 | const presets = [ 4 | [ 5 | "@babel/preset-env", 6 | { 7 | targets: { 8 | esmodules: true, 9 | }, 10 | }, 11 | ], 12 | ]; 13 | const plugins = ["@babel/plugin-proposal-optional-chaining"]; 14 | return { 15 | presets, 16 | plugins, 17 | }; 18 | }; 19 | -------------------------------------------------------------------------------- /willsCheatMenu/hot-reload.mjs: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | import { Server } from "socket.io"; 3 | import http from "http"; 4 | import { exec } from "child_process"; 5 | 6 | const app = http.createServer(); 7 | 8 | const io = new Server(app, { 9 | cors: { 10 | origin: "*", 11 | methods: ["GET", "POST"], 12 | } 13 | }); 14 | 15 | fs.watch("./src/", { recursive: true }, () => { 16 | exec("npx webpack --mode development", (error, stdout) => { 17 | if (error) { 18 | console.log(stdout); 19 | throw error; 20 | } 21 | fs.readFile("./dist/bundle.js", (err, data) => { 22 | if (err) throw err; 23 | io.emit("update", data.toString()); 24 | }); 25 | }); 26 | }); 27 | 28 | app.listen(3001, () => console.log("Listening on port 3001")); 29 | -------------------------------------------------------------------------------- /willsCheatMenu/loader.js: -------------------------------------------------------------------------------- 1 | (async() => { 2 | eval(await (await fetch("https://raw.githubusercontent.com/PatheticMustan/ProdigyMathGameHacking/HEAD/willsCheatMenu/dist/bundle.js")).text()) 3 | })() -------------------------------------------------------------------------------- /willsCheatMenu/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "willscheatmenu", 3 | "version": "1.0.0", 4 | "description": "will's cheat menu lmao", 5 | "main": "dist/bundle.js", 6 | "scripts": { 7 | "setup": "npm install", 8 | "build": "webpack --config webpack.config.js", 9 | "dev:start": "node hot-reload.mjs" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/Prodigy-Hacking/ProdigyMathGameHacking/tree/master/willsCheatMenu" 14 | }, 15 | "keywords": [ 16 | "wills", 17 | "cheat", 18 | "menu" 19 | ], 20 | "author": "Will", 21 | "license": "ISC", 22 | "dependencies": { 23 | "@babel/core": "^7.13.10", 24 | "@babel/plugin-proposal-optional-chaining": "^7.13.8", 25 | "@babel/preset-env": "^7.13.10", 26 | "autoprefixer": "^10.2.5", 27 | "babel": "^6.23.0", 28 | "babel-loader": "^8.2.2", 29 | "css-loader": "^5.1.2", 30 | "postcss": "^8.2.10", 31 | "postcss-loader": "^5.2.0", 32 | "sass": "^1.32.8", 33 | "sass-loader": "^11.0.1", 34 | "socket.io": "^4.1.3", 35 | "socket.io-client": "^4.1.3", 36 | "source-map-loader": "^2.0.1", 37 | "style-loader": "^2.0.0", 38 | "sweetalert2": "^10.15.5", 39 | "ts-loader": "^8.0.18", 40 | "typescript": "^4.2.3", 41 | "webpack": "^5.67.0", 42 | "webpack-cli": "^4.5.0" 43 | }, 44 | "devDependencies": { 45 | "@typescript-eslint/eslint-plugin": "^4.4.1", 46 | "@typescript-eslint/parser": "^4.4.1", 47 | "eslint": "^7.11.0", 48 | "eslint-config-standard": "^16.0.3" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /willsCheatMenu/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('autoprefixer') 4 | ] 5 | }; -------------------------------------------------------------------------------- /willsCheatMenu/src/assets/academy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/willsCheatMenu/src/assets/academy.png -------------------------------------------------------------------------------- /willsCheatMenu/src/assets/archives.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/willsCheatMenu/src/assets/archives.png -------------------------------------------------------------------------------- /willsCheatMenu/src/assets/bonfire_spire.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/willsCheatMenu/src/assets/bonfire_spire.png -------------------------------------------------------------------------------- /willsCheatMenu/src/assets/crystal_caverns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/willsCheatMenu/src/assets/crystal_caverns.png -------------------------------------------------------------------------------- /willsCheatMenu/src/assets/darktower.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/willsCheatMenu/src/assets/darktower.png -------------------------------------------------------------------------------- /willsCheatMenu/src/assets/dyno.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/willsCheatMenu/src/assets/dyno.png -------------------------------------------------------------------------------- /willsCheatMenu/src/assets/earthtower.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/willsCheatMenu/src/assets/earthtower.png -------------------------------------------------------------------------------- /willsCheatMenu/src/assets/elemental_guardian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/willsCheatMenu/src/assets/elemental_guardian.png -------------------------------------------------------------------------------- /willsCheatMenu/src/assets/forest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/willsCheatMenu/src/assets/forest.png -------------------------------------------------------------------------------- /willsCheatMenu/src/assets/house.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/willsCheatMenu/src/assets/house.png -------------------------------------------------------------------------------- /willsCheatMenu/src/assets/lamplight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/willsCheatMenu/src/assets/lamplight.png -------------------------------------------------------------------------------- /willsCheatMenu/src/assets/shipwreck_shore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/willsCheatMenu/src/assets/shipwreck_shore.png -------------------------------------------------------------------------------- /willsCheatMenu/src/assets/shiverchill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/willsCheatMenu/src/assets/shiverchill.png -------------------------------------------------------------------------------- /willsCheatMenu/src/assets/skywatch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/willsCheatMenu/src/assets/skywatch.png -------------------------------------------------------------------------------- /willsCheatMenu/src/assets/tower_town.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/willsCheatMenu/src/assets/tower_town.png -------------------------------------------------------------------------------- /willsCheatMenu/src/assets/toyzone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/63fa9c43681c4734d585a95777a214af7709b44e/willsCheatMenu/src/assets/toyzone.png -------------------------------------------------------------------------------- /willsCheatMenu/src/declarations.d.ts: -------------------------------------------------------------------------------- 1 | import {} from "../../typings/pixi"; -------------------------------------------------------------------------------- /willsCheatMenu/src/hacks/battle.ts: -------------------------------------------------------------------------------- 1 | import { Toast, NumberInput } from "../utils/swal"; 2 | import { Hack, category, Toggler } from "../index"; 3 | import { _, prodigy, game } from "../utils/util"; 4 | 5 | new Toggler(category.battle, "Disable math").setEnabled(async () => { 6 | _.constants.constants["GameConstants.Debug.EDUCATION_ENABLED"] = false; 7 | }).setDisabled(async () => { 8 | _.constants.constants["GameConstants.Debug.EDUCATION_ENABLED"] = true; 9 | }); 10 | 11 | new Hack(category.battle, "Escape Battle", "Escape any battle!").setClick(async () => { 12 | const currentState = game.state.current; 13 | if (currentState === "PVP") Object.fromEntries(_.instance.game.state.states).PVP.endPVP(); 14 | else if (currentState === "CoOp") prodigy.world.$(_.player.data.zone); 15 | else if (!["Battle", "SecureBattle"].includes(currentState)) { 16 | Toast.fire( 17 | "Invalid State.", 18 | "You are currently not in a battle.", 19 | "error" 20 | ); 21 | } else { 22 | Object.fromEntries(_.instance.game.state.states)[currentState].runAwayCallback(); 23 | Toast.fire( 24 | "Escaped!", 25 | "You have successfully escaped from the battle.", 26 | "success" 27 | ); 28 | } 29 | }); 30 | 31 | new Hack(category.battle, "Win Battle", "Instantly win a monster battle.").setClick(async () => { 32 | const currentState = game.state.current; 33 | if (currentState === "PVP" || currentState === "CoOp") { 34 | return Toast.fire( 35 | "Invalid State.", 36 | "PVP is not supported for this hack.", 37 | "error" 38 | ); 39 | } else if (currentState === "Battle") { 40 | Object.fromEntries(_.instance.game.state.states).Battle.startVictory(); 41 | Toast.fire( 42 | "Victory!", 43 | "You have successfully won the battle.", 44 | "success" 45 | ); 46 | } else if (currentState === "SecureBattle") { 47 | Object.fromEntries(_.instance.game.state.states).SecureBattle.battleVictory(); 48 | Toast.fire( 49 | "Victory!", 50 | "You have successfully won the battle.", 51 | "success" 52 | ); 53 | } else { 54 | Toast.fire( 55 | "Invalid State.", 56 | "You are currently not in a battle.", 57 | "error" 58 | ); 59 | } 60 | }); 61 | 62 | new Hack(category.battle, "Set Battle Hearts", "Sets your hearts in battle. Automatically raises max hearts.").setClick(async () => { 63 | const hp = await NumberInput.fire("Health Amount", "How much HP do you want?", "question"); 64 | if (hp.value === undefined) return; 65 | _.player.getMaxHearts = () => +hp.value; 66 | _.player.pvpHP = +hp.value; 67 | _.player.data.hp = +hp.value; 68 | Toast.fire("Success!", "Your hearts have been set.", "success"); 69 | }); 70 | new Hack(category.battle, "Fill Battle Energy", "Fills up your battle energy.").setClick(async () => { 71 | const state = game.state.getCurrentState(); 72 | if (!("teams" in state)) return Toast.fire("Error", "You are currently not in a battle.", "error"); 73 | state.teams[0].setEnergy(99); 74 | Toast.fire("Success!", "Your battle energy has been filled.", "success"); 75 | }); 76 | 77 | new Hack(category.battle, "Heal Team").setClick(async () => { 78 | const currentState = game.state.current; 79 | if (["Battle", "SecureBattle"].includes(currentState)) { 80 | _.player.heal(); 81 | Toast.fire( 82 | "Success!", 83 | "Your team has been healed successfully!", 84 | "success" 85 | ); 86 | } else { 87 | Toast.fire( 88 | "Invalid State.", 89 | "Your are currently not in a battle.", 90 | "error" 91 | ); 92 | } 93 | }); 94 | -------------------------------------------------------------------------------- /willsCheatMenu/src/hacks/inventory.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import { Hack, category } from "../index"; 3 | import { Swal, Toast, Confirm, NumberInput } from "../utils/swal"; 4 | import { _, saveCharacter } from "../utils/util"; 5 | import { Item } from "../../../typings/item"; 6 | 7 | const names = ["Boots", "Buddies", "Fossils", "Hats", "Items", "Key Items", "Tower Town Frames", "Tower Town Interiors", "Mounts", "Outfits", "Relics", "Weapons", "Currencies"]; 8 | const ids = ["boots", "follow", "fossil", "hat", "item", "key", "mathTownFrame", "mathTownInterior", "mount", "outfit", "spellRelic", "weapon", "currency"]; 9 | const itemify = (item: Item[], amount: number) => 10 | item.map(x => ({ 11 | ID: x.ID, 12 | N: amount 13 | })).filter(v => v !== undefined); 14 | 15 | // typescript is picky af 16 | 17 | // sorry for spamming ts-ignore 18 | new Hack(category.inventory, "Item stacker").setClick(async () => { 19 | const num = await NumberInput.fire("Amount", "How many of every item would you like?", "question"); 20 | if (!num.value) return; 21 | if (!(await Confirm.fire("Are you sure you want to get all items in the game?")).value) return; 22 | 23 | ids.forEach(id => { 24 | _.player.backpack.data[id] = itemify(_.gameData[id].filter(l => id === "follow" ? ![125,126,127,128,129,134,135,136,137].includes(l.ID) : l), num.value); 25 | }); 26 | _.gameData.dorm.forEach(x => 27 | _.player.house.data.items[x.ID] = { A: [], N: num.value } 28 | ); 29 | 30 | // Remove bounty notes (#229) 31 | const bountyIndex = () => _.player.backpack.data.item.findIndex(v => v.ID === 84 || v.ID === 85 || v.ID === 86); 32 | while (bountyIndex() > -1) _.player.backpack.data.item.splice(bountyIndex(), 1); 33 | Toast.fire("Success!", "All items added!", "success"); 34 | }); 35 | new Hack(category.inventory, "Clear inventory").setClick(async () => { 36 | if (!(await Confirm.fire("Are you sure you want to clear your inventory?")).value) return; 37 | Object.keys(_.player.backpack.data).forEach(d => _.player.backpack.data[d] = []) 38 | Toast.fire("Success!", "Inventory cleared.", "success"); 39 | }) 40 | 41 | new Hack(category.inventory, "Selector (Basic)").setClick(async () => { 42 | // @ts-ignore 43 | const val = await Swal.fire({ 44 | title: "What would you like to obtain?", 45 | input: "select", 46 | inputOptions: names, 47 | inputPlaceholder: "Select...", 48 | inputValidator: (res: any) => res ? "" : "Please select which you'd like to obtain.", 49 | showCancelButton: true 50 | }).then(async val => { 51 | const num = parseInt(val.value); 52 | const name = names[num]; 53 | const id = ids[num]; 54 | if (!name) return; 55 | const amt = await NumberInput.fire("Amount", "How many each object would you like?", "question"); 56 | if (!amt.value) return; 57 | if (!(await Confirm.fire(`Are you sure you want to get all ${name.toLowerCase()}?`)).value) return; 58 | // @ts-ignore 59 | _.player.backpack.data[id] = itemify(_.gameData[id].filter(a => {return id === 'follow' ? ![125,126,127,128,129,134,135,136,137].includes(a.ID) : a}), amt.value); 60 | Toast.fire( 61 | `${name} Added!`, 62 | `All ${name.toLowerCase()} have been added to your inventory!`, 63 | "success" 64 | ); 65 | saveCharacter(); 66 | }); 67 | }); 68 | new Hack(category.inventory, "Selector (Advanced)", "Choose a specific object and quantity to obtain.").setClick(async () => { 69 | // @ts-ignore 70 | const val = await Swal.fire({ 71 | title: "What would you like to obtain?", 72 | input: "select", 73 | inputOptions: names, 74 | inputPlaceholder: "Select...", 75 | inputValidator: (res: any) => res ? "" : "Please select which you'd like to obtain.", 76 | showCancelButton: true 77 | }).then(async val => { 78 | if (!_.gameData[ids[val.value]]) return; 79 | const objs : [] = []; 80 | // @ts-ignore 81 | _.gameData[ids[val.value]].forEach(elem => { objs.push(elem.data.name); }); 82 | // @ts-ignore 83 | const spec = await Swal.fire({ 84 | title: `What specific object categorized as ${names[val.value].toLowerCase()} would you like to get?`, 85 | input: "select", 86 | inputOptions: objs, 87 | inputPlaceholder: "Select...", 88 | inputValidator: (res: any) => res ? "" : "Please select which you'd like to get.", 89 | showCancelButton: true 90 | }).then(async spec => { 91 | const correct = parseInt(spec.value); 92 | if (!_.gameData[ids[val.value]][correct]) return; 93 | const amt = await NumberInput.fire("Amount", "How many of the object would you like?", "question"); 94 | if (!amt.value) return; 95 | 96 | // @ts-ignore 97 | if (_.player.backpack.data[ids[val.value]].findIndex(e => e.ID === _.gameData[ids[val.value]][correct].ID) === -1) { 98 | _.player.backpack.data[ids[val.value]].push({ 99 | ID: _.gameData[ids[val.value]][correct].ID, 100 | N: amt.value 101 | }); 102 | } else { 103 | // @ts-ignore 104 | const num = _.player.backpack.data[ids[val.value]].findIndex(e => e.ID === _.gameData[ids[val.value]][correct].ID); 105 | } 106 | 107 | Toast.fire(`${names[val.value]} Added!`, `Your selected ${names[val.value].toLowerCase()} have been added.`, "success"); 108 | saveCharacter(); 109 | }); 110 | }); 111 | }); 112 | new Hack(category.inventory, "Get all runes").setClick(async () => { 113 | if (!(await Confirm.fire({ 114 | title: "Hang on!", 115 | html: "This feature is in beta. Using this could break your account in a specific way. This should be used for experimentation only.

Proceed?", 116 | icon: "warning" 117 | })).value) return; 118 | 119 | const amount = parseInt((await NumberInput.fire({ 120 | title: "Amount", 121 | text: "How many of each would you like?", 122 | icon: "question", 123 | inputValidator: (res: any) => res ? "" : "Please select which you'd like to get." 124 | })).value); 125 | if (isNaN(amount)) return; 126 | let mod; 127 | 128 | Array.from(_.instance.prodigy.gameContainer._inversifyContainer._bindingDictionary._map).forEach(e => { 129 | try { 130 | if (_.instance.prodigy.gameContainer.get(e[0]).battleData) { 131 | mod = e[0]; 132 | } 133 | } catch { 134 | console.log(`Error for ${e[0]}`); 135 | } 136 | }); 137 | 138 | const runeify = (item, amount) => 139 | item.map(x => ({ 140 | ID: x.ID, 141 | quantity: amount 142 | })).filter(v => v !== undefined); 143 | 144 | _.instance.prodigy.gameContainer.get(mod).battleData._secureCharacterState._data.inventory.orb = runeify(_.gameData.orb, amount); 145 | Toast.fire("Runes Added!", "Your runes have been added!", "success"); 146 | }); 147 | 148 | new Hack(category.inventory, "Obtain All Furniture").setClick(async () => { 149 | const amt = await NumberInput.fire("Amount", "How many of each piece of furniture would you like?", "question"); 150 | if (!amt.value) return; 151 | if (!(await Confirm.fire("Are you sure you want to get all furniture?")).value) return; 152 | _.gameData.dorm.forEach(x => 153 | _.player.house.data.items[x.ID] = { A: [], N: amt.value } 154 | ); 155 | Toast.fire("Furniture Added!", "All furniture has been added to your inventory!", "success"); 156 | }); 157 | 158 | new Hack(category.inventory, "Obtain All Mounts", "This gives you the Fluffy Cloud and the Rainbow Cloud.").setClick(async () => { 159 | _.player.backpack.data.mount = itemify(_.gameData.mount, 1); 160 | Toast.fire("Mounts Added!", "All mounts have been added to your inventory!"); 161 | }); 162 | 163 | /* 164 | const inventoryHack = (name: string, id: BackpackItemType, amount: number = 1) => { 165 | new Hack(category.inventory, `Obtain All ${name}`).setClick(async () => { 166 | if (!(await Confirm.fire(`Are you sure you want to get all ${name}?`)).value) return; 167 | _.player.backpack.data[id] = itemify(_.gameData[id], amount); 168 | Toast.fire( 169 | `${name} Added!`, 170 | `All ${name.toLowerCase()} have been added to your inventory!`, 171 | "success" 172 | ); 173 | }); 174 | }; 175 | inventoryHack("Boots", "boots"); 176 | inventoryHack("Buddies", "follow"); 177 | inventoryHack("Fossils", "fossil", VERY_LARGE_NUMBER); 178 | inventoryHack("Hats", "hat"); 179 | inventoryHack("Items", "item", VERY_LARGE_NUMBER); 180 | inventoryHack("Key Items", "key", VERY_LARGE_NUMBER); 181 | inventoryHack("Math Town Frames", "mathTownFrame", VERY_LARGE_NUMBER); 182 | inventoryHack("Math Town Interiors", "mathTownInterior", VERY_LARGE_NUMBER); 183 | inventoryHack("Mounts", "mount"); 184 | inventoryHack("Outfits", "outfit"); 185 | inventoryHack("Relics", "relic"); 186 | inventoryHack("Spell Relics", "spellRelic"); 187 | inventoryHack("Weapons", "weapon"); 188 | inventoryHack("Currency", "currency", VERY_LARGE_NUMBER); 189 | 190 | new Hack(category.inventory, "Obtain All Furniture").setClick(async () => { 191 | if (!(await Confirm.fire("Are you sure you want to get all furniture?")).value) return; 192 | _.gameData.dorm.forEach(x => 193 | _.player.house.data.items[x.ID] = {A: [], N: VERY_LARGE_NUMBER} 194 | ) 195 | Toast.fire("Furniture Added!", "All furniture have been added to your inventory!", "success"); 196 | 197 | }); 198 | */ 199 | 200 | new Hack(category.inventory, "Remove item").setClick(async () => { 201 | const category = await Swal.fire({ 202 | title: "What category would you like to remove an item from?", 203 | input: "select", 204 | inputOptions: names, 205 | inputPlaceholder: "Select...", 206 | inputValidator: (res: any) => res ? "" : "Please select which you'd like to obtain.", 207 | showCancelButton: true 208 | }); 209 | if (!_.gameData[ids[category.value]]) return; 210 | const objs = _.gameData[ids[category.value]].map(elem => elem.data.name); 211 | let item = await Swal.fire({ 212 | title: `What specific object categorized as ${names[category.value].toLowerCase()} would you like to remove?`, 213 | input: "select", 214 | inputOptions: objs, 215 | inputPlaceholder: "Select...", 216 | inputValidator: (res: any) => res ? "" : "Please select which you'd like to get.", 217 | showCancelButton: true 218 | }); 219 | item = parseInt(item.value); 220 | if (!_.gameData[ids[category.value]][item]) return; 221 | const amt = await NumberInput.fire("Amount", "How many of the object would you like to remove?", "question"); 222 | if (!amt.value) return; 223 | if (_.player.backpack.data[ids[category.value]].findIndex(e => e.ID === _.gameData[ids[category.value]][item].ID) === -1) { 224 | await Swal.fire("Item Does Not Exist", `You do not have any ${_.gameData[ids[category.value]][item].name}.`, "error"); 225 | return; 226 | } 227 | 228 | const num = _.player.backpack.data[ids[category.value]].findIndex(e => e.ID === _.gameData[ids[category.value]][item].ID); 229 | _.player.backpack.data[ids[category.value]][num].N -= parseInt(amt.value); 230 | if (_.player.backpack.data[ids[category.value]][num].N <= 0) { 231 | _.player.backpack.data[ids[category.value]].splice(num, 1); // if the amount is 0 or below then the item should not exist 232 | } 233 | 234 | Toast.fire("Removed!", `Successfully removed ${amt.value} ${_.gameData[ids[category.value]][item].name}!`, "success"); 235 | saveCharacter(); 236 | }); 237 | -------------------------------------------------------------------------------- /willsCheatMenu/src/hacks/location.ts: -------------------------------------------------------------------------------- 1 | import { Hack, category } from "../index"; 2 | import { NumberInput, Swal, Toast } from "../utils/swal"; 3 | import { _, locations, prodigy } from "../utils/util"; 4 | 5 | new Hack(category.location, "Teleport To Map (interactive)").setClick( 6 | async () => { 7 | const radioPopup = Swal.mixin({ 8 | focusConfirm: false, 9 | showCancelButton: true, 10 | preConfirm: () => { 11 | return document 12 | .querySelector(".radioDiv[checked]") 13 | ?.getAttribute("zone"); 14 | } 15 | }); 16 | const container = document.createElement("div"); 17 | container.classList.add("radioContainer"); 18 | for (const zone of Object.keys(prodigy.world.zones)) { 19 | const radio = document.createElement("DIV"); 20 | radio.classList.add("radioDiv"); 21 | radio.setAttribute("zone", zone); 22 | const locationURL = locations[zone as keyof typeof locations]; 23 | if (locationURL) { radio.style.backgroundImage = `url(${locationURL})`; } else radio.innerText = zone; 24 | radio.onclick = () => { 25 | document 26 | .querySelectorAll(".radioDiv[checked]") 27 | .forEach(x => x.removeAttribute("checked")); 28 | radio.setAttribute("checked", ""); 29 | }; 30 | container.append(radio); 31 | } 32 | const zone = await radioPopup.fire({ 33 | title: "Teleport Zone", 34 | html: container, 35 | customClass: { 36 | popup: "radioSwal" 37 | } 38 | }); 39 | if (!zone.value) return; 40 | const mapList = Object.keys( 41 | prodigy.world.zones[zone.value].maps 42 | ); 43 | const area = await Swal.fire({ 44 | input: "select", 45 | inputOptions: new Map(mapList.map(x => [x, x])), 46 | title: "Map", 47 | text: "Which map in the zone do you want to teleport to?" 48 | }); 49 | if (!area.value) return; 50 | 51 | // fix #1158 52 | const x = (await NumberInput.fire("Please enter the x to teleport to. (Try 500?)")).value || 500; 53 | const y = (await NumberInput.fire("Please enter the y to teleport to. (Try 500?)")).value || 500; 54 | 55 | prodigy.world.zones[zone.value].teleport(area.value, x, y, {}, {}) 56 | Toast.fire("Teleported", "You have been teleported!", "success"); 57 | } 58 | ); 59 | 60 | function toHouse (userID: number) { 61 | if (_.player.userID !== userID) { 62 | const friendCount = _.instance.prodigy.friendsListNetworkHandler.friendsList.length; 63 | const classMates = _.instance.prodigy.friendsListNetworkHandler.classList.length; 64 | 65 | _.instance.prodigy.gameContainer.get("2e1-e659") 66 | .create("house-visit", "click", "hub", friendCount, classMates, null, null, userID) 67 | .broadcast(); 68 | } 69 | const zone = _.instance.prodigy.world.getZone(_.instance.prodigy.world.getCurrentZone()); 70 | if (!zone) return Swal.fire({ title: "Error", text: "You are not in a zone!", icon: "error" }); 71 | zone.handleLeaving(2, () => teleportToHouse(userID)); 72 | } 73 | 74 | function teleportToHouse (userID: number) { 75 | _.instance.prodigy.loading(true); 76 | 77 | const responseCallback = (data: any) => { 78 | const playerData = data !== null && data !== undefined ? data[userID] : null; 79 | 80 | if (playerData !== null && playerData.house !== undefined && playerData.house !== null) { 81 | _.instance.prodigy.loading(false); 82 | const house = _.cloneDeep(_.player.house); 83 | house.setItems(playerData.house); 84 | if (!(playerData.data.allowsHouseVisitors !== undefined && playerData.data.allowsHouseVisitors !== null ? playerData.data.allowsHouseVisitors : false)) { 85 | return Swal.fire(`Teleporting to ${userID} is not allowed.`, "Try another user.", "error"); 86 | } 87 | _.instance.prodigy.world._("house", null, null, { house, getAllowsHouseVisitors: () => playerData.data.allowsHouseVisitors !== undefined && playerData.data.allowsHouseVisitors !== null ? playerData.data.allowsHouseVisitors : false, setAllowsHouseVisitors: (v: boolean) => { playerData.data.allowsHouseVisitors = v; } }); 88 | } 89 | }; 90 | 91 | _.network.getCharData(userID.toString(), ["house", "data"], responseCallback, responseCallback); 92 | } 93 | 94 | new Hack(category.location, "Teleport to house by userID").setClick(async () => { 95 | const userID = (await NumberInput.fire("Please enter the userID.")).value; 96 | if (!userID) return; 97 | toHouse(userID); 98 | Toast.fire("Teleported!", "You have been teleported!", "success"); 99 | }); 100 | 101 | new Hack(category.location, "Get Map Location").setClick(async () => { 102 | Swal.fire({ 103 | title: "Map Location", 104 | html: `You are at
${_.player.data.zone} .
You can save this to get to the same zone.`, 105 | icon: "info" 106 | }); 107 | }); 108 | 109 | /* 110 | new Hack(category.location, "Teleport To Dark Tower Floor").setClick( 111 | async () => { 112 | const floor = await NumberInput.fire( 113 | "Dark Tower Floor", 114 | "What floor do you want to teleport to?", 115 | "question" 116 | ); 117 | if (floor.value === undefined) return; 118 | prodigy.debugMisc.tpTowerFloor(+floor.value); 119 | Toast.fire( 120 | "Success!", 121 | "You have been teleport to the requested floor." 122 | ); 123 | } 124 | ); 125 | 126 | new Hack( 127 | category.location, 128 | "Unlock All Zones (school)", 129 | "Unlocks all the zones that are locked in school." 130 | ).setClick(async () => { 131 | prodigy.classModeController.lockedZones = 0; 132 | Toast.fire("Success!", "All zones are now unlocked that were locked in school.", "success") 133 | }); 134 | */ 135 | -------------------------------------------------------------------------------- /willsCheatMenu/src/hacks/minigame.ts: -------------------------------------------------------------------------------- 1 | import { category, Toggler } from "../index"; 2 | import { _ } from "../utils/util"; 3 | 4 | new Toggler(category.minigames, "20x Walk Speed", "Walk really fast!").setEnabled(async () => { 5 | _.instance.game.state.states.get("DinoDig").walkSpeed = 20; 6 | }).setDisabled(async () => { 7 | _.instance.game.state.states.get("DinoDig").walkSpeed = 1.5; 8 | }); 9 | -------------------------------------------------------------------------------- /willsCheatMenu/src/hacks/misc.ts: -------------------------------------------------------------------------------- 1 | import { Toast, Confirm } from "../utils/swal"; 2 | import { Hack, category, Toggler } from "../index"; 3 | import { _ } from "../utils/util"; 4 | 5 | new Hack(category.misc, "Skip Tutorial").setClick(async () => { 6 | const setQuest = (t: string, i: number, n?: unknown, e?: unknown) => { 7 | _.instance.prodigy.world.getZone(t).testQuest(i, n, e); 8 | try { 9 | Object.fromEntries(_.instance.game.state.states).TileScreen.process(); 10 | } catch {} 11 | }; 12 | 13 | setQuest("house", 2); 14 | setQuest("academy", 2); 15 | _.player.state.set("tutorial-0", 4); 16 | _.player.backpack.addKeyItem(13, 0); 17 | _.player.tutorial.data.menus[14] = [1]; 18 | _.instance.prodigy.open.map(true, []); 19 | _.player.onTutorialComplete(); 20 | _.player.data.level = Math.max(_.player.data.level, 5); 21 | }); 22 | /* 23 | new Hack(category.misc, "Disable Timeout Dialog").setClick(async () => { 24 | prodigy.debugMisc.disableTimeoutDialogue(); 25 | }); 26 | */ 27 | 28 | new Toggler(category.misc, "Disable Monster Encounters").setEnabled(async () => { 29 | _.constants.constants["GameConstants.Debug.SCALE_ENCOUNTER_DISTANCE"] = 0; 30 | }).setDisabled(() => { 31 | _.constants.constants["GameConstants.Debug.SCALE_ENCOUNTER_DISTANCE"] = 1; 32 | }); 33 | 34 | new Toggler(category.misc, "Skip enemy turn").setEnabled(async () => { 35 | _.constants.constants["GameConstants.Battle.SKIP_ENEMY_TURN"] = true; 36 | }).setDisabled(() => { 37 | _.constants.constants["GameConstants.Battle.SKIP_ENEMY_TURN"] = false; 38 | }); 39 | 40 | new Hack(category.misc, "Bobbify", "Converts your account into Bobby Fancywoman.").setClick(async () => { 41 | if (!( 42 | await Confirm.fire("Are you sure you want your account to be turned into Bobby Fancywoman?", "This action is not reversable.") 43 | ).value) return; 44 | 45 | _.player.name.data.nickname = null; 46 | _.player.name.data.firstName = 44; 47 | _.player.name.data.middleName = 754; 48 | _.player.name.data.lastName = 882; 49 | _.player.data.stars = -1e22; 50 | _.player.data.level = 69; 51 | 52 | _.player.appearance.setGender("male"); 53 | _.player.appearance.setEyeColor(1); 54 | _.player.appearance.setFace(4); 55 | _.player.appearance.setHair(19, 1); 56 | _.player.appearance.setSkinColor(1); 57 | _.player.equipment.setFollow(19); 58 | _.player.equipment.setHat(19); 59 | _.player.equipment.setBoots(19); 60 | _.player.equipment.setOutfit(19); 61 | _.player.equipment.setWeapon(19); 62 | Toast.fire("Bobbified!", "You are now Bobby Fancywoman.", "success"); 63 | }); 64 | 65 | new Hack(category.misc, "Reset Account", "Completely resets your account.").setClick(async () => { 66 | if (!(await Confirm.fire("Are you sure you want to reset your account?", "This action is not reversable.")).value) return; 67 | _.player.resetAccount(); 68 | }); 69 | 70 | 71 | 72 | /* we'll miss you 73 | new Hack(category.misc, "OwO", "Click it and find out. It doesn't bite.").setClick(async () => { 74 | // @ts-ignore 75 | // eslint-disable-next-line 76 | Object.chance = t => { const e = {}; let r = 0; for (const n of Object.keys(t).sort((t, r) => e[t] - e[r]))e[n] = [], e[n][0] = r + 1, e[n][1] = t[n] + r, r = t[n] + r; return e; }, Object.random = t => { const e = Object.values(t); const r = e[e.length - 1][1]; const n = Math.randint(r); return Object.reverse(t)[e.find(t => n >= t[0] && n <= t[1])]; }, Array.prototype.join = function (t = ",") { return typeof t === "string" ? this.reduce((e, r, n, o) => e + (n < this.length - 1 ? r + t : r), "") : t instanceof Function ? this.reduce((e, r, n, o) => e + (n < this.length - 1 ? r + t(o[n], n, o) : r), "") : void 0; }, Array.prototype.leftJoin = function (t = ",") { return typeof t === "string" ? this.reduce((e, r, n) => e + (n ? t + r : r), "") : t instanceof Function ? this.reduce((e, r, n, o) => e + (n ? t(o[n], n, o) + r : r), "") : void 0; }, String.UWUFX = t => { const e = Object.chance({ "owo :3": 20, "✧w✧": 20, UwU: 20, OwO: 10, rawr: 10, "uwu :3": 5, ":3 meow": 15, ":3": 15, X3: 15, "*purrs*": 15, owo: 15, uwu: 15, "^w^": 15, "x3 rawr": 15, owowowowo: 15 }); return t.split(" ").leftJoin((t, e) => Math.floor(6 * Math.random()) === 0 && /[A-Za-z]/.test(t[0]) ? ` ${t[0]}-` : " ").split(" ").join((t, r) => Math.floor(5 * Math.random()) === 0 ? ` ${Object.random(e)} ` : " "); }, String.UWUTable = { y: "wy", l: "w", r: "w", ss: "zs", n: "nw", ove: "uv", ome: "um", x: "ks", com: "cum", stu: "stew", au: "aw" }, Math.randint = (t, e = 0) => Math.floor(Math.random() * t - e) + e, String.prototype.escapeRegex = function () { return this.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); }, String.prototype.replaceAll = function (t, e) { return this.replace(new RegExp(t.toString().escapeRegex(), "gi"), t => e); }, Object.fromArrays = (t, e) => { const r = {}; return t.forEach((t, n) => { r[t] = e[n]; }), r; }, Object.reverse = t => Object.fromArrays(Object.values(t), Object.keys(t)), String.prototype.bulkReplace = function (t) { let e = this; for (const r in t)e = e.replaceAll(r, t[r]); return e; }, String.UWU = t => String(t).bulkReplace(String.UWUTable); Object.keys(_.localizer.dataSource._languageData).map(x => _.localizer.dataSource._languageData[x] = String.UWUFX(String.UWU(_.localizer.dataSource._languageData[x]))); Object.values(_.gameData).map(x => x.map(y => [y.data.name && (y.data.name = String.UWUFX(String.UWU(y.data.name))), y.name && (y.name = String.UWUFX(String.UWU(y.name))), y.data.flavorText && (y.data.flavorText = String.UWUFX(String.UWU(y.data.flavorText)))])); 77 | Toast.fire("OwO", "UwU", "success"); 78 | }); 79 | */ -------------------------------------------------------------------------------- /willsCheatMenu/src/hacks/pets.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import { Swal, Toast, NumberInput, Input, Confirm } from "../utils/swal"; 3 | import { Hack, category } from "../index"; 4 | import { _, VERY_LARGE_NUMBER } from "../utils/util"; 5 | import { TODO } from "../../../typings/util"; 6 | 7 | new Hack(category.pets, "Get All Pets").setClick(async () => { 8 | // add pets 9 | _.gameData.pet.forEach(x => { 10 | _.player.kennel.addPet(x.ID.toString(), VERY_LARGE_NUMBER, 26376, 100); 11 | }); 12 | 13 | // add encounter info 14 | _.player.kennel._encounterInfo._data.pets = []; 15 | _.gameData.pet.map((pet: {ID: number}) => { 16 | _.player.kennel._encounterInfo._data.pets.push({ 17 | firstSeenDate: Date.now(), 18 | ID: pet.ID, 19 | timesBattled: 1, 20 | timesRescued: 1 21 | }); 22 | }); 23 | // Fix broken pets 24 | _.player.kennel.petTeam.forEach((v: any) => { 25 | if (v && (v as any).assignRandomSpells) (v as any).assignRandomSpells(); 26 | }); 27 | 28 | Toast.fire("Success!", "All pets have been added!", "success"); 29 | }); 30 | 31 | new Hack(category.pets, "Get All Legacy Epics").setClick(async () => { 32 | const epics = _.gameData.pet.filter(x => [125, 126, 127, 128, 129, 130, 131, 132, 133].includes(x.ID)); 33 | epics.forEach(x => { 34 | _.player.kennel.addPet(x.ID.toString(), VERY_LARGE_NUMBER, 26376, 100); 35 | }); 36 | // Fix broken pets 37 | _.player.kennel.petTeam.forEach((v: any) => { 38 | if (v && (v as any).assignRandomSpells) (v as any).assignRandomSpells(); 39 | }); 40 | Toast.fire("Success!", "All legacy epics have been added!", "success"); 41 | }); 42 | 43 | // TODO: I need Aura's ID 44 | new Hack(category.pets, "Get All Mythical Epics").setClick(async () => { 45 | const epics = _.gameData.pet.filter(x => [158, 166, 168].includes(x.ID)); 46 | epics.forEach(x => { 47 | _.player.kennel.addPet(x.ID.toString(), VERY_LARGE_NUMBER, 26376, 100); 48 | }); 49 | // Fix broken pets 50 | _.player.kennel.petTeam.forEach((v: any) => { 51 | if (v && (v as any).assignRandomSpells) (v as any).assignRandomSpells(); 52 | }); 53 | Toast.fire("Success!", "All mythical epics have been added!", "success"); 54 | }); 55 | 56 | 57 | new Hack(category.pets, "Fix Battle Crash").setClick(async () => { 58 | _.player.kennel.petTeam.forEach((v: any) => { 59 | if (v && (v as any).assignRandomSpells) (v as any).assignRandomSpells(); 60 | }); 61 | 62 | Toast.fire("Success!", "Fixed kennel attack bug!", "success"); 63 | }); 64 | 65 | new Hack(category.pets, "Clear Pets").setClick(async () => { 66 | _.player.kennel.data.length = 0; 67 | 68 | Toast.fire("Success!", "Your pets have been cleared!", "success"); 69 | }); 70 | 71 | new Hack(category.pets, "Add Pet", "Adds a pet from a list.").setClick(async () => { 72 | const pet = await Swal.fire({ 73 | input: "select", 74 | inputOptions: new Map(_.gameData.pet.map(x => [x.ID.toString(), `${x.ID}: ${x.data.name}`])), 75 | title: "Choose Pet", 76 | text: "Which pet do you want to obtain?" 77 | }); 78 | if (pet.value === undefined) return; 79 | _.player.kennel.addPet(pet.value); 80 | // add encounter data 81 | _.player.kennel._encounterInfo._data.pets.push({ 82 | firstSeenDate: Date.now(), 83 | ID: pet.value, 84 | timesBattled: 1, 85 | timesRescued: 1 86 | }); 87 | 88 | Toast.fire("Success!", "Your chosen pet has been added to your pets!", "success"); 89 | }); 90 | 91 | new Hack(category.pets, "Uncap pet level (client side only, doesn't save on reload)", "Change your pet's level to anything, even over 100.").setClick(async () => { 92 | const petTeam = _.player.kennel.petTeam.slice(0); 93 | petTeam.shift(); 94 | const names = petTeam.map(pet => pet.getName()); 95 | const pet = await Swal.fire({ 96 | title: "Which pet would you like to edit?", 97 | input: "select", 98 | inputOptions: names, 99 | inputPlaceholder: "Select...", 100 | inputValidator: res => res ? "" : "Please select which you'd like to obtain.", 101 | showCancelButton: true 102 | }); 103 | const amt = await NumberInput.fire("Level", "What would you like to set your pet's level to? (Can be set over 100)", "question"); 104 | if (!amt.value) return; 105 | const num = amt.value; 106 | // sorry in advance 107 | eval(`_.player.kennel.petTeam[parseInt(${pet.value})+1].getLevel = () => {return ${num}}`); 108 | Toast.fire("Updated!", "The level of your pet was successfully updated.", "success"); 109 | }); 110 | 111 | const getPet = async (text: string): Promise => { 112 | const pet = await Swal.fire({ 113 | input: "select", 114 | inputOptions: new Map( 115 | _.player.kennel.data.map((x: TODO, i: number) => [ 116 | i.toString(), 117 | `Level ${x.level} - ${x.nickname ?? _.gameData.pet.find(y => +y.ID === +x.ID)?.data.name ?? "Unknown"}` 118 | ]) as [string, string][] 119 | ), 120 | title: "Choose Pet", 121 | text: text 122 | }); 123 | return pet.value; 124 | }; 125 | 126 | new Hack(category.pets, "Edit Pet (BETA)", "Edit a pet.").setClick(async () => { 127 | if (!(await Confirm.fire({ 128 | title: "Hang on!", 129 | html: "This feature is in beta. Using this could break your account in a specific way. This should be used for experimentation only.

Proceed?", 130 | icon: "warning" 131 | })).value) { return; } 132 | const pet = await getPet("Choose the pet to edit."); 133 | if (pet === undefined) return; 134 | const selected = _.player.kennel.data[pet]; 135 | const opt = await Swal.fire({ 136 | input: "select", 137 | inputOptions: { level: "Level", attacks: "Attacks", name: "Name" }, 138 | title: "Edit Property", 139 | text: "What do you want to edit?" 140 | }); 141 | if (opt.value === undefined) return; 142 | if (opt.value === "level") { 143 | const level = await NumberInput.fire( 144 | "Level Number", 145 | "What level do you want to set your pet to?", 146 | "question" 147 | ); 148 | if (level.value === undefined) return; 149 | selected.level = +level.value; 150 | Toast.fire("Success!", "The pet's level has been set.", "success"); 151 | } else if (opt.value === "attacks") { 152 | const attackList = _.gameData.spell; 153 | const div = document.createElement("div"); 154 | const select = document.createElement("select"); 155 | select.classList.add("selectSpell"); 156 | for (const spell of attackList) { 157 | const spellElement = document.createElement("option"); 158 | spellElement.value = spell.ID.toString(); 159 | spellElement.innerText = `${spell.ID}: ${spell.name} (${spell.data.element}) - Damage: ${spell.data.damage}`; 160 | select.options.add(spellElement); 161 | } 162 | div.append(select); 163 | div.append(select.cloneNode(true)); 164 | const attacks = await Swal.fire({ 165 | title: "Attack List", 166 | focusConfirm: false, 167 | showCancelButton: true, 168 | html: div, 169 | preConfirm: () => { 170 | return Array.prototype.slice 171 | .call(document.querySelectorAll(".selectSpell")) 172 | .map((x: HTMLSelectElement) => x.options[x.selectedIndex].value); 173 | } 174 | }); 175 | if (attacks.value === undefined) return; 176 | (selected.foreignSpells as number[]).splice(0, 2, ...attacks.value.map((x: string) => +x)); 177 | Toast.fire("Attacks updated!", "The attack list of the pet you selected has been edited.", "success"); 178 | } else if (opt.value === "name") { 179 | const name = await Input.fire("Input Name", "What do you want to name the pet?", "question"); 180 | if (name.value === undefined) return; 181 | selected.nickname = name.value; 182 | await Swal.fire("Successfully renamed!", "The name of the pet has been changed.", "success"); 183 | } 184 | }); 185 | 186 | new Hack(category.pets, "Delete Pet", "Delete a pet.").setClick(async () => { 187 | const pet = await getPet("Which pet do you wish to delete?"); 188 | if (pet === undefined) return; 189 | _.player.kennel.data.splice(pet, 1); 190 | await Swal.fire("Successfully deleted!", "The selected pet was deleted successfully.", "success"); 191 | }); 192 | -------------------------------------------------------------------------------- /willsCheatMenu/src/hacks/player.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import { Swal, Toast, NumberInput, Input, Confirm } from "../utils/swal"; 3 | import { Hack, category, Toggler } from "../index"; 4 | import { _, getItem, VERY_LARGE_NUMBER, prodigy } from "../utils/util"; 5 | 6 | new Hack(category.player, "Set Gold").setClick(async () => { 7 | const gold = await NumberInput.fire("Gold Amount", "What number do you want to set your gold to?", "question"); 8 | if (gold.value === undefined) return; 9 | if (gold.value > 10000000) return Toast.fire("Error", "Cannot have more than 10,000,000 gold.", "error"); 10 | _.player.data.gold = +gold.value; 11 | Toast.fire("Success!", `You now have ${gold.value} gold.`, "success"); 12 | }); 13 | new Hack(category.player, "Set Level").setClick(async () => { 14 | const level = await NumberInput.fire("Level", "What number do you want to set your level to?", "question"); 15 | if (level.value === undefined) return; 16 | 17 | // fixes #394 18 | // calculate how many stars the level *should* have 19 | // from 3-16-1.js:8382 20 | if (level.value === 1) return 0; 21 | const i = level.value - 2; 22 | // xpConstant from 3-16-1.js:8528 23 | const xpConstant = 1.042; 24 | _.player.data.stars = Math.round((1 - Math.pow(xpConstant, i)) / (1 - xpConstant) * 20 + 10); 25 | _.player.data.level = +level.value; 26 | _.player.getLevel = () => { return _.player.data.level; }; 27 | 28 | Toast.fire("Success!", `You are now level ${level.value}.`, "success"); 29 | }); 30 | 31 | new Hack(category.player, "Get member stars").setClick(async () => { 32 | const amount = await NumberInput.fire("Stars", "How many member stars do you want?", "question"); 33 | if (amount.value === undefined) return; 34 | _.player.data.storedMemberStars = amount.value; 35 | Toast.fire("Success!", `You have set your member stars to ${amount.value}.`, "success"); 36 | }); 37 | 38 | new Hack(category.player, "Set Bounty Points").setClick(async () => { 39 | const points = await NumberInput.fire( 40 | "Bounty Points", 41 | "What number do you want to set your bounty points to? (Max is 100)", 42 | "question" 43 | ); 44 | if (points.value === undefined) return; 45 | _.player.data.bountyScore = Math.min(+points.value, 100); 46 | Toast.fire("Success!", `You now have ${_.player.data.bountyScore} bounty point${_.player.data.bountyScore != 1 ? "s" : ""}.`, "success"); 47 | }); 48 | 49 | new Hack(category.player, "Obtain Conjure Cubes").setClick(async () => { 50 | const cubes = await NumberInput.fire("Conjure Cubes", "How many conjure cubes do you want to get? (Max 99)", "question"); 51 | if (cubes.value === undefined) return; 52 | for (let i = 0; i < Math.min(99, +cubes.value); i++) { prodigy.giftBoxController.receiveGiftBox(null, getItem("giftBox", 1)); } 53 | Toast.fire("Success!", `You have gained ${cubes.value} conjure cube${cubes.value != 1 ? "s" : ""}.`, "success"); 54 | }); 55 | 56 | new Hack(category.player, "Set Wins").setClick(async () => { 57 | const amount = await NumberInput.fire("Wins", "What number do you want to set your wins to?", "question"); 58 | if (amount.value === undefined) return; 59 | _.player.data.win = +amount.value; 60 | Toast.fire("Success!", `You have set your win${amount.value != 1 ? "s" : ""} to ${amount.value}.`, "success"); 61 | }); 62 | 63 | new Hack(category.player, "Set Losses").setClick(async () => { 64 | const amount = await NumberInput.fire("Losses", "What number do you want to set your losses to?", "question"); 65 | if (amount.value === undefined) return; 66 | _.player.data.loss = +amount.value; 67 | Toast.fire("Success!", `You have set your loss${amount.value != 1 ? "es" : ""} to ${amount.value}.`, "success"); 68 | }); 69 | 70 | new Toggler(category.player, "Instant Kill").setEnabled(async () => { 71 | _.player.modifiers.damage = VERY_LARGE_NUMBER; 72 | }).setDisabled(() => { 73 | _.player.modifiers.damage = 1; 74 | }); 75 | 76 | new Hack(category.player, "PVP Health").setClick(async () => { 77 | _.player.pvpHP = VERY_LARGE_NUMBER; 78 | _.player.getMaxHearts = () => VERY_LARGE_NUMBER; 79 | Toast.fire("Success!", "You now have lots of health!", "success"); 80 | }); 81 | 82 | new Toggler(category.player, "Toggle membership").setEnabled(async () => { 83 | function getMemberModule () { return _.player.hasMembership.toString().split("\"")[1]; } 84 | _.instance.prodigy.gameContainer.get(getMemberModule()).data.membership.active = true; 85 | _.player.appearanceChanged = true; 86 | }).setDisabled(() => { 87 | function getMemberModule () { return _.player.hasMembership.toString().split("\"")[1]; } 88 | _.instance.prodigy.gameContainer.get(getMemberModule()).data.membership.active = false; 89 | _.player.appearanceChanged = true; 90 | }); 91 | 92 | new Hack(category.player, "Set name (Client side only)").setClick(async () => { 93 | const name = await Input.fire("What would you like to set your name to?"); 94 | if (!name.value) return; 95 | _.player.getName = () => { return name.value; }; 96 | Toast.fire("Changed!", "Your name was changed."); 97 | }); 98 | 99 | /* 100 | 101 | let interval: unknown | null = null; 102 | 103 | new Hack(category.player, "Arena Point Increaser").setClick(async () => { 104 | if (interval) 105 | return Swal.fire( 106 | "Already Enabled", 107 | "Arena Point Increaser is already enabled.", 108 | "error" 109 | ); 110 | interval = setInterval(async () => { 111 | const data = await ( 112 | await fetch( 113 | `https://api.prodigygame.com/leaderboard-api/season/${prodigy.pvpNetworkHandler.seasonID}/user/${_.player.userID}/pvp?userID=${_.player.userID}`, 114 | { 115 | headers: { 116 | authorization: `Bearer ${prodigy.network.jwtAuthProvider.getToken()}`, 117 | "content-type": 118 | "application/x-www-form-urlencoded; charset=UTF-8", 119 | }, 120 | body: `seasonID=${prodigy.pvpNetworkHandler.seasonID}&action=win`, 121 | method: "POST", 122 | mode: "cors", 123 | } 124 | ) 125 | ).text(); 126 | if (data !== "") { 127 | const jsoned: { 128 | points: number; 129 | weeklyPoints: number; 130 | modifiedDate: string; 131 | seasonID: number; 132 | numMatches: number; 133 | } = JSON.parse(data); 134 | console.log(`[API] ${jsoned.points} Points (+100)`); 135 | } else console.log(`[API] Failed to add points.`); 136 | }, 60500); 137 | await Swal.fire("Enabled", "Arena Point Increaser has been enabled.", "success"); 138 | }); 139 | */ 140 | new Hack(category.player, "Change Name", "Change the name of your wizard.").setClick(async () => { 141 | const names = _.gameData.name; 142 | const div = document.createElement("div"); 143 | const createSelect = (arr: Map, equalityFunc: (str: string) => boolean) => { 144 | const select = document.createElement("select"); 145 | select.classList.add("selectName"); 146 | for (const opt of arr.entries()) { 147 | const optt = document.createElement("option"); 148 | [optt.value, optt.innerText] = opt; 149 | 150 | if (equalityFunc(optt.value)) optt.selected = true; 151 | select.options.add(optt); 152 | } 153 | return select; 154 | }; 155 | const nameSelect = (type: number, equalityFunc: (num: number) => boolean) => 156 | createSelect(new Map( 157 | names.filter(x => x.data.type === type).map(x => [x.ID.toString(), x.name])), 158 | val => equalityFunc(+val) 159 | ); 160 | div.append(nameSelect(0, x => x === _.player.name.data.firstName)); 161 | div.append(nameSelect(1, x => x === _.player.name.data.middleName)); 162 | div.append(nameSelect(2, x => x === _.player.name.data.lastName)); 163 | div.append( 164 | createSelect( 165 | new Map( 166 | [["null", "[none]"]].concat(_.gameData.nickname.map(x => [x.ID.toString(), x.name])) as [ 167 | string, 168 | string 169 | ][] 170 | ), 171 | x => +x === _.player.name.data.nickname || String(_.player.name.data.nickname) === x 172 | ) 173 | ); 174 | const name = await Swal.fire({ 175 | title: "Set Player Name", 176 | focusConfirm: false, 177 | showCancelButton: true, 178 | html: div, 179 | preConfirm: () => { 180 | return Array.prototype.slice 181 | .call(document.querySelectorAll(".selectName")) 182 | .map((x: HTMLSelectElement) => x.options[x.selectedIndex].value); 183 | } 184 | }); 185 | if (name.value === undefined) return; 186 | if (name.value[3] === "null") name.value[3] = null; 187 | [ 188 | _.player.name.data.firstName, 189 | _.player.name.data.middleName, 190 | _.player.name.data.lastName, 191 | _.player.name.data.nickname 192 | ] = (name.value as string[]).map(x => ((x as unknown) as number) && +x); 193 | Toast.fire("Name Changed!", "Your name was successfully changed.", "success"); 194 | }); 195 | 196 | new Hack(category.player, "Uncap player level (client side only)").setClick(async () => { 197 | const level = await NumberInput.fire("Level", "What would you like to set your level to? (Can be 100+)", "question"); 198 | if (!level.value) return; 199 | localStorage.setItem("level", level.value); 200 | eval(`_.player.getLevel = () => {return ${level.value}}`); 201 | Toast.fire("Updated!", "Your level has been successfully updated", "success"); 202 | }); 203 | 204 | new Hack(category.player, "Get all achievements").setClick(async () => { 205 | for (var i = 0; i < 100; i ++) { 206 | _.player.achievements.data.progress[i] = 10; 207 | } 208 | 209 | Toast.fire("Success!", "Obtained all achievements!", "success"); 210 | }); 211 | 212 | new Hack(category.player, "Morph Player (DEV)", "Morph into a pet, furnishing, or follow.").setClick(async () => { 213 | const morphType = await Swal.fire({ 214 | title: "Which morph type?", 215 | input: "select", 216 | inputOptions: { 217 | pet: "Pet", 218 | dorm: "Furniture", 219 | follow: "Follow" 220 | }, 221 | inputPlaceholder: "Morph Type", 222 | inputValidator: res => res ? "" : "Please select a morph type.", 223 | showCancelButton: true 224 | }); 225 | 226 | if (!morphType?.value) return; 227 | 228 | // swal inputOptions accepts an object, the property being the value it returns, the value being what it displays 229 | // kinda weird to explain, just look at how morphType does it 230 | // we want it to display a pretty string, and return the petID 231 | const morphOptions = {}; 232 | // fuck you typescript, I'll do what I want 233 | // @ts-ignore 234 | _.gameData[morphType.value].forEach((morph) => morphOptions[morph.ID] = `${morph.name} (${morph.ID})`); 235 | 236 | const morphID = await Swal.fire({ 237 | title: "Which morph?", 238 | input: "select", 239 | inputOptions: morphOptions, 240 | inputPlaceholder: "Morph ID", 241 | inputValidator: res => res ? "" : "Please select a morph ID.", 242 | showCancelButton: true 243 | }); 244 | 245 | if (!morphID?.value) return; 246 | // shut up typescript, I don't need you on my nuts every time I use Swal 247 | // typescript makes me cry 248 | _.player.getPlayerData().playerTransformation = { 249 | transformType: morphType.value, 250 | transformID: morphID.value, 251 | maxTime: 60 * 60 * 1000, 252 | timeRemaining: 60 * 60 * 1000 253 | }; 254 | _.player.appearanceChanged = true; 255 | 256 | Toast.fire("Morphed!", "You've been morphed.", "success"); 257 | }); 258 | 259 | new Hack(category.player, "Fix Morph Crash").setClick(async () => { 260 | _.player.getPlayerData().playerTransformation = undefined; 261 | _.player.appearanceChanged = true; 262 | 263 | Toast.fire("Success!", "Fixed morph crash bug.", "success"); 264 | }); 265 | 266 | new Hack(category.player, "Permanent Morph", "Makes Your Current Morph Last Forever.").setClick(async () => { 267 | if (!_.player.data.playerTransformation) { 268 | await Swal.fire("No Morph Active", "Please use a Morph Marble and try again.", "error"); 269 | return; 270 | } 271 | _.player.data.playerTransformation.maxTime = Infinity; 272 | _.player.data.playerTransformation.timeRemaining = Infinity; 273 | Toast.fire("Success!", "You're morph will last forever!", "success"); 274 | }); 275 | 276 | new Hack(category.player, "Complete Current Task In Quest", "Completes current task in quest. (Use this button a lot to complete a quest.)").setClick(async () => { 277 | const zones = {}; 278 | Object.keys(_.instance.prodigy.world.zones).forEach(element => { 279 | zones[element] = _.instance.prodigy.world.zones[element].name; 280 | }); 281 | const questName = (await Input.fire({ 282 | title: "What Quest Do You Want To Complete?", 283 | input: "select", 284 | inputOptions: zones 285 | })).value; 286 | if (!questName) return; 287 | const questID = _.instance.prodigy.world.zones[questName].getCurrentQuestID(); 288 | if (_.instance.prodigy.world.zones[questName].completeQuest(questID)) { 289 | _.instance.prodigy.world.goToZoneHub(questName); 290 | Toast.fire("Success!", `Completed current task in the ${_.instance.prodigy.world.zones[questName].name} quest successfully!`, "success"); 291 | } else { 292 | Toast.fire("Could Not Complete Current Task In Quest.", "There was an error completing the quest. Did you already complete it?", "error"); 293 | } 294 | }); 295 | 296 | new Hack(category.player, "Set Dark Tower Floor").setClick(async () => { 297 | const floor = await NumberInput.fire({ 298 | title: "What floor do you want to be on, in the dark tower.", 299 | icon: "question", 300 | inputValidator: (res) => (res > 100 || res < 1) ? `You can only be on floors from 1-100 not ${res}` : false 301 | }); 302 | if (!floor.value) return; 303 | _.player.data.tower = parseInt(floor.value); 304 | Toast.fire("Success!", `Successfully set dark tower floor to ${floor}!`, "success"); 305 | }); 306 | 307 | new Hack(category.player, "Get UserID").setClick(async () => { 308 | Swal.fire({ 309 | title: "User ID", 310 | html: `Here is your User ID:
${_.player.userID}
You can use this for copying your account.`, 311 | icon: "info" 312 | }); 313 | }); 314 | 315 | new Hack(category.player, "Copy Account", "Copy Account From userID").setClick(async () => { 316 | const userID = (await NumberInput.fire("What is the userID of the account you want to copy?", undefined, "question")).value; 317 | if (!userID) return; 318 | if (!(await Confirm.fire("Are you sure you want to copy the account?", "This will replace all data on your account with the account your copying."))) return; 319 | const playerData = await (await fetch(`https://api.prodigygame.com/game-api/v2/characters/${userID}?fields=inventory%2Cdata%2CisMember%2Ctutorial%2Cpets%2Cencounters%2Cquests%2Cappearance%2Cequipment%2Chouse%2Cachievements%2Cstate&userID=${_.player.userID}`, { 320 | headers: { 321 | Authorization: localStorage.JWT_TOKEN 322 | } 323 | })).json(); 324 | await fetch(`https://api.prodigygame.com/game-api/v3/characters/${_.player.userID}`, { 325 | headers: { 326 | "Content-Type": "application/json", 327 | Authorization: localStorage.JWT_TOKEN 328 | }, 329 | body: JSON.stringify({ 330 | data: JSON.stringify(playerData[userID]), 331 | userID: _.player.userID 332 | }), 333 | method: "POST" 334 | }); 335 | Toast.fire("Success!", "Copied Account Successfully! Please reload.", "success"); 336 | }); 337 | 338 | new Hack(category.player, "Set Grade").setClick(async () => { 339 | const grade = await NumberInput.fire("What number do you want to set your grade to?"); 340 | if (!grade.value) return; 341 | _.player.grade = parseInt(grade.value); 342 | Toast.fire("Success", `Successfully changed grade to ${grade}!`, "success"); 343 | }); 344 | -------------------------------------------------------------------------------- /willsCheatMenu/src/hacks/utility.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import { Toast, Input } from "../utils/swal"; 3 | import { Hack, category, Toggler, dimensions } from "../index"; 4 | import { _, saveCharacter } from "../utils/util"; 5 | 6 | new Hack(category.utility, "Save Character Locally", "Saves your character locally.").setClick(async () => { 7 | localStorage.setItem("playerData", JSON.stringify(_.player.getUpdatedData(true))); 8 | Toast.fire("Success!", "Note: Load Character will only work on this device.", "success"); 9 | }); 10 | 11 | new Hack(category.utility, "Stuck in Unfinished Tower Fix", "Takes you out of an unfinished tower if you're stuck in one.").setClick(async () => { 12 | _.instance.prodigy.world.zones["house"].teleport("exit"); 13 | Toast.fire("Success!", "You've been teleported outside of your house.", "success"); 14 | }); 15 | 16 | new Hack(category.utility, "Load local character", "Loads your character locally.").setClick(async () => { 17 | if (!localStorage.getItem("playerData")) { 18 | Toast.fire("Error", "No saved character.", "error"); 19 | } else { 20 | const playerData = localStorage.getItem("playerData"); 21 | const req = await fetch(`https://api.prodigygame.com/game-api/v3/characters/${_.player.userID}`, { 22 | headers: { 23 | accept: "*/*", 24 | "accept-language": "en-US,en;q=0.9", 25 | authorization: localStorage.JWT_TOKEN, 26 | "content-type": "application/json", 27 | "sec-ch-ua": "\" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"91\", \"Chromium\";v=\"91\"", 28 | "sec-ch-ua-mobile": "?0", 29 | "sec-fetch-dest": "empty", 30 | "sec-fetch-mode": "cors", 31 | "sec-fetch-site": "same-site" 32 | }, 33 | referrer: "https://play.prodigygame.com/", 34 | referrerPolicy: "strict-origin-when-cross-origin", 35 | body: JSON.stringify({ 36 | data: playerData, 37 | userID: _.player.userID 38 | }), 39 | method: "POST", 40 | mode: "cors" 41 | }); 42 | if (!req.ok) return Toast.fire("Request failed.", `An error occurred while loading the character. Error code: ${req.status}`, "error"); 43 | Toast.fire("Success!", "Character has been successfully loaded. Reload for the changes to take effect.", "success"); 44 | } 45 | }); 46 | 47 | new Hack(category.utility, "Save Character", "Helps fix bugs where not all hacks save.").setClick(async () => { 48 | saveCharacter(); 49 | Toast.fire("Success!", "Your character has been saved!", "success"); 50 | }); 51 | new Hack(category.utility, "Close all popups", "Closes all popups in Prodigy.").setClick(async () => { 52 | _.instance.prodigy.open.menuCloseAll(); 53 | Toast.fire("Closed!", "All open popups were closed.", "success"); 54 | }); 55 | new Hack(category.utility, "Update menu", "Updates menu to the latest version without needing to reload.").setClick(async () => { 56 | document.getElementById("cheat-menu")?.remove(); 57 | document.getElementById("menu-toggler")?.remove(); 58 | (async () => { 59 | eval(await (await fetch(`https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/HEAD/willsCheatMenu/dist/bundle.js?updated=${Date.now()}`)).text()); // updated parameter is so browser ignores cached version 60 | })(); 61 | Toast.fire("Updated!", "Cheat menu was updated.", "success"); 62 | }); 63 | new Hack(category.utility, "Disable inactivity kick", "Keeps you from being logged out for inactivity.").setClick(async () => { 64 | _.constants.constants["GameConstants.Inactivity.LOG_OUT_TIMER_SECONDS"] = 0; 65 | Toast.fire("Success!", "You now will never be logged out!", "success"); 66 | }); 67 | 68 | new Toggler(category.utility, "Enable menu resize drag (bottom right corner)", "Allows you to resize the menu via dragging.").setEnabled(async () => { 69 | document.getElementById("cheat-menu").style.resize = "both"; 70 | }).setDisabled(() => { 71 | document.getElementById("cheat-menu").style.resize = "none"; 72 | document.getElementById("cheat-menu").style.height = dimensions.height; 73 | document.getElementById("cheat-menu").style.width = dimensions.width; 74 | }); 75 | 76 | new Hack(category.utility, "Edit walkspeed").setClick(async () => { 77 | const walkSpeed = await Input.fire("What do you want to set your walk speed to?"); 78 | if (!walkSpeed.value) return; 79 | if (!_.player._playerContainer) { 80 | const interval = setInterval(() => { 81 | if (_.player._playerContainer) { 82 | clearInterval(interval); 83 | _.player._playerContainer.walkSpeed = parseFloat(walkSpeed.value); 84 | } 85 | }, 100); 86 | } else _.player._playerContainer.walkSpeed = parseFloat(walkSpeed.value) || 1.5; 87 | Toast.fire("Success!", `Successfully made walk speed ${parseFloat(walkSpeed.value) || 1.5}!`, "success"); 88 | }); 89 | 90 | let teleportingInterval = -1; 91 | 92 | new Toggler(category.utility, "Toggle Click Teleporting").setEnabled(async () => { 93 | teleportingInterval = setInterval(() => { 94 | try { 95 | _.player._playerContainer.walkSpeed = 500; 96 | } catch (e) { 97 | // "when switching between scenes, there's a brief moment when _.player._playerContainer.walkSpeed is inaccessible" - Mustan 98 | } 99 | }); 100 | Toast.fire("Success!", "Successfully enabled teleport click.", "success"); 101 | }).setDisabled(async () => { 102 | clearInterval(teleportingInterval); 103 | _.player._playerContainer.walkSpeed = 1.5; 104 | Toast.fire("Success!", "Successfully disabled teleport click.", "success"); 105 | }); 106 | 107 | new Toggler(category.utility, "Pause Game").setEnabled(async () => { 108 | _.network.game._paused = true; 109 | Toast.fire("Success!", "Successfully paused Prodigy.", "success"); 110 | }).setDisabled(async () => { 111 | _.network.game._paused = false; 112 | Toast.fire("Success!", "Successfully resumed Prodigy.", "success"); 113 | }); 114 | -------------------------------------------------------------------------------- /willsCheatMenu/src/index.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import { io } from "socket.io-client"; 3 | import "./style.scss"; 4 | import { saveCharacter, _ } from "./utils/util"; 5 | import Swal from 'sweetalert2' 6 | export const menu = document.createElement("div"); 7 | export const wrapper = document.getElementById("game-wrapper"); 8 | 9 | document.getElementById("cheat-menu")?.remove(); 10 | document.getElementById("menu-toggler")?.remove(); 11 | menu.id = "cheat-menu"; 12 | wrapper?.prepend(menu); 13 | 14 | export const toggler = document.createElement("button"); 15 | toggler.id = "menu-toggler"; 16 | toggler.style.fontSize = "35px" 17 | toggler.style.height = "35px" 18 | toggler.style.width = "70px" 19 | 20 | let visible = false; 21 | wrapper?.prepend(toggler); 22 | toggler.onclick = () => { 23 | visible = !visible; 24 | 25 | if (visible) { 26 | toggler.innerText = "▼"; 27 | menu.style.top = "-100vh"; 28 | } else { 29 | toggler.innerText = "▲"; 30 | menu.style.top = ""; 31 | } 32 | }; 33 | toggler.onclick({} as any); 34 | 35 | const menuleft = document.createElement("DIV"); 36 | menuleft.classList.add("menu-left"); 37 | menu.append(menuleft); 38 | 39 | export const addArea = (title: string) => { 40 | const area = document.createElement("div"); 41 | area.classList.add("menu-area"); 42 | menuleft.append(area); 43 | 44 | const header = document.createElement("h1"); 45 | header.innerText = title; 46 | area.append(header); 47 | return area; 48 | }; 49 | 50 | const title = document.createElement("h1"); 51 | title.classList.add("menu-title"); 52 | title.innerText = "Will's Prodigy Cheat Menu"; 53 | menuleft.append(title); 54 | const disc = document.createElement("h2"); 55 | disc.style.fontSize = "30px"; 56 | disc.innerHTML = "Join our Discord for giveaways, access to new hacks, and notices of hack outages! https://discord.gg/XQDfbfq
Press SHIFT to show/hide the menu."; 57 | menuleft.append(disc); 58 | const subtitle = document.createElement("h3"); 59 | subtitle.style.fontSize = "20px"; 60 | subtitle.innerHTML = `On behalf of ProdigyMathGameHacking. Learn about our mission. 61 |
62 | This is free and open-source software. If you paid for this or accessed this behind a paywall/AdFly link, demand a refund. If you sell this software, or otherwise make a commercial advantage from it, you are violating Github conduct by not cooperating with our license.`; 63 | menuleft.append(subtitle); 64 | 65 | export class Hack { 66 | public element: HTMLButtonElement; 67 | public name: String; 68 | private description: String; 69 | 70 | constructor ( 71 | public parent: HTMLDivElement, 72 | name?: string, 73 | description?: string 74 | ) { 75 | this.name = ""; 76 | this.description = ""; 77 | this.element = document.createElement("button"); 78 | this.element.classList.add("menu-hack"); 79 | this.parent.append(this.element); 80 | 81 | if (name) this.setName(name); 82 | if (description) this.setDesc(description); 83 | } 84 | 85 | setName (name: string) { 86 | this.element.innerText = name; 87 | this.name = name; 88 | return this; 89 | } 90 | 91 | setClick (event: () => unknown) { 92 | this.element.onclick = async () => { 93 | await event(); 94 | saveCharacter(); 95 | console.log(`Triggered ${this.name}.`); 96 | }; 97 | return this; 98 | } 99 | 100 | setDesc (desc: string) { 101 | this.element.title = desc; 102 | this.description = desc; 103 | return this; 104 | } 105 | } 106 | 107 | export class Toggler extends Hack { 108 | enabled?: () => unknown; 109 | disabled?: () => unknown; 110 | constructor ( 111 | public parent: HTMLDivElement, 112 | name?: string, 113 | description?: string 114 | ) { 115 | super(parent, name, description); 116 | this.element.setAttribute("status", "false"); 117 | this.setClick(async () => { 118 | this.status = !this.status; 119 | if (this.status) { 120 | localStorage.setItem(this.name, "true"); 121 | await this.enabled?.(); 122 | } else { 123 | localStorage.setItem(this.name, "false"); 124 | await this.disabled?.(); 125 | } 126 | }); 127 | } 128 | 129 | get status () { 130 | return JSON.parse(this.element.getAttribute("status")!) as boolean; 131 | } 132 | 133 | set status (val) { 134 | this.element.setAttribute("status", val.toString()); 135 | } 136 | 137 | setEnabled (event: () => unknown) { 138 | this.enabled = event; 139 | if (localStorage.getItem(this.name) === "true") { 140 | this.element.click(); 141 | } 142 | return this; 143 | } 144 | 145 | setDisabled (event: () => unknown) { 146 | this.disabled = event; 147 | return this; 148 | } 149 | } 150 | 151 | export const category = { 152 | player: addArea("Player Hacks"), 153 | inventory: addArea("Inventory Hacks"), 154 | location: addArea("Location Hacks"), 155 | pets: addArea("Pet Hacks"), 156 | battle: addArea("Battle Hacks"), 157 | minigames: addArea("Minigames"), 158 | misc: addArea("Miscellaneous Hacks"), 159 | utility: addArea("Utility Hacks") 160 | }; 161 | 162 | if(!localStorage.hasTip){ 163 | (async () => { 164 | Swal.fire({ 165 | title: 'Hey!', 166 | html: `To get started with the hacks, click this dropdown!`, 167 | icon: 'info', 168 | backdrop: ` 169 | url("https://i.imgur.com/CdV9piu.png") 170 | left top 171 | no-repeat 172 | ` 173 | })})() 174 | localStorage.hasTip = true; 175 | 176 | } 177 | 178 | if (localStorage.getItem("level")) { 179 | _.player.getLevel = () => localStorage.getItem("level"); 180 | } 181 | 182 | document.addEventListener("keydown", function (event) { 183 | if (event.key == "Shift") { 184 | if (document.getElementById("cheat-menu").style.display == "block" && document.getElementById("menu-toggler").style.display == "block") { 185 | // Cheats are shown, so let's hide them. 186 | document.getElementById("cheat-menu").style.display = "none"; 187 | document.getElementById("menu-toggler").style.display = "none"; 188 | } else { 189 | // Cheats are hidden, so let's show them. 190 | document.getElementById("cheat-menu").style.display = "block"; 191 | document.getElementById("menu-toggler").style.display = "block"; 192 | } 193 | } 194 | }); 195 | 196 | if (process.env.NODE_ENV === "development") { 197 | const socket = io("http://localhost:3001"); 198 | let used = false; 199 | socket.on("update", data => { 200 | if (used) return; 201 | used = true; 202 | socket.disconnect(); 203 | document.getElementById("cheat-menu")?.remove(); 204 | document.getElementById("menu-toggler")?.remove(); 205 | eval(data); 206 | }); 207 | } -------------------------------------------------------------------------------- /willsCheatMenu/src/style.scss: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css?family=Arvo:400,700|Sen:400,700,800&display=swap&subset=latin-ext"); 2 | #game-wrapper { 3 | font-family: "Sen", sans-serif; 4 | #cheat-menu { 5 | height: 465px; 6 | background-color: #eeeb; 7 | padding: 2px; 8 | position: absolute; 9 | top: 0px; 10 | left: 0px; 11 | transition: top 0.35s; 12 | padding: 10px; 13 | border: #fffa 2px solid; 14 | overflow-y: scroll; 15 | resize: vertical; 16 | overflow: auto; 17 | } 18 | .menu-left { 19 | width: 70%; 20 | height: 100%; 21 | float: left; 22 | } 23 | #menu-toggler { 24 | z-index: 1; 25 | position: absolute; 26 | background-color: #fffb; 27 | transition: background-color 0.15s; 28 | &:hover { 29 | background-color: #dddb; 30 | } 31 | &:active { 32 | background-color: #bbbb; 33 | } 34 | } 35 | .menu-area { 36 | h1 { 37 | font-family: "Sen", sans-serif; 38 | font-size: 30px; 39 | font-weight: 700; 40 | color: #111; 41 | margin: 10px; 42 | } 43 | button { 44 | background-color: black; 45 | color: white; 46 | border-radius: 5px; 47 | border: 1px solid #eee; 48 | padding: 1%; 49 | transition: all 0.15s; 50 | margin: 5px 5px; 51 | transition-property: border-color, background-color; 52 | &:hover { 53 | border-color: #777d; 54 | background-color: #ddd; 55 | } 56 | &:active { 57 | border-color: #555; 58 | background-color: #bbb; 59 | } 60 | &[status="true"] { 61 | border-color: #5a5d; 62 | background-color: #9bee9b; 63 | &:hover { 64 | border-color: #b3bbb0dd; 65 | background-color: #bffebf; 66 | } 67 | &:active { 68 | border-color: #4e5c50; 69 | background-color: #24be6a; 70 | } 71 | } 72 | &[status="false"] { 73 | border-color: #766d; 74 | background-color: #9b9b9b; 75 | &:hover { 76 | border-color: #858585dd; 77 | background-color: #bfbfbf; 78 | } 79 | &:active { 80 | border-color: #4c3e40; 81 | background-color: #be246a; 82 | } 83 | } 84 | } 85 | } 86 | .menu-title { 87 | font-family: "Arvo", sans-serif; 88 | font-size: 35px; 89 | font-weight: 900; 90 | } 91 | } 92 | 93 | .radioDiv { 94 | width: 125px; 95 | height: 125px; 96 | display: inline-block; 97 | margin: 7px; 98 | background-color: #5a7e3f; 99 | color: black; 100 | background-size: cover; 101 | outline: black 5px solid; 102 | vertical-align: top; 103 | font-weight: 700; 104 | user-select: none; 105 | -webkit-user-drag: none; 106 | cursor: pointer; 107 | &:hover { 108 | background-blend-mode: overlay; 109 | color: lightgray; 110 | } 111 | &:active { 112 | background-blend-mode: multiply; 113 | color: white; 114 | } 115 | &[checked] { 116 | background-blend-mode: color-dodge; 117 | color: blanchedalmond; 118 | } 119 | &[checked]:active { 120 | background-blend-mode: color-burn; 121 | color: cyan; 122 | } 123 | } 124 | .radioSwal { 125 | width: fit-content !important; 126 | min-width: 32em !important; 127 | max-width: 46em !important; 128 | } 129 | -------------------------------------------------------------------------------- /willsCheatMenu/src/utils/keybinds.ts: -------------------------------------------------------------------------------- 1 | window.addEventListener("keydown", event => { 2 | /* 3 | if (event.code === "KeyL") { 4 | Phaser.GAMES[0].state.states.Login._gameObj.user.x = Phaser.GAMES[0].input.mousePointer.position.x; 5 | Phaser.GAMES[0].state.states.Login._gameObj.user.y = Phaser.GAMES[0].input.mousePointer.position.y; 6 | } 7 | if (event.code === "Escape") { 8 | Phaser.GAMES[0].state.states.Login._gameObj.open.menus.map(x => x.close()); 9 | } 10 | if (!Phaser.GAMES[0].state.states.Login._gameObj.open.menus.length) { 11 | if (event.code === "KeyE") { 12 | Phaser.GAMES[0].state.states.Login._gameObj.open.backpack(); 13 | } 14 | if (event.code === "KeyT") { 15 | Phaser.GAMES[0].state.states.Login._gameObj.open.chat(); 16 | } 17 | } 18 | */ 19 | }); 20 | -------------------------------------------------------------------------------- /willsCheatMenu/src/utils/swal.ts: -------------------------------------------------------------------------------- 1 | import swal from "sweetalert2"; 2 | export const Swal = swal; 3 | export const Input = Swal.mixin({ 4 | input: "text", 5 | showCancelButton: true, 6 | showConfirmButton: true 7 | }); 8 | export const NumberInput = Input.mixin({ 9 | input: "number" 10 | }); 11 | export const Toast = Swal.mixin({ 12 | toast: true, 13 | position: "bottom" 14 | }); 15 | export const Confirm = Swal.mixin({ 16 | icon: "warning", 17 | showCancelButton: true, 18 | confirmButtonText: "Confirm", 19 | cancelButtonText: "Cancel" 20 | }); 21 | -------------------------------------------------------------------------------- /willsCheatMenu/src/utils/util.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import { GameItemKey } from "../../../typings/_.gameData"; 3 | import { gameData as GameData } from "../../../typings/gameData"; 4 | import { Item } from "../../../typings/item"; 5 | import { Prodigy } from "../../../typings/prodigy"; 6 | import { Game } from "../../../typings/game"; 7 | export const _ = window._; 8 | const base: { game: Game, prodigy: Prodigy } = _.instance; 9 | export const game = base.game; 10 | export const prodigy = base.prodigy; 11 | export const gameData: GameData = _.instance.game.state.states.get("Boot").gameData; 12 | export const getItem = (type: T, id: number): Item | null => 13 | (_.gameData[type].find(x => x.ID === id) as null | Item) ?? null; 14 | export const VERY_LARGE_NUMBER = 9e9; 15 | export const states = Object.fromEntries(_.instance.game.state.states); 16 | export const saveCharacter = () => { 17 | _.network.processPlayer = true; 18 | _.player.forceSaveCharacter(); 19 | }; 20 | 21 | export const assetURL = "https://raw.githubusercontent.com/Prodigy-Hacking/ProdigyMathGameHacking/HEAD/willsCheatMenu/src/assets/"; 22 | export const joinAsset = (asset: string) => `${assetURL}${asset}`; 23 | export const locations = { 24 | academy: joinAsset("academy.png"), 25 | bonfire_spire: joinAsset("bonfire_spire.png"), 26 | forest: joinAsset("forest.png"), 27 | shipwreck_shore: joinAsset("shipwreck_shore.png"), 28 | shiverchill: joinAsset("shiverchill.png"), 29 | skywatch: joinAsset("skywatch.png"), 30 | dyno: joinAsset("dyno.png"), 31 | elemental_guardian: joinAsset("elemental_guardian.png"), 32 | darktower: joinAsset("darktower.png"), 33 | earthtower: joinAsset("earthtower.png"), 34 | crystal_caverns: joinAsset("crystal_caverns.png"), 35 | archives: joinAsset("archives.png"), 36 | house: joinAsset("house.png"), 37 | toyzone: joinAsset("toyzone.png"), 38 | tower_town: joinAsset("tower_town.png"), 39 | lamplight: joinAsset("lamplight.png") 40 | }; 41 | export const pickRandom = (arr: T[]): T => arr[Math.floor(Math.random() * arr.length)]; 42 | -------------------------------------------------------------------------------- /willsCheatMenu/statusmessage.json: -------------------------------------------------------------------------------- 1 | { 2 | "enabled": true, 3 | "message": "We are aware some hacks do not function in general, and most hacks don't work on Harmony Island." 4 | } 5 | -------------------------------------------------------------------------------- /willsCheatMenu/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "./src/**/*", "babel.config.js" 4 | ], 5 | "compilerOptions": { 6 | /* Basic Options */ 7 | // "incremental": true, /* Enable incremental compilation */ 8 | "target": "es2020", 9 | /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ 10 | "module": "amd", 11 | /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ 12 | // "lib": [], /* Specify library files to be included in the compilation. */ 13 | // "allowJs": true, /* Allow javascript files to be compiled. */ 14 | // "checkJs": true, /* Report errors in .js files. */ 15 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 16 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 17 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 18 | "sourceMap": true, 19 | /* Generates corresponding '.map' file. */ 20 | // "outFile": "./dist/index.js", 21 | /* Concatenate and emit output to single file. */ 22 | "outDir": "./dist/", 23 | /* Redirect output structure to the directory. */ 24 | "rootDir": "./src/", 25 | /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 26 | // "composite": true, /* Enable project compilation */ 27 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 28 | // "removeComments": true, /* Do not emit comments to output. */ 29 | // "noEmit": true, /* Do not emit outputs. */ 30 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 31 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 32 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 33 | 34 | /* Strict Type-Checking Options */ 35 | "strict": true, 36 | /* Enable all strict type-checking options. */ 37 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 38 | // "strictNullChecks": true, /* Enable strict null checks. */ 39 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 40 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 41 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 42 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 43 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 44 | 45 | /* Additional Checks */ 46 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 47 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 48 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 49 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 50 | 51 | /* Module Resolution Options */ 52 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 53 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 54 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 55 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 56 | // "typeRoots": [], /* List of folders to include type definitions from. */ 57 | // "types": [], /* Type declaration files to be included in compilation. */ 58 | "allowSyntheticDefaultImports": true, 59 | /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 60 | "esModuleInterop": true, 61 | /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 62 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 63 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 64 | 65 | /* Source Map Options */ 66 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 67 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 68 | // "inlineSourceMap": true, 69 | /* Emit a single file with source maps instead of having a separate file. */ 70 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 71 | 72 | /* Experimental Options */ 73 | "experimentalDecorators": true, 74 | /* Enables experimental support for ES7 decorators. */ 75 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 76 | 77 | /* Advanced Options */ 78 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ 79 | } 80 | } -------------------------------------------------------------------------------- /willsCheatMenu/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const glob = require("glob"); 3 | const autoprefixer = require("autoprefixer"); 4 | module.exports = { 5 | mode: "production", 6 | //devtool: "inline-source-map", 7 | entry: ["./src/index.ts", ...glob.sync(path.join(__dirname, "src/@(hacks|utils)/**/*.ts"))], 8 | module: { 9 | rules: [ 10 | { 11 | test: /\.ts$/, 12 | use: ["babel-loader", "ts-loader"], 13 | exclude: /node_modules/, 14 | }, 15 | { 16 | test: /\.(txt|css)$/i, 17 | use: "raw-loader", 18 | }, 19 | { 20 | test: /\.s[ac]ss$/i, 21 | use: [ 22 | "style-loader", 23 | // Translates CSS into CommonJS 24 | "css-loader", 25 | "postcss-loader", 26 | // Compiles Sass to CSS 27 | "sass-loader", 28 | ], 29 | }, 30 | /*{ 31 | test: /\.(png|jpe?g|gif)$/i, 32 | use: [ 33 | { 34 | loader: "url-loader", 35 | options: { 36 | }, 37 | }, 38 | ], 39 | },*/ 40 | ], 41 | }, 42 | resolve: { 43 | extensions: [".ts", ".js"], 44 | }, 45 | output: { 46 | filename: "bundle.js", 47 | path: path.resolve(__dirname, "dist"), 48 | }, 49 | }; 50 | --------------------------------------------------------------------------------