├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── android.yml ├── .gitignore ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── google-services.json ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ ├── club │ │ └── fdpclient │ │ │ └── club │ │ │ └── script │ │ │ ├── AbstractScriptManager.kt │ │ │ ├── Script.kt │ │ │ ├── ScriptApi.kt │ │ │ ├── ScriptManager.kt │ │ │ └── ScriptManagerFileSystem.kt │ └── dev │ │ └── sora │ │ └── protohax │ │ ├── MyApplication.kt │ │ ├── relay │ │ ├── AccountManager.kt │ │ ├── MinecraftRelay.kt │ │ ├── modules │ │ │ └── ModuleESP.kt │ │ ├── netty │ │ │ ├── channel │ │ │ │ ├── NativeRakChannel.kt │ │ │ │ ├── NativeRakConfig.kt │ │ │ │ └── NativeRakServerChannel.kt │ │ │ └── log │ │ │ │ ├── NettyLogger.java │ │ │ │ └── NettyLoggerFactory.java │ │ └── service │ │ │ ├── AppService.kt │ │ │ └── ServiceListener.kt │ │ ├── ui │ │ ├── activities │ │ │ ├── AppPickerActivity.kt │ │ │ ├── LogActivity.kt │ │ │ ├── MainActivity.kt │ │ │ └── MicrosoftLoginActivity.kt │ │ ├── components │ │ │ ├── AppBar.kt │ │ │ ├── AppIcon.kt │ │ │ ├── Clickable.kt │ │ │ ├── Connection.kt │ │ │ ├── DashboardCards.kt │ │ │ ├── HyperlinkText.kt │ │ │ ├── Item.kt │ │ │ ├── PHaxApp.kt │ │ │ └── screen │ │ │ │ ├── AccountsScreen.kt │ │ │ │ ├── ConfigScreen.kt │ │ │ │ ├── DashboardScreen.kt │ │ │ │ └── settings │ │ │ │ ├── BoolSetting.kt │ │ │ │ ├── ISetting.kt │ │ │ │ ├── Settings.kt │ │ │ │ ├── SettingsScreen.kt │ │ │ │ └── TabSetting.kt │ │ ├── navigation │ │ │ ├── NavigationAction.kt │ │ │ └── NavigationComponents.kt │ │ ├── overlay │ │ │ ├── ConfigSectionShortcut.kt │ │ │ ├── MyLifecycleOwner.kt │ │ │ ├── OverlayManager.kt │ │ │ ├── RenderLayerView.kt │ │ │ ├── Shortcut.kt │ │ │ ├── hud │ │ │ │ ├── HudAlignment.kt │ │ │ │ ├── HudElement.kt │ │ │ │ ├── HudElementModule.kt │ │ │ │ ├── HudManager.kt │ │ │ │ └── elements │ │ │ │ │ ├── ModuleIndicatorElement.kt │ │ │ │ │ ├── TargetIndicatorElement.kt │ │ │ │ │ └── TextElement.kt │ │ │ └── menu │ │ │ │ ├── ConfigureMenu.kt │ │ │ │ └── tabs │ │ │ │ ├── CheatCategory.kt │ │ │ │ ├── Config.kt │ │ │ │ └── Hud.kt │ │ └── theme │ │ │ └── Theme.kt │ │ └── util │ │ ├── CircularBuffer.java │ │ ├── Color.java │ │ ├── ContextUtils.kt │ │ ├── ModifierUtils.kt │ │ ├── StringUtils.kt │ │ └── WindowStateUtils.kt │ └── res │ ├── drawable │ ├── ic_launcher_foreground.xml │ ├── mdi_arrow_back.xml │ ├── mdi_list_alt.xml │ ├── mdi_sprint.xml │ ├── mdi_swords.xml │ ├── mdi_view_in_ar.xml │ └── notification_icon.xml │ ├── layout │ └── activity_microsoft_login.xml │ ├── mipmap-anydpi-v26 │ └── ic_launcher.xml │ ├── values-de │ └── strings.xml │ ├── values-v31 │ └── colors.xml │ ├── values-zh-rCN │ └── strings.xml │ ├── values-zh-rHK │ └── strings.xml │ ├── values-zh-rTW │ └── strings.xml │ ├── values │ ├── colors.xml │ ├── strings.xml │ └── themes.xml │ └── xml │ ├── backup_rules.xml │ ├── data_extraction_rules.xml │ └── provider_paths.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── signing.jks /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | charset = utf-8 6 | insert_final_newline = true 7 | 8 | [*.{kt,kts}] 9 | indent_style = tab 10 | tab_width = 4 11 | trim_trailing_whitespace = true 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG] " 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Please complete the following information:** 27 | - OS: [e.g. Android 13] 28 | - Version [e.g. 1.3.2] 29 | 30 | **Additional context** 31 | Add any other context about the problem here. 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[FEAT]" 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/android.yml: -------------------------------------------------------------------------------- 1 | name: Android CI 2 | 3 | on: 4 | push 5 | 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | env: 10 | USERNAME_GITHUB: ${{ secrets.GITHUB_USERNAME }} 11 | TOKEN_GITHUB: ${{ secrets.GITHUB_TOKEN }} 12 | steps: 13 | - uses: actions/checkout@v3 14 | - name: set up JDK 11 15 | uses: actions/setup-java@v3 16 | with: 17 | java-version: '17' 18 | distribution: 'temurin' 19 | cache: gradle 20 | 21 | - name: Grant execute permission for gradlew 22 | run: chmod +x gradlew 23 | - name: Build with Gradle 24 | run: ./gradlew app:assembleRelease 25 | - name: Upload build artifacts 26 | uses: actions/upload-artifact@v2 27 | with: 28 | name: ProtoHax-build-${{ github.sha }} 29 | path: ./app/build/outputs/apk/release/app-release.apk 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | build/ 3 | local.properties 4 | .gradle -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ProtoHax-Android 2 | 3 | 4 | 5 | ProtoHax-Android is the Android implementation of [ProtoHax](https://github.com/SkidderMC/ProtoHax), an open-source cheat for Minecraft: Bedrock Edition that works through the network layer. This repository contains the Android-specific code for the cheat. 6 | ## Features 7 | 1. No modifications to Minecraft client 8 | 2. Seamless switching/adapting multiple versions 9 | 3. Full control of the packet layer 10 | 11 | ## Issues 12 | - If you notice any bugs or missing features in the Android-specific code, you can let us know by opening an issue [here](https://github.com/SkidderMC/ProtoHax-Android/issues). 13 | - If you're having issues with the cheat features themselves, please send the issue to the main repository [here](https://github.com/SkidderMC/ProtoHax/issues). 14 | 15 | Please notice that this is an **English-only** repository, so all issues and pull requests must be in English, if you can't speak English, please use a [translator](https://translate.google.com/). 16 | 17 | ## License 18 | This project is subject to the [GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.en.html). This does only apply for source code located directly in this clean repository. During the development and compilation process, additional source code may be used to which we have obtained no rights. Such code is not covered by the GPL license. 19 | 20 | For those who are unfamiliar with the license, here is a summary of its main points. This is by no means legal advice nor legally binding. 21 | 22 | *Actions that you are allowed to do:* 23 | 24 | - Use 25 | - Share 26 | - Modify 27 | 28 | *If you do decide to use ANY code from the source:* 29 | 30 | - **You must disclose the source code of your modified work and the source code you took from this project. This means you are not allowed to use code from this project (even partially) in a closed-source (or even obfuscated) application.** 31 | - **Your modified application must also be licensed under the GPL** 32 | 33 | ## Installation 34 | We have used the [local maven repository](https://docs.gradle.org/current/userguide/declaring_repositories.html#sec:case-for-maven-local), you need to build and publish [ProtoHax](https://github.com/SkidderMC/ProtoHax) to the repository before you can build, sorry for inconvenience. 35 | 36 | ### With Android Studio 37 | 1. Clone the repository: `git clone https://github.com/SkidderMC/ProtoHax-Android.git` 38 | 2. Import the project into Android Studio 39 | 3. Connect your Android device to your computer 40 | 4. Build and run the project on your device 41 | 42 | ### With Gradle 43 | 1. Clone the repository: `git clone https://github.com/SkidderMC/ProtoHax-Android.git` 44 | 2. CD into the local repository. 45 | 3. Connect your Android device to your computer 46 | 3. Run `gradlew app:assembleDebug` 47 | 48 | ## Contributing 49 | We welcome contributions to ProtoHax! If you would like to contribute, please fork the repository and make changes as you'd like. Pull requests are welcome. 50 | 51 | ## Disclaimer 52 | Please use ProtoHax at your own risk. We **DO NOT** take responsibility for any bans or punishments that may occur as a result of using this cheat. 53 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /release 3 | /debug 4 | /libs -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'org.jetbrains.kotlin.android' 4 | id 'com.google.gms.google-services' 5 | id 'com.google.firebase.crashlytics' 6 | } 7 | android { 8 | signingConfigs { 9 | debug { 10 | storeFile rootProject.file('signing.jks') 11 | keyAlias 'sora' 12 | keyPassword '1145141919' 13 | storePassword '1145141919' 14 | 15 | enableV1Signing true 16 | enableV2Signing true 17 | enableV3Signing true 18 | enableV4Signing false 19 | } 20 | } 21 | namespace 'dev.sora.protohax' 22 | compileSdk 34 23 | 24 | defaultConfig { 25 | applicationId 'dev.sora.protohax' 26 | minSdk 28 27 | targetSdk 34 28 | versionCode 1 29 | versionName '1.4.0' 30 | 31 | vectorDrawables { 32 | useSupportLibrary true 33 | } 34 | 35 | ndk { 36 | abiFilters 'arm64-v8a', 'x86_64' 37 | } 38 | } 39 | buildFeatures { 40 | compose true 41 | } 42 | composeOptions { 43 | kotlinCompilerExtensionVersion compose_compiler_version 44 | } 45 | buildTypes { 46 | release { 47 | shrinkResources true 48 | minifyEnabled true 49 | zipAlignEnabled true 50 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 51 | signingConfig signingConfigs.getByName('debug') 52 | } 53 | } 54 | compileOptions { 55 | sourceCompatibility '11' 56 | targetCompatibility '11' 57 | } 58 | kotlinOptions { 59 | jvmTarget = '11' 60 | } 61 | packagingOptions { 62 | resources { 63 | excludes += '/META-INF/**' 64 | excludes += '/kotlin/**' 65 | excludes += '/DebugProbesKt.bin' 66 | excludes += '/kotlin-tooling-metadata.json' 67 | } 68 | jniLibs.useLegacyPackaging true 69 | } 70 | configurations { 71 | all { 72 | resolutionStrategy { 73 | // exclude duplicate classes 74 | exclude group: 'com.google.guava', module: 'listenablefuture' 75 | exclude group: 'com.google.errorprone', module: 'error_prone_annotations' 76 | } 77 | } 78 | } 79 | } 80 | 81 | dependencies { 82 | implementation('dev.sora.relay:protohax:1.4.0') { 83 | transitive = false 84 | } 85 | implementation 'dev.sora.networking:libmitm:1.2.3-raknet' 86 | 87 | implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.2' 88 | 89 | implementation 'androidx.core:core-ktx:1.10.1' 90 | implementation 'androidx.activity:activity-compose:1.7.2' 91 | implementation "androidx.compose.ui:ui:$compose_version" 92 | implementation "androidx.compose.material3:material3:$compose_material_version" 93 | implementation "androidx.compose.material3:material3-window-size-class:$compose_material_version" 94 | implementation "androidx.compose.material:material-icons-extended:$compose_version" 95 | implementation 'androidx.navigation:navigation-compose:2.6.0' 96 | 97 | implementation "com.google.accompanist:accompanist-navigation-animation:$accompanist_version" 98 | implementation "com.google.accompanist:accompanist-adaptive:$accompanist_version" 99 | implementation "com.google.accompanist:accompanist-systemuicontroller:$accompanist_version" 100 | implementation "com.google.accompanist:accompanist-drawablepainter:$accompanist_version" 101 | 102 | implementation 'org.luaj:luaj-jse:3.0.1' 103 | implementation 'com.google.firebase:firebase-crashlytics:18.3.7' 104 | implementation 'com.google.firebase:firebase-analytics:21.3.0' 105 | } 106 | -------------------------------------------------------------------------------- /app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "954846711145", 4 | "project_id": "protohax-6fe27", 5 | "storage_bucket": "protohax-6fe27.appspot.com" 6 | }, 7 | "client": [ 8 | { 9 | "client_info": { 10 | "mobilesdk_app_id": "1:954846711145:android:68b72ebed6da969cb1c1f8", 11 | "android_client_info": { 12 | "package_name": "dev.sora.protohax" 13 | } 14 | }, 15 | "oauth_client": [ 16 | { 17 | "client_id": "954846711145-eobt6d7cg13adacslvljf197pe47lt5g.apps.googleusercontent.com", 18 | "client_type": 3 19 | } 20 | ], 21 | "api_key": [ 22 | { 23 | "current_key": "AIzaSyCKrTSuvvhHz9vS1Vc_EGnFHIi5iOpboHA" 24 | } 25 | ], 26 | "services": { 27 | "appinvite_service": { 28 | "other_platform_oauth_client": [ 29 | { 30 | "client_id": "954846711145-eobt6d7cg13adacslvljf197pe47lt5g.apps.googleusercontent.com", 31 | "client_type": 3 32 | } 33 | ] 34 | } 35 | } 36 | } 37 | ], 38 | "configuration_version": "1" 39 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | -renamesourcefileattribute null 22 | 23 | # keep netty related classes 24 | -keep class io.netty.** { *; } 25 | -keep class kotlinx.** { *; } 26 | -keep class org.luaj.** { *; } 27 | -keep class org.cloudburstmc.netty.** { *; } 28 | -keep @io.netty.channel.ChannelHandler$Sharable class * 29 | 30 | -keepclassmembers class * { 31 | @com.google.gson.annotations.SerializedName ; 32 | } 33 | -keep class coelho.msftauth.api.** { *; } 34 | #-keep class dev.sora.** { *; } 35 | #-keep class org.cloudburstmc.** { *; } 36 | 37 | # disable R8 warning for missing classes 38 | -dontwarn ** 39 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | 12 | 13 | 24 | 25 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 39 | 40 | 44 | 45 | 49 | 50 | 51 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 69 | 72 | 73 | 74 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /app/src/main/java/club/fdpclient/club/script/AbstractScriptManager.kt: -------------------------------------------------------------------------------- 1 | package club.fdpclient.club.script 2 | 3 | import android.os.Handler 4 | import android.os.Looper 5 | import android.widget.Toast 6 | import com.google.gson.Gson 7 | import com.google.gson.GsonBuilder 8 | import com.google.gson.JsonObject 9 | import dev.sora.protohax.MyApplication 10 | import dev.sora.protohax.relay.MinecraftRelay 11 | import dev.sora.protohax.util.ContextUtils.toast 12 | import dev.sora.relay.utils.logError 13 | import java.io.File 14 | import java.io.InputStream 15 | 16 | abstract class AbstractScriptManager(val scriptManager: ScriptManager) { 17 | 18 | abstract fun listScript(): List 19 | 20 | protected abstract fun loadScriptData(name: String): InputStream? 21 | protected abstract fun getScriptFile(name: String): File 22 | 23 | protected abstract fun saveScriptData(name: String, data: ByteArray) 24 | 25 | abstract fun deleteScript(name: String): Boolean 26 | 27 | open fun copyScript(src: String, dst: String): Boolean { 28 | val reader = loadScriptData(src) ?: return false 29 | saveScriptData(dst, reader.readBytes()) 30 | return true 31 | } 32 | 33 | open fun renameScript(src: String, dst: String): Boolean { 34 | if (!copyScript(src, dst)) return false 35 | return deleteScript(dst) 36 | } 37 | 38 | /** 39 | * @return false if failed to load the Script or Script not exists 40 | */ 41 | open fun loadScript(name: String): Boolean { 42 | return try { 43 | scriptManager.registerModule(Script(getScriptFile(name),name)) 44 | 45 | true 46 | } catch (t: Throwable) { 47 | 48 | Handler(Looper.getMainLooper()).post(Runnable { 49 | Toast.makeText( 50 | MyApplication.instance, 51 | "[Script]failed to load $name", 52 | Toast.LENGTH_LONG 53 | ).show() 54 | }) 55 | logError("failed to load Script", t) 56 | false 57 | } 58 | } 59 | 60 | open fun saveScript(name: String) { 61 | try { 62 | val json = JsonObject() 63 | saveScriptData(name, DEFAULT_GSON.toJson(json).toByteArray(Charsets.UTF_8)) 64 | } catch (t: Throwable) { 65 | logError("failed to save Script", t) 66 | } 67 | } 68 | 69 | companion object { 70 | val DEFAULT_GSON: Gson = GsonBuilder().setPrettyPrinting().create() 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/club/fdpclient/club/script/Script.kt: -------------------------------------------------------------------------------- 1 | package club.fdpclient.club.script 2 | 3 | import android.annotation.SuppressLint 4 | import dev.sora.protohax.relay.MinecraftRelay 5 | import dev.sora.relay.cheat.module.CheatCategory 6 | import dev.sora.relay.cheat.module.CheatModule 7 | import dev.sora.relay.game.event.EventDisconnect 8 | import dev.sora.relay.game.event.EventEntitySpawn 9 | import dev.sora.relay.game.event.EventPacketInbound 10 | import dev.sora.relay.game.event.EventPacketOutbound 11 | import dev.sora.relay.game.event.EventPacketPostOutbound 12 | import dev.sora.relay.game.event.EventPostTick 13 | import dev.sora.relay.game.event.EventTick 14 | import org.luaj.vm2.Globals 15 | import org.luaj.vm2.LuaValue 16 | import org.luaj.vm2.lib.jse.CoerceJavaToLua 17 | import org.luaj.vm2.lib.jse.JsePlatform 18 | import java.io.File 19 | 20 | 21 | @SuppressLint("SuspiciousIndentation") 22 | class Script( 23 | private val file: File, name: String, 24 | defaultOn: Boolean = false, 25 | canToggle: Boolean = true 26 | ) : CheatModule(name,CheatCategory.MISC,defaultOn,canToggle) { 27 | private val moduleScript: Globals = JsePlatform.standardGlobals() 28 | private var onDisable: LuaValue 29 | private var onEnable: LuaValue 30 | private var onTick: LuaValue 31 | private var onPostTick: LuaValue 32 | private var onDisconnect: LuaValue 33 | private var onEntitySpawn: LuaValue 34 | private var onPacketInbound: LuaValue 35 | private var onPacketOutbound: LuaValue 36 | private var onPostPacketOutbound: LuaValue 37 | 38 | init { 39 | moduleScript.loadfile(file.absolutePath).call() 40 | onDisable = moduleScript.get(LuaValue.valueOf("onDisable")) 41 | onEnable = moduleScript[LuaValue.valueOf("onEnable")] 42 | onTick = moduleScript.get(LuaValue.valueOf("onTick")) 43 | onPostTick = moduleScript.get(LuaValue.valueOf("onPostTick")) 44 | onDisconnect = moduleScript.get(LuaValue.valueOf("onDisconnect")) 45 | onEntitySpawn = moduleScript.get(LuaValue.valueOf("onEntitySpawn")) 46 | onPacketInbound = moduleScript.get(LuaValue.valueOf("onPacketInbound")) 47 | onPacketOutbound = moduleScript.get(LuaValue.valueOf("onPacketOutbound")) 48 | onPostPacketOutbound = moduleScript.get(LuaValue.valueOf("onPostPacketOutbound")) 49 | try { 50 | moduleScript.get(LuaValue.valueOf("onLoad")).call(CoerceJavaToLua.coerce(ScriptApi(this))) 51 | } catch (e: Exception) { 52 | e.printStackTrace() 53 | } 54 | } 55 | 56 | private fun run(method: LuaValue) { 57 | try { 58 | method.call() 59 | } catch (e: Exception) { 60 | e.printStackTrace() 61 | } 62 | } 63 | 64 | private fun run(method: LuaValue, value: LuaValue) { 65 | try { 66 | method.call(value) 67 | } catch (e: Exception) { 68 | e.printStackTrace() 69 | } 70 | } 71 | 72 | override fun onDisable() { 73 | super.onDisable() 74 | run(onDisable) 75 | } 76 | 77 | override fun onEnable() { 78 | super.onEnable() 79 | run(onEnable,CoerceJavaToLua.coerce(MinecraftRelay.session)) 80 | } 81 | 82 | private val EventOnTick = handle { 83 | run(onTick, CoerceJavaToLua.coerce(this)) 84 | } 85 | private val EventOnPostTick = handle { 86 | run(onPostTick, CoerceJavaToLua.coerce(this)) 87 | } 88 | private val EventEntitySpawn = handle { 89 | run(onEntitySpawn, CoerceJavaToLua.coerce(this)) 90 | } 91 | 92 | private val EventDisconnect = handle { 93 | run(onDisconnect, CoerceJavaToLua.coerce(this)) 94 | } 95 | 96 | private val EventPacketOutbound = handle { 97 | run(onPacketOutbound, CoerceJavaToLua.coerce(this)) 98 | } 99 | 100 | private val EventonTick = handle { 101 | run(onTick, CoerceJavaToLua.coerce(this)) 102 | } 103 | 104 | private val EventPacketInbound = handle { 105 | run(onPacketInbound, CoerceJavaToLua.coerce(this)) 106 | } 107 | 108 | private val EventPostPacketOutbound = handle { 109 | run(onPostPacketOutbound, CoerceJavaToLua.coerce(this)) 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /app/src/main/java/club/fdpclient/club/script/ScriptApi.kt: -------------------------------------------------------------------------------- 1 | package club.fdpclient.club.script 2 | 3 | import android.os.Handler 4 | import android.os.Looper 5 | import android.widget.Toast 6 | import dev.sora.protohax.MyApplication 7 | import dev.sora.protohax.util.ContextUtils.toast 8 | import dev.sora.relay.cheat.value.BoolValue 9 | import dev.sora.relay.cheat.value.FloatValue 10 | import dev.sora.relay.cheat.value.IntValue 11 | import dev.sora.relay.utils.logInfo 12 | 13 | 14 | class ScriptApi(val script: Script) { 15 | val thePlayer 16 | get() = run { script.session.player } 17 | 18 | fun escapeHtml(input: String): String { 19 | val escaped = StringBuilder() 20 | for (c in input.toCharArray()) { 21 | when (c) { 22 | '<' -> escaped.append("<") 23 | '>' -> escaped.append(">") 24 | '&' -> escaped.append("&") 25 | '"' -> escaped.append(""") 26 | '\'' -> escaped.append("'") 27 | else -> escaped.append(c) 28 | } 29 | } 30 | return escaped.toString() 31 | } 32 | 33 | fun toast(str: String) { 34 | val handler = Handler(Looper.getMainLooper()) 35 | handler.post { 36 | logInfo("Message: $str") 37 | Toast.makeText( 38 | MyApplication.instance, 39 | str, 40 | Toast.LENGTH_SHORT 41 | ).show() 42 | } 43 | 44 | } 45 | 46 | fun tosat(str: String) { 47 | MyApplication.instance.toast(str) 48 | } 49 | 50 | fun registerFloatValue( 51 | name: String, 52 | value: Float, 53 | minValue: Float, 54 | maxValue: Float, 55 | chinese: String = name 56 | ): FloatValue { 57 | val value = FloatValue(name, value, minValue..maxValue) 58 | script.values.add(value) 59 | return value 60 | } 61 | 62 | fun registerIntValue( 63 | name: String, 64 | value: Int, 65 | minValue: Int, 66 | maxValue: Int, 67 | chinese: String = name 68 | ): IntValue { 69 | val value = IntValue(name, value, minValue..maxValue) 70 | script.values.add(value) 71 | return value 72 | } 73 | 74 | fun registerBoolValue(name: String, value: Boolean, chinese: String = name): BoolValue { 75 | val value = BoolValue(name, value) 76 | script.values.add(value) 77 | return value 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/club/fdpclient/club/script/ScriptManager.kt: -------------------------------------------------------------------------------- 1 | package club.fdpclient.club.script 2 | 3 | import club.fdpclient.club.script.Script 4 | import dev.sora.protohax.relay.MinecraftRelay 5 | import dev.sora.relay.game.GameSession 6 | 7 | class ScriptManager { 8 | private val scripts = mutableListOf