From d8fc5c9d9ff743758e1119c389782cb54cb6caec Mon Sep 17 00:00:00 2001 From: isPointer Date: Sat, 21 Feb 2026 10:01:00 +0600 Subject: [PATCH] Add files via upload --- LICENSE | 402 +++--- README.md | 154 +-- app/build.gradle | 179 +-- app/proguard-rules.pro | 40 +- app/src/main/AndroidManifest.xml | 8 +- app/src/main/ic_launcher-playstore.png | Bin 0 -> 3209 bytes .../com/android/support/MainActivity.java | 18 + .../main/java/com/android/support/Menu.java | 1086 +++++++++++++++++ .../java/com/android/support/Preferences.java | 483 ++++++++ app/src/main/jni/Android.mk | 23 +- app/src/main/jni/Application.mk | 4 +- app/src/main/jni/Includes/Dex.h | 1 + app/src/main/jni/Includes/Interface.h | 76 ++ app/src/main/jni/Includes/Logger.h | 32 +- app/src/main/jni/Includes/Macros.h | 152 +-- app/src/main/jni/Includes/Utils.h | 47 +- app/src/main/jni/Main.cpp | 181 ++- app/src/main/jni/Menu/Menu.h | 68 ++ app/src/main/jni/Menu/Setup.h | 59 + .../jni/Menu/get_device_api_level_inlines.h | 48 + .../res/drawable/ic_launcher_foreground.xml | 15 + app/src/main/res/layout/activity_main.xml | 16 +- .../res/mipmap-anydpi-v26/ic_launcher.xml | 8 +- .../mipmap-anydpi-v26/ic_launcher_round.xml | 8 +- app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 2034 -> 848 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 4905 -> 2651 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 1190 -> 693 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 2783 -> 1647 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 2214 -> 1166 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 6895 -> 3831 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 3344 -> 1809 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 10413 -> 6144 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 4619 -> 2581 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 15132 -> 9075 bytes app/src/main/res/values/colors.xml | 8 +- .../res/values/ic_launcher_background.xml | 4 + app/src/main/res/values/strings.xml | 6 +- app/src/main/res/values/styles.xml | 14 +- build.gradle | 6 +- gradle.properties | 40 +- gradle/libs.versions.toml | 44 +- gradle/wrapper/gradle-wrapper.properties | 16 +- gradlew | 502 ++++---- gradlew.bat | 188 +-- settings.gradle | 46 +- 45 files changed, 2896 insertions(+), 1086 deletions(-) create mode 100644 app/src/main/ic_launcher-playstore.png create mode 100644 app/src/main/java/com/android/support/MainActivity.java create mode 100644 app/src/main/java/com/android/support/Menu.java create mode 100644 app/src/main/java/com/android/support/Preferences.java create mode 100644 app/src/main/jni/Includes/Dex.h create mode 100644 app/src/main/jni/Includes/Interface.h create mode 100644 app/src/main/jni/Menu/Menu.h create mode 100644 app/src/main/jni/Menu/Setup.h create mode 100644 app/src/main/jni/Menu/get_device_api_level_inlines.h create mode 100644 app/src/main/res/drawable/ic_launcher_foreground.xml create mode 100644 app/src/main/res/values/ic_launcher_background.xml diff --git a/LICENSE b/LICENSE index 261eeb9..29f81d8 100644 --- a/LICENSE +++ b/LICENSE @@ -1,201 +1,201 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index 7b761ca..1d6134a 100644 --- a/README.md +++ b/README.md @@ -1,77 +1,77 @@ -# NativeModMenu - -### High-Performance In-Memory Dex Loader for Android - -`NativeModMenu` is a sophisticated reimplementation of the LGL Android Mod Menu. It leverages `InMemoryDexClassLoader` to load the Java UI layer directly from system memory, eliminating the need for physical `.dex` files on the device storage. - ---- - -## Technical Overview - -This implementation focuses on stealth and efficiency by embedding the `FloatingModMenu.dex` as a HEX-encoded string within the native binary. At runtime, the JNI layer performs a dynamic bootstrap to initialize the menu without leaving any traces in the application's assets or data folders. - -### Key Architectural Differences - -* **Zero Disk Footprint:** No external dex file is shipped; the menu exists only in memory. -* **Volatile Loading:** Utilizes `dalvik.system.InMemoryDexClassLoader` for runtime execution. -* **Native-Led Initialization:** The entire menu lifecycle is managed via JNI native bindings. -* **Reduced Attack Surface:** Eliminates file-based detection vectors by avoiding asset extraction. -* **Native Compatibility:** Fully compatible with existing LGL Java menu logic. - ---- - -## Core Logic Flow - -1. **Data Embedding:** The `FloatingModMenu.dex` is converted to a HEX string and compiled into the C++ source. -2. **Buffer Reconstruction:** At runtime, the HEX string is decoded into a `ByteBuffer`. -3. **Class Loading:** The `InMemoryDexClassLoader` interprets the buffer and loads the `uk.lgl.modmenu.FloatingModMenu` class. -4. **JNI Registration:** Native functions are dynamically bound to the Java class methods. -5. **Execution:** The `binJava()` entry point triggers `FloatingModMenu.antik(Context)` to render the UI. - ---- - -## JNI Native Interface - -The following methods are registered dynamically to bridge the Native and Java layers: - -| Method | Functionality | -| --- | --- | -| `Icon()` | Returns the primary menu icon | -| `IconWebViewData()` | Manages WebView icon resources | -| `getFeatureList()` | Retrieves the feature configuration array | -| `settingsList()` | Retrieves the menu settings configuration | -| `Changes(...)` | Main event handler for feature toggles | -| `setTitleText(...)` | Customizes the UI title appearance | -| `setHeadingText(...)` | Customizes the UI heading appearance | - ---- - -## Implementation Details - -### Requirements - -* **Android Version:** 8.0 (API 26) or higher -* **Architecture:** ARMv7, ARM64-v8a -* **Environment:** Native JNI-based injection - -### Entry Point - -```cpp -// Executed post JNI_OnLoad -void binJava(); - -``` - -The `binJava` function is responsible for retrieving the `Application` context via `ActivityThread` and initiating the memory-loading sequence. - ---- - -## Legal Notice - -This project is developed strictly for **educational and research purposes**. Modifying the runtime behavior of third-party applications may violate their Terms of Service. The developers assume no liability for misuse. - -## Acknowledgments - -* **Original Architecture:** LGL Android Mod Menu -* **Lead Developer:** AntikMods -* **Memory Loading Logic:** NepMods +# NativeModMenu + +### High-Performance In-Memory Dex Loader for Android + +`NativeModMenu` is a sophisticated reimplementation of the LGL Android Mod Menu. It leverages `InMemoryDexClassLoader` to load the Java UI layer directly from system memory, eliminating the need for physical `.dex` files on the device storage. + +--- + +## Technical Overview + +This implementation focuses on stealth and efficiency by embedding the `FloatingModMenu.dex` as a HEX-encoded string within the native binary. At runtime, the JNI layer performs a dynamic bootstrap to initialize the menu without leaving any traces in the application's assets or data folders. + +### Key Architectural Differences + +* **Zero Disk Footprint:** No external dex file is shipped; the menu exists only in memory. +* **Volatile Loading:** Utilizes `dalvik.system.InMemoryDexClassLoader` for runtime execution. +* **Native-Led Initialization:** The entire menu lifecycle is managed via JNI native bindings. +* **Reduced Attack Surface:** Eliminates file-based detection vectors by avoiding asset extraction. +* **Native Compatibility:** Fully compatible with existing LGL Java menu logic. + +--- + +## Core Logic Flow + +1. **Data Embedding:** The `FloatingModMenu.dex` is converted to a HEX string and compiled into the C++ source. +2. **Buffer Reconstruction:** At runtime, the HEX string is decoded into a `ByteBuffer`. +3. **Class Loading:** The `InMemoryDexClassLoader` interprets the buffer and loads the `uk.lgl.modmenu.FloatingModMenu` class. +4. **JNI Registration:** Native functions are dynamically bound to the Java class methods. +5. **Execution:** The `binJava()` entry point triggers `FloatingModMenu.antik(Context)` to render the UI. + +--- + +## JNI Native Interface + +The following methods are registered dynamically to bridge the Native and Java layers: + +| Method | Functionality | +| --- | --- | +| `Icon()` | Returns the primary menu icon | +| `IconWebViewData()` | Manages WebView icon resources | +| `getFeatureList()` | Retrieves the feature configuration array | +| `settingsList()` | Retrieves the menu settings configuration | +| `Changes(...)` | Main event handler for feature toggles | +| `setTitleText(...)` | Customizes the UI title appearance | +| `setHeadingText(...)` | Customizes the UI heading appearance | + +--- + +## Implementation Details + +### Requirements + +* **Android Version:** 8.0 (API 26) or higher +* **Architecture:** ARMv7, ARM64-v8a +* **Environment:** Native JNI-based injection + +### Entry Point + +```cpp +// Executed post JNI_OnLoad +void binJava(); + +``` + +The `binJava` function is responsible for retrieving the `Application` context via `ActivityThread` and initiating the memory-loading sequence. + +--- + +## Legal Notice + +This project is developed strictly for **educational and research purposes**. Modifying the runtime behavior of third-party applications may violate their Terms of Service. The developers assume no liability for misuse. + +## Acknowledgments + +* **Original Architecture:** LGL Android Mod Menu +* **Lead Developer:** AntikMods +* **Memory Loading Logic:** NepMods diff --git a/app/build.gradle b/app/build.gradle index f53a8dc..e89d584 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,90 +1,91 @@ -import com.android.build.gradle.tasks.ExternalNativeBuildTask -import java.io.FileInputStream - -plugins { - alias(libs.plugins.android.application) -} - -class JavaDex { - public static String xxd_p(String filePath) { - StringBuilder hexString = new StringBuilder() - File file = new File(filePath) - try (FileInputStream fis = new FileInputStream(file)) { - byte[] data = fis.readAllBytes() - for (byte b : data) { - hexString.append(String.format("%02X", b)) - } - } - return hexString.toString() - } -} - -android { - namespace 'uk.lgl' - compileSdk 36 - - defaultConfig { - applicationId "uk.lgl" - minSdk 28 - targetSdk 36 - versionCode 1 - versionName "1.0" - - ndk { - abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64' - } - - multiDexEnabled false - } - - buildTypes { - release { - minifyEnabled true - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } - - externalNativeBuild { - ndkBuild { - path file('src/main/jni/Android.mk') - } - } - - android.applicationVariants.all { variant -> - def variantName = variant.name.capitalize() - def taskName = "Dex2CppAnd8Up${variantName}" - - def customTask = tasks.register(taskName) { - outputs.upToDateWhen { false } - - def mergeDexTask = tasks.findByName("mergeDex${variantName}") - if (mergeDexTask) { - dependsOn mergeDexTask - } - - doLast { - def dexDir = file("${project.buildDir}/intermediates/dex/${variant.name}/mergeDex${variantName}") - def dexFiles = fileTree(dir: dexDir, include: "**/classes.dex") - - if (dexFiles.isEmpty()) { - throw new GradleException("classes.dex not found for ${variant.name} in ${dexDir}") - } - - def dexFile = dexFiles.first() - String hexString = JavaDex.xxd_p(dexFile.absolutePath) - def headerFile = file("${project.projectDir}/src/main/jni/JavaGPP/Interface/OreoOrMore.h") - - headerFile.parentFile.mkdirs() - headerFile.write("#define OreoOrMore \"${hexString}\"\n") - println ">>> Success: Generated header for ${variantName}" - } - } - - tasks.configureEach { task -> - if (task.name.startsWith("buildNdkBuild${variantName}") || - task.name.startsWith("externalNativeBuild${variantName}")) { - task.dependsOn customTask - } - } - } +import com.android.build.gradle.tasks.ExternalNativeBuildTask +import java.io.FileInputStream + +plugins { + alias(libs.plugins.android.application) +} + +class JavaDex { + public static String xxd_p(String filePath) { + StringBuilder hexString = new StringBuilder() + File file = new File(filePath) + try (FileInputStream fis = new FileInputStream(file)) { + byte[] data = fis.readAllBytes() + for (byte b : data) { + hexString.append(String.format("%02X", b)) + } + } + return hexString.toString() + } +} + +android { + namespace 'com.android.support' + compileSdk 36 + + defaultConfig { + applicationId "com.android.support" + minSdk 28 + targetSdk 36 + versionCode 1 + versionName "1.0" + + ndk { + abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64' + } + + multiDexEnabled false + } + + buildTypes { + release { + minifyEnabled true + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + externalNativeBuild { + ndkBuild { + path file('src/main/jni/Android.mk') + } + ndkVersion = '28.2.13676358' + } + + android.applicationVariants.all { variant -> + def variantName = variant.name.capitalize() + def taskName = "Dex2CppAnd8Up${variantName}" + + def customTask = tasks.register(taskName) { + outputs.upToDateWhen { false } + + def mergeDexTask = tasks.findByName("mergeDex${variantName}") + if (mergeDexTask) { + dependsOn mergeDexTask + } + + doLast { + def dexDir = file("${project.buildDir}/intermediates/dex/${variant.name}/mergeDex${variantName}") + def dexFiles = fileTree(dir: dexDir, include: "**/classes.dex") + + if (dexFiles.isEmpty()) { + throw new GradleException("classes.dex not found for ${variant.name} in ${dexDir}") + } + + def dexFile = dexFiles.first() + String hexString = JavaDex.xxd_p(dexFile.absolutePath) + def headerFile = file("${project.projectDir}/src/main/jni/Includes/Dex.h") + + headerFile.parentFile.mkdirs() + headerFile.write("#define hexdex \"${hexString}\"\n") + println ">>> Success: Generated header for ${variantName}" + } + } + + tasks.configureEach { task -> + if (task.name.startsWith("buildNdkBuild${variantName}") || + task.name.startsWith("externalNativeBuild${variantName}")) { + task.dependsOn customTask + } + } + } } \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 481bb43..64b4a05 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,21 +1,21 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. #-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7d033f3..e524f52 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,14 +1,16 @@ + package="com.android.support"> - @@ -16,4 +18,4 @@ - \ No newline at end of file + diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000000000000000000000000000000000000..cbc1231eb29d97ea1bf0ee75a9e6b3da723f2834 GIT binary patch literal 3209 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&zE~)R&4YzZe*J0z6$DLn`9lUejGC`$VcO zvFH|;j4jpuEa=3#ScVr*nM>`}(qw7<$zxVge@zdAs|1%z7ye?n; zcPsyY{q2Gb%Kr2A@7VMI>gw*9Gw0siTwniY@^10&e%A)@ERjsef~L|LM0QrH(sr z;r9HR`kz1knKSV1_;;hde)?_BhKa|^zfb?Z@6Xdu&+q?d0Ojzw`nQMwpU!1DaANXv zeZBYfUtc8w%h7Ld?#usv^6qFhIGv9c!t|?s`rp0Ne_!|Q@zdAy|1&&jc-_DE->r6V yEG#s)|MTtBx#jlYcpFhA^JpuSMy>IG?9BWb-P=Wu%msEa7(8A5T-G@yGywo-#sPEy literal 0 HcmV?d00001 diff --git a/app/src/main/java/com/android/support/MainActivity.java b/app/src/main/java/com/android/support/MainActivity.java new file mode 100644 index 0000000..0a67956 --- /dev/null +++ b/app/src/main/java/com/android/support/MainActivity.java @@ -0,0 +1,18 @@ +package com.android.support; + +import android.app.Activity; +import android.os.Bundle; + +public class MainActivity extends Activity { + + static { + System.loadLibrary("LGL"); + } + + //To call onCreate, please refer to README.md + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // Menu.CreateMenu(this); + } +} diff --git a/app/src/main/java/com/android/support/Menu.java b/app/src/main/java/com/android/support/Menu.java new file mode 100644 index 0000000..eb63b37 --- /dev/null +++ b/app/src/main/java/com/android/support/Menu.java @@ -0,0 +1,1086 @@ +//Please don't replace listeners with lambda! + +package com.android.support; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.res.ColorStateList; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.graphics.PixelFormat; +import android.graphics.PorterDuff; +import android.graphics.Typeface; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.GradientDrawable; +import android.graphics.drawable.LayerDrawable; +import android.net.Uri; +import android.os.Build; +import android.os.Handler; +import android.os.Looper; +import android.text.Html; +import android.text.InputFilter; +import android.text.InputType; +import android.text.TextUtils; +import android.text.method.DigitsKeyListener; +import android.util.Base64; +import android.util.Log; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.view.inputmethod.InputMethodManager; +import android.webkit.WebView; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RadioButton; +import android.widget.RadioGroup; +import android.widget.RelativeLayout; +import android.widget.ScrollView; +import android.widget.SeekBar; +import android.widget.Spinner; +import android.widget.Switch; +import android.widget.TextView; +import android.widget.Toast; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; +import static android.widget.RelativeLayout.ALIGN_PARENT_LEFT; +import static android.widget.RelativeLayout.ALIGN_PARENT_RIGHT; + +public class Menu { + //********** Here you can easly change the menu appearance **********// + + //region Variable + public static final String TAG = "Mod_Menu"; //Tag for logcat + + int TEXT_COLOR = Color.parseColor("#82CAFD"); + int TEXT_COLOR_2 = Color.parseColor("#FFFFFF"); + int BTN_COLOR = Color.parseColor("#1C262D"); + int MENU_BG_COLOR = Color.parseColor("#EE1C2A35"); //#AARRGGBB + int MENU_FEATURE_BG_COLOR = Color.parseColor("#DD141C22"); //#AARRGGBB + int MENU_WIDTH = 290; + int MENU_HEIGHT = 210; + int POS_X = 0; + int POS_Y = 100; + + float MENU_CORNER = 4f; + int ICON_SIZE = 45; //Change both width and height of image + float ICON_ALPHA = 0.7f; //Transparent + int ToggleON = Color.GREEN; + int ToggleOFF = Color.RED; + int BtnON = Color.parseColor("#1b5e20"); + int BtnOFF = Color.parseColor("#7f0000"); + int CategoryBG = Color.parseColor("#2F3D4C"); + int SeekBarColor = Color.parseColor("#80CBC4"); + int SeekBarProgressColor = Color.parseColor("#80CBC4"); + int CheckBoxColor = Color.parseColor("#80CBC4"); + int RadioColor = Color.parseColor("#FFFFFF"); + String NumberTxtColor = "#41c300"; + //********************************************************************// + + RelativeLayout mCollapsed, mRootContainer; + LinearLayout mExpanded, mods, mSettings, mCollapse; + LinearLayout.LayoutParams scrlLLExpanded, scrlLL; + WindowManager mWindowManager; + WindowManager.LayoutParams vmParams; + ImageView startimage; + FrameLayout rootFrame; + ScrollView scrollView; + boolean stopChecking, overlayRequired; + Context getContext; + + //initialize methods from the native library + native void Init(Context context, TextView title, TextView subTitle); + + native String Icon(); + + native String IconWebViewData(); + + native String[] GetFeatureList(); + + native String[] SettingsList(); + + public static native void Changes(Context con, int fNum, String fName, int i, boolean bool, String str); + + + //Here we write the code for our Menu + // Reference: https://www.androidhive.info/2016/11/android-floating-widget-like-facebook-chat-head/ + public Menu(Context context) { + + getContext = context; + Preferences.context = context; + rootFrame = new FrameLayout(context); // Global markup + rootFrame.setOnTouchListener(onTouchListener()); + mRootContainer = new RelativeLayout(context); // Markup on which two markups of the icon and the menu itself will be placed + mCollapsed = new RelativeLayout(context); // Markup of the icon (when the menu is minimized) + mCollapsed.setVisibility(View.VISIBLE); + mCollapsed.setAlpha(ICON_ALPHA); + + //********** The box of the mod menu ********** + mExpanded = new LinearLayout(context); // Menu markup (when the menu is expanded) + mExpanded.setVisibility(View.GONE); + mExpanded.setBackgroundColor(MENU_BG_COLOR); + mExpanded.setOrientation(LinearLayout.VERTICAL); + // mExpanded.setPadding(1, 1, 1, 1); //So borders would be visible + mExpanded.setLayoutParams(new LinearLayout.LayoutParams(dp(MENU_WIDTH), WRAP_CONTENT)); + GradientDrawable gdMenuBody = new GradientDrawable(); + gdMenuBody.setCornerRadius(MENU_CORNER); //Set corner + gdMenuBody.setColor(MENU_BG_COLOR); //Set background color + gdMenuBody.setStroke(1, Color.parseColor("#32cb00")); //Set border + //mExpanded.setBackground(gdMenuBody); //Apply GradientDrawable to it + + //********** The icon to open mod menu ********** + startimage = new ImageView(context); + startimage.setLayoutParams(new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)); + int applyDimension = (int) TypedValue.applyDimension(1, ICON_SIZE, context.getResources().getDisplayMetrics()); //Icon size + startimage.getLayoutParams().height = applyDimension; + startimage.getLayoutParams().width = applyDimension; + //startimage.requestLayout(); + startimage.setScaleType(ImageView.ScaleType.FIT_XY); + byte[] decode = Base64.decode(Icon(), 0); + startimage.setImageBitmap(BitmapFactory.decodeByteArray(decode, 0, decode.length)); + ((ViewGroup.MarginLayoutParams) startimage.getLayoutParams()).topMargin = convertDipToPixels(10); + //Initialize event handlers for buttons, etc. + startimage.setOnTouchListener(onTouchListener()); + startimage.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + mCollapsed.setVisibility(View.GONE); + mExpanded.setVisibility(View.VISIBLE); + } + }); + + //********** The icon in Webview to open mod menu ********** + WebView wView = new WebView(context); //Icon size width=\"50\" height=\"50\" + wView.setLayoutParams(new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)); + int applyDimension2 = (int) TypedValue.applyDimension(1, ICON_SIZE, context.getResources().getDisplayMetrics()); //Icon size + wView.getLayoutParams().height = applyDimension2; + wView.getLayoutParams().width = applyDimension2; + wView.loadData("" + + "" + + "" + + "" + + "" + + "", "text/html", "utf-8"); + wView.setBackgroundColor(0x00000000); //Transparent + wView.setAlpha(ICON_ALPHA); + wView.setOnTouchListener(onTouchListener()); + + //********** Settings icon ********** + TextView settings = new TextView(context); //Android 5 can't show ⚙, instead show other icon instead + settings.setText(Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M ? "⚙" : "\uD83D\uDD27"); + settings.setTextColor(TEXT_COLOR); + settings.setTypeface(Typeface.DEFAULT_BOLD); + settings.setTextSize(20.0f); + RelativeLayout.LayoutParams rlsettings = new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); + rlsettings.addRule(ALIGN_PARENT_RIGHT); + settings.setLayoutParams(rlsettings); + settings.setOnClickListener(new View.OnClickListener() { + boolean settingsOpen; + + @Override + public void onClick(View v) { + try { + settingsOpen = !settingsOpen; + if (settingsOpen) { + scrollView.removeView(mods); + scrollView.addView(mSettings); + scrollView.scrollTo(0, 0); + } else { + scrollView.removeView(mSettings); + scrollView.addView(mods); + } + } catch (IllegalStateException e) { + } + } + }); + + //********** Settings ********** + mSettings = new LinearLayout(context); + mSettings.setOrientation(LinearLayout.VERTICAL); + featureList(SettingsList(), mSettings); + + //********** Title ********** + RelativeLayout titleText = new RelativeLayout(context); + titleText.setPadding(10, 5, 10, 5); + titleText.setVerticalGravity(16); + + TextView title = new TextView(context); + title.setTextColor(TEXT_COLOR); + title.setTextSize(18.0f); + title.setGravity(Gravity.CENTER); + RelativeLayout.LayoutParams rl = new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); + rl.addRule(RelativeLayout.CENTER_HORIZONTAL); + title.setLayoutParams(rl); + + //********** Sub title ********** + TextView subTitle = new TextView(context); + subTitle.setEllipsize(TextUtils.TruncateAt.MARQUEE); + subTitle.setMarqueeRepeatLimit(-1); + subTitle.setSingleLine(true); + subTitle.setSelected(true); + subTitle.setTextColor(TEXT_COLOR); + subTitle.setTextSize(10.0f); + subTitle.setGravity(Gravity.CENTER); + subTitle.setPadding(0, 0, 0, 5); + + //********** Mod menu feature list ********** + scrollView = new ScrollView(context); + //Auto size. To set size manually, change the width and height example 500, 500 + scrlLL = new LinearLayout.LayoutParams(MATCH_PARENT, dp(MENU_HEIGHT)); + scrlLLExpanded = new LinearLayout.LayoutParams(mExpanded.getLayoutParams()); + scrlLLExpanded.weight = 1.0f; + scrollView.setLayoutParams(Preferences.isExpanded ? scrlLLExpanded : scrlLL); + scrollView.setBackgroundColor(MENU_FEATURE_BG_COLOR); + mods = new LinearLayout(context); + mods.setOrientation(LinearLayout.VERTICAL); + + //********** RelativeLayout for buttons ********** + RelativeLayout relativeLayout = new RelativeLayout(context); + relativeLayout.setPadding(10, 3, 10, 3); + relativeLayout.setVerticalGravity(Gravity.CENTER); + + //********** Hide/Kill button ********** + RelativeLayout.LayoutParams lParamsHideBtn = new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); + lParamsHideBtn.addRule(ALIGN_PARENT_LEFT); + + Button hideBtn = new Button(context); + hideBtn.setLayoutParams(lParamsHideBtn); + hideBtn.setBackgroundColor(Color.TRANSPARENT); + hideBtn.setText("HIDE/KILL (Hold)"); + hideBtn.setTextColor(TEXT_COLOR); + hideBtn.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + mCollapsed.setVisibility(View.VISIBLE); + mCollapsed.setAlpha(0); + mExpanded.setVisibility(View.GONE); + Toast.makeText(view.getContext(), "Icon hidden. Remember the hidden icon position", Toast.LENGTH_LONG).show(); + } + }); + hideBtn.setOnLongClickListener(new View.OnLongClickListener() { + public boolean onLongClick(View view) { + Toast.makeText(view.getContext(), "Menu killed", Toast.LENGTH_LONG).show(); + rootFrame.removeView(mRootContainer); + mWindowManager.removeView(rootFrame); + return false; + } + }); + + //********** Close button ********** + RelativeLayout.LayoutParams lParamsCloseBtn = new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); + lParamsCloseBtn.addRule(ALIGN_PARENT_RIGHT); + + Button closeBtn = new Button(context); + closeBtn.setLayoutParams(lParamsCloseBtn); + closeBtn.setBackgroundColor(Color.TRANSPARENT); + closeBtn.setText("MINIMIZE"); + closeBtn.setTextColor(TEXT_COLOR); + closeBtn.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + mCollapsed.setVisibility(View.VISIBLE); + mCollapsed.setAlpha(ICON_ALPHA); + mExpanded.setVisibility(View.GONE); + } + }); + + //********** Adding view components ********** + mRootContainer.addView(mCollapsed); + mRootContainer.addView(mExpanded); + if (IconWebViewData() != null) { + mCollapsed.addView(wView); + } else { + mCollapsed.addView(startimage); + } + titleText.addView(title); + titleText.addView(settings); + mExpanded.addView(titleText); + mExpanded.addView(subTitle); + scrollView.addView(mods); + mExpanded.addView(scrollView); + relativeLayout.addView(hideBtn); + relativeLayout.addView(closeBtn); + mExpanded.addView(relativeLayout); + + Init(context, title, subTitle); + } + + + private static Menu menu; + + public static void CreateMenu(final Context context) { + if (!(context instanceof Activity)) { + Handler handler = new Handler(Looper.getMainLooper()); + handler.post(new Runnable() { + @Override + public void run() { + Activity activity = getTopActivity(); + if (activity != null) { + activity.setTheme(android.R.style.Theme_Material); + menu = new Menu(activity); + menu.SetWindowManagerActivity(); + menu.ShowMenu(); + } + } + }); + } else { + ((Activity) context).setTheme(android.R.style.Theme_Material); + menu = new Menu((Activity) context); + menu.SetWindowManagerActivity(); + menu.ShowMenu(); + } + } + + private static Activity getTopActivity() { + try { + Class at = Class.forName("android.app.ActivityThread"); + Method current = at.getDeclaredMethod("currentActivityThread"); + current.setAccessible(true); + Object atObj = current.invoke(null); + + Field activities = at.getDeclaredField("mActivities"); + activities.setAccessible(true); + Map map = (Map) activities.get(atObj); + + for (Object record : map.values()) { + Class ar = record.getClass(); + Field paused = ar.getDeclaredField("paused"); + paused.setAccessible(true); + if (!paused.getBoolean(record)) { + Field activity = ar.getDeclaredField("activity"); + activity.setAccessible(true); + return (Activity) activity.get(record); + } + } + } catch (Throwable ignored) {} + return null; + } + + + public void ShowMenu() { + rootFrame.addView(mRootContainer); + + final Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + boolean viewLoaded = false; + + @Override + public void run() { + mods.removeAllViews(); + featureList(GetFeatureList(), mods); + + } + }, 500); + } + + + @SuppressLint("WrongConstant") + public void SetWindowManagerActivity() { + vmParams = new WindowManager.LayoutParams( + WindowManager.LayoutParams.WRAP_CONTENT, + WindowManager.LayoutParams.WRAP_CONTENT, + POS_X,//initialX + POS_Y,//initialy + WindowManager.LayoutParams.TYPE_APPLICATION, + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | + WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN | + WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | + WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, + PixelFormat.TRANSPARENT + ); + vmParams.gravity = 51; + vmParams.x = POS_X; + vmParams.y = POS_Y; + + mWindowManager = ((Activity) getContext).getWindowManager(); + mWindowManager.addView(rootFrame, vmParams); + } + + private View.OnTouchListener onTouchListener() { + return new View.OnTouchListener() { + final View collapsedView = mCollapsed; + final View expandedView = mExpanded; + private float initialTouchX, initialTouchY; + private int initialX, initialY; + + public boolean onTouch(View view, MotionEvent motionEvent) { + switch (motionEvent.getAction()) { + case MotionEvent.ACTION_DOWN: + initialX = vmParams.x; + initialY = vmParams.y; + initialTouchX = motionEvent.getRawX(); + initialTouchY = motionEvent.getRawY(); + return true; + case MotionEvent.ACTION_UP: + int rawX = (int) (motionEvent.getRawX() - initialTouchX); + int rawY = (int) (motionEvent.getRawY() - initialTouchY); + mExpanded.setAlpha(1f); + mCollapsed.setAlpha(1f); + //The check for Xdiff <10 && YDiff< 10 because sometime elements moves a little while clicking. + //So that is click event. + if (rawX < 10 && rawY < 10 && isViewCollapsed()) { + //When user clicks on the image view of the collapsed layout, + //visibility of the collapsed layout will be changed to "View.GONE" + //and expanded view will become visible. + try { + collapsedView.setVisibility(View.GONE); + expandedView.setVisibility(View.VISIBLE); + } catch (NullPointerException e) { + + } + } + return true; + case MotionEvent.ACTION_MOVE: + mExpanded.setAlpha(0.5f); + mCollapsed.setAlpha(0.5f); + //Calculate the X and Y coordinates of the view. + vmParams.x = initialX + ((int) (motionEvent.getRawX() - initialTouchX)); + vmParams.y = initialY + ((int) (motionEvent.getRawY() - initialTouchY)); + //Update the layout with new X & Y coordinate + mWindowManager.updateViewLayout(rootFrame, vmParams); + return true; + default: + return false; + } + } + }; + } + + private void featureList(String[] listFT, LinearLayout linearLayout) { + //Currently looks messy right now. Let me know if you have improvements + int featNum, subFeat = 0; + LinearLayout llBak = linearLayout; + + for (int i = 0; i < listFT.length; i++) { + boolean switchedOn = false; + //Log.i("featureList", listFT[i]); + String feature = listFT[i]; + if (feature.contains("_True")) { + switchedOn = true; + feature = feature.replaceFirst("_True", ""); + } + + linearLayout = llBak; + if (feature.contains("CollapseAdd_")) { + //if (collapse != null) + linearLayout = mCollapse; + feature = feature.replaceFirst("CollapseAdd_", ""); + } + String[] str = feature.split("_"); + + //Assign feature number + if (TextUtils.isDigitsOnly(str[0]) || str[0].matches("-[0-9]*")) { + featNum = Integer.parseInt(str[0]); + feature = feature.replaceFirst(str[0] + "_", ""); + subFeat++; + } else { + //Subtract feature number. We don't want to count ButtonLink, Category, RichTextView and RichWebView + featNum = i - subFeat; + } + String[] strSplit = feature.split("_"); + switch (strSplit[0]) { + case "Toggle": + Switch(linearLayout, featNum, strSplit[1], switchedOn); + break; + case "SeekBar": + SeekBar(linearLayout, featNum, strSplit[1], Integer.parseInt(strSplit[2]), Integer.parseInt(strSplit[3])); + break; + case "Button": + Button(linearLayout, featNum, strSplit[1]); + break; + case "ButtonOnOff": + ButtonOnOff(linearLayout, featNum, strSplit[1], switchedOn); + break; + case "Spinner": + TextView(linearLayout, strSplit[1]); + Spinner(linearLayout, featNum, strSplit[1], strSplit[2]); + break; + case "InputText": + InputText(linearLayout, featNum, strSplit[1]); + break; + case "InputValue": + if (strSplit.length == 3) + InputNum(linearLayout, featNum, strSplit[2], Integer.parseInt(strSplit[1])); + if (strSplit.length == 2) + InputNum(linearLayout, featNum, strSplit[1], 0); + break; + case "CheckBox": + CheckBox(linearLayout, featNum, strSplit[1], switchedOn); + break; + case "RadioButton": + RadioButton(linearLayout, featNum, strSplit[1], strSplit[2]); + break; + case "Collapse": + Collapse(linearLayout, strSplit[1], switchedOn); + subFeat++; + break; + case "ButtonLink": + subFeat++; + ButtonLink(linearLayout, strSplit[1], strSplit[2]); + break; + case "Category": + subFeat++; + Category(linearLayout, strSplit[1]); + break; + case "RichTextView": + subFeat++; + TextView(linearLayout, strSplit[1]); + break; + case "RichWebView": + subFeat++; + WebTextView(linearLayout, strSplit[1]); + break; + } + } + } + + private void Switch(LinearLayout linLayout, final int featNum, final String featName, boolean swiOn) { + final Switch switchR = new Switch(getContext); + ColorStateList buttonStates = new ColorStateList( + new int[][]{ + new int[]{-android.R.attr.state_enabled}, + new int[]{android.R.attr.state_checked}, + new int[]{} + }, + new int[]{ + Color.BLUE, + ToggleON, // ON + ToggleOFF // OFF + } + ); + //Set colors of the switch. Comment out if you don't like it + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + try { + switchR.getThumbDrawable().setTintList(buttonStates); + switchR.getTrackDrawable().setTintList(buttonStates); + } catch (NullPointerException ex) { + Log.d(TAG, String.valueOf(ex)); + } + } + switchR.setText(featName); + switchR.setTextColor(TEXT_COLOR_2); + switchR.setPadding(10, 5, 0, 5); + switchR.setChecked(Preferences.loadPrefBool(featName, featNum, swiOn)); + switchR.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + public void onCheckedChanged(CompoundButton compoundButton, boolean bool) { + Preferences.changeFeatureBool(featName, featNum, bool); + switch (featNum) { + case -1: //Save perferences + Preferences.with(switchR.getContext()).writeBoolean(-1, bool); + if (bool == false) + Preferences.with(switchR.getContext()).clear(); //Clear perferences if switched off + break; + case -3: + Preferences.isExpanded = bool; + scrollView.setLayoutParams(bool ? scrlLLExpanded : scrlLL); + break; + } + } + }); + + linLayout.addView(switchR); + } + + private void SeekBar(LinearLayout linLayout, final int featNum, final String featName, final int min, int max) { + int loadedProg = Preferences.loadPrefInt(featName, featNum); + LinearLayout linearLayout = new LinearLayout(getContext); + linearLayout.setPadding(10, 5, 0, 5); + linearLayout.setOrientation(LinearLayout.VERTICAL); + linearLayout.setGravity(Gravity.CENTER); + + final TextView textView = new TextView(getContext); + textView.setText(Html.fromHtml(featName + ": " + ((loadedProg == 0) ? min : loadedProg))); + textView.setTextColor(TEXT_COLOR_2); + + SeekBar seekBar = new SeekBar(getContext); + seekBar.setPadding(25, 10, 35, 10); + seekBar.setMax(max); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) + seekBar.setMin(min); //setMin for Oreo and above + seekBar.setProgress((loadedProg == 0) ? min : loadedProg); + seekBar.getThumb().setColorFilter(SeekBarColor, PorterDuff.Mode.SRC_ATOP); + seekBar.getProgressDrawable().setColorFilter(SeekBarProgressColor, PorterDuff.Mode.SRC_ATOP); + seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + public void onStartTrackingTouch(SeekBar seekBar) { + } + + public void onStopTrackingTouch(SeekBar seekBar) { + } + + public void onProgressChanged(SeekBar seekBar, int i, boolean z) { + //if progress is greater than minimum, don't go below. Else, set progress + seekBar.setProgress(i < min ? min : i); + Preferences.changeFeatureInt(featName, featNum, i < min ? min : i); + textView.setText(Html.fromHtml(featName + ": " + (i < min ? min : i))); + } + }); + linearLayout.addView(textView); + linearLayout.addView(seekBar); + + linLayout.addView(linearLayout); + } + + private void Button(LinearLayout linLayout, final int featNum, final String featName) { + final Button button = new Button(getContext); + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT); + layoutParams.setMargins(7, 5, 7, 5); + button.setLayoutParams(layoutParams); + button.setTextColor(TEXT_COLOR_2); + button.setAllCaps(false); //Disable caps to support html + button.setText(Html.fromHtml(featName)); + button.setBackgroundColor(BTN_COLOR); + button.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + switch (featNum) { + + case -6: + scrollView.removeView(mSettings); + scrollView.addView(mods); + break; + case -100: + stopChecking = true; + break; + } + Preferences.changeFeatureInt(featName, featNum, 0); + } + }); + + linLayout.addView(button); + } + + private void ButtonLink(LinearLayout linLayout, final String featName, final String url) { + final Button button = new Button(getContext); + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT); + layoutParams.setMargins(7, 5, 7, 5); + button.setLayoutParams(layoutParams); + button.setAllCaps(false); //Disable caps to support html + button.setTextColor(TEXT_COLOR_2); + button.setText(Html.fromHtml(featName)); + button.setBackgroundColor(BTN_COLOR); + button.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setData(Uri.parse(url)); + getContext.startActivity(intent); + } + }); + linLayout.addView(button); + } + + private void ButtonOnOff(LinearLayout linLayout, final int featNum, String featName, boolean switchedOn) { + final Button button = new Button(getContext); + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT); + layoutParams.setMargins(7, 5, 7, 5); + button.setLayoutParams(layoutParams); + button.setTextColor(TEXT_COLOR_2); + button.setAllCaps(false); //Disable caps to support html + + final String finalfeatName = featName.replace("OnOff_", ""); + boolean isOn = Preferences.loadPrefBool(featName, featNum, switchedOn); + if (isOn) { + button.setText(Html.fromHtml(finalfeatName + ": ON")); + button.setBackgroundColor(BtnON); + isOn = false; + } else { + button.setText(Html.fromHtml(finalfeatName + ": OFF")); + button.setBackgroundColor(BtnOFF); + isOn = true; + } + final boolean finalIsOn = isOn; + button.setOnClickListener(new View.OnClickListener() { + boolean isOn = finalIsOn; + + public void onClick(View v) { + Preferences.changeFeatureBool(finalfeatName, featNum, isOn); + //Log.d(TAG, finalfeatName + " " + featNum + " " + isActive2); + if (isOn) { + button.setText(Html.fromHtml(finalfeatName + ": ON")); + button.setBackgroundColor(BtnON); + isOn = false; + } else { + button.setText(Html.fromHtml(finalfeatName + ": OFF")); + button.setBackgroundColor(BtnOFF); + isOn = true; + } + } + }); + linLayout.addView(button); + } + + private void Spinner(LinearLayout linLayout, final int featNum, final String featName, final String list) { + Log.d(TAG, "spinner " + featNum + " " + featName + " " + list); + final List lists = new LinkedList<>(Arrays.asList(list.split(","))); + + // Create another LinearLayout as a workaround to use it as a background + // to keep the down arrow symbol. No arrow symbol if setBackgroundColor set + LinearLayout linearLayout2 = new LinearLayout(getContext); + LinearLayout.LayoutParams layoutParams2 = new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT); + layoutParams2.setMargins(7, 2, 7, 2); + linearLayout2.setOrientation(LinearLayout.VERTICAL); + linearLayout2.setBackgroundColor(BTN_COLOR); + linearLayout2.setLayoutParams(layoutParams2); + + final Spinner spinner = new Spinner(getContext, Spinner.MODE_DROPDOWN); + spinner.setLayoutParams(layoutParams2); + spinner.getBackground().setColorFilter(1, PorterDuff.Mode.SRC_ATOP); //trick to show white down arrow color + //Creating the ArrayAdapter instance having the list + ArrayAdapter aa = new ArrayAdapter(getContext, android.R.layout.simple_spinner_dropdown_item, lists); + aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + //Setting the ArrayAdapter data on the Spinner' + spinner.setAdapter(aa); + spinner.setSelection(Preferences.loadPrefInt(featName, featNum)); + spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parentView, View selectedItemView, int position, long id) { + Preferences.changeFeatureInt(spinner.getSelectedItem().toString(), featNum, position); + ((TextView) parentView.getChildAt(0)).setTextColor(TEXT_COLOR_2); + } + + @Override + public void onNothingSelected(AdapterView parent) { + } + }); + linearLayout2.addView(spinner); + linLayout.addView(linearLayout2); + } + + private void InputNum(LinearLayout linLayout, final int featNum, final String featName, final int maxValue) { + LinearLayout linearLayout = new LinearLayout(getContext); + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT); + layoutParams.setMargins(7, 5, 7, 5); + + final Button button = new Button(getContext); + int num = Preferences.loadPrefInt(featName, featNum); + button.setText(Html.fromHtml(featName + ": " + ((num == 0) ? 1 : num) + "")); + button.setAllCaps(false); + button.setLayoutParams(layoutParams); + button.setBackgroundColor(BTN_COLOR); + button.setTextColor(TEXT_COLOR_2); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + AlertDialog.Builder alertName = new AlertDialog.Builder(getContext); + final EditText editText = new EditText(getContext); + if (maxValue != 0) + editText.setHint("Max value: " + maxValue); + editText.setInputType(InputType.TYPE_CLASS_NUMBER); + editText.setKeyListener(DigitsKeyListener.getInstance("0123456789-")); + InputFilter[] FilterArray = new InputFilter[1]; + FilterArray[0] = new InputFilter.LengthFilter(10); + editText.setFilters(FilterArray); + editText.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + InputMethodManager imm = (InputMethodManager) getContext.getSystemService(getContext.INPUT_METHOD_SERVICE); + if (hasFocus) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY); + } else { + imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0); + } + } + }); + editText.requestFocus(); + + alertName.setTitle("Input number"); + alertName.setView(editText); + LinearLayout layoutName = new LinearLayout(getContext); + layoutName.setOrientation(LinearLayout.VERTICAL); + layoutName.addView(editText); // displays the user input bar + alertName.setView(layoutName); + + alertName.setPositiveButton("OK", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + int num; + try { + num = Integer.parseInt(TextUtils.isEmpty(editText.getText().toString()) ? "0" : editText.getText().toString()); + if (maxValue != 0 && num >= maxValue) + num = maxValue; + } catch (NumberFormatException ex) { + if (maxValue != 0) + num = maxValue; + else + num = 2147483640; + } + + button.setText(Html.fromHtml(featName + ": " + num + "")); + Preferences.changeFeatureInt(featName, featNum, num); + + editText.setFocusable(false); + } + }); + + alertName.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + // dialog.cancel(); // closes dialog + InputMethodManager imm = (InputMethodManager) getContext.getSystemService(getContext.INPUT_METHOD_SERVICE); + imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0); + } + }); + + if (overlayRequired) { + AlertDialog dialog = alertName.create(); // display the dialog + dialog.getWindow().setType(Build.VERSION.SDK_INT >= 26 ? 2038 : 2002); + dialog.show(); + } else { + alertName.show(); + } + } + }); + + linearLayout.addView(button); + linLayout.addView(linearLayout); + } + + private void InputText(LinearLayout linLayout, final int featNum, final String featName) { + LinearLayout linearLayout = new LinearLayout(getContext); + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT); + layoutParams.setMargins(7, 5, 7, 5); + + final Button button = new Button(getContext); + + String string = Preferences.loadPrefString(featName, featNum); + button.setText(Html.fromHtml(featName + ": " + string + "")); + + button.setAllCaps(false); + button.setLayoutParams(layoutParams); + button.setBackgroundColor(BTN_COLOR); + button.setTextColor(TEXT_COLOR_2); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + AlertDialog.Builder alertName = new AlertDialog.Builder(getContext); + + final EditText editText = new EditText(getContext); + editText.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + InputMethodManager imm = (InputMethodManager) getContext.getSystemService(getContext.INPUT_METHOD_SERVICE); + if (hasFocus) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY); + } else { + imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0); + } + } + }); + editText.requestFocus(); + + alertName.setTitle("Input text"); + alertName.setView(editText); + LinearLayout layoutName = new LinearLayout(getContext); + layoutName.setOrientation(LinearLayout.VERTICAL); + layoutName.addView(editText); // displays the user input bar + alertName.setView(layoutName); + + alertName.setPositiveButton("OK", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + String str = editText.getText().toString(); + button.setText(Html.fromHtml(featName + ": " + str + "")); + Preferences.changeFeatureString(featName, featNum, str); + editText.setFocusable(false); + } + }); + + alertName.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + //dialog.cancel(); // closes dialog + InputMethodManager imm = (InputMethodManager) getContext.getSystemService(getContext.INPUT_METHOD_SERVICE); + imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0); + } + }); + + + if (overlayRequired) { + AlertDialog dialog = alertName.create(); // display the dialog + dialog.getWindow().setType(Build.VERSION.SDK_INT >= 26 ? 2038 : 2002); + dialog.show(); + } else { + alertName.show(); + } + } + }); + + linearLayout.addView(button); + linLayout.addView(linearLayout); + } + + private void CheckBox(LinearLayout linLayout, final int featNum, final String featName, boolean switchedOn) { + final CheckBox checkBox = new CheckBox(getContext); + checkBox.setText(featName); + checkBox.setTextColor(TEXT_COLOR_2); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) + checkBox.setButtonTintList(ColorStateList.valueOf(CheckBoxColor)); + checkBox.setChecked(Preferences.loadPrefBool(featName, featNum, switchedOn)); + checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (checkBox.isChecked()) { + Preferences.changeFeatureBool(featName, featNum, isChecked); + } else { + Preferences.changeFeatureBool(featName, featNum, isChecked); + } + } + }); + linLayout.addView(checkBox); + } + + private void RadioButton(LinearLayout linLayout, final int featNum, String featName, final String list) { + //Credit: LoraZalora + final List lists = new LinkedList<>(Arrays.asList(list.split(","))); + + final TextView textView = new TextView(getContext); + textView.setText(featName + ":"); + textView.setTextColor(TEXT_COLOR_2); + + final RadioGroup radioGroup = new RadioGroup(getContext); + radioGroup.setPadding(10, 5, 10, 5); + radioGroup.setOrientation(LinearLayout.VERTICAL); + radioGroup.addView(textView); + + for (int i = 0; i < lists.size(); i++) { + final RadioButton Radioo = new RadioButton(getContext); + final String finalfeatName = featName, radioName = lists.get(i); + View.OnClickListener first_radio_listener = new View.OnClickListener() { + public void onClick(View v) { + textView.setText(Html.fromHtml(finalfeatName + ": " + radioName)); + Preferences.changeFeatureInt(finalfeatName, featNum, radioGroup.indexOfChild(Radioo)); + } + }; + System.out.println(lists.get(i)); + Radioo.setText(lists.get(i)); + Radioo.setTextColor(Color.LTGRAY); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) + Radioo.setButtonTintList(ColorStateList.valueOf(RadioColor)); + Radioo.setOnClickListener(first_radio_listener); + radioGroup.addView(Radioo); + } + + int index = Preferences.loadPrefInt(featName, featNum); + if (index > 0) { //Preventing it to get an index less than 1. below 1 = null = crash + textView.setText(Html.fromHtml(featName + ": " + lists.get(index - 1))); + ((RadioButton) radioGroup.getChildAt(index)).setChecked(true); + } + linLayout.addView(radioGroup); + } + + private void Collapse(LinearLayout linLayout, final String text, final boolean expanded) { + LinearLayout.LayoutParams layoutParamsLL = new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT); + layoutParamsLL.setMargins(0, 5, 0, 0); + + LinearLayout collapse = new LinearLayout(getContext); + collapse.setLayoutParams(layoutParamsLL); + collapse.setVerticalGravity(16); + collapse.setOrientation(LinearLayout.VERTICAL); + + final LinearLayout collapseSub = new LinearLayout(getContext); + collapseSub.setVerticalGravity(16); + collapseSub.setPadding(0, 5, 0, 5); + collapseSub.setOrientation(LinearLayout.VERTICAL); + collapseSub.setBackgroundColor(Color.parseColor("#222D38")); + collapseSub.setVisibility(View.GONE); + mCollapse = collapseSub; + + final TextView textView = new TextView(getContext); + textView.setBackgroundColor(CategoryBG); + textView.setText("▽ " + text + " ▽"); + textView.setGravity(Gravity.CENTER); + textView.setTextColor(TEXT_COLOR_2); + textView.setTypeface(null, Typeface.BOLD); + textView.setPadding(0, 20, 0, 20); + + if (expanded) { + collapseSub.setVisibility(View.VISIBLE); + textView.setText("△ " + text + " △"); + } + + textView.setOnClickListener(new View.OnClickListener() { + boolean isChecked = expanded; + + @Override + public void onClick(View v) { + + boolean z = !isChecked; + isChecked = z; + if (z) { + collapseSub.setVisibility(View.VISIBLE); + textView.setText("△ " + text + " △"); + return; + } + collapseSub.setVisibility(View.GONE); + textView.setText("▽ " + text + " ▽"); + } + }); + collapse.addView(textView); + collapse.addView(collapseSub); + linLayout.addView(collapse); + } + + private void Category(LinearLayout linLayout, String text) { + TextView textView = new TextView(getContext); + textView.setBackgroundColor(CategoryBG); + textView.setText(Html.fromHtml(text)); + textView.setGravity(Gravity.CENTER); + textView.setTextColor(TEXT_COLOR_2); + textView.setTypeface(null, Typeface.BOLD); + textView.setPadding(0, 5, 0, 5); + linLayout.addView(textView); + } + + private void TextView(LinearLayout linLayout, String text) { + TextView textView = new TextView(getContext); + textView.setText(Html.fromHtml(text)); + textView.setTextColor(TEXT_COLOR_2); + textView.setPadding(10, 5, 10, 5); + linLayout.addView(textView); + } + + private void WebTextView(LinearLayout linLayout, String text) { + WebView wView = new WebView(getContext); + wView.loadData(text, "text/html", "utf-8"); + wView.setBackgroundColor(0x00000000); //Transparent + wView.setPadding(0, 5, 0, 5); + linLayout.addView(wView); + } + + private boolean isViewCollapsed() { + return rootFrame == null || mCollapsed.getVisibility() == View.VISIBLE; + } + + //For our image a little converter + private int convertDipToPixels(int i) { + return (int) ((((float) i) * getContext.getResources().getDisplayMetrics().density) + 0.5f); + } + + private int dp(int i) { + return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float) i, getContext.getResources().getDisplayMetrics()); + } + + public void setVisibility(int view) { + if (rootFrame != null) { + rootFrame.setVisibility(view); + } + } + + public void onDestroy() { + if (rootFrame != null) { + mWindowManager.removeView(rootFrame); + } + } +} diff --git a/app/src/main/java/com/android/support/Preferences.java b/app/src/main/java/com/android/support/Preferences.java new file mode 100644 index 0000000..050dfdb --- /dev/null +++ b/app/src/main/java/com/android/support/Preferences.java @@ -0,0 +1,483 @@ +package com.android.support; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Build; + +import java.util.LinkedHashSet; +import java.util.Set; + +public class Preferences { + private static SharedPreferences sharedPreferences; + private static Preferences prefsInstance; + public static Context context; + public static boolean loadPref, isExpanded; + + private static final String LENGTH = "_length"; + private static final String DEFAULT_STRING_VALUE = ""; + private static final int DEFAULT_INT_VALUE = 0; //-1 + private static final double DEFAULT_DOUBLE_VALUE = 0d; //-1d + private static final float DEFAULT_FLOAT_VALUE = 0f; //-1f + private static final long DEFAULT_LONG_VALUE = 0L; //-1L + private static final boolean DEFAULT_BOOLEAN_VALUE = false; + + + public static void changeFeatureInt(String featureName, int featureNum, int value) { + Preferences.with(context).writeInt(featureNum, value); + Menu.Changes(context, featureNum, featureName, value, false, null); + } + + public static void changeFeatureString(String featureName, int featureNum, String str) { + Preferences.with(context).writeString(featureNum, str); + Menu.Changes(context, featureNum, featureName, 0, false, str); + } + + public static void changeFeatureBool(String featureName, int featureNum, boolean bool) { + Preferences.with(context).writeBoolean(featureNum, bool); + Menu.Changes(context, featureNum, featureName, 0, bool, null); + } + + public static int loadPrefInt(String featureName, int featureNum) { + if (loadPref) { + int i = Preferences.with(context).readInt(featureNum); + Menu.Changes(context, featureNum, featureName, i, false, null); + return i; + } + return 0; + } + + public static boolean loadPrefBool(String featureName, int featureNum, boolean bDef) { + boolean bool = Preferences.with(context).readBoolean(featureNum, bDef); + if (featureNum == -1) { + loadPref = bool; + } + if (featureNum == -3) { + isExpanded = bool; + } + if (loadPref || featureNum < 0) { + bDef = bool; + } + + Menu.Changes(context, featureNum, featureName, 0, bDef, null); + return bDef; + } + + public static String loadPrefString(String featureName, int featureNum) { + if (loadPref || featureNum <= 0) { + String str = Preferences.with(context).readString(featureNum); + Menu.Changes(context, featureNum, featureName, 0, false, str); + return str; + } + return ""; + } + + private Preferences(Context context) { + sharedPreferences = context.getApplicationContext().getSharedPreferences( + context.getPackageName() + "_preferences", + Context.MODE_PRIVATE + ); + } + + private Preferences(Context context, String preferencesName) { + sharedPreferences = context.getApplicationContext().getSharedPreferences( + preferencesName, + Context.MODE_PRIVATE + ); + } + + /** + * @param context + * @return Returns a 'Preferences' instance + */ + public static Preferences with(Context context) { + if (prefsInstance == null) { + prefsInstance = new Preferences(context); + } + return prefsInstance; + } + + /** + * @param context + * @param forceInstantiation + * @return Returns a 'Preferences' instance + */ + public static Preferences with(Context context, boolean forceInstantiation) { + if (forceInstantiation) { + prefsInstance = new Preferences(context); + } + return prefsInstance; + } + + /** + * @param context + * @param preferencesName + * @return Returns a 'Preferences' instance + */ + public static Preferences with(Context context, String preferencesName) { + if (prefsInstance == null) { + prefsInstance = new Preferences(context, preferencesName); + } + return prefsInstance; + } + + /** + * @param context + * @param preferencesName + * @param forceInstantiation + * @return Returns a 'Preferences' instance + */ + public static Preferences with(Context context, String preferencesName, + boolean forceInstantiation) { + if (forceInstantiation) { + prefsInstance = new Preferences(context, preferencesName); + } + return prefsInstance; + } + + // String related methods + + /** + * @param what + * @return Returns the stored value of 'what' + */ + public String readString(String what) { + return sharedPreferences.getString(what, DEFAULT_STRING_VALUE); + } + + /** + * @param what + * @return Returns the stored value of 'what' + */ + public String readString(int what) { + try { + return sharedPreferences.getString(String.valueOf(what), DEFAULT_STRING_VALUE); + } catch (java.lang.ClassCastException ex) { + return ""; + } + } + + /** + * @param what + * @param defaultString + * @return Returns the stored value of 'what' + */ + public String readString(String what, String defaultString) { + return sharedPreferences.getString(what, defaultString); + } + + /** + * @param where + * @param what + */ + public void writeString(String where, String what) { + sharedPreferences.edit().putString(where, what).apply(); + } + + /** + * @param where + * @param what + */ + public void writeString(int where, String what) { + sharedPreferences.edit().putString(String.valueOf(where), what).apply(); + } + + // int related methods + + /** + * @param what + * @return Returns the stored value of 'what' + */ + public int readInt(String what) { + return sharedPreferences.getInt(what, DEFAULT_INT_VALUE); + } + + + /** + * @param what + * @return Returns the stored value of 'what' + */ + public int readInt(int what) { + try { + return sharedPreferences.getInt(String.valueOf(what), DEFAULT_INT_VALUE); + } catch (java.lang.ClassCastException ex) { + return 0; + } + } + + /** + * @param what + * @param defaultInt + * @return Returns the stored value of 'what' + */ + public int readInt(String what, int defaultInt) { + return sharedPreferences.getInt(what, defaultInt); + } + + /** + * @param where + * @param what + */ + public void writeInt(String where, int what) { + sharedPreferences.edit().putInt(where, what).apply(); + } + + /** + * @param where + * @param what + */ + public void writeInt(int where, int what) { + sharedPreferences.edit().putInt(String.valueOf(where), what).apply(); + } + + // double related methods + + /** + * @param what + * @return Returns the stored value of 'what' + */ + public double readDouble(String what) { + if (!contains(what)) + return DEFAULT_DOUBLE_VALUE; + return Double.longBitsToDouble(readLong(what)); + } + + /** + * @param what + * @param defaultDouble + * @return Returns the stored value of 'what' + */ + public double readDouble(String what, double defaultDouble) { + if (!contains(what)) + return defaultDouble; + return Double.longBitsToDouble(readLong(what)); + } + + /** + * @param where + * @param what + */ + public void writeDouble(String where, double what) { + writeLong(where, Double.doubleToRawLongBits(what)); + } + + // float related methods + + /** + * @param what + * @return Returns the stored value of 'what' + */ + public float readFloat(String what) { + return sharedPreferences.getFloat(what, DEFAULT_FLOAT_VALUE); + } + + /** + * @param what + * @param defaultFloat + * @return Returns the stored value of 'what' + */ + public float readFloat(String what, float defaultFloat) { + return sharedPreferences.getFloat(what, defaultFloat); + } + + /** + * @param where + * @param what + */ + public void writeFloat(String where, float what) { + sharedPreferences.edit().putFloat(where, what).apply(); + } + + // long related methods + + /** + * @param what + * @return Returns the stored value of 'what' + */ + public long readLong(String what) { + return sharedPreferences.getLong(what, DEFAULT_LONG_VALUE); + } + + /** + * @param what + * @param defaultLong + * @return Returns the stored value of 'what' + */ + public long readLong(String what, long defaultLong) { + return sharedPreferences.getLong(what, defaultLong); + } + + /** + * @param where + * @param what + */ + public void writeLong(String where, long what) { + sharedPreferences.edit().putLong(where, what).apply(); + } + + // boolean related methods + + /** + * @param what + * @return Returns the stored value of 'what' + */ + public boolean readBoolean(String what) { + return sharedPreferences.getBoolean(what, DEFAULT_BOOLEAN_VALUE); + } + + /** + * @param what + * @return Returns the stored value of 'what' + */ + public boolean readBoolean(int what) { + return sharedPreferences.getBoolean(String.valueOf(what), DEFAULT_BOOLEAN_VALUE); + } + + /** + * @param what + * @param defaultBoolean + * @return Returns the stored value of 'what' + */ + public boolean readBoolean(String what, boolean defaultBoolean) { + /*if (defaultBoolean == true && !sharedPreferences.contains(what)) + writeBoolean(what, true);*/ + return sharedPreferences.getBoolean(what, defaultBoolean); + } + + /** + * @param what + * @param defaultBoolean + * @return Returns the stored value of 'what' + */ + public boolean readBoolean(int what, boolean defaultBoolean) { + /*if (defaultBoolean == true && !sharedPreferences.contains(String.valueOf(what))) + writeBoolean(what, true);*/ + try { + return sharedPreferences.getBoolean(String.valueOf(what), defaultBoolean); + } catch (java.lang.ClassCastException ex) { + return defaultBoolean; + } + } + + /** + * @param where + * @param what + */ + public void writeBoolean(String where, boolean what) { + sharedPreferences.edit().putBoolean(where, what).apply(); + } + + /** + * @param where + * @param what + */ + public void writeBoolean(int where, boolean what) { + sharedPreferences.edit().putBoolean(String.valueOf(where), what).apply(); + } + + // String set methods + + /** + * @param key + * @param value + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + public void putStringSet(final String key, final Set value) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + sharedPreferences.edit().putStringSet(key, value).apply(); + } else { + // Workaround for pre-HC's lack of StringSets + putOrderedStringSet(key, value); + } + } + + /** + * @param key + * @param value + */ + public void putOrderedStringSet(String key, Set value) { + int stringSetLength = 0; + if (sharedPreferences.contains(key + LENGTH)) { + // First read what the value was + stringSetLength = readInt(key + LENGTH); + } + writeInt(key + LENGTH, value.size()); + int i = 0; + for (String aValue : value) { + writeString(key + "[" + i + "]", aValue); + i++; + } + for (; i < stringSetLength; i++) { + // Remove any remaining values + remove(key + "[" + i + "]"); + } + } + + /** + * @param key + * @param defValue + * @return Returns the String Set with HoneyComb compatibility + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + public Set getStringSet(final String key, final Set defValue) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + return sharedPreferences.getStringSet(key, defValue); + } else { + // Workaround for pre-HC's missing getStringSet + return getOrderedStringSet(key, defValue); + } + } + + /** + * @param key + * @param defValue + * @return Returns the ordered String Set + */ + public Set getOrderedStringSet(String key, final Set defValue) { + if (contains(key + LENGTH)) { + LinkedHashSet set = new LinkedHashSet<>(); + int stringSetLength = readInt(key + LENGTH); + if (stringSetLength >= 0) { + for (int i = 0; i < stringSetLength; i++) { + set.add(readString(key + "[" + i + "]")); + } + } + return set; + } + return defValue; + } + + // end related methods + + /** + * @param key + */ + public void remove(final String key) { + if (contains(key + LENGTH)) { + // Workaround for pre-HC's lack of StringSets + int stringSetLength = readInt(key + LENGTH); + if (stringSetLength >= 0) { + sharedPreferences.edit().remove(key + LENGTH).apply(); + for (int i = 0; i < stringSetLength; i++) { + sharedPreferences.edit().remove(key + "[" + i + "]").apply(); + } + } + } + sharedPreferences.edit().remove(key).apply(); + } + + /** + * @param key + * @return Returns if that key exists + */ + public boolean contains(final String key) { + return sharedPreferences.contains(key); + } + + /** + * Clear all the preferences + */ + public void clear() { + sharedPreferences.edit().clear().apply(); + } +} diff --git a/app/src/main/jni/Android.mk b/app/src/main/jni/Android.mk index e0404db..fcfe6dc 100644 --- a/app/src/main/jni/Android.mk +++ b/app/src/main/jni/Android.mk @@ -1,20 +1,23 @@ LOCAL_PATH := $(call my-dir) -MAIN_LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) -LOCAL_MODULE := nativelgl +# Here is the name of your lib. +# When you change the lib name, change also on System.loadLibrary("") under OnCreate method on StaticActivity.java +# Both must have same name +LOCAL_MODULE := LGL -LOCAL_CFLAGS := -Wno-error=format-security -fvisibility=hidden -ffunction-sections -fdata-sections -w -LOCAL_CFLAGS += -fno-rtti -fno-exceptions -fpermissive -LOCAL_CPPFLAGS := -Wno-error=format-security -fvisibility=hidden -ffunction-sections -fdata-sections -w -Werror -s -std=c++17 -LOCAL_CPPFLAGS += -Wno-error=c++11-narrowing -fms-extensions -fno-rtti -fno-exceptions -fpermissive -LOCAL_LDFLAGS += -Wl,--gc-sections,--strip-all, -llog +# -std=c++17 is required to support AIDE app with NDK +LOCAL_CFLAGS := -w -s -Wno-error=format-security -fvisibility=hidden -fpermissive -fexceptions +LOCAL_CPPFLAGS := -w -s -Wno-error=format-security -fvisibility=hidden -Werror -std=c++17 +LOCAL_CPPFLAGS += -Wno-error=c++11-narrowing -fpermissive -Wall -fexceptions +LOCAL_LDFLAGS += -Wl,--gc-sections,--strip-all,-llog +LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv2 LOCAL_ARM_MODE := arm -LOCAL_C_INCLUDES += $(MAIN_LOCAL_PATH) +LOCAL_C_INCLUDES += $(LOCAL_PATH) +# Here you add the cpp file to compile LOCAL_SRC_FILES := Main.cpp \ - JavaGPP/Interface/Interface.cpp \ Substrate/hde64.c \ Substrate/SubstrateDebug.cpp \ Substrate/SubstrateHook.cpp \ @@ -26,6 +29,4 @@ LOCAL_SRC_FILES := Main.cpp \ KittyMemory/KittyUtils.cpp \ And64InlineHook/And64InlineHook.cpp \ -LOCAL_LDLIBS := -llog -landroid -lGLESv2 - include $(BUILD_SHARED_LIBRARY) diff --git a/app/src/main/jni/Application.mk b/app/src/main/jni/Application.mk index b80731c..1b6ff66 100644 --- a/app/src/main/jni/Application.mk +++ b/app/src/main/jni/Application.mk @@ -1,4 +1,6 @@ -APP_ABI := arm64-v8a armeabi-v7a x86 x86_64 +# To AIDE Users: If you are using 32-bit/ARMv7 phone, please remove arm64-v8a +APP_ABI := armeabi-v7a arm64-v8a x86 +# APP_PLATFORM := android-18 #APP_PLATFORM does not need to be set. It will automatically defaulting APP_STL := c++_static APP_OPTIM := release APP_THIN_ARCHIVE := true diff --git a/app/src/main/jni/Includes/Dex.h b/app/src/main/jni/Includes/Dex.h new file mode 100644 index 0000000..c2c9a7d --- /dev/null +++ b/app/src/main/jni/Includes/Dex.h @@ -0,0 +1 @@ +#define hexdex "6465780A3033390088AFB5BBB2B8D5D302A3CF4C6C34DBEBC380D7DA27757F8304B200007000000078563412000000000000000034B10000E80200007000000096000000100C0000B3000000680E000091000000CC16000086010000541B0000230000008427000020860000E42B0000087400000A7400000D74000013740000197400002C74000038740000437400004C740000557400005E740000677400007074000079740000827400008B740000947400009F740000AA740000B3740000B7740000BA740000BF740000C4740000CB740000CE740000D7740000DA740000E7740000EA740000FB7400000275000008750000117500001B7500005E750000667500006A7500006F750000757500007F7500008A7500009275000099750000A1750000AD750000BA750000C2750000CC750000D8750000E1750000EB750000FA75000004760000127600001E760000217600002F760000467600005C760000717600008476000098760000AE760000B2760000B6760000BB760000BE760000C4760000CC760000D0760000D5760000E2760000F27600000477000007770000137700001E77000022770000287700002C77000031770000367700003C7700006C7700007D77000083770000917700009D770000A7770000B2770000BE770000C1770000C5770000C9770000CE770000D1770000D9770000DE770000E2770000E6770000EB770000F0770000F6770000FB77000000780000067800000C78000011780000297800004C7800006778000082780000B5780000D8780000F27800001E79000043790000697900008A790000A5790000C7790000E1790000057A0000227A0000487A0000767A0000897A00009E7A0000B47A0000C97A0000E27A0000F77A0000207B0000387B00005D7B0000777B0000A07B0000C37B0000DA7B0000F97B00000D7C0000287C0000447C0000697C0000947C0000BD7C0000E27C0000F77C00001E7D00004B7D0000627D00008D7D0000AB7D0000DA7D0000F47D0000297E0000477E0000657E0000867E0000A57E0000BE7E0000D97E0000127F0000337F00004E7F00006C7F0000927F0000AE7F0000DA7F0000F97F000017800000348000006280000083800000A0800000D2800000EC8000000681000027810000408100005B8100007381000097810000B6810000D5810000F48100001382000032820000538200007482000095820000B4820000D5820000F68200001783000036830000558300007483000093830000B1830000CF830000ED8300000B84000029840000478400006584000083840000A1840000BD840000E0840000FF84000021850000418500006185000081850000A0850000B9850000DD8500000286000022860000458600006B8600008A860000A1860000BB860000CE860000E486000004870000188700003B870000508700007287000095870000A9870000BF870000D3870000EE870000028800001D880000398800004D880000658800007B88000096880000C5880000DD880000EF88000015890000268900003B8900004C8900005D890000828900008B8900009A890000A7890000BE890000CB890000D7890000E1890000F4890000018A00000E8A0000198A0000238A0000338A0000378A00003F8A0000468A00004D8A00005F8A00006C8A0000788A0000808A00008E8A00009B8A0000A58A0000AE8A0000BC8A0000D28A0000EC8A0000FA8A0000048B00000D8B0000158B00001A8B0000268B0000348B00003E8B0000468B0000518B00005B8B00005E8B0000628B0000668B00006B8B0000728B00007C8B0000818B0000868B00008A8B00008F8B0000948B0000998B00009F8B0000A58B0000AC8B0000B48B0000BC8B0000C58B0000CC8B0000D48B0000DB8B0000E18B0000E68B0000EB8B0000F18B0000F88B0000FF8B0000058C00000C8C0000168C00001C8C0000218C0000298C0000318C0000358C0000428C0000458C0000498C00004E8C0000528C0000588C00005D8C0000628C0000678C00006A8C00006E8C0000728C00008F8C0000A38C0000B88C0000CD8C0000D28C0000D58C0000D88C0000DF8C0000E88C0000F68C0000FE8C0000028D00000E8D00001A8D0000268D0000328D00003E8D00004B8D0000578D0000618D0000708D0000758D00007E8D0000878D0000928D0000AE8D0000CA8D0000D48D0000DC8D0000E38D0000F38D0000048E0000088E0000108E0000148E00001B8E0000218E0000328E0000388E0000408E00004E8E00005A8E00006D8E00007F8E0000948E00009E8E0000A58E0000AF8E0000B98E0000C68E0000D58E0000DC8E0000EC8E0000F68E0000FF8E0000138F00001B8F0000248F00003B8F00003E8F0000468F0000578F0000618F0000718F0000808F00008E8F00009A8F0000A78F0000B68F0000BF8F0000C78F0000DC8F0000E08F0000EA8F0000F08F0000FA8F00000290000006900000109000001E90000028900000319000003A9000004790000054900000609000006B9000007A9000009090000099900000AD900000B7900000C3900000C8900000D3900000EA900000F990000005910000119100001B91000027910000399100004C9100005F91000069910000769100007E9100008F91000098910000A7910000BC910000CC910000E1910000EA910000F39100000192000012920000289200003392000041920000539200005C9200006692000078920000889200009A920000A9920000B4920000C6920000CF920000D8920000E2920000EB920000F5920000FD9200000693000009930000169300002E93000046930000599300005D93000062930000699300007793000086930000959300009F930000A9930000B7930000BF930000C7930000D2930000E0930000E9930000F5930000FB9300000C940000169400001B9400002C9400003C94000044940000509400005E9400006D9400007D9400008894000096940000A5940000AB940000B3940000BA940000C1940000CB940000D8940000E2940000F0940000FD9400000D950000199500002B95000038950000439500004F9500005A9500006A95000075950000859500008F950000949500009D950000A2950000AC950000B2950000B7950000BF950000C5950000D2950000D8950000DF950000E5950000EA950000FC950000059600000F9600001A960000299600003996000046960000599600006C9600008296000097960000A0960000B1960000B6960000C7960000CF960000DB960000E2960000EE960000F8960000009700000A970000109700001D9700002E9700003D97000046970000529700005C970000649700006D970000829700008D9700009B970000A7970000B2970000B8970000BE970000CB970000D7970000E2970000EB970000F597000001980000099800001998000021980000319800003D98000046980000549800006298000066980000729800007D98000082980000969800009E980000AE980000B8980000C4980000CD980000DF980000E4980000F3980000FF9800000B99000015990000299900003C990000489900005299000062990000739900007C99000095990000A3990000AF990000B9990000C7990000D3990000DC990000EC990000FA9900000A9A00001B9A0000279A00003E9A0000469A00004E9A0000619A00007D9A0000919A0000AB9A0000C69A0000DE9A0000FA9A00000E9B00001E9B00002A9B00003D9B00004A9B0000589B0000659B0000739B0000829B00008D9B0000969B0000A49B0000B19B0000BB9B0000C89B0000D29B0000DB9B0000E89B0000FC9B0000059C0000149C00001E9C00002C9C00003F9C0000459C00004B9C0000549C00005E9C0000659C0000749C0000809C00008E9C0000939C00009D9C0000A59C0000B69C0000BD9C0000C69C0000D09C0000D79C0000E09C0000EC9C0000F29C0000FD9C0000079D00000F9D0000179D00001E9D0000299D0000339D0000449D00004F9D0000619D0000669D00006D9D0000709D00007C9D0000889D0000969D0000A79D0000B59D0000C39D0000D19D0000DE9D0000ED9D0000009E00000E9E0000179E0000279E0000369E0000439E0000509E00005A9E0000689E0000719E0000789E0000819E0000899E00008F9E00009B9E0000A59E0000AC9E0000B49E0000BA9E0000C19E0000CE9E0000D59E0000DB9E0000E99E0000F69E0000029F00000C9F0000179F0000249F0000279F00002B9F00002F9F0000339F0000369F0000399F0000A19F00008FA5000095A500009BA5000037000000420000004A0000005B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000000800000008100000082000000830000008400000085000000860000008700000088000000890000008A0000008B0000008C0000008D0000008E0000008F000000900000009100000092000000930000009400000095000000960000009700000098000000990000009A0000009B0000009C0000009F000000A0000000A1000000A2000000A3000000A4000000A5000000A6000000A7000000A8000000A9000000AA000000AB000000AC000000AD000000AE000000AF000000B0000000B1000000B2000000B3000000B4000000B5000000B6000000B7000000B8000000B9000000BA000000BB000000BC000000BD000000BE000000BF000000C0000000C1000000C2000000C3000000C4000000C5000000C6000000C7000000C8000000C9000000CA000000CB000000CC000000CD000000CE000000CF000000D0000000D1000000D2000000D3000000D4000000D5000000D6000000D7000000D8000000D9000000DA000000DB000000DC000000DD000000DE000000DF000000E0000000E1000000E3000000E4000000E5000000E6000000E7000000E8000000E9000000EA000000EB000000EC000000ED000000EE000000EF000000F0000000F1000000F2000000F3000000F5000000F6000000F8000000FA0000002401000048010000510100005201000053010000540100005501000056010000570100003F000000000000006C70000040000000000000007470000041000000000000007C7000004200000001000000000000004300000001000000847000004500000001000000747000004600000001000000907000004A00000002000000000000004D00000002000000987000004F00000002000000A07000004F00000002000000747000005000000002000000A87000005100000002000000B07000005C00000003000000B87000005D00000003000000747000005E00000003000000C07000005F00000004000000000000006300000005000000A07000006300000005000000C87000006800000005000000D07000005F00000006000000000000005F0000000700000000000000620000000A00000098700000630000000A000000D87000005F0000000B00000000000000630000000B00000074700000640000000B00000090700000650000000B000000A8700000670000000B000000C0700000680000000B000000B0700000680000000B000000E07000006B0000000B000000E8700000650000000C000000A8700000620000000D000000987000005F0000000E00000000000000660000000F000000F07000005F00000014000000000000006300000016000000747000005F00000019000000000000005F0000001A00000000000000630000001D000000747000006300000020000000747000005F00000023000000000000005F0000002A00000000000000620000002B000000987000005F0000002C000000000000005F0000002E000000000000005F0000003000000000000000690000004B000000FC7000005F00000066000000000000006300000066000000087100006300000067000000107100006800000067000000187100006A00000067000000207100006B000000670000002C7100005F00000077000000000000006300000077000000747000005F0000007E00000000000000620000007E00000098700000630000007E00000034710000680000007E0000003C710000630000007E000000747000005F00000080000000000000006200000080000000987000006800000080000000447100006300000080000000347100006300000080000000747000006500000080000000A87000006800000080000000B070000062000000810000009870000063000000810000007470000063000000830000007470000068000000840000004C7100005F00000086000000000000005F0000008700000000000000630000008A00000054710000680000008C000000E0700000240100008D00000000000000250100008D0000005C710000260100008D00000098700000270100008D00000064710000280100008D0000006C710000290100008D000000787100002A0100008D0000008C7100002A0100008D000000947100002B0100008D0000009C7100002C0100008D000000107100002F0100008D000000A4710000350100008D000000AC710000310100008D000000BC7100003F0100008D000000C87100003B0100008D000000187100002F0100008D000000D47100002C0100008D000000DC7100002C0100008D000000E47100002C0100008D000000EC7100002C0100008D000000F47100002F0100008D000000FC7100002C0100008D000000047200002C0100008D0000000C7200002C0100008D000000147200002C0100008D0000001C7200002C0100008D0000002C7000002C0100008D0000003C7000002C0100008D000000547000002C0100008D000000647000002C0100008D000000A07000003B0100008D00000024720000430100008D0000002C7200002C0100008D000000347200002C0100008D000000347000002C0100008D0000003C7200003D0100008D000000447200002C0100008D0000004C700000430100008D000000507200002C0100008D00000058720000310100008D00000060720000320100008D0000006C720000330100008D00000078720000360100008D00000088720000380100008D000000947200003B0100008D000000A07200003F0100008D000000A8720000420100008D000000B47200002C0100008D000000247000002C0100008D000000C0720000390100008D000000C87200002C0100008D000000D47200002C0100008D000000DC7200003B0100008D000000E47200002C0100008D000000EC7200003B0100008D000000F47200002C0100008D00000008710000370100008D000000FC720000310100008D0000000C730000340100008D00000018730000400100008D00000028730000400100008D000000347300003C0100008D00000040730000410100008D0000004C7300003B0100008D000000607300003E0100008D00000068730000450100008D00000074730000440100008D000000847300003F0100008D000000947300002C0100008D000000C87000002C0100008D000000747000002D0100008D0000007C7000002E0100008D000000907000002F0100008D000000A8700000300100008D000000A0730000310100008D000000AC730000390100008D000000B87300003A0100008D000000C07000003B0100008D000000B07000003F0100008D000000C47300003B0100008D000000E0700000430100008D000000E87000002C0100008D000000D0730000460100008D000000D87300002C0100008D000000E07300003B0100008D000000E87300003B0100008D000000F0730000480100008E00000000000000490100008E000000987000004A0100008E0000009C7100004B0100008E000000A07000004E0100008E000000F87300004B0100008E000000087100004B0100008E000000C87000004B0100008E000000347100004B0100008E0000005C7000004D0100008E000000007400004B0100008E000000747000004C0100008E000000B87300004F0100008E000000E8700000650000008F000000A87000005F0000009400000000000000630000009400000074700000120012001401000013001300380000001E001E00FD00000023000100980100002C000200D90100002C000200D50200002D000200B20200002F000200D40100002F000200DD0200002F000200E10200003C003C00440000003E000100D10200004D006600AC0200004D008000BD0200004D000200BE0200004D000200C20200004D004A00C80200004E006600AC0200004E008000BD0200004E000200BE0200004F006600AC0200004F008000C902000050008E00EF01000050006600AC02000050003600B802000050000200BE02000050008E00BF02000050008000C002000051006600AC02000051000200BE02000051004700C502000052005500AD02000053005500AD02000053003A00BB02000054005500AD02000055006600AC02000055003600B802000055008000BD02000055000200BE02000055000200C102000056005900AD02000057005900AD02000057003A00BB02000058005900AD02000059006600AC02000059003600B802000059008000BD02000059000200BE0200005A006600AC0200005A003700B90200005A008000BD0200005A000200BE0200005B006600AC0200005B004000B70200005B000200BE0200005B008000C00200005B004100C30200005B008000C40200005B004A00C80200005C008E00EB0100005C006600AC0200005C003F00BA0200005C008E00BC0200005C008000C70200005C004A00C80200005D006600AC0200005E008E00950200005E006600AC0200005F006600AC02000060006600AC02000061006600AC02000063006600AC02000063008E00CE02000064002B008501000064002B00A201000064000100E401000064000100E501000064000200E601000064000200E701000064006600AC02000065006600AC02000065008000BD02000065000200BE02000065004900C602000066000200280000006600020029000000660002002A00000066000200300000006600020033000000660001004B000000660002004C00000066000200FE00000066000100FF0000006600020000010000660002000101000066000200020100006600800009010000660002000C010000660002000D010000660002001001000066000200160100006600020017010000660080001D010000660002001E010000660002001F0100006600020022010000660002002301000066000700B701000066003F000A020000660043000B02000066003F000C020000660043000D02000066003F000E020000660030000F020000660066001502000066003F001802000066008E002C02000066003B005402000066003E005702000066003E0058020000660044005A02000066003D009D02000066008E009E02000066002F00CF02000067008E0039000000670000003A000000670001003B000000670002003C000000670003003D000000670080003E0000006700800060000000670007008901000067008E00EE01000067008E0003020000670067003702000067000C0096020000680002007801000068000200DD01000069000200DE0100006A000200670100006B000200DC0100006B000200DF0100006C0002006E0100006D00020027000000820075002B02000004004D002300000004002F00D3010000040062002002000004004F008C0200000500560023000000050014008B01000005001300780200000500130082020000050012008E0200000500110092020000050014009702000006002E00D201000006004D009702000007001500B201000007003E00C201000007002200C601000007002000C801000007003D00CB01000007005D009C0200000A009200230000000A001700680200000A0016006C0200000B004D00700100000B001800810100000B001F00390200000B001A003A0200000B001B003B0200000B001C003C0200000B001D003E0200000B001E003F0200000B0019004C0200000C00AD00880100000C0018009D0100000C00AF00B40100000C000600BB0100000C000B00BD0100000C000F00BF0100000C004400C90100000C004C00CA0100000D00A200230000000D002100CB0200000E002A00BA010000100023009001000011000A0030020000140053006602000014005E008D02000015004D002300000015004F006502000015004E00670200001500500088020000160025002F02000018004D002300000018006300230000001800AB00340200001800AC003502000019002600C00100001B002800AE0100001C004F00230000001F00A900EC0100001F00A900ED01000020002900BC0100002200B0008F01000024000C008E010000250004007101000026000700B101000026000300C401000026000300C50100002B001500B70100002B004F00930200002E004F008F0200002F0052002300000030006B006A01000030006A004E02000030006B00B302000031005000B1020000320056002300000032002D00BE01000032009B000102000032004E006102000032004F006202000032006D0073020000320069007F020000320051008102000034002C00B5010000350059002300000035004F0069020000360056002300000036009F006002000036004F006202000036006D0073020000360066007A020000360068007D020000360091008902000036004F008A02000037005600230000003700A300EB01000037005E006302000037009F00640200003700710079020000370091008902000037004F008A0200003A005600230000003A002700CC0100003A00A300510200003A00A0006B0200003A009F006D0200003A0091006F0200003A004F00710200003A006500720200003A0067007B0200003B005600230000003B006A006A0100003B006A004E0200003B0069007F0200003B004F00930200003D005600230000003D002D00BE0100003D005F00700200003D006D00730200003D0066007A0200003D0069007F0200003D007300840200003E005000230000003E006D00230000003E005100740200003F005600230000003F006A006A0100003F002D00BE0100003F004D004D0200003F004E00610200003F004F00620200003F004F006E0200003F006D00730200003F004F00800200003F005100810200003F004F00910200003F004F0093020000400056002300000040005E006302000040009F0064020000400066007A020000400091008902000040004F008A020000410056002300000041006A006A01000041002C00B501000041000900E301000041004F00800200004100510081020000420050002300000042004F0069010000430056002300000043006A006A01000043000700D101000043004E0061020000430051008102000043004F009102000043004F0093020000440056002300000044006A006A01000044006A004E020000440050005902000044004F006202000044006D0073020000460056002300000046002400C301000046002400CD01000046004F007602000046004F007702000046007C007E020000460051008102000046004F0083020000470057002300000047002400B301000047003900C701000047007F005F02000047006D007302000047006E007C02000047004F0086020000490056002300000049001500B701000049002400CE01000049002400D001000049009F006402000049007100790200004900510081020000490091008902000049004F008A0200004A005600230000004A004F00620200004A0064006A0200004A004F006E0200004A006D00730200004A004F00750200004A0066007A0200004A005100810200004A009F00850200004A009F00870200004A009100890200004A004F008A0200004A004E008B0200004A006000900200004A006100900200004B003000100200004B004D00970200004C004D00210000004C004D00230000004C006200200200004D008700230000004D007E00260200004D007D00270200004D007D00280200004E008600230000004E006A001F0200004F008C00230000004F006A001F02000050008F002300000050006A001F02000051008A0023000000510070002302000051006F0025020000520080002300000052006C0022020000530081002300000053005C001F020000540080002300000054005C001F020000550085002300000055006A001F020000560082002300000056006C0022020000570083002300000057005C001F020000580082002300000058005C001F020000590088002300000059006A001F0200005A008900230000005A0072001E0200005B008B00230000005B006A001F0200005C008E00230000005C006A001F0200005D008400230000005D006A001F0200005E008400230000005E006A001F0200005F008400230000005F006A001F02000060008400230000006000A60024020000610084002300000061006A001F02000062004D002300000062004D0055020000630084002300000063004D005502000064008400230000006400A7002902000065008D0023000000650072001E0200006600560023000000660074002B00000066007A002C000000660078002D000000660079002F0000006600580031000000660078003200000066007B003400000066005600360000006600B1004800000066003E005200000066003E005400000066005A005500000066007500580000006600740059000000660077000F010000660076001501000066004D00180100006600B1001901000066004D001A010000660077001B010000660078001C01000066007900200100006600790047010000660010005F0100006600310060010000660032006101000066009000620100006600A80063010000660008008A010000660008009B0100006600A100A601000066001000CF0100006600A300F001000066004D002102000066002B002A02000066004F0093020000670056002300000067005B0023000000670098007D010000670096007E010000670097007F01000067004D00810100006700AD008801000067004C00C101000067004C00CA0100006700AE000402000067000B0005020000670043000602000067009C003D02000067009C003F0200006700A400440200006700A500440200006700AD00440200006700AF00440200006700010045020000670002004502000067000500460200006700060046020000670008004702000067000A004702000067000B004702000067000E004802000067000F004802000067003F004902000067004200490200006700440049020000670092004C02000067003300D602000067003400D602000067003500D602000067003600D602000067005500D702000067009D00D702000067009300D802000067009400D902000067005000DA02000067009500DA02000067009900DB02000067005400DC02000067009A00DC02000068004D002300000069004D00230000006A004D00230000006B004D00230000006C004D00230000006D004D00230000006E004D0023000000750092003802000077003800AC01000077004700B801000077004800B901000079000D009A01000079000000080200007B000A00310200007E004D00230000007E003700B60100007E003E00B00200008000A900880100008000AA009F01000080000700D80100008000AD0012020000800040004F02000080004400500200008000B2009B02000080003F00CB02000080004100CB02000081004D0023000000810045006F010000810046006F01000081003E00B0020000820092000202000083003B00B00100008300AA00B401000083009F005E02000084003C00EA01000084009F005E02000085004B007401000086004A00F10100008700A300D7010000870039001C02000088004D00230000008800AA006801000089009E00230000008A003A00B00100008A000700980200008B004900CC0200008C004A00F10100008C000700980200004C000000010000000400000000000000040100000000000081A70000000000004D000000000000007E000000247000000701000034AE000097A70000000000004E000000000000007E0000002C700000070100004CAE0000BEA70000000000004F000000000000007E0000002C7000000701000064AE0000D7A700000000000050000000000000007E0000002C700000070100007CAE0000EDA700000000000051000000000000007E000000347000000701000094AE00000EA800000000000052000000000000007E0000003C70000007010000BCAE00002BA800000000000053000000000000007E0000004470000007010000D4AE00003EA800000000000054000000000000007E0000004470000007010000ECAE000054A800000000000055000000000000007E0000002C7000000701000004AF000067A800000000000056000000000000007E0000003C700000070100001CAF000086A800000000000057000000000000007E000000447000000701000034AF000099A800000000000058000000000000007E00000044700000070100004CAF0000AFA800000000000059000000000000007E0000002C7000000701000064AF0000C2A80000000000005A000000000000007E0000004C700000070100007CAF0000DEA80000000000005B000000000000007E0000002C7000000701000094AF0000FAA80000000000005C000000000000007E0000002C70000007010000ACAF00001FA90000000000005D000000000000007E0000002C70000007010000C4AF000040A90000000000005E000000000000007E0000002C70000007010000DCAF000053A90000000000005F000000000000007E0000002C70000007010000F4AF000068A900000000000060000000000000007E00000054700000070100000CB000007BA900000000000061000000000000007E0000002C7000000701000024B000008EA900000000000062000000000000007E0000005C700000070100003CB00000A1A900000000000063000000000000007E0000005C700000070100004CB00000B1A900000000000064000000000000007E000000647000000701000064B00000C6A900000000000065000000000000007E0000004C700000070100007CB00000E5A900000000000066000000010000007E00000000000000070100000000000001AA000070AC000067000000010000007E000000000000000E01000094B0000008AB000074AC000068000000110000007E00000000000000FFFFFFFFC4B0000006AC000083AC000069000000110000007E00000000000000FFFFFFFFD4B0000017AC00008EAC00006A000000110000007E00000000000000FFFFFFFFE4B0000026AC000094AC00006B000000110000007E00000000000000FFFFFFFFF4B0000035AC00009AAC00006C000000110000007E00000000000000FFFFFFFF04B1000046AC0000A5AC00006D000000110000007E00000000000000FFFFFFFF14B1000055AC0000ABAC00006E000000110000007E00000000000000FFFFFFFF24B1000064AC000000000000010000000100000084640000060000001A0061007110740100000E00010001000100000089640000040000007010000000000E0002000200020000008D640000040000006F20020010000E000600060001000000946400000E0000005B010C0059020F005B030D0059040E005B0510007010640100000E0007000400030000009F6400005300000052300F003505050052300F00280201506E20AB00040054300D0052310E0052320F003525050052320F002802015271302D011002543010002201810070107001010054320D006E20720121000C011A021D006E20720121000C0154320C00542260006E20720121000C011A0213006E20720121000C0152320F003525050052320F00280201526E20710121000C016E10730101000C017110380001000C016E20C60010000E0000000200020000000000AF640000010000000E0000000200020000000000B6640000010000000E0000000400040001000000BD6400000A0000005B011100590213005B0312007010640100000E000500020003000000C664000036000000523013002C002A000000281D543011005400780054311100541170006E20A0001000543011005400780054311100541173006E209F00100028065430110012115C017A005430120052311300120271302D0110020E000000000202009CFFFFFFFAFFFFFF1B000000040000000300030001000000D3640000080000005B0114005B0215007010640100000E000400020002000000DB6400001D00000022000A001A016D01702013001000150100106E2015001000542115007110320001000C016E20140010005421140054116B006E20120001000E0000000600060001000000EB640000120000005B0117005C021A005B031B00590419005B05180070106401000055021A005C0216000E000500020003000000F76400006300000054301B00523119005532160071302C0110025530160038002D00543018002201810070107001010054321B006E20720121000C011A021F006E20720121000C016E10730101000C017110380001000C016E205C0010005430180054311700521156006E205800100012005C301600282B543018002201810070107001010054321B006E20720121000C011A021E006E20720121000C016E10730101000C017110380001000C016E205C0010005430180054311700521155006E205800100012105C3016000E00000004000400010000000A6500000A0000005B011C005B021E0059031D007010640100000E000800060003000000136500001E00000054201E006E10AE0000000C006E10660100000C0052211D0071302D01100512006E20530003000C001F004A0054211C00521168006E20C70010000E00020002000000000028650000010000000E000000020002000100000035650000060000005B011F007010640100000E0006000300030000003C6500002100000054301F005400230054006B0054311F005411230054116B001A01E8016E20110010000C001F00310012113805070012226E304A002001280512026E304A0010020E000000030003000100000050650000080000005B0120005B0221007010640100000E0007000300030001005865000092000000544021006E10660000000C006E10660100000C0071103B0000000A00380005001A001A00280B544021006E10660000000C006E10660100000C007110630100000A00544120005211270038010D005441200052112700341007005441200052112700011028120D005441200052112700380108005441200052112700011028051401F8FFFF7F011054412000541124002202810070107001020054432000543325006E20720132000C021A031D006E20720132000C025443200054332300543360006E20720132000C021A0313006E20720132000C026E20710102000C021A0320006E20720132000C026E10730102000C027110380002000C026E205C0021005441200054112500544220005222260071302D0121005441210012026E20690021000E00000000003100010001017D3302000200010000008C650000060000005B0122007010640100000E000600030003000000936500001A000000543022005400230054006B00543122005411230054116B001A01E8016E20110010000C001F003100121112026E304A0010020E000600060001000000A56500000E0000005B012300590227005B0324005B042500590526007010640100000E000900020003000000B06500009F000000220005005471230054116B0070200400100022013A005472230054226B007020650021005272270038021A00220281007010700102001A0305016E20720132000C02527327006E20710132000C026E10730102000C026E206A00210012226E206B0021001A021B0071103C0002000C026E206C00210012122323910022041C0013050A0070203900540012054D0403056E2068003100220452007020DD0074006E206D0041006E10670001001A0456006E20080040006E200900100022043F005475230054556B0070207D0054006E20850024006E207E0014006E2009004000220253007030DF0072011A050A016E3007005002220254007020E10072001A052E006E30060050025472230055227400380213006E10050000000C026E100B0002000C051306F6076E20450065006E100C00020028046E100A0000000E0000000200020001000000F1650000060000005B0128007010640100000E000600030003000000F8650000210000005430280054002C0054006B005431280054112C0054116B001A01E8016E20110010000C001F00310012113805070012226E304A002001280512026E304A0010020E00000003000300010000000C660000080000005B0129005B022A007010640100000E000700030003000000146600005800000054402A006E10660000000C006E10660100000C005441290054112D00220281007010700102005443290054332E006E20720132000C021A031D006E20720132000C025443290054332C00543360006E20720132000C021A0313006E20720132000C026E20720102000C021A0320006E20720132000C026E10730102000C027110380002000C026E205C0021005441290054112E005442290052222F0071302E01210054412A0012026E20690021000E00020002000100000029660000060000005B012B007010640100000E000600030003000000306600001A00000054302B0054002C0054006B0054312B0054112C0054116B001A01E8016E20110010000C001F003100121112026E304A0010020E000500050001000000426600000C0000005B012C005B022D005B032E0059042F007010640100000E0008000200030000004C660000670000002200050054612C0054116B0070200400100022013A0054622C0054226B00702065002100220256007020E50062006E206D0021006E10670001001A0257006E20080020006E200900100022023F0054632C0054336B0070207D00320012136E20850032006E207E0012006E2009002000220357007030E70063011A040A016E3007004003220358007020E90063001A042E006E300600400354632C0055337400380313006E10050000000C036E100B0003000C041305F6076E20450054006E100C00030028046E100A0000000E00000005000500010000007D6600000C0000005B0130005B0231005B033200590433007010640100000E0005000300030000008766000018000000542031006E105F0000000A0038000A00542032005221330071302C0110042808542032005221330071302C0110040E00080008000100000093660000120000005B0134005B023A005B0337005B043900590536005B0638005B0735007010640100000E000600020003000000A06600004200000054403A0022018100701070010100544237006E20720121000C011A021D006E20720121000C0154423400542260006E20720121000C011A0213006E20720121000C01544239006E20720121000C016E10730101000C017110380001000C016E20C6001000544037005241360054423800544335006E20920032000A0271302D0110020E000600060001000000AB660000120000005B013C005C023E005B033D005B0440005B053F0070106401000055023E005C023B000E000600020002000000B76600005700000055403B00DF0000015C403B003800290054413D0012026E208800210054414000220281007010700102001A03E5026E20720132000C0254433F006E20720132000C021A0302006E20720132000C026E10730102000C026E20C60021000E0054413D00130208006E208800210054414000220281007010700102001A03E6026E20720132000C0254433F006E20720132000C021A0303006E20720132000C026E10730102000C026E20C60021000E0000000200020001000000D0660000060000005B0141007010640100000E000400020002000000D7660000120000005420410054006D00130108006E209D0010005420410054006E0012016E20880010000E000200020001000000E0660000060000005B0143007010640100000E000500020003000100E766000045000000553042001201390004001210280201105C3042005530420038002000543043005400780054324300542273006E20A0002000543043005400780054324300542270006E209F00200054304300540078006E30A10010012817543043005400780054314300541170006E20A0001000543043005400780054314300541173006E209F00100028020D000E000000000000004200010001017A430200020001000000F7660000060000005B0144007010640100000E000500020003000000FE660000280000005430440054006D0012016E209D0010005430440054006D0012016E209A0010005430440054006E00130108006E20880010006E10430004000C001A01530012127130CB0010020C006E10CC0000000E00050002000300000009670000260000006E10430004000C001A01060112127130CB0010020C006E10CC00000054304500540075005431450054116F006E20700010005430450054007100543145005411750072204800100012000F00020002000100000013670000060000005B0145007010640100000E0002000200010000001A670000060000005B0146007010640100000E000400020002000000216700001D0000005420460054006D0012016E209D0010005420460054006D0054214600521159006E209A0010005420460054006E00130108006E20880010000E00000001000100010000002B670000040000007010640100000E000300010002000000306700002300000071001D0100000C0038001E001401240203016E20030010002201660070200501010071101F01010071001E0100000C016E101601010071001E0100000C016E10180101000E000000030002000100000040670000090000005B12470070106401010012005C1048000E0000000400010003000000486700001700000054304700540073006E108000000054304700543147006E100E0101000C0154324700542273007130200110020E00000009000300030001004F670000B00000006E10400008000A00120112122B00A00000000F0154604F0054006E001501003F6E208100100054604F0054006D006E209A00100054604F0054007B0052614D006E10410008000A0352644B00C7438733B0315901080054604F0054007B0052614E006E10420008000A0352644C00C7438733B0315901090054604F005400710054614F005411750054634F0054337B007230490010030F026E10410008000A0052634B00C73087006E10420008000A0352644C00C743873354644F0054446E001505803F6E208100540054644F0054446D006E209A00540013040A0035401A003543180054644F007110210104000A043804100054644900130508006E204400540054644A006E204400140028020D010F0254604F0054007B005200080059604D0054604F0054007B005200090059604E006E10410008000A0059604B006E10420008000A0059604C000F0200010300000000008300000046000000040000007A0000000C00010001017C8701000000030002000100000088670000120000005B124F0070106401010054104F0054006D005B10490054104F0054006E005B104A000E000500050001000000916700000C0000005B0150005B025100590352005B0453007010640100000E0005000300030000009B67000048000000542051005221520071302C011004522052002B00350000002831542053006E10B40000000C007110490100000C0012F16E304D01100439042200542053006E10B40000000C007110490100000C006E102F01000028136A04840054205000540078005421500038040500541177002803541176006E20A30010000E0000010300FDFFFFFF2200000003000000040000000100000000000000AD670000050000007100250100000C00110000000C00000003000100B16700006300000012001A016C0171105E0101000C011A028D011203233492006E30600121040C0212146E2079014200233393006E30780102030C031A0509026E205F0151000C056E20770145006E20750135000C061F068B007210830106000C0772107B0107000C0772107C0107000A0838082A0072107D0107000C086E10650108000C091A0A32026E205F01A9000C0A6E2077014A006E2076018A000A0B390B12001A0766016E205F0179000C076E20770147006E20750187000C041F040400110428D328020D01000011000000010000005C000100010060000200010002000000166800000600000022006400702001011000110002000100010000001B680000050000007010260101000A000F000000020001000100000021680000110000005410750038000D0054106D006E10990000000A003900030028031200280212100F0000000100000000000000AD67000003000000620072001100000001000100000000001B68000003000000690072001100000004000200010000002668000013000000823054216B006E100F0001000C016E10290001000C0152110300C8101501003FC61087000F00000005000200030000002D68000012000000824054316B006E100F0001000C016E10290001000C01121271303F0002010A0087000F001600020005000000346800007E03000008001400080115007010640100001A020F0071102B0002000A02590267001A02120071102B0002000A03590368001A03070071102B0003000A03590354001A03110071102B0003000A0359035B001A03100071102B0003000A0359035D001303220159035F001303D20059035E0012035903610013046400590462001504804059045C0013042D0059045A0014043333333F59045900140400FF00FF59046A001504FFFF590469001A04080071102B0004000A04590456001A040D0071102B0004000A04590455001A040A0071102B0004000A04590457001A040E0071102B0004000A055905640071102B0004000A055905650071102B0004000A045904580071102B0002000A02590263001A020C005B0260005B016B006901830022023B0070206E0012005B027500540275007010280100000C046E2071004200220243007020970012005B026F00220243007020970012005B026D0054026D006E209D00320054026D00520459006E209A00420022023F0070207D0012005B026E0054026E00130408006E208800420054026E0052045B006E208200420054026E0012146E208500420054026E0022053E0052065F007020230160000A0612E770307A0065076E20840052002202150070102E00020052055C006E203000520052055B006E202F0052001A050B0071102B0005000A056E303100420522053D007020730015005B05790054057900220642007030950076076E207600650052055A0082556E100F0001000C066E10290006000C0671303F0054060A058755540679006E10740006000C0659650400540679006E10740006000C06596505005406790062080A006E20790086006E100F0100000C0671203D0036000C0654087900216971302A0036090C096E2075009800540879006E10740008000C081F082D0013090A007020220190000A0A598A0600540879007010280100000C0A6E207800A80054087900220A5D007020F3000A006E207700A8002208320070204B001800220A4200703095007A076E205000A800520A5A0082AA6E100F0001000C0B6E1029000B000C0B71303F00A40B0A0A87AA6E104C0008000C0B59BA04006E104C0008000C0B59BA0500220B8100701070010B001A0C22006E207201CB000C0B6E10100100000C0C6E207201CB000C0B1A0C06006E207201CB000C0B520C5A006E207101CB000C0B1A0C05006E207201CB000C0B520C5A006E207101CB000C0B1A0C04006E207201CB000C0B6E1073010B000C0B1A0CAA021A0DB5026E404D00B8DC6E204F003800520B59006E204E00B8007010280100000C0B6E205100B800220B4A007020BC001B001A0CE7026E20C600CB00520C67006E20C700CB00620C01006E20C900CB00150CA0416E20C800CB00220C4200703095007C07130D0B006E209600DC006E20C000CB00220E5E007020F5000E006E20C200EB00220E3F0070207D001E005B0E7000540E70006E2085004E006E10170100000C0E540F700070302401E00F220E4300702097001E00125F6E5F9B009E9F130D10006E209C00DE00220D4A007020BC001D00520967006E20C7009D00150990416E20C8009D00130911006E20BF009D002203420070309500730713070E006E20960073006E20C0003D0022074A007020BC001700620F02006E20BE00F70012FF6E20C100F7006E20C50047006E20C4004700520467006E20C7004700150420416E20C80047006E20BF009700125412096E54C30097992204440070209E0014005B04780022043E0052095E007020230190000A0970307A00F4095B04760022043E0054096E006E107F0009000C0970207B0094005B047700540477001509803F59490B00540478006309840038090500540977002803540976006E20A30094005404780052095D006E20A200940022043F0070207D0014005B0473005404730012196E2085009400220443007020970014001239130F0A006E599B00F4F9130911006E209C0094002209420012EF70309500F90F130F09006E209600F900220F3600702056001F006E2059009F000811020012026E2058002F001A0249006E205C002F00520267006E205D002F0022025F007020F70002006E205A002F00220260007020F90002006E205B002F00220242000813030012E370309500320313030B006E2096003200220336007020560013006E20590023000810020012026E20580023001A0203016E205C002300520267006E205D002300220261007020FB0002006E205A00230054026F000212050054056D006E209800520054026F0054056E006E20980052006E10100100000C023802080054026D006E2098008200280854026D00540579006E20980052006E209800DE006E209800BE0054026E006E207E00E20054026E006E207E00720054027800540573006E209F00520054026E00540578006E207E0052006E209800F4006E209800340054026E006E207E0042006E401101107D0E00080004000500000043690000360000002200360054416B0070205600100022013E0012F270307A002102127212536E537C0021236E2059001000524268006E205D00200012026E20570020007110380007000C026E205C002000524254006E205800200022024E007040D40042766E205A0020006E207E0005000E00080004000500000064690000360000002200360054416B0070205600100022013E0012F270307A002102127212536E537C0021236E205900100012026E2057002000524268006E205D0020007110380006000C026E205C002000524254006E205800200022024F007030D60042076E205A0020006E207E0005000E000D00050006000000836900007D0000002200360054816B00702056001000070722003E0012F170307A001001127112526E527C0010126E2059000700528168006E205D00170012016E20570017001A010B011A0200006E306B011B020C0571303301AB0C0A0138012300220281007010700102006E20720152000C021A031F006E20720132000C026E10730102000C027110380002000C026E205C002700528256006E205800270012012821220281007010700102006E20720152000C021A031E006E20720132000C026E10730102000C027110380002000C026E205C002700528255006E20580027001211011422025000078301A67606D80002006E205A0027006E207E0079000E0000000600030005000000CD6900002B00000022004A0054316B007020BC001000523157006E20BD0010007110380005000C016E20C6001000130111006E20BF001000523168006E20C7001000120112126E30CA001002120112526E52C30010126E207E0004000E0000000700050005000000E36900002C0000002200370054216B0070205E0010006E2063005000522168006E20640010000000522158007110280001000C016E20600010007130330145060A016E206100100022015A007054ED0021506E20620010006E207E0003000E000E00040006000000FD690000B300000022003E0012F270307A0020020706120012526E507C00060222033F0054A46B0070207D00430007376E2084006700130310006E208700370012146E208500470022083F0054A96B0070207D0098006E20870038006E52860008026E20850048001A02090071102B0002000A026E2082002800130208006E20880028005BA86C0022024A0054A36B007020BC00320052A357006E20BD003200220381007010700103001A09E6026E20720193000C036E207201C3000C031A0903006E20720193000C036E10730103000C036E20C6003200130311006E20BF00320052A368006E20C700320012036E30CA003204130314006E53C3000203380D21006E2088000800220081007010700100001A03E5026E20720130000C006E207201C0000C001A0302006E20720130000C006E10730100000C006E20C600020022005C0007A107C50724078301D27606F10000006E20C20004006E207E0047006E207E0037006E207E007B000E00000003000100020000004D6A0000340000002020040039001400220018007100370000000C01702034001000220162007010FD0001006E2035001000281E07201F0004001401240203016E20030010002200660007211F01040070200501100069007200620072006E1016010000620072006E10180100000E000F00050006000000656A00007700000022003F0054A16B0070207D00100022013E0012F270307A002102127212536E537C0021232202360054A36B00702056003200072771203401CD000A02220381007010700103006E207201D3000C031A041D006E20720143000C0354A460006E20720143000C031A0413006E20720143000C03390204001214280201246E20710143000C031A0420006E20720143000C036E10730103000C037110380003000C036E205C00370012036E20570037006E205900170052A354006E205800370052A368006E205D0037002204550007A501C907D801E67606E30004006E205A0047006E207E0070006E207E000B000E0000000A00040005000000B06A00006D00000022003F0054616B0070207D00100022013E0012F270307A002102127212536E537C0021232202360054636B007020560032007120350189000C03220481007010700104006E20720194000C041A051D006E20720154000C04546560006E20720154000C041A0513006E20720154000C046E20720134000C041A0520006E20720154000C046E10730104000C047110380004000C046E205C00420012046E20570042006E2059001200526454006E2058004200526468006E205D004200220459007058EB0064926E205A0042006E207E0020006E207E0007000E0000001300050008000000E16A0000DD00000008001100220189001A021800080312006E206D0123000C0271107A0102000C0270208001210022024A0054E46B007020BC0042000727220281007010700102006E20720102000C021A041C006E20720142000C026E10730102000C026E20C600270052E268006E20C7002700220B410054E26B0070208F002B0013020A0012546E5494002B2412126E2093002B006E2090007B0012047210820101000A0535544700220C400054E56B00702089005C00080811007220810141000C0507591F09800022055B0007E6020A10007608EF000500620A90007220810141000C0D1F0D80006E205D01DA007220810141000C0A1F0A76006E208D00AC00140ACCCCCCFF6E208E00AC00000052EA6300711028000A000C0A6E208A00AC006E208C005C006E209000CB00D804040128B6020A100071203401A0000A043D043D00220581007010700105006E20720105000C051A081D006E20720185000C0554E860006E20720185000C051A0813006E20720185000C05D80804FF7220810181000C081F0880006E20720185000C056E10730105000C057110380005000C056E20C60057006E2091004B000C051F0540006E208B0025006E207E00BF000E0000001100060006000000516B0000A200000071203401DE000A0022013F0054B26B0070207D0021001252120313040A006E528600413212126E2085002100130211006E208300210022024A0054B36B007020BC003200072A220281007010700102006E207201E2000C021A031D006E20720132000C0254B360006E20720132000C021A0313006E20720132000C023900040001F3280201036E20710132000C026E10730102000C027110380002000C026E20C6002A0052B268006E20C7002A002202460054B36B007020A400320013031900130523006E54AA003254020310006E20A700320000006E20A800F2003900040001F4280201046E20AB0042006E10A60002000C0452B56400620600006E302C0054066E10A50002000C0452B56500620600006E302C00540622054D0007B601D907E801F77606D00005006E20A90052006E207E00A1006E207E0021006E207E001C000E0009000100080000008C6B00003800000022002F00528361005284620014060801800212E712E112E212257608460000005B807B0054807B00130133005901070054807B00528161005901080054807B00528162005901090054806B001F0004006E10010000000C005B807100548071005481750054827B007230470010020E0005000100040000009B6B0000170000005440750054416F006E206F00100022001800701033000000220163007020FF0041001602F4016E40360010320E0000000C00050005000000A86B000091000000220081007010700100001A019A026E20720110000C006E20710190000C001A0101006E20720110000C006E207201A0000C006E20720110000C006E207201B0000C006E10730100000C001A01080171203E000100220089001A0118006E206D011B000C0171107A0101000C0170208001100022013F0054726B0070207D00210022023E0012F312E470307A003204127312246E547C00323412136E2085003100527454006E20820041006E20840021002204470054756B007030AC0054036E20B00024006E10AD0004000C05620600006E302C0035062203350054756B001406090009017040540053066E20550063006E20AF003400712034019A000A056E20B2005400220551007040DA0075946E20B10054006E207E0041006E207E0018000E0000000C00050005000100E76B0000670000002200490054716B007020B300100022010D00140262FFFEFE2410900002000C021403A00001012410900003000C031204234590002430950032050C0252736A00527569001406FF0000FF2430900036050C0370302700210300006E10B50000000C026E202D0012006E10B60000000C026E202D001200280B0D021A03080171106F0102000C0571203E0053006E20BA00A000527268006E20BB00200013020A0012536E53B9002043713033019A0B0A026E20B70020002202650070500301729A6E20B80020006E207E0008000E0000002D0000000E00010001017C3C0600030005000000196C00001D00000022004A0054316B007020BC0010007110380005000C016E20C6001000523168006E20C700100013010A0012526E52C30010126E207E0004000E00000006000300050000002C6C00001A0000002200320054316B0070204B0010001A01AA021A02B5026E404D00502112016E204F00100012526E52520010126E207E0004000E0003000300030000003F6C0000040000007030240110020E001400030006000000496C00001002000008001100080612001201080713001202012801120801130021633538A8011203460406081A055A016E20670154000A091A0A00003809090012136E306C01540A0C0401392802013907711A0335006E20670134000A053805080054016C006E306C01340A0C041A0359016E206D0134000C0B1205460C0B0571103A000C000A0C390C1400460C0B051A0D19006E206A01DC000A0C380C03002808910A080201AC012A01C2074C2823460C0B05711063010C000A0C220D8100701070010D00460E0B056E207201ED000C0D6E2072013D000C0D6E1073010D000C0D6E306C01D40A0C04D8020201012A01C2074C6E206D013C000C0D46030D056E10690103000A04123E122F131001002C043201000029009A001A042B006E20680143000A033803F8FF01F3290090001A0432006E20680143000A033803EDFF1273290085001A040F016E20680143000A033803E2FF13030800290079001A0413016E20680143000A033803D6FF13030D0029006D001A042F006E20680143000A033803CAFF13030B00290061001A0412016E20680143000A033803BEFF13030C0028551A042D006E20680143000A033803B3FF01E3284B1A041B016E20680143000A033803A9FF124328411A0434006E20680143000A0338039FFF1303090028361A0459006E20680143000A03380394FF1253282C1A0415016E20680143000A0338038AFF0203100028211A045A006E20680143000A0338037FFF126328171A0421016E20680143000A03380375FF0153280D1A042C006E20680143000A0338036BFF13030A00280212F32B03CE00000029008B00D80A0A0146030D1070301C01100329008200D80A0A0146030D1070301B01100329007900D80A0A0146030D1070300901100329007000D80A0A0146030D1046040D0F704007011043286546030D1070400C011093D80A0A01285D46030D1046040D0F705414011032285546030D1070590B011032284F21D333E30D0046030D0F46040D107110630104000A0470541201103221D333F33F0046030D10705512011032283846030D10704013011032283246030D1070301B01100346030D1046040D0F705419011032282546030D10705908011032281F46030D10704006011032281946030D1046040D0F7110630104000A0446050D0E7110630105000A05760615010000280746030D1070591A0110320000D808080101A2290059FE0E0000020E006C3E2D8C74A7A395E773F1C85B9ABFD8F73B30DDCD872DDEF949BFEBDEA6A6F98E1AF1041E21DD067D177719EDA6462EC307755F5213477792000000880000007E00000073000000690000005E000000540000004A0000003F00000033000000270000001B000000100000000500000000010E00000000008800000076000000700000006A0000005D00000057000000400000003A000000320000002A00000020000000170000000E0000000500000003000100020000001D6D00000C000000542075003800090054207100542175007220480010000E000300020002000000246D00000A0000005410750038000700541075006E20720020000E0003000200020000002D6D0000070000006200870072201F0020000A000F0000000A00030006000000346D000029000000620083007110490100000C006E30390180090A0012F1331804006A00850012D1331804006A00840063018500390107003B0803002803019528030109019562018300120412060773018277060A0101000F0500000500020003000000656D00000C0000006200870071106E0104000C0112027230210010020A000F0005000300030001006C6D00000D0000006200870071106E0103000C017230210010040A000F000D000F040000000000000A0001000101780B04000200030000007C6D0000080000006200870012017230210030010A000F000400030003000000836D000007000000620087007230210020030A000F00000002000100020000008C6D00000E00000062008600390009002200670070202A011000690086006200860011000300020002000000946D00000C000000380209002200670070202A0110006900860062008600110003000200030000009E6D00000E00000062008600390009002200670070302B011002690086006200860011000400030003000000A86D00000C000000380309002200670070302B011002690086006200860011000400020002000000B56D0000120000006E20300132000A00390005001600000010006E20430132000B007120620110000B0010000600040002000000BE6D0000100000006E20300132000A003900030010046E20430132000B007120620110000B0010000400020003000000C96D0000080000006200870012017230220030010A000F000400030003000000D06D000007000000620087007230220020030A000F0000000900020006000000D96D00001B0000006300850038001600620083007110490100000C006E20400180000A0462018300120512060773018277060A0101000F04077312070F07000005000200030001000B6E00000E00000012006201870071106E0104000C027230230021000A000F000D010F00010000000A0001000101780C0400020003000000196E0000080000006200870012017230230030010A000F000400030003000000206E000007000000620087007230230020030A000F0000000900020006000000296E00001E00000063008500390008003C08030028041A0000001100620083007110490100000C006E20450180000C0662018300120412050773018277060A010100110605000200030001004C6E00000F0000001A0000006201870071106E0104000C027230250021000C0011000D0111000000020000000A0001000101780D04000200030000005A6E000009000000620087001A0100007230250030010C00110000000400030003000000616E000007000000620087007230250020030C001100000008000300020000006A6E000061000000220081007010700100006E20720160000C001A015B016E20720110000C006E10730100000C006E20300105000A00380049002200880070107E010000220281007010700102006E20720162000C026E20720112000C016E10730101000C016E20410115000A013A012C00120235122900220381007010700103006E20720163000C031A0450016E20720143000C036E20710123000C031A0458016E20720143000C036E10730103000C036E20460135000C036E207F013000D802020128D81100110700000400030003000000A26E0000080000000000620087007230260020030C0011000500020004000000B36E00000900000062008700160100007240240040210B00100000000600040004000000BA6E000007000000620087007240240030540B00100000000500020003000000C36E0000260000007010640103006E100D0004000C00220181007010700101006E100E0004000C026E20720121000C011A025C016E20720121000C016E10730101000C0112026E30100010020C00690087000E000500030003000000CF6E00000F0000007010640102006E100D0003000C0012016E30100040010C00690087000E0000000A00030006000000D96E000014000000620083007110490100000C006E304D018009620183001204120607730182019577060A0101000E000A00030006000000FE6E000014000000620083007110490100000C006E3051018009620183001205120607730182019477060A0101000E000A00030006000000226F000014000000620083007110490100000C006E3054018009620183001204120507730182079677060A0101000E000200010001000000476F00000E000000620087007210200000000C007210170000000C007210160000000E000A000300030000004D6F0000A0000000120062018700220281007010700102006E20720182000C021A035B016E20720132000C026E10730102000C0272201F0021000A0138011700220181007010700101006E20720181000C016E20720131000C016E10730101000C016E20410117000A00220181007010700101006E20720181000C016E20720131000C016E10730101000C017210850109000A026E305201170212017210840109000C0272107C0102000A031A0458011A0550013803280072107D0102000C031F038000220681007010700106006E20720186000C066E20720156000C056E20710115000C056E20720145000C046E10730104000C046E30550147030000D801010128D135012100220281007010700102006E20720182000C026E20720152000C026E20710112000C026E20720142000C026E10730102000C026E2048012700D801010128E00E000400030003000000896F00000F0000000000620087007210200000000C0072301D0020030C007210160000000E00000007000200020000009B6F00008C000000220081007010700100006E20720160000C001A015B016E20720110000C006E10730100000C006E20300105000A0038006700220081007010700100006E20720160000C006E20720110000C006E10730100000C006E20410105000A003A005000620287007210200002000C02220381007010700103006E20720163000C036E20720113000C016E10730101000C0172201E0012000C01721016000100120135012F00620287007210200002000C02220381007010700103006E20720163000C031A0450016E20720143000C036E20710113000C031A0458016E20720143000C036E10730103000C0372201E0032000C02721016000200D801010128D2620087007210200000000C0072201E0060000C007210160000000E000500030003000000C26F000012000000620087007210200000000C0071106E0103000C017230180010040C007210160000000E000400030003000000CE6F00000E000000620087007210200000000C007230180020030C007210160000000E000600040004000000D86F0000080000007120610154000B006E40530132100E000400030003000000E26F00000E000000620087007210200000000C007230190020030C007210160000000E000500030003000000EC6F000012000000620087007210200000000C0071106E0103000C0172301A0010040C007210160000000E000400030003000000F86F00000E000000620087007210200000000C0072301A0020030C007210160000000E000500040004000000027000000E000000620087007210200000000C0072401B0020430C007210160000000E0005000300030000000C70000012000000620087007210200000000C0071106E0103000C0172301C0010040C007210160000000E000400030003000000187000000E000000620087007210200000000C0072301C0020030C007210160000000E00010001000100000000000000040000007010640100000E00010001000100000000000000040000007010640100000E00010001000100000000000000040000007010640100000E00010001000100000000000000040000007010640100000E00010001000100000000000000040000007010640100000E00010001000100000000000000040000007010640100000E00010001000100000000000000040000007010640100000E0009000E5A0006000E000F01D7040E3D00EC0405AD05000000000E00F50403DC04DC03E3050EB4F001380F00EE0401DC040E00F10401DC040E00890503AD0500000E008B0501B7050E6BB4B41F5C8700A50502AD05000E00A70501B7050E780300EA030B5A967800C40505AD05000000000ED200C80501B7050E974B011E0F964C011E0F963D00EE0503AD0500000E00F1050400DD04B404E1030E0403AF04359F01F0E100F70501000E0401AE04359F0100950601AE050E00980602B705D7030E01140F0300E203323C5B4C00A90602AE05000E00AD06029A03D5050E01210F03009E0403C35F027B1D05001E0300A1037E69010503019E04031F05014D03009E0403013C0FB56900BE0601AE050E00C106029A03D5050E01140F0300E203325A00890605AD05000000000E008C0601CE050E960300EC02069603019F033B4B01180F4B963C0303489201A53C020B863D5A3C960304F703403C3C3D0215A4AC694B03029A0307963C05021E3D00E80601AE050E00EB0602B705D7030E01140F0300E203323C5B4C00FC0602AE05000E00FE06029A03D5050EA50300A0058101013C0FB46900850701AE050E008807029A03D5050E01140F0300E203325A00E20604AD050000000E00E50601CE050E970300EC02069603019F033B020B863D5A3C960302F703404B3C3DADAD694B03039A0307963C05031E3D00A30704AD050000000E00A60702FD02EC030E87887900C00707AD050000000000000E00C20701B7050E01320FF000F50705AD05000000000ED200FB0701B7050E4B0300E3058F012D2D6901200F1F7801200F00A40101AD050E00A60101CE050E968700C40101AD050E00CA0101B7050EA54BB4B488B4B61C1F008E0201AD050E00900201CE050E878796E100980201CE050EE1B4B400960201AD050E00A80201AD050E00AA0201CE050E87B49600CB02000E00CE02000E4B0300E702052D6987787900FD0201AD050E5A008203000E78F100A80302CE059A040E02249502771D967901110F011110F002661D870300C30403870303C40403967AE5785C1B2102691D050005038787696900A10301AD050E5A6900C50404AD050000000E00C704028803FA020E786AE12DE32D0110110045000E00E102000E780401F60278E3019603028D0385014B6A0303F7027F690305E60284013C6A040692048C01FA0101120F0308CB047F4B0409F40278E30169030AB30484013C69690307E70284013C79050705080509050A02771D05010502050305050506272D00A103000E004501DF050E00A708000E00AC0801DC030E00B00801DC030E007F018A030E024C7787878787874B4B3C4C4B4B5A5A4B8787878769696902204A2D2D789678785A7A7878786A01110F5A0302B003165A5A9978A5FF0305F2020387887887030690039001A501101096AC5A0308D1053387FF030AF302036969B6012A0B7D3C5A7A5A030B95054B5A5A5A5A5A030CD404435A3C021586785A985A030EB005444B5B5A030DAF054B5A5A5A5A0303D304435A3E5A0307A6054B5A4B3C3C5A5A3C5C79D2D269E178786B5A0304CC0444695C690309F503435B5A030FDB03373C010305020311B003163C5A5A8E90010505030313D304433C0302F403435B5A03038303373C010305020310F403433C5A5A8F010405050312F202035A78696A793C3C5A5A78783C3C5B3C00810503FB03A503A4030E780300FB0237690301F8033F5A3C5A4B785A0210863C009D0503FB03A403B5050E780300FB0237690301F8033F5A3C4B5A785A8E3C00B10504FB03A503A403A9050E870307FB0237690300F8033F5A3C5A4C870305AB0381014B0301F0038F012D011A0F5A2E011A0F5A1F1E0304AA038F010104050A0306A503030211683C008C0802FB03AA050E780300AC054B5A785A5A5A5A3C009D0704FB03A503A403A9050E7803008103383C5A1E9678903C00D80703FB03AA05A2030E780306FA033F5B8703078403403C5A4C7803088503403C3C3C965A2E780302AC054B5A011C0F5A5A4B5B2D3C011C1101070502050803038503400304AC054B0211683C3C3C00C902018A030E4B960300D60319020C8605001E96A55A5B00FE0504FB03A503A40395040E780300FC0340690301F8033F5B870307FB02374B03029E040301350F4B3C5A5A0106050C050D050E03069504030308A40381010309A5030302C700683C3C00D50603FB03A503A4030E780300FC0340690301F8033F5B790302FB02374B0303A20581010130104B3C5A5A0236863C3C00B20704FB03A503A403FE030E011310040180048B01F801870307AC054B01160F5B78030BC10442694B3D01010304DC03036978030C92024101020308AB038101780309C20481018C0305AC0328B496691E963C02713B050505080509050C02123B0504690304E303032D01320F973C00DA0405FB03A503A403970494040E4B0300880403780301FC0340784B5B87030AAC054B012F0F5B780302DC0447785A1E3C87B4B4020EC23C3D3C008C03000E020C01120E69696AA59600FA02000E795A0300D60319AE00D90504FB03A503A403FE030E012A0FF3040080048B01F801780301FD0340780302F9033F5A4B5A3D7803049A05483C97A50303DF02363D3C78020B863C3C00AB0404FB03A503A403A7050E780300A8054A020D01250E0301FC020E1F787A1B1E0302A1037D9805023C5A69780211863C00970802FB03AA050E780300AC054B785A693C009F0802FB03AA050E780300D10533784B4B3C004503DF05E005E1050E00D40302FF03FC030E5A0301A505032E0307810440010505130301FC03400302A505030308DC03033C1F0303A9058F012D0304A6038101A51E662205030309A9058F011E882D4C6B030BA00595010114140106030AA50303027B1D050A69030CA5030301170F5E05040302A50303030AA50503030CA60381014B030DA1059501023101AD010E2D027B772D5A027A2C2D5A027A2C2D78027A1D5A2D027B1D78195A02791D3CB43C027A685A027B1D5A78027B1D5A195A1901110F195A02621D0509050B050C050D02D100590508050A0302A5050300BA08000E4B7900B40801CE050E4B5B00DA0301F3030E003303A803A903F8020EA50300FA028F013C2E3C2E962F05090305F8028F010106050705080302A903030303A80381013C00CD0201D3050E00E40202D30593030EB41E0300A1037900C50201D3050E00D80202D30593030E005E018A030E4B79006A028A03AE030E2D790076028A03B7040E4B79008401038A03B704AE030E2D7900F00101D3050E693C00FB0102D30594030E691E008F0201D3050E00980202D30595030E002A02A803A9030E4BA50304DC03030106050705080302A903030303A80381013C1F0502050305040607060801010507060300CA0101D3050EC31E0301A1037900C00101D3050E00D60102D30596030E004302A803A9030E7C37A50306A00581010106050705080302A903030303A80381013C009A0101D3050ED21E0301A1037900910101D3050E00A60102D30598030E00B50302F303000E040792038D01FD0101190F5A0400DE048901F50101150F0301A305032D01010302DC03032D01240D3F05021F0500050100A70302F303000E040392038D01FD011E00AA0201D3050E00B30202D30597030E004B018A030E3C9601120D7B0052028A03B7040E3CB7002503A803A903FA020E9601070507050805090302A903030303A80381010305FA028F013C001B03A803A903CB050E9601070507050805090302A903030303A80381010304CB05033C002003A803A903A0050E9601070507050805090302A903030303A80381010306A00581013C00E103000ED2008F0302F303000E0409CB058D01FD011E0300A30503011B1001151001180F1E0301DC030301140F0303DE028101011C0F010105032D1E2E011C0C3F00820302F303000E0403CB058D01FD011ED600C80301F3030E01191001150F0300A305032D011E0F01010301DC03032D012A0D4005000501D200F70202D405D3050E01110F00EF0202D405D3050ED200850202D405D3050E7800A00202D405D3050ED200E60102D405D3050E01110F00DE0102D405D3050ED200BB0202D405D3050ED200B60102D405D3050E01110F00AE0102D405D3050ED20000000100000045000000010000002700000001000000330000000100000028000000010000000800000001000000380000000100000029000000010000007F000000010000002A00000001000000030000000100000080000000020000008000000003000000020001002300000002000000800001000100000002000000010000002B00000002000000800002000200000080008000010000000000000002000000800003000100000076000000020000007600080001000000160000000200000080008C000200000080008E00030000008F0002000200000003000000070076000200000001000000660000000100000007000000020000000700800003000000070080008E0000000200000007008E00010000007E000000020000007E009300020000007600760002000000800092000100000093000000010000000100000002000000020002000400000002000200020002000700000002000200020002000200020002000000020000000200120002000000020080000200000002008E0002000000070002000600000007000200800002008E00800003000000070002008A0000000300000007004A004A0000000200000009000200010000000A000000010000000D000000010000000F0000000100000013000000020000001300020001000000170000000100000019000000010000001E0000000100000021000000020000002B002C00020000002B008E00010000002C00000001000000340000000400000034002B00020003000200000039008E00010000003C000000030000003F00020080000000040000003F00020080000200050000003F0002008000020002000000040000003F00020080008000040000003F00020080008E00020000003F008000030000003F00800080000000030000003F0080008E000000010000004600000003000000460002008E000000010000004800000001000000550000000200000055003A0001000000590000000200000059003A00050000006600020036008000020000000300000066000200800000000500000066000200800002004A0000000400000066003600800002000400000066003700800002000300000066004700020000000700000066004A0080008000020041004000000002000000660080000400000066008000020049000500000066008E003F004A00800000000500000066008E00800002003600000003000000660094003F00000003000000800002000200000003000000800002008000000003000000800002008E0000000300000080008000800000000100000086000000010000008E00000001000000910000000200000094003F000200000095009000020000002B002600020000007F00030000000120000220E296B3000220E296BD001122203E3C2F626F64793E3C2F68746D6C3E000A22206865696768743D220009222077696474683D22000723314332363244000723316235653230000723323232443338000723324633443443000723333263623030000723343163333030000723376630303030000723383043424334000723383243414644000923444431343143323200092345453143324133350007234646464646460002273E000128000328295600032A3E3B00052A3E3B295600012C00072D5B302D395D2A000130000B303132333435363738392D00013A000F3A203C666F6E7420636F6C6F723D2700053A204F464600043A204F4E00073C2F666F6E743E00083C636C696E69743E00413C68746D6C3E3C686561643E3C2F686561643E3C626F6479207374796C653D226D617267696E3A20303B2070616464696E673A2030223E3C696D67207372633D2200063C696E69743E00023E3B00033E3B2900043E3B295600084170705468656D65000942544E5F434F4C4F52000642746E4F4646000542746E4F4E0006427574746F6E000A427574746F6E4C696E6B000B427574746F6E4F6E4F6666000643616E63656C000843617465676F7279000A43617465676F7279424700074368616E6765730008436865636B426F78000D436865636B426F78436F6C6F720008436F6C6C61707365000C436F6C6C617073654164645F000A4372656174654D656E75000144000C44454641554C545F424F4C44001544454641554C545F424F4F4C45414E5F56414C5545001444454641554C545F444F55424C455F56414C5545001344454641554C545F464C4F41545F56414C5545001144454641554C545F494E545F56414C5545001244454641554C545F4C4F4E475F56414C5545001444454641554C545F535452494E475F56414C55450002444A0002444C0003444C4400014600044649464C00064649545F58590002464C0003464C46000B46696C7465724172726179000E476574466561747572654C6973740010484944452F4B494C4C2028486F6C6429000149000A49434F4E5F414C504841000949434F4E5F53495A45000249490004494A29560002494C0003494C490003494C4C000449636F6E002E49636F6E2068696464656E2E2052656D656D626572207468652068696464656E2069636F6E20706F736974696F6E000F49636F6E57656256696577446174610004496E6974000C496E707574206E756D626572000A496E70757420746578740008496E7075744E756D0009496E70757454657874000A496E70757456616C756500014A00024A4400024A4C00034A4C4A00014C00064C454E47544800034C474C00024C4900024C4C00034C4C4600034C4C4900044C4C494900034C4C4A00034C4C4C00044C4C4C4900044C4C4C5A00034C4C5A00164C616E64726F69642F6170702F41637469766974793B00214C616E64726F69642F6170702F416C6572744469616C6F67244275696C6465723B00194C616E64726F69642F6170702F416C6572744469616C6F673B00194C616E64726F69642F636F6E74656E742F436F6E746578743B00314C616E64726F69642F636F6E74656E742F4469616C6F67496E74657266616365244F6E436C69636B4C697374656E65723B00214C616E64726F69642F636F6E74656E742F4469616C6F67496E746572666163653B00184C616E64726F69642F636F6E74656E742F496E74656E743B002A4C616E64726F69642F636F6E74656E742F536861726564507265666572656E63657324456469746F723B00234C616E64726F69642F636F6E74656E742F536861726564507265666572656E6365733B00244C616E64726F69642F636F6E74656E742F7265732F436F6C6F7253746174654C6973743B001F4C616E64726F69642F636F6E74656E742F7265732F5265736F75726365733B00194C616E64726F69642F67726170686963732F4269746D61703B00204C616E64726F69642F67726170686963732F4269746D6170466163746F72793B00184C616E64726F69642F67726170686963732F436F6C6F723B00224C616E64726F69642F67726170686963732F506F7274657244756666244D6F64653B001B4C616E64726F69642F67726170686963732F54797065666163653B00244C616E64726F69642F67726170686963732F6472617761626C652F4472617761626C653B002C4C616E64726F69642F67726170686963732F6472617761626C652F4772616469656E744472617761626C653B00114C616E64726F69642F6E65742F5572693B00134C616E64726F69642F6F732F42756E646C653B00144C616E64726F69642F6F732F48616E646C65723B00134C616E64726F69642F6F732F4C6F6F7065723B00174C616E64726F69642F746578742F4564697461626C653B00134C616E64726F69642F746578742F48746D6C3B00274C616E64726F69642F746578742F496E70757446696C746572244C656E67746846696C7465723B00164C616E64726F69642F746578742F5370616E6E65643B00234C616E64726F69642F746578742F546578745574696C73245472756E6361746541743B00184C616E64726F69642F746578742F546578745574696C733B00274C616E64726F69642F746578742F6D6574686F642F4469676974734B65794C697374656E65723B00214C616E64726F69642F746578742F6D6574686F642F4B65794C697374656E65723B00154C616E64726F69642F7574696C2F4261736536343B001D4C616E64726F69642F7574696C2F446973706C61794D6574726963733B00124C616E64726F69642F7574696C2F4C6F673B00194C616E64726F69642F7574696C2F547970656456616C75653B001A4C616E64726F69642F766965772F4D6F74696F6E4576656E743B00234C616E64726F69642F766965772F56696577244F6E436C69636B4C697374656E65723B00294C616E64726F69642F766965772F56696577244F6E466F6375734368616E67654C697374656E65723B00274C616E64726F69642F766965772F56696577244F6E4C6F6E67436C69636B4C697374656E65723B00234C616E64726F69642F766965772F56696577244F6E546F7563684C697374656E65723B00134C616E64726F69642F766965772F566965773B00254C616E64726F69642F766965772F5669657747726F7570244C61796F7574506172616D733B002B4C616E64726F69642F766965772F5669657747726F7570244D617267696E4C61796F7574506172616D733B00154C616E64726F69642F766965772F57696E646F773B00294C616E64726F69642F766965772F57696E646F774D616E61676572244C61796F7574506172616D733B001C4C616E64726F69642F766965772F57696E646F774D616E616765723B002D4C616E64726F69642F766965772F696E7075746D6574686F642F496E7075744D6574686F644D616E616765723B00184C616E64726F69642F7765626B69742F576562566965773B00334C616E64726F69642F7769646765742F4164617074657256696577244F6E4974656D53656C65637465644C697374656E65723B001C4C616E64726F69642F7769646765742F41646170746572566965773B001C4C616E64726F69642F7769646765742F41646170746572566965773C001F4C616E64726F69642F7769646765742F41646170746572566965773C2A3E3B001D4C616E64726F69642F7769646765742F4172726179416461707465723B00174C616E64726F69642F7769646765742F427574746F6E3B00194C616E64726F69642F7769646765742F436865636B426F783B00374C616E64726F69642F7769646765742F436F6D706F756E64427574746F6E244F6E436865636B65644368616E67654C697374656E65723B001F4C616E64726F69642F7769646765742F436F6D706F756E64427574746F6E3B00194C616E64726F69642F7769646765742F45646974546578743B001C4C616E64726F69642F7769646765742F4672616D654C61796F75743B00244C616E64726F69642F7769646765742F496D61676556696577245363616C65547970653B001A4C616E64726F69642F7769646765742F496D616765566965773B002A4C616E64726F69642F7769646765742F4C696E6561724C61796F7574244C61796F7574506172616D733B001D4C616E64726F69642F7769646765742F4C696E6561724C61796F75743B001C4C616E64726F69642F7769646765742F526164696F427574746F6E3B001B4C616E64726F69642F7769646765742F526164696F47726F75703B002C4C616E64726F69642F7769646765742F52656C61746976654C61796F7574244C61796F7574506172616D733B001F4C616E64726F69642F7769646765742F52656C61746976654C61796F75743B001B4C616E64726F69642F7769646765742F5363726F6C6C566965773B00304C616E64726F69642F7769646765742F5365656B426172244F6E5365656B4261724368616E67654C697374656E65723B00184C616E64726F69642F7769646765742F5365656B4261723B00184C616E64726F69642F7769646765742F5370696E6E65723B001F4C616E64726F69642F7769646765742F5370696E6E6572416461707465723B00174C616E64726F69642F7769646765742F5377697463683B00194C616E64726F69642F7769646765742F54657874566965773B00164C616E64726F69642F7769646765742F546F6173743B00224C636F6D2F616E64726F69642F737570706F72742F4D61696E41637469766974793B001D4C636F6D2F616E64726F69642F737570706F72742F4D656E752431303B001D4C636F6D2F616E64726F69642F737570706F72742F4D656E752431313B001D4C636F6D2F616E64726F69642F737570706F72742F4D656E752431323B001D4C636F6D2F616E64726F69642F737570706F72742F4D656E752431333B001D4C636F6D2F616E64726F69642F737570706F72742F4D656E752431343B001F4C636F6D2F616E64726F69642F737570706F72742F4D656E7524313524313B001F4C636F6D2F616E64726F69642F737570706F72742F4D656E7524313524323B001F4C636F6D2F616E64726F69642F737570706F72742F4D656E7524313524333B001D4C636F6D2F616E64726F69642F737570706F72742F4D656E752431353B001F4C636F6D2F616E64726F69642F737570706F72742F4D656E7524313624313B001F4C636F6D2F616E64726F69642F737570706F72742F4D656E7524313624323B001F4C636F6D2F616E64726F69642F737570706F72742F4D656E7524313624333B001D4C636F6D2F616E64726F69642F737570706F72742F4D656E752431363B001D4C636F6D2F616E64726F69642F737570706F72742F4D656E752431373B001D4C636F6D2F616E64726F69642F737570706F72742F4D656E752431383B001D4C636F6D2F616E64726F69642F737570706F72742F4D656E752431393B001C4C636F6D2F616E64726F69642F737570706F72742F4D656E7524313B001C4C636F6D2F616E64726F69642F737570706F72742F4D656E7524323B001C4C636F6D2F616E64726F69642F737570706F72742F4D656E7524333B001C4C636F6D2F616E64726F69642F737570706F72742F4D656E7524343B001C4C636F6D2F616E64726F69642F737570706F72742F4D656E7524353B001C4C636F6D2F616E64726F69642F737570706F72742F4D656E7524363B001C4C636F6D2F616E64726F69642F737570706F72742F4D656E7524373B001C4C636F6D2F616E64726F69642F737570706F72742F4D656E7524383B001C4C636F6D2F616E64726F69642F737570706F72742F4D656E7524393B001A4C636F6D2F616E64726F69642F737570706F72742F4D656E753B00214C636F6D2F616E64726F69642F737570706F72742F507265666572656E6365733B001D4C636F6D2F616E64726F69642F737570706F72742F5224636F6C6F723B00204C636F6D2F616E64726F69642F737570706F72742F52246472617761626C653B001E4C636F6D2F616E64726F69642F737570706F72742F52246C61796F75743B001E4C636F6D2F616E64726F69642F737570706F72742F52246D69706D61703B001E4C636F6D2F616E64726F69642F737570706F72742F5224737472696E673B001D4C636F6D2F616E64726F69642F737570706F72742F52247374796C653B00174C636F6D2F616E64726F69642F737570706F72742F523B00224C64616C76696B2F616E6E6F746174696F6E2F456E636C6F73696E67436C6173733B00234C64616C76696B2F616E6E6F746174696F6E2F456E636C6F73696E674D6574686F643B001E4C64616C76696B2F616E6E6F746174696F6E2F496E6E6572436C6173733B00214C64616C76696B2F616E6E6F746174696F6E2F4D656D626572436C61737365733B00244C64616C76696B2F616E6E6F746174696F6E2F4D6574686F64506172616D65746572733B001D4C64616C76696B2F616E6E6F746174696F6E2F5369676E61747572653B00154C6A6176612F696F2F5072696E7453747265616D3B00184C6A6176612F6C616E672F4368617253657175656E63653B00114C6A6176612F6C616E672F436C6173733B00144C6A6176612F6C616E672F436C6173733C2A3E3B001E4C6A6176612F6C616E672F436C61737343617374457863657074696F6E3B00124C6A6176612F6C616E672F446F75626C653B00214C6A6176612F6C616E672F496C6C6567616C5374617465457863657074696F6E3B00134C6A6176612F6C616E672F496E74656765723B00204C6A6176612F6C616E672F4E756C6C506F696E746572457863657074696F6E3B00214C6A6176612F6C616E672F4E756D626572466F726D6174457863657074696F6E3B00124C6A6176612F6C616E672F4F626A6563743B00144C6A6176612F6C616E672F52756E6E61626C653B00124C6A6176612F6C616E672F537472696E673B00194C6A6176612F6C616E672F537472696E674275696C6465723B00124C6A6176612F6C616E672F53797374656D3B00194C6A6176612F6C616E672F7265666C6563742F4669656C643B001A4C6A6176612F6C616E672F7265666C6563742F4D6574686F643B00124C6A6176612F7574696C2F4172726179733B00164C6A6176612F7574696C2F436F6C6C656374696F6E3B00144C6A6176612F7574696C2F4974657261746F723B00194C6A6176612F7574696C2F4C696E6B6564486173685365743B002D4C6A6176612F7574696C2F4C696E6B6564486173685365743C4C6A6176612F6C616E672F537472696E673B3E3B00164C6A6176612F7574696C2F4C696E6B65644C6973743B00104C6A6176612F7574696C2F4C6973743B00244C6A6176612F7574696C2F4C6973743C4C6A6176612F6C616E672F537472696E673B3E3B000F4C6A6176612F7574696C2F4D61703B00134C6A6176612F7574696C2F4D61703C2A2A3E3B000F4C6A6176612F7574696C2F5365743B000F4C6A6176612F7574696C2F5365743C00234C6A6176612F7574696C2F5365743C4C6A6176612F6C616E672F537472696E673B3E3B00074D415251554545000D4D454E555F42475F434F4C4F52000B4D454E555F434F524E455200154D454E555F464541545552455F42475F434F4C4F52000B4D454E555F484549474854000A4D454E555F574944544800084D494E494D495A4500114D61696E41637469766974792E6A617661000B4D61782076616C75653A20000B4D656E75206B696C6C656400094D656E752E6A61766100084D6F645F4D656E75000E4E756D626572547874436F6C6F7200024F4B00064F6E4F66665F0005504F535F580005504F535F590010507265666572656E6365732E6A617661000B526164696F427574746F6E000A526164696F436F6C6F720006526164696F6F000C526963685465787456696577000B526963685765625669657700085352435F41544F5000075365656B426172000C5365656B426172436F6C6F7200145365656B42617250726F6772657373436F6C6F72001853657457696E646F774D616E616765724163746976697479000C53657474696E67734C697374000853686F774D656E7500075370696E6E657200065377697463680003544147000A544558545F434F4C4F52000C544558545F434F4C4F525F32000854657874566965770006546F67676C650009546F67676C654F46460008546F67676C654F4E000156000256460002564900035649490005564949494900085649494949494949000356494C000356495A0002564C0003564C440003564C460003564C490004564C49490004564C494C0005564C494C490006564C494C49490006564C494C494C0007564C494C495A4C0005564C494C4C0006564C494C4C490005564C494C5A0004564C495A0003564C4A0003564C4C0004564C4C490005564C4C494A0005564C4C494C0004564C4C4C0005564C4C4C490008564C4C4C4C494C4C0004564C4C5A0003564C5A0006564C5A4C494C0006564C5A4C4C4C0002565A000B576562546578745669657700015A00025A4900035A495A00025A4C00045A4C495A00035A4C4A00035A4C4C00035A4C5A00015B00025B4200025B49001B5B4C616E64726F69642F746578742F496E70757446696C7465723B00125B4C6A6176612F6C616E672F436C6173733B00135B4C6A6176612F6C616E672F4F626A6563743B00135B4C6A6176612F6C616E672F537472696E673B00035B5B4900015D00015F00055F5472756500075F6C656E677468000C5F707265666572656E63657300066156616C756500026161000A61636365737324303030000A61636365737324313030000A61636365737324313032000A61636365737324323030000A61636365737324333030000B616363657373466C616773000A6163746976697469657300086163746976697479000D61637469766974795F6D61696E0003616464000761646452756C650007616464566965770009616C6572744E616D65001A616E64726F69642E6170702E4163746976697479546872656164001A616E64726F69642E696E74656E742E616374696F6E2E5649455700086170705F6E616D650006617070656E6400056170706C79000E6170706C7944696D656E73696F6E000F6170706C7944696D656E73696F6E3200026172000661734C69737400026174000561744F626A000462446566000F6261636B67726F756E64436F6C6F720004626F6F6C0006627574746F6E000C627574746F6E537461746573000A627574746F6E5669657700116368616E676546656174757265426F6F6C00106368616E676546656174757265496E7400136368616E676546656174757265537472696E670008636865636B426F780005636C6561720008636C6F736542746E0008636F6C6C61707365000B636F6C6C61707365537562000D636F6C6C6170736564566965770005636F6C6F72000E636F6D706F756E64427574746F6E0008636F6E7461696E730007636F6E746578740012636F6E76657274446970546F506978656C730006637265617465000763757272656E74001563757272656E74416374697669747954687265616400016400066465636F6465000F6465636F6465427974654172726179000864656656616C7565000E64656661756C74426F6F6C65616E000D64656661756C74446F75626C65000C64656661756C74466C6F6174000A64656661756C74496E74000B64656661756C744C6F6E67000D64656661756C74537472696E67000764656E7369747900066469616C6F670013646F75626C65546F5261774C6F6E67426974730002647000086472617761626C65000465646974000865646974546578740006657175616C73000265780008657870616E646564000C657870616E646564566965770008666561744E616D650007666561744E756D000766656174757265000B666561747572654C697374000B666561747572654E616D65000A666561747572654E756D000966696E616C49734F6E000D66696E616C666561744E616D65001466697273745F726164696F5F6C697374656E65720007666F724E616D650012666F726365496E7374616E74696174696F6E000866726F6D48746D6C000A67644D656E75426F647900036765740009676574416374696F6E00156765744170706C69636174696F6E436F6E74657874000D6765744261636B67726F756E64000A676574426F6F6C65616E000A6765744368696C6441740008676574436C617373000A676574436F6E7465787400106765744465636C617265644669656C6400116765744465636C617265644D6574686F640011676574446973706C61794D6574726963730008676574466C6F6174000B676574496E7374616E63650006676574496E74000F6765744C61796F7574506172616D7300076765744C6F6E67000D6765744D61696E4C6F6F70657200136765744F726465726564537472696E67536574000E6765745061636B6167654E616D65001367657450726F67726573734472617761626C65000767657452617758000767657452617759000C6765745265736F7572636573000F67657453656C65637465644974656D0014676574536861726564507265666572656E6365730009676574537472696E67000C676574537472696E67536574001067657453797374656D5365727669636500076765745465787400086765745468756D6200106765745468756D624472617761626C65000E676574546F7041637469766974790010676574547261636B4472617761626C65000D6765745669736962696C697479000967657457696E646F77001067657457696E646F774D616E61676572000767726176697479000768616E646C65720008686173466F63757300076861734E657874000868617368436F6465000668656967687400076869646542746E000169000B69635F6C61756E63686572001669635F6C61756E636865725F6261636B67726F756E64001669635F6C61756E636865725F666F726567726F756E64001169635F6C61756E636865725F726F756E64000269640003696D6D0005696E646578000C696E6465784F664368696C64000D696E697469616C546F75636858000D696E697469616C546F756368590008696E697469616C580008696E697469616C59000C696E7075745F6D6574686F640006696E74656E740006696E766F6B6500096973436865636B6564000C69734469676974734F6E6C7900076973456D707479000A6973457870616E646564000469734F6E000F697356696577436F6C6C617073656400086974657261746F7200036B6579000F6C506172616D73436C6F736542746E000E6C506172616D734869646542746E00066C61796F7574000A6C61796F75744E616D65000C6C61796F7574506172616D73000D6C61796F7574506172616D7332000E6C61796F7574506172616D734C4C00096C696E4C61796F7574000C6C696E6561724C61796F7574000D6C696E6561724C61796F75743200046C69737400066C697374465400056C6973747300056C6C42616B00086C6F616444617461000B6C6F61644C69627261727900086C6F616450726566000C6C6F616450726566426F6F6C000B6C6F616450726566496E74000E6C6F616450726566537472696E67000A6C6F6164656450726F6700106C6F6E6742697473546F446F75626C65000B6D4163746976697469657300096D436F6C6C61707365000A6D436F6C6C617073656400096D457870616E646564000E6D526F6F74436F6E7461696E657200096D53657474696E6773000E6D57696E646F774D616E6167657200086D616B655465787400036D617000076D61746368657300036D617800086D617856616C756500046D656E7500036D696E00066D69706D617000046D6F6473000B6D6F74696F6E4576656E7400046E616D6500056E616D657300046E65787400036E756D00106F6E436865636B65644368616E67656400076F6E436C69636B00086F6E43726561746500096F6E44657374726F79000D6F6E466F6375734368616E6765000E6F6E4974656D53656C6563746564000B6F6E4C6F6E67436C69636B00116F6E4E6F7468696E6753656C656374656400116F6E50726F67726573734368616E67656400146F6E5374617274547261636B696E67546F75636800136F6E53746F70547261636B696E67546F75636800076F6E546F756368000F6F6E546F7563684C697374656E657200036F7574000F6F7665726C617952657175697265640006706172656E74000A706172656E745669657700057061727365000A7061727365436F6C6F7200087061727365496E7400067061757365640008706F736974696F6E0004706F7374000B706F737444656C61796564000F707265666572656E6365734E616D65000D7072656673496E7374616E636500077072696E746C6E000A707574426F6F6C65616E0008707574466C6F61740006707574496E7400077075744C6F6E6700137075744F726465726564537472696E675365740009707574537472696E67000C707574537472696E67536574000A726164696F47726F75700009726164696F4E616D65000472617758000472617759000B72656164426F6F6C65616E000A72656164446F75626C65000972656164466C6F6174000772656164496E740008726561644C6F6E67000A72656164537472696E6700067265636F7264000E72656C61746976654C61796F7574000672656D6F7665000E72656D6F7665416C6C5669657773000A72656D6F76655669657700077265706C616365000C7265706C6163654669727374000C72657175657374466F6375730002726C000A726C73657474696E67730009726F6F744672616D65000372756E00127361766564496E7374616E6365537461746500067363726C4C4C000E7363726C4C4C457870616E64656400087363726F6C6C546F000A7363726F6C6C5669657700077365656B426172001073656C65637465644974656D566965770003736574000D73657441636365737369626C65000A73657441646170746572000A736574416C6C436170730008736574416C70686100127365744261636B67726F756E64436F6C6F720011736574427574746F6E54696E744C697374000A736574436865636B65640008736574436F6C6F72000E736574436F6C6F7246696C746572000F736574436F726E6572526164697573000773657444617461001773657444726F70446F776E566965775265736F75726365000C736574456C6C697073697A65000A73657446696C746572730008736574466C616773000C736574466F63757361626C65000A73657447726176697479000773657448696E74000E736574496D6167654269746D6170000C736574496E70757454797065000E7365744B65794C697374656E6572000F7365744C61796F7574506172616D73000A7365744D617267696E7300157365744D6172717565655265706561744C696D697400067365744D617800067365744D696E00117365744E65676174697665427574746F6E001A7365744F6E436865636B65644368616E67654C697374656E657200127365744F6E436C69636B4C697374656E657200187365744F6E466F6375734368616E67654C697374656E657200197365744F6E4974656D53656C65637465644C697374656E657200167365744F6E4C6F6E67436C69636B4C697374656E6572001A7365744F6E5365656B4261724368616E67654C697374656E657200127365744F6E546F7563684C697374656E6572000E7365744F7269656E746174696F6E000A73657450616464696E670011736574506F736974697665427574746F6E000B73657450726F6772657373000C7365745363616C6554797065000B73657453656C6563746564000C73657453656C656374696F6E000D73657453696E676C654C696E6500097365745374726F6B65000773657454657874000C73657454657874436F6C6F72000B7365745465787453697A6500087365745468656D65000B73657454696E744C69737400087365745469746C65000773657454797065000B73657454797065666163650012736574566572746963616C47726176697479000773657456696577000D7365745669736962696C697479000873657474696E6773000C73657474696E67734F70656E0011736861726564507265666572656E636573000473686F77000473697A6500077370696E6E657200087370696E6E657220000573706C6974000D73746172744163746976697479000A7374617274696D616765000C73746F70436865636B696E670003737472000873747253706C69740006737472696E67000F737472696E675365744C656E67746800057374796C6500077375624665617400087375625469746C6500057377694F6E000773776974636852000A73776974636865644F6E0004746578740009746578742F68746D6C000874657874566965770006746869732430000674686973243100057469746C6500097469746C65546578740008746F537472696E67000F746F67676C65536F6674496E7075740009746F704D617267696E0010757064617465566965774C61796F7574000375726C00057574662D38000176000A76616C24526164696F6F000A76616C24627574746F6E000C76616C24636865636B426F78000F76616C24636F6C6C61707365537562000C76616C246564697454657874000C76616C24657870616E646564000C76616C24666561744E616D65000B76616C24666561744E756D000D76616C2466696E616C49734F6E001176616C2466696E616C666561744E616D65000C76616C246D617856616C7565000776616C246D696E000E76616C24726164696F47726F7570000D76616C24726164696F4E616D65000B76616C247370696E6E6572000B76616C2473776974636852000876616C2474657874000C76616C247465787456696577000776616C2475726C000576616C7565000776616C75654F66000676616C756573000476696577000A766965774C6F616465640008766D506172616D7300057756696577000677656967687400047768617400057768657265000B7768696368427574746F6E00057769647468000477697468000C7772697465426F6F6C65616E000B7772697465446F75626C65000A7772697465466C6F617400087772697465496E74000977726974654C6F6E67000B7772697465537472696E6700017800027830000278310002783200017900017A00667E7E44387B226261636B656E64223A22646578222C22636F6D70696C6174696F6E2D6D6F6465223A226465627567222C226861732D636865636B73756D73223A747275652C226D696E2D617069223A32382C2276657273696F6E223A22382E31332E3139227D00EB0B7E7E7E7B224C636F6D2F616E64726F69642F737570706F72742F4D61696E41637469766974793B223A226362316134626130222C224C636F6D2F616E64726F69642F737570706F72742F4D656E752431303B223A2262656434663762222C224C636F6D2F616E64726F69642F737570706F72742F4D656E752431313B223A226463333663376533222C224C636F6D2F616E64726F69642F737570706F72742F4D656E752431323B223A223463353932633361222C224C636F6D2F616E64726F69642F737570706F72742F4D656E752431333B223A223136363232663031222C224C636F6D2F616E64726F69642F737570706F72742F4D656E752431343B223A223337613631666265222C224C636F6D2F616E64726F69642F737570706F72742F4D656E7524313524313B223A2264363561643339222C224C636F6D2F616E64726F69642F737570706F72742F4D656E7524313524323B223A226266343437313764222C224C636F6D2F616E64726F69642F737570706F72742F4D656E7524313524333B223A223731616263313634222C224C636F6D2F616E64726F69642F737570706F72742F4D656E752431353B223A226530666130326332222C224C636F6D2F616E64726F69642F737570706F72742F4D656E7524313624313B223A2234383331383732222C224C636F6D2F616E64726F69642F737570706F72742F4D656E7524313624323B223A226431303133343431222C224C636F6D2F616E64726F69642F737570706F72742F4D656E7524313624333B223A223732393463396363222C224C636F6D2F616E64726F69642F737570706F72742F4D656E752431363B223A223936653965326566222C224C636F6D2F616E64726F69642F737570706F72742F4D656E752431373B223A223838613364303365222C224C636F6D2F616E64726F69642F737570706F72742F4D656E752431383B223A226565383931323033222C224C636F6D2F616E64726F69642F737570706F72742F4D656E752431393B223A223933663065663465222C224C636F6D2F616E64726F69642F737570706F72742F4D656E7524313B223A226364343637363063222C224C636F6D2F616E64726F69642F737570706F72742F4D656E7524323B223A223364396632373531222C224C636F6D2F616E64726F69642F737570706F72742F4D656E7524333B223A226361313837633164222C224C636F6D2F616E64726F69642F737570706F72742F4D656E7524343B223A223230623961636262222C224C636F6D2F616E64726F69642F737570706F72742F4D656E7524353B223A226132303830643738222C224C636F6D2F616E64726F69642F737570706F72742F4D656E7524363B223A223339633561363434222C224C636F6D2F616E64726F69642F737570706F72742F4D656E7524373B223A223263393239623231222C224C636F6D2F616E64726F69642F737570706F72742F4D656E7524383B223A226333326531353634222C224C636F6D2F616E64726F69642F737570706F72742F4D656E7524393B223A223434313064343764222C224C636F6D2F616E64726F69642F737570706F72742F4D656E753B223A226231366261333637222C224C636F6D2F616E64726F69642F737570706F72742F507265666572656E6365733B223A226164393634346265222C224C636F6D2F616E64726F69642F737570706F72742F5224636F6C6F723B223A223930616230363438222C224C636F6D2F616E64726F69642F737570706F72742F52246472617761626C653B223A223232316434383261222C224C636F6D2F616E64726F69642F737570706F72742F52246C61796F75743B223A223961326164383034222C224C636F6D2F616E64726F69642F737570706F72742F52246D69706D61703B223A223766636136636664222C224C636F6D2F616E64726F69642F737570706F72742F5224737472696E673B223A223334383265656530222C224C636F6D2F616E64726F69642F737570706F72742F52247374796C653B223A223434376666366232222C224C636F6D2F616E64726F69642F737570706F72742F523B223A226462613261316637227D0002E296B3200002E296BD200001E29A9900027302E4021C05441080002410102410102410102410109B041C051E1E1E1E1E027401CA051C011715027001CA053A1501027102E40204009A041E027302E4021C03441080002410102410109B041C031E1E1E027001CA053A0601027302E4021C02441080002410109B041C021E1E027001CA053A0701027001CA053A0801027401CA051C051714179D17161793174E027401CA051C031714179D1717027001CA053A1901027302E4021C01441080009B041C011E027001CA051AE4027001CA053A1201027001CA051AEC027302E4021C04441080002410102410102410109B041C041E1E1E1E027001CA053A1301027001CA053A0B01027302E4021C07441080002410102410102410102410102410102410109B041C071E1E1E1E1E1E1E027001CA053A1401027001CA053A0C01027001CA053A0501027001CA053A0D01027001CA053A1801027001CA053A2801027001CA053A1A01027401CA051C08171417EB17FB17EB172517FB17EB1724027401CA051C05171417EB17FB17EB1726027102E40204199A04378601026F01CA05186E027102E40204199A04379C01027102E40204199A0437F501027102E40204199A04371702027102E40204199A0437A102027102E40204199A0437A302027201CA051C0618681869186A186B186C186D00000201CD01888004E457018180048058CF01049858000501030C9020019020019020019020019020D001808004B058D10101DC580101945A0101A85A00030101119020019020019020D401808004BC5AD50101E05A00020101149020019020D601808004DC5BD70101FC5B000601011600019020019020019020019020019020D801808004C85CD90101FC5C000301021C9020019020019020DA01808004D45EDB0101F85E0101C45F000101011F9020DD01808004D85FDE0101F45F00020101209020019020DF01808004C860E00101E86000010101229020E101808004A863E20101C46300050101239020019020019020019020019020E3018080048864E40101B46400010101289020E5018080048467E60101A06700020101299020019020E701808004F467E801019468000101012B9020E901808004D469EA0101F069000401012C9020019020019020019020EB01808004B46AEC0101DC6A00040101309020019020019020019020ED01808004BC6CEE0101E46C00070101349020019020019020019020019020019020019020EF01808004A46DF00101D86D000601013B00019020019020019020019020019020F101808004EC6EF20101A06F00010101419020F301808004E070F40101FC70000201014200019020F501808004B071F60101CC7100010101449020F701808004F472F80101907300010101459020F901808004CC74FA0101F07300010101469020FB01808004E874FC0101847500000101FD01808004D075FE0101E875000201014790200100FF01808004C076800201E476000701014910011001020102010201020190208102808004A47A820201A477000401015090200190200190200190208302808004D87A840201807B02261C0966190C0A540001000100010001000100010001000100010001000100010001000100010001000100020001000100010001000100010001000100010001000200010001000100010001000100010001008502818004A880010102B48E010102B08F010102AC90010102B89201018902000102A09301010288940101098097010502F897010102F899010102E49B010102B09F010402C4A3010102F8A5010102E4A7010102B0A801018820A07C0188208C7F018820A47F018820F4A801018820BC7E0102BC7F0102F47F01028CA901010ABC7C0102D87E0202A07E8E02800200018002000180020001800200050184A20101800200010184A3010F01BCB1010201E4B1010C000C207C1A011A011A011A011A011A011A010901090109010A010AAA02828004BCBC010182800498BD010109C8BD01010980BE010109B8BE010509A8B2010109F8B6010109B8B8011409ACB401010980B5010109ACB5010109D8B401AF0201F0BE01010188B201010184BA010101D8BB0104019CBF010101ECC10101018CB3010101B4B3010101ECB30101018CB4010101D4B501010188B6010101B8B6010101D8B6010101C0B7010101F8B701010198B8010101F8BB0101019CBC01010184B9010101C0B9010101E4B90101019CC2010501C4C4010101F8C4010101A4C5010101C4C5010101F0C5010101A4C6010101D0C6010101FCC6010101B0C701020001008801090109D602828004DCC701010001008A0109D702828004F4C701010001008B0109D8028280048CC801020001008C01090109D902828004A4C801010001008E0109DA02828004BCC801010001008F0109DB02828004D4C80100000100DC02828004ECC80101370801071F11001000040006001700375B0102640000017F640100017F01640000027F01640000037F02640000047F640100047F01640000057F01640000067F00000002000000A0A50000C0A5000002000000C9A50000D1A5000002000000DBA50000C0A5000002000000F3A50000D1A5000002000000FBA50000C0A50000020000000FA60000D1A500000200000017A60000D1A50000010000001FA600000100000030A60000020000003DA60000D1A500000100000045A600000200000055A60000D1A50000020000005CA60000D1A500000200000064A60000D1A50000020000006BA60000C0A500000200000087A60000D1A50000020000008FA60000D1A500000200000097A60000C0A5000002000000BFA60000D1A5000002000000C7A60000D1A5000002000000CFA60000D1A5000002000000D7A60000D1A5000002000000DFA60000D1A5000002000000E7A60000D1A5000002000000EFA60000D1A5000001000000F7A60000010000000EA70000020000002BA700001FA70000020000002BA7000032A70000020000002BA700003EA70000020000002BA700004AA70000020000002BA7000056A70000020000002BA7000062A70000010000006EA70000C0AC0000000000000100000000000000D0000000B4AC0000D8AC0000000000000100000000000000D4000000CCAC0000F0AC0000000000000100000000000000D6000000E4AC0000FCAC0000000000000100000000000000D8000000B4AC000018AD0000000000000300000000000000DA000000CCAC0000DB00000008AD0000DC00000010AD00002CAD0000000000000100000000000000DD00000024AD00002CAD0000000000000100000000000000DF000000E4AC00002CAD0000000000000100000000000000E100000024AD000038AD0000000000000100000000000000E3000000B4AC000044AD0000000000000100000000000000E500000024AD000044AD0000000000000100000000000000E7000000E4AC000044AD0000000000000100000000000000E900000024AD00005CAD0000000000000100000000000000EB00000050AD000068AD0000000000000100000000000000ED00000050AD000080AD0000000000000100000000000000EF00000074AD00008CAD0000000000000100000000000000F1000000B4AC000098AD0000000000000100000000000000F300000024AD000098AD0000000000000100000000000000F500000024AD000098AD0000000000000100000000000000F700000024AD000098AD0000000000000100000000000000F900000024AD000098AD0000000000000100000000000000FB00000024AD0000A4AD0000000000000000000000000000B0AD0000000000000100000000000000FF00000024AD0000BCAD00000000000001000000000000000101000024AD0000C8AD00000000000001000000000000000301000050AD00000000000000000000040000000000000031010000D4AD000032010000D4AD000036010000DCAD000037010000DCAD0000E4AD0000000000000000000000000000F0AD0000000000000000000000000000FCAD000000000000000000000000000008AE000000000000000000000000000014AE000000000000000000000000000020AE00000000000000000000000000002CAE00000000000000000000000000001100000000000000010000000000000001000000E8020000700000000200000096000000100C000003000000B3000000680E00000400000091000000CC1600000500000086010000541B0000060000002300000084270000012000008A000000E42B000003200000810000008464000001100000670000002470000002200000E8020000087400000420000025000000A0A50000002000002300000081A70000052000000800000070AC00000310000022000000B4AC0000062000002100000034AE0000001000000100000034B10000" diff --git a/app/src/main/jni/Includes/Interface.h b/app/src/main/jni/Includes/Interface.h new file mode 100644 index 0000000..624ea4c --- /dev/null +++ b/app/src/main/jni/Includes/Interface.h @@ -0,0 +1,76 @@ +#include "Dex.h" +#include + +JavaVM *antik = nullptr; +JNIEnv *antikYt = nullptr; + +namespace InterfaceMethods { + void *Icon; + void *IconWebViewData; + void *Init; + void *SettingsList; + void *GetFeatureList; + void *Changes; +} +jclass menuClass; + +static void RegisterMethods(JNIEnv *env) { + JNINativeMethod NativeMethodsClassMethods[] = { + {"Icon", "()Ljava/lang/String;", InterfaceMethods::Icon}, + {"IconWebViewData", "()Ljava/lang/String;", InterfaceMethods::IconWebViewData}, + {"Init", "(Landroid/content/Context;Landroid/widget/TextView;Landroid/widget/TextView;)V", InterfaceMethods::Init}, + {"SettingsList", "()[Ljava/lang/String;", InterfaceMethods::SettingsList}, + {"GetFeatureList", "()[Ljava/lang/String;", InterfaceMethods::GetFeatureList}, + {"Changes", "(Landroid/content/Context;ILjava/lang/String;IZLjava/lang/String;)V", InterfaceMethods::Changes}, + }; + + env->RegisterNatives(menuClass, NativeMethodsClassMethods,sizeof(NativeMethodsClassMethods) / sizeof(NativeMethodsClassMethods[0])); +} + +static jobjectArray HEX(JNIEnv* env, const std::string& hex) { + int len = hex.length() / 2; + jbyteArray arr = env->NewByteArray(len); + jbyte* buf = env->GetByteArrayElements(arr, nullptr); + for (int i = 0; i < len; i++) { + char h = hex[i * 2]; + char l = hex[i * 2 + 1]; + int hi = isdigit(h) ? h - '0' : tolower(h) - 'a' + 10; + int lo = isdigit(l) ? l - '0' : tolower(l) - 'a' + 10; + buf[i] = (jbyte)((hi << 4) | lo); + } + env->ReleaseByteArrayElements(arr, buf, 0); + jclass bbCls = env->FindClass("java/nio/ByteBuffer"); + jmethodID wrap = env->GetStaticMethodID(bbCls,"wrap","([B)Ljava/nio/ByteBuffer;"); + jobject bb = env->CallStaticObjectMethod(bbCls, wrap, arr); + return env->NewObjectArray(1, bbCls, bb); +} + +static void loadDex(JNIEnv* env, jobject context) { + jobjectArray buffers = HEX(env, hexdex); + if (!buffers) return; + jclass classLoaderClass = env->FindClass("java/lang/ClassLoader"); + jmethodID getSystemClassLoader = env->GetStaticMethodID(classLoaderClass,"getSystemClassLoader","()Ljava/lang/ClassLoader;"); + jobject parentCl = env->CallStaticObjectMethod(classLoaderClass, getSystemClassLoader); + jclass imCls = env->FindClass("dalvik/system/InMemoryDexClassLoader"); + jmethodID ctor = env->GetMethodID(imCls,"","([Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;)V"); + jobject dexLoader = env->NewObject(imCls, ctor, buffers, parentCl); + + jmethodID loadClass = env->GetMethodID(imCls,"loadClass","(Ljava/lang/String;)Ljava/lang/Class;"); + jstring clsName = env->NewStringUTF("com.android.support.Menu"); + menuClass = (jclass) env->CallObjectMethod(dexLoader, loadClass, clsName); + if (!menuClass) return; + menuClass = (jclass) env->NewGlobalRef(menuClass); + RegisterMethods(env); + jmethodID antikMethod = env->GetStaticMethodID(menuClass,"CreateMenu","(Landroid/content/Context;)V"); + if (!antikMethod) return; + env->CallStaticVoidMethod(menuClass, antikMethod, context); +} + +void binJava() { + if (antik->AttachCurrentThread(&antikYt, nullptr) != JNI_OK) return; + jclass atCls = antikYt->FindClass("android/app/ActivityThread"); + jmethodID curApp = antikYt->GetStaticMethodID(atCls,"currentApplication","()Landroid/app/Application;"); + jobject app = antikYt->CallStaticObjectMethod(atCls, curApp); + if (!app) return; + loadDex(antikYt, app); +} diff --git a/app/src/main/jni/Includes/Logger.h b/app/src/main/jni/Includes/Logger.h index 72021bf..df303d6 100644 --- a/app/src/main/jni/Includes/Logger.h +++ b/app/src/main/jni/Includes/Logger.h @@ -1,21 +1,27 @@ -#ifndef DAWN_LOGGER_H -#define DAWN_LOGGER_H +// +// Logger.h +// +// Created by MJ (Ruit) on 1/1/19. +// +#ifndef Logger_h +#define Logger_h + +#include #include -enum daLogType { - daDEBUG = 3, - daERROR = 6, - daINFO = 4, - daWARN = 5 +enum LogType { + oDEBUG = 3, + oERROR = 6, + oINFO = 4, + oWARN = 5 }; -//Change this to another Log Tag if ya want. IN the batch script I provide you change the log tag then too #define TAG OBFUSCATE("Mod_Menu") -#define LOGD(...) ((void)__android_log_print(daDEBUG, TAG, __VA_ARGS__)) -#define LOGE(...) ((void)__android_log_print(daERROR, TAG, __VA_ARGS__)) -#define LOGI(...) ((void)__android_log_print(daINFO, TAG, __VA_ARGS__)) -#define LOGW(...) ((void)__android_log_print(daWARN, TAG, __VA_ARGS__)) +#define LOGD(...) ((void)__android_log_print(oDEBUG, TAG, __VA_ARGS__)) +#define LOGE(...) ((void)__android_log_print(oERROR, TAG, __VA_ARGS__)) +#define LOGI(...) ((void)__android_log_print(oINFO, TAG, __VA_ARGS__)) +#define LOGW(...) ((void)__android_log_print(oWARN, TAG, __VA_ARGS__)) -#endif //DAWN_LOGGER_H \ No newline at end of file +#endif /* Logger_h */ diff --git a/app/src/main/jni/Includes/Macros.h b/app/src/main/jni/Includes/Macros.h index e0f9f90..c36d4c8 100644 --- a/app/src/main/jni/Includes/Macros.h +++ b/app/src/main/jni/Includes/Macros.h @@ -1,113 +1,117 @@ +// thanks to shmoo and joeyjurjens for the usefull stuff under this comment. #ifndef ANDROID_MOD_MENU_MACROS_H #define ANDROID_MOD_MENU_MACROS_H -#include -#include -#include -#include - -// thanks to shmoo and joeyjurjens for the usefull stuff under this comment. - #if defined(__aarch64__) //Compile for arm64 lib only #include -#define HOOK(offset, ptr, orig) A64HookFunction((void *)getAbsoluteAddress(targetLibName, string2Offset(OBFUSCATE(offset))), (void *)ptr, (void **)&orig) -#define HOOK_LIB(lib, offset, ptr, orig) A64HookFunction((void *)getAbsoluteAddress(OBFUSCATE(lib), string2Offset(OBFUSCATE(offset))), (void *)ptr, (void **)&orig) - -#define HOOK_NO_ORIG(offset, ptr) A64HookFunction((void *)getAbsoluteAddress(targetLibName, string2Offset(OBFUSCATE(offset))), (void *)ptr, NULL) -#define HOOK_LIB_NO_ORIG(lib, offset, ptr) A64HookFunction((void *)getAbsoluteAddress(OBFUSCATE(lib), string2Offset(OBFUSCATE(offset))), (void *)ptr, NULL) - -#define HOOKSYM(sym, ptr, org) A64HookFunction(dlsym(dlopen(targetLibName, 4), OBFUSCATE(sym)), (void *)ptr, (void **)&org) -#define HOOKSYM_LIB(lib, sym, ptr, org) A64HookFunction(dlsym(dlopen(OBFUSCATE(lib), 4), OBFUSCATE(sym)), (void *)ptr, (void **)&org) - -#define HOOKSYM_NO_ORIG(sym, ptr) A64HookFunction(dlsym(dlopen(targetLibName, 4), OBFUSCATE(sym)), (void *)ptr, NULL) -#define HOOKSYM_LIB_NO_ORIG(lib, sym, ptr) A64HookFunction(dlsym(dlopen(OBFUSCATE(lib), 4), OBFUSCATE(sym)), (void *)ptr, NULL) - #else //Compile for armv7 lib only. Do not worry about greyed out highlighting code, it still works - #include #include -#define HOOK(offset, ptr, orig) MSHookFunction((void *)getAbsoluteAddress(targetLibName, string2Offset(OBFUSCATE(offset))), (void *)ptr, (void **)&orig) -#define HOOK_LIB(lib, offset, ptr, orig) MSHookFunction((void *)getAbsoluteAddress(OBFUSCATE(lib), string2Offset(OBFUSCATE(offset))), (void *)ptr, (void **)&orig) +#endif + +void hook(void *offset, void* ptr, void **orig) +{ +#if defined(__aarch64__) + A64HookFunction(offset, ptr, orig); +#else + MSHookFunction(offset, ptr, orig); +#endif +} -#define HOOK_NO_ORIG(offset, ptr) MSHookFunction((void *)getAbsoluteAddress(targetLibName, string2Offset(OBFUSCATE(offset))), (void *)ptr, NULL) -#define HOOK_LIB_NO_ORIG(lib, offset, ptr) MSHookFunction((void *)getAbsoluteAddress(OBFUSCATE(lib), string2Offset(OBFUSCATE(offset))), (void *)ptr, NULL) +#define HOOK(offset, ptr, orig) hook((void *)getAbsoluteAddress(targetLibName, string2Offset(OBFUSCATE(offset))), (void *)ptr, (void **)&orig) +#define HOOK_LIB(lib, offset, ptr, orig) hook((void *)getAbsoluteAddress(OBFUSCATE(lib), string2Offset(OBFUSCATE(offset))), (void *)ptr, (void **)&orig) -#define HOOKSYM(sym, ptr, org) MSHookFunction(dlsym(dlopen(targetLibName, 4), OBFUSCATE(sym)), (void *)ptr, (void **)&org) -#define HOOKSYM_LIB(lib, sym, ptr, org) MSHookFunction(dlsym(dlopen(OBFUSCATE(lib), 4), OBFUSCATE(sym)), (void *)ptr, (void **)&org) +#define HOOK_NO_ORIG(offset, ptr) hook((void *)getAbsoluteAddress(targetLibName, string2Offset(OBFUSCATE(offset))), (void *)ptr, NULL) +#define HOOK_LIB_NO_ORIG(lib, offset, ptr) hook((void *)getAbsoluteAddress(OBFUSCATE(lib), string2Offset(OBFUSCATE(offset))), (void *)ptr, NULL) -#define HOOKSYM_NO_ORIG(sym, ptr) MSHookFunction(dlsym(dlopen(targetLibName, 4), OBFUSCATE(sym)), (void *)ptr, NULL) -#define HOOKSYM_LIB_NO_ORIG(lib, sym, ptr) MSHookFunction(dlsym(dlopen(OBFUSCATE(lib), 4), OBFUSCATE(sym)), (void *)ptr, NULL) +#define HOOKSYM(sym, ptr, org) hook(dlsym(dlopen(targetLibName, 4), OBFUSCATE(sym)), (void *)ptr, (void **)&org) +#define HOOKSYM_LIB(lib, sym, ptr, org) hook(dlsym(dlopen(OBFUSCATE(lib), 4), OBFUSCATE(sym)), (void *)ptr, (void **)&org) -#endif +#define HOOKSYM_NO_ORIG(sym, ptr) hook(dlsym(dlopen(targetLibName, 4), OBFUSCATE(sym)), (void *)ptr, NULL) +#define HOOKSYM_LIB_NO_ORIG(lib, sym, ptr) hook(dlsym(dlopen(OBFUSCATE(lib), 4), OBFUSCATE(sym)), (void *)ptr, NULL) -// Obfuscate offset -#define OBFUSCATEOFFSET(str) string2Offset(OBFUSCATE(str)) // Encrypt offset +std::vector memoryPatches; +std::vector offsetVector; // Patching a offset without switch. -void patchOffset(const char *fileName, uint64_t offset, std::string hexBytes) { +void patchOffset(const char *fileName, uint64_t offset, std::string hexBytes, bool isOn) { + MemoryPatch patch = MemoryPatch::createWithHex(fileName, offset, hexBytes); - if(!patch.isValid()){ - LOGE(OBFUSCATE("Failing offset: 0x%llu, please re-check the hex you entered."), offset); - return; - } - if(!patch.Modify()) { - LOGE(OBFUSCATE("Something went wrong while patching this offset: 0x%llu"), offset); - return; + + //Check if offset exists in the offsetVector + if (std::find(offsetVector.begin(), offsetVector.end(), offset) != offsetVector.end()) { + //LOGE(OBFUSCATE("Already exists")); + std::vector::iterator itr = std::find(offsetVector.begin(), offsetVector.end(), offset); + patch = memoryPatches[std::distance(offsetVector.begin(), itr)]; //Get index of memoryPatches vector + } else { + memoryPatches.push_back(patch); + offsetVector.push_back(offset); + //LOGI(OBFUSCATE("Added")); } -} -void patchOffset(uint64_t offset, std::string hexBytes) { - MemoryPatch patch = MemoryPatch::createWithHex(targetLibName, offset, hexBytes); - if(!patch.isValid()){ - LOGE(OBFUSCATE("Failing offset: 0x%llu, please re-check the hex you entered."), offset); + if (!patch.isValid()) { + LOGE(OBFUSCATE("Failing offset: 0x%llu, please re-check the hex"), offset); return; } - if(!patch.Modify()) { - LOGE(OBFUSCATE("Something went wrong while patching this offset: 0x%llu"), offset); - return; + if (isOn) { + if (!patch.Modify()) { + LOGE(OBFUSCATE("Something went wrong while patching this offset: 0x%llu"), offset); + } + } else { + if (!patch.Restore()) { + LOGE(OBFUSCATE("Something went wrong while restoring this offset: 0x%llu"), offset); + } } } -inline void patchOffsetSym(uintptr_t addr, - const std::string &hex, - bool enable) { - static std::map patchMap; +void patchOffsetSym(uintptr_t absolute_address, std::string hexBytes, bool isOn) { - if (!addr) { - LOGE("patchOffsetSym: NULL address"); - return; - } + MemoryPatch patch = MemoryPatch::createWithHex(absolute_address, hexBytes); - if (!patchMap.count(addr)) { - patchMap[addr] = MemoryPatch::createWithHex(addr, hex); + //Check if offset exists in the offsetVector + if (std::find(offsetVector.begin(), offsetVector.end(), absolute_address) != offsetVector.end()) { + //LOGE(OBFUSCATE("Already exists")); + std::vector::iterator itr = std::find(offsetVector.begin(), offsetVector.end(), absolute_address); + patch = memoryPatches[std::distance(offsetVector.begin(), itr)]; //Get index of memoryPatches vector + } else { + memoryPatches.push_back(patch); + offsetVector.push_back(absolute_address); + //LOGI(OBFUSCATE("Added")); } - MemoryPatch &patch = patchMap[addr]; - if (!patch.isValid()) { - LOGE("patchOffsetSym: invalid patch at %p", (void*)addr); + LOGE(OBFUSCATE("Failing offset: 0x%llu, please re-check the hex"), absolute_address); return; } - - if (enable) { - patch.Modify(); + if (isOn) { + if (!patch.Modify()) { + LOGE(OBFUSCATE("Something went wrong while patching this offset: 0x%llu"), absolute_address); + } } else { - patch.Restore(); + if (!patch.Restore()) { + LOGE(OBFUSCATE("Something went wrong while restoring this offset: 0x%llu"), absolute_address); + } } } -#define PATCHOFFSET(offset, hex) patchOffset(string2Offset(OBFUSCATE(offset)), OBFUSCATE(hex)) -#define PATCHOFFSET_LIB(lib, offset, hex) patchOffset(OBFUSCATE(lib), string2Offset(OBFUSCATE(offset)), OBFUSCATE(hex)) +#define PATCH(offset, hex) patchOffset(targetLibName, string2Offset(OBFUSCATE(offset)), OBFUSCATE(hex), true) +#define PATCH_LIB(lib, offset, hex) patchOffset(OBFUSCATE(lib), string2Offset(OBFUSCATE(offset)), OBFUSCATE(hex), true) + +#define PATCH_SYM(sym, hex) patchOffset(dlsym(dlopen(targetLibName, 4), OBFUSCATE(sym)), OBFUSCATE(hex), true) +#define PATCH_LIB_SYM(lib, sym, hex) patchOffset(dlsym(dlopen(lib, 4), OBFUSCATE(sym)), OBFUSCATE(hex), true) + +#define PATCH_SWITCH(offset, hex, boolean) patchOffset(targetLibName, string2Offset(OBFUSCATE(offset)), OBFUSCATE(hex), boolean) +#define PATCH_LIB_SWITCH(lib, offset, hex, boolean) patchOffset(OBFUSCATE(lib), string2Offset(OBFUSCATE(offset)), OBFUSCATE(hex), boolean) + +#define PATCH_SYM_SWITCH(sym, hex, boolean) patchOffsetSym((uintptr_t)dlsym(dlopen(targetLibName, 4), OBFUSCATE(sym)), OBFUSCATE(hex), boolean) +#define PATCH_LIB_SYM_SWITCH(lib, sym, hex, boolean) patchOffsetSym((uintptr_t)dlsym(dlopen(lib, 4), OBFUSCATE(sym)), OBFUSCATE(hex), boolean) -#define PATCH_SYM_SWITCH(sym, hex, state) \ -patchOffsetSym((uintptr_t)dlsym(dlopen(targetLibName, RTLD_NOW), OBFUSCATE(sym)), \ - OBFUSCATE(hex), state) +#define RESTORE(offset) patchOffset(targetLibName, string2Offset(OBFUSCATE(offset)), "", false) +#define RESTORE_LIB(lib, offset) patchOffset(OBFUSCATE(lib), string2Offset(OBFUSCATE(offset)), "", false) -#define PATCH_LIB_SYM_SWITCH(lib, sym, hex, state) \ -patchOffsetSym((uintptr_t)dlsym(dlopen(OBFUSCATE(lib), RTLD_NOW), OBFUSCATE(sym)), \ - OBFUSCATE(hex), state) - -#endif //ANDROID_MOD_MENU_MACROS_H +#define RESTORE_SYM(sym) patchOffsetSym((uintptr_t)dlsym(dlopen(targetLibName, 4), OBFUSCATE(sym)), "", false) +#define RESTORE_LIB_SYM(lib, sym) patchOffsetSym((uintptr_t)dlsym(dlopen(lib, 4), OBFUSCATE(sym)), "", false) +#endif //ANDROID_MOD_MENU_MACROS_H \ No newline at end of file diff --git a/app/src/main/jni/Includes/Utils.h b/app/src/main/jni/Includes/Utils.h index 24cb311..c703500 100644 --- a/app/src/main/jni/Includes/Utils.h +++ b/app/src/main/jni/Includes/Utils.h @@ -12,7 +12,7 @@ typedef unsigned long DWORD; static uintptr_t libBase; -bool isGameLibLoaded = false; +bool libLoaded = false; DWORD findLibrary(const char *library) { char filename[0xFF] = {0}, @@ -51,22 +51,20 @@ DWORD getAbsoluteAddress(const char *libraryName, DWORD relativeAddr) { return (reinterpret_cast(libBase + relativeAddr)); } -extern "C" { -JNIEXPORT jboolean JNICALL -Java_uk_lgl_modmenu_FloatingModMenuService_isGameLibLoaded(JNIEnv *env, jobject thiz) { - return isGameLibLoaded; -} + +jboolean isGameLibLoaded(JNIEnv *env, jobject thiz) { + return libLoaded; } bool isLibraryLoaded(const char *libraryName) { - //isGameLibLoaded = true; + //libLoaded = true; char line[512] = {0}; FILE *fp = fopen(OBFUSCATE("/proc/self/maps"), OBFUSCATE("rt")); if (fp != NULL) { while (fgets(line, sizeof(line), fp)) { std::string a = line; if (strstr(line, libraryName)) { - isGameLibLoaded = true; + libLoaded = true; return true; } } @@ -75,35 +73,6 @@ bool isLibraryLoaded(const char *libraryName) { return false; } -//Credit: Octowolve -void MakeToast(JNIEnv *env, jobject thiz, const char *text, int length) { - //Add our toast in here so it wont be easy to change by simply editing the smali and cant - //be cut out because this method is needed to start the hack (Octowolve is smart) - jstring jstr = env->NewStringUTF(text); //Edit this text to your desired toast message! - jclass toast = env->FindClass(OBFUSCATE("android/widget/Toast")); - jmethodID methodMakeText = - env->GetStaticMethodID( - toast, - OBFUSCATE("makeText"), - OBFUSCATE( - "(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;")); - if (methodMakeText == NULL) { - LOGE(OBFUSCATE("toast.makeText not Found")); - return; - } - //The last int is the length on how long the toast should be displayed - //0 = Short, 1 = Long - jobject toastobj = env->CallStaticObjectMethod(toast, methodMakeText, - thiz, jstr, length); - - jmethodID methodShow = env->GetMethodID(toast, OBFUSCATE("show"), OBFUSCATE("()V")); - if (methodShow == NULL) { - LOGE(OBFUSCATE("toast.show not Found")); - return; - } - env->CallVoidMethod(toastobj, methodShow); -} - uintptr_t string2Offset(const char *c) { int base = 16; // See if this function catches all possibilities. @@ -123,9 +92,9 @@ uintptr_t string2Offset(const char *c) { return strtoull(c, nullptr, base); } -namespace Toast { +namespace ToastLength { inline const int LENGTH_LONG = 1; inline const int LENGTH_SHORT = 0; } -#endif +#endif \ No newline at end of file diff --git a/app/src/main/jni/Main.cpp b/app/src/main/jni/Main.cpp index 85c92c7..698a0a4 100644 --- a/app/src/main/jni/Main.cpp +++ b/app/src/main/jni/Main.cpp @@ -1,13 +1,8 @@ -// -// Created by aantik on 2/1/2026. -// - -//Main.cpp - #include #include -#include +#include #include +#include #include #include #include @@ -17,28 +12,16 @@ #include "Includes/Logger.h" #include "Includes/obfuscate.h" #include "Includes/Utils.h" - #include "KittyMemory/MemoryPatch.h" -#include "And64InlineHook/And64InlineHook.hpp" -#include "Menu.h" +#include "Menu/Setup.h" +#include "Includes/Interface.h" +//Target lib here #define targetLibName OBFUSCATE("libFileA.so") #include "Includes/Macros.h" -#include "JavaGPP/Interface/Interface.h" - - - -// fancy struct for patches for kittyMemory -struct My_Patches { - // let's assume we have patches for these functions for whatever game - // like show in miniMap boolean function - MemoryPatch GodMode, GodMode2, SliderExample; - // etc... -} hexPatches; - bool feature1, feature2, featureHookToggle, Health; int sliderValue = 1, level = 0; void *instanceBtn; @@ -81,7 +64,6 @@ void FunctionExample(void *instance) { return old_FunctionExample(instance); } - // we will run our hacks in a new thread so our while loop doesn't block process main thread void *hack_thread(void *) { LOGI(OBFUSCATE("pthread created")); @@ -100,18 +82,6 @@ void *hack_thread(void *) { LOGI(OBFUSCATE("%s has been loaded"), (const char *) targetLibName); #if defined(__aarch64__) //To compile this code for arm64 lib only. Do not worry about greyed out highlighting code, it still works - // New way to patch hex via KittyMemory without need to specify len. Spaces or without spaces are fine - // ARM64 assembly example - // MOV X0, #0x0 = 00 00 80 D2 - // RET = C0 03 5F D6 - hexPatches.GodMode = MemoryPatch::createWithHex(targetLibName, - string2Offset(OBFUSCATE("0x123456")), - OBFUSCATE("00 00 80 D2 C0 03 5F D6")); - //You can also specify target lib like this - hexPatches.GodMode2 = MemoryPatch::createWithHex("libtargetLibHere.so", - string2Offset(OBFUSCATE("0x222222")), - OBFUSCATE("20 00 80 D2 C0 03 5F D6")); - // Hook example. Comment out if you don't use hook // Strings in macros are automatically obfuscated. No need to obfuscate! HOOK("str", FunctionExample, old_FunctionExample); @@ -124,23 +94,12 @@ void *hack_thread(void *) { HOOKSYM_LIB_NO_ORIG("libFileB.so", "__SymbolNameExample", FunctionExample); // Patching offsets directly. Strings are automatically obfuscated too! - PATCHOFFSET("0x20D3A8", "00 00 A0 E3 1E FF 2F E1"); - PATCHOFFSET_LIB("libFileB.so", "0x20D3A8", "00 00 A0 E3 1E FF 2F E1"); + PATCH("0x20D3A8", "00 00 A0 E3 1E FF 2F E1"); + PATCH_LIB("libFileB.so", "0x20D3A8", "00 00 A0 E3 1E FF 2F E1"); AddMoneyExample = (void(*)(void *,int))getAbsoluteAddress(targetLibName, 0x123456); #else //To compile this code for armv7 lib only. - // New way to patch hex via KittyMemory without need to specify len. Spaces or without spaces are fine - // ARMv7 assembly example - // MOV R0, #0x0 = 00 00 A0 E3 - // BX LR = 1E FF 2F E1 - hexPatches.GodMode = MemoryPatch::createWithHex(targetLibName, //Normal obfuscate - string2Offset(OBFUSCATE("0x123456")), - OBFUSCATE("00 00 A0 E3 1E FF 2F E1")); - //You can also specify target lib like this - hexPatches.GodMode2 = MemoryPatch::createWithHex("libtargetLibHere.so", - string2Offset(OBFUSCATE("0x222222")), - OBFUSCATE("01 00 A0 E3 1E FF 2F E1")); // Hook example. Comment out if you don't use hook // Strings in macros are automatically obfuscated. No need to obfuscate! @@ -154,22 +113,39 @@ void *hack_thread(void *) { HOOKSYM_LIB_NO_ORIG("libFileB.so", "__SymbolNameExample", FunctionExample); // Patching offsets directly. Strings are automatically obfuscated too! - PATCHOFFSET("0x20D3A8", "00 00 A0 E3 1E FF 2F E1"); - PATCHOFFSET_LIB("libFileB.so", "0x20D3A8", "00 00 A0 E3 1E FF 2F E1"); + PATCH("0x20D3A8", "00 00 A0 E3 1E FF 2F E1"); + PATCH_LIB("libFileB.so", "0x20D3A8", "00 00 A0 E3 1E FF 2F E1"); + + //Restore changes to original + RESTORE("0x20D3A8"); + RESTORE_LIB("libFileB.so", "0x20D3A8"); AddMoneyExample = (void (*)(void *, int)) getAbsoluteAddress(targetLibName, 0x123456); LOGI(OBFUSCATE("Done")); #endif + //Anti-leech + /*if (!iconValid || !initValid || !settingsValid) { + //Bad function to make it crash + sleep(5); + int *p = 0; + *p = 0; + }*/ + return NULL; } +// Do not change or translate the first text unless you know what you are doing +// Assigning feature numbers is optional. Without it, it will automatically count for you, starting from 0 +// Assigned feature numbers can be like any numbers 1,3,200,10... instead in order 0,1,2,3,4,5... +// ButtonLink, Category, RichTextView and RichWebView is not counted. They can't have feature number assigned +// Toggle, ButtonOnOff and Checkbox can be switched on by default, if you add True_. Example: CheckBox_True_The Check Box +// To learn HTML, go to this page: https://www.w3schools.com/ -jobjectArray getFeatureList(JNIEnv *env, jobject context) { +jobjectArray GetFeatureList(JNIEnv *env, jobject context) { jobjectArray ret; - const char *features[] = { OBFUSCATE("Category_The Category"), //Not counted OBFUSCATE("Toggle_The toggle"), @@ -193,10 +169,11 @@ jobjectArray getFeatureList(JNIEnv *env, jobject context) { OBFUSCATE("CollapseAdd_Toggle_The toggle"), OBFUSCATE("CollapseAdd_Toggle_The toggle"), OBFUSCATE("123_CollapseAdd_Toggle_The toggle"), + OBFUSCATE("122_CollapseAdd_CheckBox_Check box"), OBFUSCATE("CollapseAdd_Button_The button"), //Create new collapse again - OBFUSCATE("Collapse_Collapse 2"), + OBFUSCATE("Collapse_Collapse 2_True"), OBFUSCATE("CollapseAdd_SeekBar_The slider_1_100"), OBFUSCATE("CollapseAdd_InputValue_Input number"), @@ -211,40 +188,49 @@ jobjectArray getFeatureList(JNIEnv *env, jobject context) { "") }; - + //Now you dont have to manually update the number everytime; int Total_Feature = (sizeof features / sizeof features[0]); - ret = (jobjectArray) env->NewObjectArray(Total_Feature, env->FindClass(OBFUSCATE("java/lang/String")),env->NewStringUTF("")); - for (int i = 0; i < Total_Feature; i++) env->SetObjectArrayElement(ret, i, env->NewStringUTF(features[i])); - pthread_t ptid; + ret = (jobjectArray) + env->NewObjectArray(Total_Feature, env->FindClass(OBFUSCATE("java/lang/String")), + env->NewStringUTF("")); + + for (int i = 0; i < Total_Feature; i++) + env->SetObjectArrayElement(ret, i, env->NewStringUTF(features[i])); return (ret); } -void Changes(JNIEnv *env, jclass clazz, jobject obj, jint featNum, jstring featName, jint value, jboolean boolean, jstring str) { +void Changes(JNIEnv *env, jclass clazz, jobject obj, + jint featNum, jstring featName, jint value, + jboolean boolean, jstring str) { LOGD(OBFUSCATE("Feature name: %d - %s | Value: = %d | Bool: = %d | Text: = %s"), featNum, env->GetStringUTFChars(featName, 0), value, boolean, str != NULL ? env->GetStringUTFChars(str, 0) : ""); + //BE CAREFUL NOT TO ACCIDENTLY REMOVE break; + switch (featNum) { case 0: - feature2 = boolean; - if (feature2) { - // To print bytes you can do this - //if (hexPatches.GodMode.Modify()) { - // LOGD(OBFUSCATE("Current Bytes: %s"), - // hexPatches.GodMode.get_CurrBytes().c_str()); - //} - hexPatches.GodMode.Modify(); - hexPatches.GodMode2.Modify(); - //LOGI(OBFUSCATE("On")); - } else { - hexPatches.GodMode.Restore(); - hexPatches.GodMode2.Restore(); - //LOGI(OBFUSCATE("Off")); - } + // A much simpler way to patch hex via KittyMemory without need to specify the struct and len. Spaces or without spaces are fine + // ARMv7 assembly example + // MOV R0, #0x0 = 00 00 A0 E3 + // BX LR = 1E FF 2F E1 + PATCH_LIB_SWITCH("libil2cpp.so", "0x100000", "00 00 A0 E3 1E FF 2F E1", boolean); break; case 100: + //Reminder that the strings are auto obfuscated + //Switchable patch + PATCH_SWITCH("0x400000", "00 00 A0 E3 1E FF 2F E1", boolean); + PATCH_LIB_SWITCH("libil2cpp.so", "0x200000", "00 00 A0 E3 1E FF 2F E1", boolean); + PATCH_SYM_SWITCH("_SymbolExample", "00 00 A0 E3 1E FF 2F E1", boolean); + PATCH_LIB_SYM_SWITCH("libNativeGame.so", "_SymbolExample", "00 00 A0 E3 1E FF 2F E1", boolean); + + //Restore patched offset to original + RESTORE("0x400000"); + RESTORE_LIB("libil2cpp.so", "0x400000"); + RESTORE_SYM("_SymbolExample"); + RESTORE_LIB_SYM("libil2cpp.so", "_SymbolExample"); break; case 110: break; @@ -257,29 +243,13 @@ void Changes(JNIEnv *env, jclass clazz, jobject obj, jint featNum, jstring featN switch (value) { //For noobies case 0: - hexPatches.SliderExample = MemoryPatch::createWithHex( - targetLibName, string2Offset( - OBFUSCATE("0x100000")), - OBFUSCATE( - "00 00 A0 E3 1E FF 2F E1")); - hexPatches.SliderExample.Modify(); + RESTORE("0x0"); break; case 1: - hexPatches.SliderExample = MemoryPatch::createWithHex( - targetLibName, string2Offset( - OBFUSCATE("0x100000")), - OBFUSCATE( - "01 00 A0 E3 1E FF 2F E1")); - hexPatches.SliderExample.Modify(); + PATCH("0x0", "01 00 A0 E3 1E FF 2F E1"); break; case 2: - hexPatches.SliderExample = MemoryPatch::createWithHex( - targetLibName, - string2Offset( - OBFUSCATE("0x100000")), - OBFUSCATE( - "02 00 A0 E3 1E FF 2F E1")); - hexPatches.SliderExample.Modify(); + PATCH("0x0", "02 00 A0 E3 1E FF 2F E1"); break; } break; @@ -311,32 +281,29 @@ void Changes(JNIEnv *env, jclass clazz, jobject obj, jint featNum, jstring featN level = value; break; case 8: - //MakeToast(env, obj, TextInput, Toast::LENGTH_SHORT); break; case 9: break; } +} +__attribute__((constructor)) +void lib_main() { + // Create a new thread so it does not block the main thread, means the game would not freeze + pthread_t ptid; + pthread_create(&ptid, NULL, hack_thread, NULL); } -JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { +JNIEXPORT jint JNICALL +JNI_OnLoad(JavaVM *vm, void *) { antik = vm; - InterfaceMethods::Icon = (void*) Icon; + InterfaceMethods::Icon = (void*) Icon; InterfaceMethods::IconWebViewData = (void *) IconWebViewData; + InterfaceMethods::Init = (void *) Init; + InterfaceMethods::SettingsList = (void *) SettingsList; + InterfaceMethods::GetFeatureList = (void *) GetFeatureList; InterfaceMethods::Changes = (void *) Changes; - InterfaceMethods::getFeatureList = (void *) getFeatureList; - InterfaceMethods::settingsList = (void *) settingsList; - InterfaceMethods::setTitleText = (void *) setTitleText; - InterfaceMethods::setHeadingText = (void *) setHeadingText; - binJava(); return JNI_VERSION_1_6; } - - -__attribute__((constructor)) -void lib_main() { - pthread_t ptid; - pthread_create(&ptid, NULL, hack_thread, NULL); -} diff --git a/app/src/main/jni/Menu/Menu.h b/app/src/main/jni/Menu/Menu.h new file mode 100644 index 0000000..4529339 --- /dev/null +++ b/app/src/main/jni/Menu/Menu.h @@ -0,0 +1,68 @@ +bool iconValid, settingsValid, initValid; + +//Big letter cause crash +void setText(JNIEnv *env, jobject obj, const char* text){ + //https://stackoverflow.com/a/33627640/3763113 + //A little JNI calls here. You really really need a great knowledge if you want to play with JNI stuff + //Html.fromHtml(""); + jclass html = (*env).FindClass(OBFUSCATE("android/text/Html")); + jmethodID fromHtml = (*env).GetStaticMethodID(html, OBFUSCATE("fromHtml"), OBFUSCATE("(Ljava/lang/String;)Landroid/text/Spanned;")); + + //setText(""); + jclass textView = (*env).FindClass(OBFUSCATE("android/widget/TextView")); + jmethodID setText = (*env).GetMethodID(textView, OBFUSCATE("setText"), OBFUSCATE("(Ljava/lang/CharSequence;)V")); + + //Java string + jstring jstr = (*env).NewStringUTF(text); + (*env).CallVoidMethod(obj, setText, (*env).CallStaticObjectMethod(html, fromHtml, jstr)); +} + +jstring Icon(JNIEnv *env, jobject thiz) { + iconValid = true; + + //Use https://www.base64encode.org/ to encode your image to base64 + return env->NewStringUTF( + OBFUSCATE("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")); +} + +jstring IconWebViewData(JNIEnv *env, jobject thiz) { + iconValid = true; + //WebView support GIF animation. Upload your image or GIF on imgur.com or other sites + + // From internet (Requires android.permission.INTERNET) + // return env->NewStringUTF(OBFUSCATE("https://i.imgur.com/SujJ85j.gif")); + + // Base64 html: + // return env->NewStringUTF("data:image/png;base64, "); + + // To disable it, return NULL. It will use normal image above: + // return NULL + + //return env->NewStringUTF(OBFUSCATE_KEY("https://i.imgur.com/SujJ85j.gif", 'u')); + return NULL; +} + +jobjectArray SettingsList(JNIEnv *env, jobject activityObject) { + jobjectArray ret; + + const char *features[] = { + OBFUSCATE("Category_Settings"), + OBFUSCATE("-1_Toggle_Save feature preferences"), //-1 is checked on Preferences.java + OBFUSCATE("-3_Toggle_Auto size vertically"), + OBFUSCATE("Category_Menu"), + OBFUSCATE("-6_Button_Close settings"), + }; + + int Total_Feature = (sizeof features / + sizeof features[0]); //Now you dont have to manually update the number everytime; + ret = (jobjectArray) + env->NewObjectArray(Total_Feature, env->FindClass(OBFUSCATE("java/lang/String")), + env->NewStringUTF("")); + int i; + for (i = 0; i < Total_Feature; i++) + env->SetObjectArrayElement(ret, i, env->NewStringUTF(features[i])); + + settingsValid = true; + + return (ret); +} diff --git a/app/src/main/jni/Menu/Setup.h b/app/src/main/jni/Menu/Setup.h new file mode 100644 index 0000000..1a9404a --- /dev/null +++ b/app/src/main/jni/Menu/Setup.h @@ -0,0 +1,59 @@ +#include +#include "Menu/Menu.h" +#include "Menu/get_device_api_level_inlines.h" + +//Jni stuff from MrDarkRX https://github.com/MrDarkRXx/DarkMod-Floating +void setDialog(jobject ctx, JNIEnv *env, const char *title, const char *msg){ + jclass Alert = env->FindClass(OBFUSCATE("android/app/AlertDialog$Builder")); + jmethodID AlertCons = env->GetMethodID(Alert, OBFUSCATE(""), OBFUSCATE("(Landroid/content/Context;)V")); + + jobject MainAlert = env->NewObject(Alert, AlertCons, ctx); + + jmethodID setTitle = env->GetMethodID(Alert, OBFUSCATE("setTitle"), OBFUSCATE("(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;")); + env->CallObjectMethod(MainAlert, setTitle, env->NewStringUTF(title)); + + jmethodID setMsg = env->GetMethodID(Alert, OBFUSCATE("setMessage"), OBFUSCATE("(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;")); + env->CallObjectMethod(MainAlert, setMsg, env->NewStringUTF(msg)); + + jmethodID setCa = env->GetMethodID(Alert, OBFUSCATE("setCancelable"), OBFUSCATE("(Z)Landroid/app/AlertDialog$Builder;")); + env->CallObjectMethod(MainAlert, setCa, false); + + jmethodID setPB = env->GetMethodID(Alert, OBFUSCATE("setPositiveButton"), OBFUSCATE("(Ljava/lang/CharSequence;Landroid/content/DialogInterface$OnClickListener;)Landroid/app/AlertDialog$Builder;")); + env->CallObjectMethod(MainAlert, setPB, env->NewStringUTF("Ok"), static_cast(NULL)); + + jmethodID create = env->GetMethodID(Alert, OBFUSCATE("create"), OBFUSCATE("()Landroid/app/AlertDialog;")); + jobject creaetob = env->CallObjectMethod(MainAlert, create); + + jclass AlertN = env->FindClass(OBFUSCATE("android/app/AlertDialog")); + + jmethodID show = env->GetMethodID(AlertN, OBFUSCATE("show"), OBFUSCATE("()V")); + env->CallVoidMethod(creaetob, show); +} + +void Toast(JNIEnv *env, jobject thiz, const char *text, int length) { + jstring jstr = env->NewStringUTF(text); + jclass toast = env->FindClass(OBFUSCATE("android/widget/Toast")); + jmethodID methodMakeText =env->GetStaticMethodID(toast,OBFUSCATE("makeText"),OBFUSCATE("(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;")); + jobject toastobj = env->CallStaticObjectMethod(toast, methodMakeText,thiz, jstr, length); + jmethodID methodShow = env->GetMethodID(toast, OBFUSCATE("show"), OBFUSCATE("()V")); + env->CallVoidMethod(toastobj, methodShow); +} + +void Init(JNIEnv *env, jobject thiz, jobject ctx, jobject title, jobject subtitle){ + //Set sub title + setText(env, title, OBFUSCATE("Modded by (yourname)")); + + //Set sub title + setText(env, subtitle, OBFUSCATE("

" + "

Modded by LGL

| " + "https://github.com/LGLTeam | Lorem Ipsum is simply dummy text of the printing and typesetting

" + "
")); + + //Dialog Example + //setDialog(ctx,env,OBFUSCATE("Title"),OBFUSCATE("Message Example")); + + //Toast Example + Toast(env,ctx,OBFUSCATE("Modded by YOU"),ToastLength::LENGTH_LONG); + + initValid = true; +} diff --git a/app/src/main/jni/Menu/get_device_api_level_inlines.h b/app/src/main/jni/Menu/get_device_api_level_inlines.h new file mode 100644 index 0000000..817dd77 --- /dev/null +++ b/app/src/main/jni/Menu/get_device_api_level_inlines.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#pragma once + + +#include + +__BEGIN_DECLS + +// Avoid circular dependencies since this is exposed from . +int __system_property_get(const char* __name, char* __value); +int atoi(const char* __s) __attribute_pure__; + +int api_level() { + char value[92] = { 0 }; + if (__system_property_get("ro.build.version.sdk", value) < 1) return -1; + int api_level = atoi(value); + return (api_level > 0) ? api_level : -1; +} + +__END_DECLS + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..6429032 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index b0fc226..40c9174 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,9 +1,9 @@ - - + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index eca70cf..1f46878 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,5 +1,5 @@ - - - - + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index eca70cf..1f46878 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,5 +1,5 @@ - - - - + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png index 4726d53874793b76be5d2d10d7315830698d7355..7c66a39b2dc636805c466076982421f8eb18fd8e 100644 GIT binary patch delta 826 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 Dj|s^T diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png index dffca3601eba7bf5f409bdd520820e2eb5122c75..07fa66dd2fcde36db47ca08b9b428ed956e175f3 100644 GIT binary patch delta 2643 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 B7s&ts literal 4905 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 delta 2776 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 delta 2203 zcmV;M2xRw;38oQ{BYy~ONklzJ)jMg9!b;mPTC}G60isi zqhlH5ER=E$awsAUSng8uRbtREbmxGF2k)1GNVq`OtdzW_06?9hw^~j@ii;`!~r}$5pBu$<}sN+)_>w z&iN|%0(=6#5&O#LSH3Q{eJU;REEPey)mg3Cp6=^AfzeE}*}`c7=U71&`(3)cueUlL zpd1gt7rakMQh!d~`DmRfO6)tI0H6iT;V9eh(e;1vYOf*AC-?Lg8_^nb7WxW+vw77> zZ?T_bggN5qa5r-LCedgS#5rB69lCpDeQlD9P-#s+|xP>whz+>D2*?+m!)Mr*vZ^2VP-DM$w$GHQn za0lf1;^`OxAOHk_01yBIKmgAIfOapN$<$44n1;?xa+@c=caD%}@GQOCJSlk&QZyxn zOx_SHmIDZq@wH5NX=z)S1Pc^vRZ^eml&-+pBxY(FvJZF;!08p1fMwdKmz6+}p05}TL z4_2$ltnD#m`c@5@yC<3)yC1;s7gZ~OBe#{LWKEnPahWgC?Dis~Nael2 zS^*ex9c1^FMl5~hSIs49d;j3JuQ(A=D}eof1%FAl51gqN%Iq;FT|NL-eJyoh--#)b z^tu3i@MQ~0+McVyPXu7VjAXe12q1@VsmRegfyC4?Pe`A$D~6>Xs#YU_dIj(xfGj^A z!Pa|^Pvsm-TQ)m>ZA_~mnsy=r0n|5uQA@RKebx?*(ENn$8_tB1dHbRfKz#$~Sd`6{ z+kbv;!kjvCk&dNJ+0X_7_yYjc{U83+gsr#lVJ4-Yan(-u(dh`lUjSxq*Rap8Ezy!g zH&x`wKT493Z$kk70??-fg>Pc@LY_e8ViXsX?g0Q?QWoxBC$(tj6p4f}%X9RO%M-x~@or#ZX0yXTz)t-S9I zrLC<=>)SF-ULQ-!Pc?hg8#*it0n`Nmx{y7O2LzCQlTw~&JOCaF)7#shT>y@5W-_sy z8@a0OMEgxLuzUliCwm+bE2K@>k~MAl<8d0lsx2uP;kiG5$Xj|zez9I%tR?0yxqmn& zjAOzG00AHX1b_e#00KY&2mk>f00e*l8Xkbc38`dpWfW7(fm@zB&X&6As2e<6FDh3$R&d}( z5I5>pBODTxm2V>zcaBGbor!zK0chTN@;R!?%>|1Z&2Cik({*fDLCtXr2U# zoB>^)0KmRk9c&1Ig_^t}9potF2jjg3u#i?o-qgWj0H8i^rXm2)w9RcK>3_37()a}c z#G1+)!2T-kq_5VHN3CiMaU-Z6OZcqCiz)ZZju0GrN-u<=@0A2Nq~-wT>~ECzIAtk(b* zS45G_e7hh|qiJFQ!xtn;UVj3SEdb{aF0`{DZP_Q0LJX+404iCPq7+nqI;>6r?R!|* zeydN0$s0g+XD<3}-}NANq6coMxuz*?B6PF(sPYy->8BB-U3ZJ1yaKCN0LH%0eUIX426+Q0S22c{@Fk+w9V@q z0Bn1EceDh)ECH~fDB27iw=#|ln)xW$${zq~c6-PcfZG^PKLCIw#DaPYK4~ktf@8usCX4_O z00KY&2mk>f00huL{=D0#0E`IWvF`wzF9D<`TkY2ofOi12Cd;4HXF0wA;Qasls3f!P z2b{vhyD3Z(GEL{G&sr;dG`Sm0QWln&X)4oO*yH^@Jx=1|diC>@_$1}zkyw4&I`El7 zI>Fmh0SF0;jDIw1P3DVE2y7ZFdds0$wR4}pFiBj7@lxYv;qU_-N)_Y_05A^<%m~yv zT%##W%rIR7%6Qe+sD7wV;?j)2HES8upRayGdEfcOREp5hNV?R8MMQMgBpJ5Er5i73 zjpiz?(Q->?vfPBFoa8*`M5Flz_(G#KYz+$!?*cwjgnxuYDSSMqB#>-GrC|jq6qzcO z%Ar&$ds6kKDwL_<+2;%?% diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png index 14ed0af35023e4f1901cf03487b6c524257b8483..33c766d4e5fec85bf1564162b896c1b601de0a57 100644 GIT binary patch literal 3831 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 diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index 040a07c330d139fd2d318542391e397108df1293..74f9c60187a7eb9a3f507eb933aac10f85c28a18 100644 GIT binary patch literal 1809 zcma)7Yg7^j6ehwXmWFAj8A#c~G^O%YS`!czXOXFBVP(Ub`G{?XGQ}6Bq2{wJN`a`^ zP?D^ssrX36%Ex?!OGTn-;)7ILBuZ&G``6jl*?!!6&pr3t^WE>B`^fOYd+I^fLjVAP zo)-@5yJYh|33$bl9`|@v4FIed@WP_~e>ySEJ{q}}uz}IdrqyzFQd7{DE3w8mrxJR6 zuVO$W9`QAqJ0Sj6KG2(H&#uih+5DIR-nGUM{d@90lV^ZF--rY8dF$ZzBvSf{v{WZ^ z(5F@v zoq{+n_rwb7a5N`LII;K7i)D6}_r;&|6pR{)QY!T}wN4 zr(mKm9c{57-1Ug$PRGP6wmf3B(F8pa%c&Dh^OXaK_`6-o0(to@4vtq| zCPew=N&}R6d8Z1cE&^VzwC~CCLte}Wrt-dhKmB;)U9n&GSzaB@3OH(}^8TYIoENSi zGhu6IRh0dDhdeTRdnG@t8ZHkFM2zS4QE|APLc3UMz`V9RTw5Q)##_{6$JXW!-lOv2 zLz#A|w82H@#*IzKsEO~ZU^RTDWLLk!{?hRhp?jCBsd{2^w97Fa_1-I_$l6Ed$qqj% zW8-;iD-BrZkI^Civ!jwO7bK|tP(1x%82#$kM-`Oy87SpNqf!QOY@-jn*N^+yfq>_Y zN}68?7w0uVK^*yO;OMUXI>d^w{NC+A^cj+Ii3wfBY5=aafTrrw8^Iu;1r(fxLhJ=v5%D^i=N_hFcOg7>1*Y^U2{?k<~P$?5JSy^n~= zg4&qn-&sOH1}UhMARyfU4DvugP3ZsPEaeHz7f(J?cj` z4`2WYq6^eXMh&C50I21Lr7FAW%}wVJ>E{2{3zJOX+mEQ>p?NxR$gI7&$*Dl6@#)^? zrl)(q!0~e^O>WxokgG9f;R`Ij%xw=~L;fzG|%-hM$55f(nqgLOf(gDGklbPb+KNNUFm5~s72QCa<^S9;al z7T!>XNgvz{N|H()K&vEV2deo6_y>ADq9*HgS1A z7$;xnd28%pSHpRXsz=pYbmKyRl=$w6JHgjkr0_jx6;lgaXuW7u^0xQM#3Z(oG;eH^ z?{p0(AJEHax$J4q=`~wDz<>SrIG#afMkVJQKE?3>bEMv)@t8P~G-gaWU5=v)MHzS|nU@dVoKL$Q8GD<5Mn3(4NVd5v zIW3UU4nMM~5XiQ*P^7U%;5L-`H8wfmQCu6by1~o&ozPk>%#tsRJgv{J8O!lY6TRu_ zms}tI+1k!JW~%Z5l5p=alYSoaxVBPUfePH@^@I9 z-3`f!(2+WQi`oQrmWee(5oB*zCmJYANlA$<)VVHR+0kpq+{fb7MC!G)W^KvEtrK2` zC_J21!os2GZ7>hvyv86z#>iA6M$|j}{M$;7^6&kSqm9kkX4sNN8K!KK;XLty_)syM zV)9-&!sB5r>_Z%)?s3X=*>@S7n-K5s(5wl4|7Z49hCDL`PMCQd?%IG=F{+CSTv!`^ zBNLSSXB}7Hhu;zfQxzy-9^S*M%0gjfpwi@{j)8ML6fjKfW_4;cdPsCpO6Y3E%UsZZp}MJo?Ci#055ku_AcgR F%3mFQJAD8E literal 3344 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 XdJ+W}DiIkV00000NkvXXu0mjfKBlg6 diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index 45d47eee6e2a954041e586093bc67f83149dff68..98715ec09d7a3f43694e84abed1335893fba03cf 100644 GIT binary patch literal 2581 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 literal 4619 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 diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png index beed3cdd2c32af5114a7dc70b9ef5b698eb8797e..74f9fdef89ef03b6c8121b49a1ac14bb9d827ac5 100644 GIT binary patch literal 9075 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 literal 15132 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 diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index b35a435..3f5b3dc 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,4 +1,4 @@ - - - #202020 - + + + #202020 + diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml new file mode 100644 index 0000000..8c40f6a --- /dev/null +++ b/app/src/main/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #0277BD + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7a355e2..2f2f6ac 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,3 @@ - - LGL Mod Menu - + + LGL Mod Menu + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index d13d67a..303f720 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,7 +1,7 @@ - - - - + + + + diff --git a/build.gradle b/build.gradle index 3756278..e26c896 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. -plugins { - alias(libs.plugins.android.application) apply false +// Top-level build file where you can add configuration options common to all sub-projects/modules. +plugins { + alias(libs.plugins.android.application) apply false } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 4387edc..f9c348f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,21 +1,21 @@ -# Project-wide Gradle settings. -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. For more details, visit -# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects -# org.gradle.parallel=true -# AndroidX package structure to make it clearer which packages are bundled with the -# Android operating system, and which are packaged with your app's APK -# https://developer.android.com/topic/libraries/support-library/androidx-rn -android.useAndroidX=true -# Enables namespacing of each library's R class so that its R class includes only the -# resources declared in the library itself and none from the library's dependencies, -# thereby reducing the size of the R class for that library +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. For more details, visit +# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Enables namespacing of each library's R class so that its R class includes only the +# resources declared in the library itself and none from the library's dependencies, +# thereby reducing the size of the R class for that library android.nonTransitiveRClass=true \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ceb0910..12255ab 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,22 +1,22 @@ -[versions] -agp = "8.13.2" -junit = "4.13.2" -junitVersion = "1.3.0" -espressoCore = "3.7.0" -appcompat = "1.7.1" -material = "1.13.0" -activity = "1.12.2" -constraintlayout = "2.2.1" - -[libraries] -junit = { group = "junit", name = "junit", version.ref = "junit" } -ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } -espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } -appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } -material = { group = "com.google.android.material", name = "material", version.ref = "material" } -activity = { group = "androidx.activity", name = "activity", version.ref = "activity" } -constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" } - -[plugins] -android-application = { id = "com.android.application", version.ref = "agp" } - +[versions] +agp = "8.13.2" +junit = "4.13.2" +junitVersion = "1.3.0" +espressoCore = "3.7.0" +appcompat = "1.7.1" +material = "1.13.0" +activity = "1.12.2" +constraintlayout = "2.2.1" + +[libraries] +junit = { group = "junit", name = "junit", version.ref = "junit" } +ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } +espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } +appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } +material = { group = "com.google.android.material", name = "material", version.ref = "material" } +activity = { group = "androidx.activity", name = "activity", version.ref = "activity" } +constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" } + +[plugins] +android-application = { id = "com.android.application", version.ref = "agp" } + diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8fd263c..3e66f1e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,8 +1,8 @@ -#Sat Jan 31 21:42:02 BDT 2026 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists +#Sat Jan 31 21:42:02 BDT 2026 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index ef07e01..c026f59 100644 --- a/gradlew +++ b/gradlew @@ -1,251 +1,251 @@ -#!/bin/sh - -# -# Copyright © 2015 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# SPDX-License-Identifier: Apache-2.0 -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH="\\\"\\\"" - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH="\\\"\\\"" + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index db3a6ac..5eed7ee 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,94 +1,94 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem -@rem SPDX-License-Identifier: Apache-2.0 -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH= - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH= + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle index af639b2..abb37eb 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,23 +1,23 @@ -pluginManagement { - repositories { - google { - content { - includeGroupByRegex("com\\.android.*") - includeGroupByRegex("com\\.google.*") - includeGroupByRegex("androidx.*") - } - } - mavenCentral() - gradlePluginPortal() - } -} -dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) - repositories { - google() - mavenCentral() - } -} - -rootProject.name = "Native-LGL" -include ':app' +pluginManagement { + repositories { + google { + content { + includeGroupByRegex("com\\.android.*") + includeGroupByRegex("com\\.google.*") + includeGroupByRegex("androidx.*") + } + } + mavenCentral() + gradlePluginPortal() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} + +rootProject.name = "Native-LGL" +include ':app'