diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..afd8b51b --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,33 @@ +name: build +on: [pull_request, push] + +jobs: + build: + strategy: + matrix: + # Use these Java versions + java: [21] + # and run on both Linux and Windows + os: [ubuntu-20.04, windows-latest] + runs-on: ${{ matrix.os }} + steps: + - name: checkout repository + uses: actions/checkout@v4 + - name: validate gradle wrapper + uses: gradle/actions/wrapper-validation@v3 + - name: setup jdk ${{ matrix.java }} + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: ${{ matrix.java }} + - name: make gradle wrapper executable + if: ${{ runner.os != 'Windows' }} + run: chmod +x ./gradlew + - name: build + run: ./gradlew build + - name: capture build artifacts + if: ${{ runner.os == 'Linux' && matrix.java == '21' }} # Only upload artifacts built from latest java on one OS + uses: actions/upload-artifact@v4 + with: + name: Artifacts + path: build/libs/ diff --git a/.github/workflows/checkstyle.yml b/.github/workflows/checkstyle.yml deleted file mode 100644 index 36c4947d..00000000 --- a/.github/workflows/checkstyle.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Checkstyle -on: - pull_request: - branches: [ '*' ] -jobs: - checkstyle: - name: Checkstyler - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: nikitasavinov/checkstyle-action@master - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - reporter: 'github-pr-check' - level: error - fail_on_error: true - checkstyle_config: checkstyle.xml \ No newline at end of file diff --git a/.github/workflows/dev-build.yml b/.github/workflows/dev-build.yml deleted file mode 100644 index 2f899e29..00000000 --- a/.github/workflows/dev-build.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Dev Build -on: - push: - branches: [ '*' ] - paths-ignore: - - '**.md' - - '**.yml' -jobs: - build: - name: Build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: gradle/wrapper-validation-action@v1 - - uses: actions/setup-java@v3 - with: - distribution: temurin - java-version: 17 - - run: ./gradlew build --stacktrace --no-daemon - - uses: actions/upload-artifact@v3 - with: - name: Artifacts from ${{ github.sha }} - path: build/libs/ diff --git a/.github/workflows/doc-compiler.yml b/.github/workflows/doc-compiler.yml deleted file mode 100644 index 7a80c206..00000000 --- a/.github/workflows/doc-compiler.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Doc Compiler -on: - push: - branches: [ '*' ] - paths-ignore: - - '**.yml' -jobs: - compile-docs: - if: github.repository == 'senseiwells/EssentialClient' - name: Generate Documentation - runs-on: ubuntu-latest - steps: - - name: Checkout EssentialClient - uses: actions/checkout@v3 - - name: Setup Java - uses: actions/setup-java@v3 - with: - distribution: temurin - java-version: 17 - - name: Generate Documentations - run: ./gradlew runClient --args="--generate ../../../generated" --stacktrace --no-daemon - - name: Commit Changes - continue-on-error: true - run: | - git config --global user.name 'github-actions-bot' - git config --global user.email 'github-actions[bot]@users.noreply.github.com' - git add . - git commit -m "Update generated documentation" || exit 0 - git push - - name: Notify Zeno - uses: appleboy/discord-action@master - with: - webhook_id: ${{ secrets.ZENO_WEBHOOK_ID }} - webhook_token: ${{ secrets.ZENO_WEBHOOK_TOKEN }} - message: Update the documentation! -# - name: Update Arucas Snippets -# uses: dmnemec/copy_file_to_another_repo_action@main -# env: -# API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }} -# with: -# source_file: generated/snippets/arucas.json -# destination_repo: senseiwells/Arucas-VSCode-Extension -# destination_folder: snippets -# user_email: senseiwells@users.noreply.github.com -# user_name: senseiwells -# commit_message: Snippets update from upstream - - name: Update Wiki - uses: Andrew-Chen-Wang/github-wiki-action@v3 - env: - WIKI_DIR: docs/wiki/ - GH_TOKEN: ${{ secrets.API_TOKEN_GITHUB }} - GH_MAIL: senseiwells@users.noreply.github.com - GH_NAME: senseiwells diff --git a/.github/workflows/pr-build.yml b/.github/workflows/pr-build.yml deleted file mode 100644 index c620faf5..00000000 --- a/.github/workflows/pr-build.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: PR Build -on: - pull_request: - branches: [ '*' ] -jobs: - build: - name: Build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 - with: - distribution: temurin - java-version: 17 - - run: ./gradlew build --stacktrace --no-daemon diff --git a/README.md b/README.md index 0c4a94bc..381e2b81 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,33 @@ # EssentialClient [![Discord](https://badgen.net/discord/online-members/7R9SfktZxH?icon=discord&label=Discord&list=what)](https://discord.gg/7R9SfktZxH) -[![GitHub downloads](https://img.shields.io/github/downloads/senseiwells/essentialclient/total?label=Github%20downloads&logo=github)](https://github.com/senseiwells/essentialclient/releases) [![Modrinth downloads](https://img.shields.io/modrinth/dt/essentialclient?label=Modrinth%20downloads&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEuNSIgY2xpcC1ydWxlPSJldmVub2RkIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgxMDB2MTAwSDB6Ii8+PGNsaXBQYXRoIGlkPSJhIj48cGF0aCBkPSJNMTAwIDBIMHYxMDBoMTAwVjBaTTQ2LjAwMiA0OS4yOTVsLjA3NiAxLjc1NyA4LjgzIDMyLjk2MyA3Ljg0My0yLjEwMi04LjU5Ni0zMi4wOTQgNS44MDQtMzIuOTMyLTcuOTk3LTEuNDEtNS45NiAzMy44MThaIi8+PC9jbGlwUGF0aD48ZyBjbGlwLXBhdGg9InVybCgjYSkiPjxwYXRoIGZpbGw9IiMwMGQ4NDUiIGQ9Ik01MCAxN2MxOC4yMDcgMCAzMi45ODggMTQuNzg3IDMyLjk4OCAzM1M2OC4yMDcgODMgNTAgODMgMTcuMDEyIDY4LjIxMyAxNy4wMTIgNTAgMzEuNzkzIDE3IDUwIDE3Wm0wIDljMTMuMjQgMCAyMy45ODggMTAuNzU1IDIzLjk4OCAyNFM2My4yNCA3NCA1MCA3NCAyNi4wMTIgNjMuMjQ1IDI2LjAxMiA1MCAzNi43NiAyNiA1MCAyNloiLz48L2c+PGNsaXBQYXRoIGlkPSJiIj48cGF0aCBkPSJNMCAwdjQ2aDUwbDEuMzY4LjI0MUw5OSA2My41NzhsLTIuNzM2IDcuNTE3TDQ5LjI5NSA1NEgwdjQ2aDEwMFYwSDBaIi8+PC9jbGlwUGF0aD48ZyBjbGlwLXBhdGg9InVybCgjYikiPjxwYXRoIGZpbGw9IiMwMGQ4NDUiIGQ9Ik01MCAwYzI3LjU5NiAwIDUwIDIyLjQwNCA1MCA1MHMtMjIuNDA0IDUwLTUwIDUwUzAgNzcuNTk2IDAgNTAgMjIuNDA0IDAgNTAgMFptMCA5YzIyLjYyOSAwIDQxIDE4LjM3MSA0MSA0MVM3Mi42MjkgOTEgNTAgOTEgOSA3Mi42MjkgOSA1MCAyNy4zNzEgOSA1MCA5WiIvPjwvZz48Y2xpcFBhdGggaWQ9ImMiPjxwYXRoIGQ9Ik01MCAwYzI3LjU5NiAwIDUwIDIyLjQwNCA1MCA1MHMtMjIuNDA0IDUwLTUwIDUwUzAgNzcuNTk2IDAgNTAgMjIuNDA0IDAgNTAgMFptMCAzOS41NDljNS43NjggMCAxMC40NTEgNC42ODMgMTAuNDUxIDEwLjQ1MSAwIDUuNzY4LTQuNjgzIDEwLjQ1MS0xMC40NTEgMTAuNDUxLTUuNzY4IDAtMTAuNDUxLTQuNjgzLTEwLjQ1MS0xMC40NTEgMC01Ljc2OCA0LjY4My0xMC40NTEgMTAuNDUxLTEwLjQ1MVoiLz48L2NsaXBQYXRoPjxnIGNsaXAtcGF0aD0idXJsKCNjKSI+PHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDBkODQ1IiBzdHJva2Utd2lkdGg9IjkiIGQ9Ik01MCA1MCA1LjE3MSA3NS44ODIiLz48L2c+PGNsaXBQYXRoIGlkPSJkIj48cGF0aCBkPSJNNTAgMGMyNy41OTYgMCA1MCAyMi40MDQgNTAgNTBzLTIyLjQwNCA1MC01MCA1MFMwIDc3LjU5NiAwIDUwIDIyLjQwNCAwIDUwIDBabTAgMjUuMzZjMTMuNTk5IDAgMjQuNjQgMTEuMDQxIDI0LjY0IDI0LjY0UzYzLjU5OSA3NC42NCA1MCA3NC42NCAyNS4zNiA2My41OTkgMjUuMzYgNTAgMzYuNDAxIDI1LjM2IDUwIDI1LjM2WiIvPjwvY2xpcFBhdGg+PGcgY2xpcC1wYXRoPSJ1cmwoI2QpIj48cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IiMwMGQ4NDUiIHN0cm9rZS13aWR0aD0iOSIgZD0ibTUwIDUwIDUwLTEzLjM5NyIvPjwvZz48cGF0aCBmaWxsPSIjMDBkODQ1IiBkPSJNMzcuMjQzIDUyLjc0NiAzNSA0NWw4LTkgMTEtMyA0IDQtNiA2LTQgMS0zIDQgMS4xMiA0LjI0IDMuMTEyIDMuMDkgNC45NjQtLjU5OCAyLjg2Ni0yLjk2NCA4LjE5Ni0yLjE5NiAxLjQ2NCA1LjQ2NC04LjA5OCA4LjAyNkw0Ni44MyA2NS40OWwtNS41ODctNS44MTUtNC02LjkyOVoiLz48L3N2Zz4=)](https://modrinth.com/mod/essentialclient) -EssentialClient is a client side only mod supporting versions above 1.17.1, originally forked -from [Carpet Client for 1.15.2](https://github.com/gnembon/carpet-client) that implements new client side features. +EssentialClient is a client-side mod that adds many client utilities as well as +providing a gui to modify carpet rules! -Feel free to contribute by adding as many features as you want! +> [!NOTE] +> EssentialClient is currently undergoing a re-write. +> Some features from previous versions have been removed, either because I do not +> believe them to fit into this mod or because they are challenging to maintain. +> +> I have completely removed the scripting ability from EssentialClient as it had +> major flaws in its design that made it awkward to maintain and also work with. +> The long-term goal is to implement a better solution; however, this will take some +> time. +> +> Moving forward, only the most recent Minecraft version will be supported. -## Here is a link to my YouTube video about the mod -[![Image](https://cdn.discordapp.com/attachments/559400132710236160/899739577995108372/EssentialClient480.jpg)](https://youtu.be/lmMkC102T24) +## Usage -## You can find all infomation about the mod on the wiki: +This mod requires the fabric-launcher, fabric-api, fabric-kotlin, and +YetAnotherConfigLib. -> [Wiki](https://github.com/senseiwells/EssentialClient/wiki) +Optionally, you can install chunk-debug, fabric-carpet, and mod-menu. + +Once installed, you can access the configuration menu through mod-menu, or by +pressing the EssentialClient Menu keybind (which can be changed in options). + +From here you can view and modify the EssentialClient settings, Carpet server +settings, or open the ChunkDebug map (provided you have ChunkDebug installed). \ No newline at end of file diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 091769b6..00000000 --- a/build.gradle +++ /dev/null @@ -1,122 +0,0 @@ -plugins { - id "maven-publish" - id "fabric-loom" version "1.6-SNAPSHOT" - id 'me.modmuss50.mod-publish-plugin' version '0.5.1' -} - -repositories { - mavenCentral() - maven { - url "https://masa.dy.fi/maven" - } - maven { - url "https://maven.terraformersmc.com/releases/" - } - maven { - url "https://jitpack.io" - } - maven { - url "https://pkgs.dev.azure.com/djtheredstoner/DevAuth/_packaging/public/maven/v1" - } - maven { - url 'https://www.cursemaven.com' - } - maven { - url = "https://api.modrinth.com/maven" - } -} - -version = "${mod_version}+mc${minecraft_version}" -group = project.maven_group - -//configurations.configureEach { -// resolutionStrategy { -// force("net.fabricmc:fabric-loader:$loader_version") -// } -//} - -dependencies { - minecraft "com.mojang:minecraft:${minecraft_version}" - mappings "net.fabricmc:yarn:${yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${loader_version}" - - modImplementation "com.github.gnembon:fabric-carpet:${carpet_version}" - modImplementation "com.terraformersmc:modmenu:${modmenu_version}" - - // Required for Arucas - include implementation("org.jetbrains.kotlin:kotlin-stdlib:1.7.10") - var arucas = arucas_version.length() > 10 ? arucas_version.substring(0, 10) : arucas_version - include implementation("com.github.senseiwells:Arucas:${arucas}") - include implementation("net.bytebuddy:byte-buddy:${bytebuddy_version}") - - modCompileOnly "maven.modrinth:essentialaddons:1.4.1+mc1.20.5" - - // Runtime Fabric API - modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_version}" - - // Account authentication at runtime - // modRuntimeOnly "me.djtheredstoner:DevAuth-fabric:1.0.0" -} - -processResources { - inputs.property "version", mod_version - - filesMatching("fabric.mod.json") { - def map = [ - "version" : mod_version, -// "carpet_dependency" : ">=" + carpet_version, - "minecraft_dependency": minecraft_dependency - ] - expand map - } -} - -tasks.withType(JavaCompile).configureEach { - options.encoding = "UTF-8" - it.options.release.set(16) -} - -java { - withSourcesJar() -} - -jar { - from "LICENSE" -} - -publishMods { - file = remapJar.archiveFile - changelog = """ - - Updated to 1.21 - """ - type = STABLE - modLoaders.add("fabric") - - displayName = "EssentialClient ${minecraft_version} v${mod_version}" - - modrinth { - accessToken = providers.environmentVariable("MODRINTH_API_KEY") - projectId = "sH0dfrKf" - minecraftVersions.add(minecraft_version) - - requires { - id = "P7dR8mSH" - } - requires { - id = "TQTTVgYE" - } - optional { - id = "mOgUt4GM" - } - } -} - -publishing { - publications { - mavenJava(MavenPublication) { - artifact(jar) { - builtBy remapJar - } - } - } -} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 00000000..960a3209 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,105 @@ +plugins { + val jvmVersion = libs.versions.fabric.kotlin.get() + .split("+kotlin.")[1] + .split("+")[0] + + kotlin("jvm").version(jvmVersion) + alias(libs.plugins.fabric.loom) + alias(libs.plugins.mod.publish) + alias(libs.plugins.kotlin.serialization) + `maven-publish` + java +} + +repositories { + mavenLocal() + mavenCentral() + maven("https://maven.parchmentmc.org/") + maven("https://maven.terraformersmc.com/") + maven("https://maven.isxander.dev/releases") + maven("https://maven.supersanta.me/snapshots") + maven("https://jitpack.io") +} + +val modVersion = "2.0.0-beta.1" +val releaseVersion = "${modVersion}+${libs.versions.minecraft.get()}" +version = releaseVersion +group = "me.senseiwells" + +dependencies { + minecraft(libs.minecraft) + @Suppress("UnstableApiUsage") + mappings(loom.layered { + officialMojangMappings() + parchment("org.parchmentmc.data:parchment-${libs.versions.parchment.get()}@zip") + }) + + modImplementation(libs.fabric.loader) + modImplementation(libs.fabric.api) + modImplementation(libs.fabric.kotlin) + + modImplementation(libs.mod.menu) + modImplementation(libs.yacl) + include(modImplementation(libs.keybinds.get())!!) + + modCompileOnly(libs.carpet) + modCompileOnly(libs.chunk.debug) +} + +java { + withSourcesJar() +} + +tasks { + processResources { + inputs.property("version", project.version) + filesMatching("fabric.mod.json") { + expand(mutableMapOf( + "version" to project.version, + "minecraft_dependency" to libs.versions.minecraft.get().replaceAfterLast('.', "x"), + "yacl_dependency" to libs.versions.yacl.get(), + "fabric_loader_dependency" to libs.versions.fabric.loader.get(), + )) + } + } + + jar { + from("LICENSE") + } + + publishMods { + file = remapJar.get().archiveFile + changelog = """ + + """.trimIndent() + type = STABLE + modLoaders.add("fabric") + + displayName = "EssentialClient $modVersion for ${libs.versions.minecraft.get()}" + version = releaseVersion + + modrinth { + accessToken = providers.environmentVariable("MODRINTH_API_KEY") + projectId = "sH0dfrKf" + minecraftVersions.add(libs.versions.minecraft) + + requires { + id = "P7dR8mSH" + } + requires { + id = "TQTTVgYE" + } + optional { + id = "mOgUt4GM" + } + } + } +} + +publishing { + publications { + create("mavenJava") { + from(project.components.getByName("java")) + } + } +} \ No newline at end of file diff --git a/checkstyle.xml b/checkstyle.xml deleted file mode 100644 index 44854899..00000000 --- a/checkstyle.xml +++ /dev/null @@ -1,228 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 17655d0e..0d184210 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/libs.versions.toml b/libs.versions.toml new file mode 100644 index 00000000..01abfa05 --- /dev/null +++ b/libs.versions.toml @@ -0,0 +1,30 @@ +[versions] +fabric-loom = "1.7-SNAPSHOT" +kotlin-serialization = "1.9.21" +mod-publish = "0.7.0" +minecraft = "1.21.1" +fabric-loader = "0.16.7" +parchment = "1.21:2024.07.28" +fabric-api = "0.103.0+1.21.1" +fabric-kotlin = "1.11.0+kotlin.2.0.0" +mod-menu = "11.0.2" +keybinds = "0.1.11+1.21.1" +yacl = "3.5.0+1.21-fabric" +carpet = "1.4.147" +chunk-debug = "2.1.1+1.21.1" + +[libraries] +minecraft = { module = "com.mojang:minecraft" , version.ref = "minecraft" } +fabric-loader = { module = "net.fabricmc:fabric-loader" , version.ref = "fabric-loader" } +fabric-api = { module = "net.fabricmc.fabric-api:fabric-api" , version.ref = "fabric-api" } +fabric-kotlin = { module = "net.fabricmc:fabric-language-kotlin" , version.ref = "fabric-kotlin" } +mod-menu = { module = "com.terraformersmc:modmenu" , version.ref = "mod-menu" } +keybinds = { module = "me.senseiwells:simple-keybinding-library", version.ref = "keybinds" } +yacl = { module = "dev.isxander:yet-another-config-lib" , version.ref = "yacl" } +carpet = { module = "com.github.gnembon:fabric-carpet" , version.ref = "carpet" } +chunk-debug = { module = "me.senseiwells:chunk-debug" , version.ref = "chunk-debug" } + +[plugins] +fabric-loom = { id = "fabric-loom" , version.ref = "fabric-loom" } +mod-publish = { id = "me.modmuss50.mod-publish-plugin" , version.ref = "mod-publish" } +kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin-serialization" } diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index ead41c3f..00000000 --- a/settings.gradle +++ /dev/null @@ -1,21 +0,0 @@ -pluginManagement { - repositories { - maven { - name = 'Fabric' - url = 'https://maven.fabricmc.net/' - } - maven { - name = 'Cotton' - url = 'https://server.bbkr.space/artifactory/libs-release/' - } - maven { - name = 'Jitpack' - url = "https://jitpack.io" - } - maven { - url "https://masa.dy.fi/maven" - } - mavenCentral() - gradlePluginPortal() - } -} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 00000000..8e5ad1f3 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,19 @@ +rootProject.name = "EssentialClient" + +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("libs.versions.toml")) + } + } +} + +pluginManagement { + repositories { + maven("https://maven.fabricmc.net/") { + name = "Fabric" + } + mavenCentral() + gradlePluginPortal() + } +} \ No newline at end of file diff --git a/src/main/java/me/senseiwells/essential_client/ducks/TranslucentLiquids.java b/src/main/java/me/senseiwells/essential_client/ducks/TranslucentLiquids.java new file mode 100644 index 00000000..4a354268 --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/ducks/TranslucentLiquids.java @@ -0,0 +1,9 @@ +package me.senseiwells.essential_client.ducks; + +import com.mojang.blaze3d.vertex.VertexConsumer; + +public interface TranslucentLiquids { + void essentialclient$setTranslucentConsumer(VertexConsumer consumer); + + VertexConsumer essentialclient$getTranslucentConsumer(); +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/auto_walk/KeyboardInputMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/auto_walk/KeyboardInputMixin.java new file mode 100644 index 00000000..2cf4e521 --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/auto_walk/KeyboardInputMixin.java @@ -0,0 +1,29 @@ +package me.senseiwells.essential_client.mixins.auto_walk; + +import me.senseiwells.essential_client.features.AutoWalk; +import net.minecraft.client.Options; +import net.minecraft.client.player.Input; +import net.minecraft.client.player.KeyboardInput; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(KeyboardInput.class) +public class KeyboardInputMixin { + @Shadow @Final private Options options; + + @Inject( + method = "tick", + at = @At( + value = "INVOKE_ASSIGN", + target = "Lnet/minecraft/client/KeyMapping;isDown()Z", + ordinal = 1 + ) + ) + private void onTick(boolean isSneaking, float sneakingSpeedMultiplier, CallbackInfo ci) { + AutoWalk.tick((Input) (Object) this, this.options); + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/better_accurate_block_placement/BlockPlaceContextMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/better_accurate_block_placement/BlockPlaceContextMixin.java new file mode 100644 index 00000000..7d2361c7 --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/better_accurate_block_placement/BlockPlaceContextMixin.java @@ -0,0 +1,20 @@ +package me.senseiwells.essential_client.mixins.better_accurate_block_placement; + +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import me.senseiwells.essential_client.features.BetterAccurateBlockPlacement; +import net.minecraft.core.Direction; +import net.minecraft.world.item.context.BlockPlaceContext; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(BlockPlaceContext.class) +public class BlockPlaceContextMixin { + @ModifyReturnValue( + method = "getNearestLookingDirection", + at = @At("RETURN") + ) + private Direction onGetNearestLookingDirection(Direction original) { + Direction fake = BetterAccurateBlockPlacement.getFakeDirection(); + return fake == null ? original : fake; + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/better_accurate_block_placement/LocalPlayerMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/better_accurate_block_placement/LocalPlayerMixin.java new file mode 100644 index 00000000..be02625e --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/better_accurate_block_placement/LocalPlayerMixin.java @@ -0,0 +1,42 @@ +package me.senseiwells.essential_client.mixins.better_accurate_block_placement; + +import me.senseiwells.essential_client.features.BetterAccurateBlockPlacement; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.world.phys.Vec2; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArgs; +import org.spongepowered.asm.mixin.injection.invoke.arg.Args; + +@Mixin(LocalPlayer.class) +public class LocalPlayerMixin { + @ModifyArgs( + method = "sendPosition", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/network/protocol/game/ServerboundMovePlayerPacket$PosRot;(DDDFFZ)V" + ) + ) + private void onConstructPosRot(Args args) { + Vec2 rotation = BetterAccurateBlockPlacement.getFakeRotation(); + if (rotation != null) { + args.set(3, rotation.y); + args.set(4, rotation.x); + } + } + + @ModifyArgs( + method = "sendPosition", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/network/protocol/game/ServerboundMovePlayerPacket$Rot;(FFZ)V" + ) + ) + private void onConstructRot(Args args) { + Vec2 rotation = BetterAccurateBlockPlacement.getFakeRotation(); + if (rotation != null) { + args.set(0, rotation.y); + args.set(1, rotation.x); + } + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/carpet_always_set_default/ClientPacketListenerMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/carpet_always_set_default/ClientPacketListenerMixin.java new file mode 100644 index 00000000..316a9d3e --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/carpet_always_set_default/ClientPacketListenerMixin.java @@ -0,0 +1,46 @@ +package me.senseiwells.essential_client.mixins.carpet_always_set_default; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.mojang.brigadier.ParseResults; +import com.mojang.brigadier.context.ParsedCommandNode; +import me.senseiwells.essential_client.EssentialClient; +import me.senseiwells.essential_client.EssentialClientConfig; +import net.minecraft.client.multiplayer.ClientPacketListener; +import net.minecraft.commands.SharedSuggestionProvider; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; + +import java.util.List; + +@Mixin(ClientPacketListener.class) +public abstract class ClientPacketListenerMixin { + @Shadow public abstract void sendCommand(String command); + + @ModifyExpressionValue( + method = {"sendCommand", "sendUnsignedCommand"}, + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/multiplayer/ClientPacketListener;parseCommand(Ljava/lang/String;)Lcom/mojang/brigadier/ParseResults;" + ) + ) + private ParseResults onSendCommand( + ParseResults original, + String command + ) { + if (!EssentialClientConfig.getInstance().getCarpetAlwaysSetDefault()) { + return original; + } + + List> nodes = original.getContext().getNodes(); + if (nodes.size() == 3) { + String root = nodes.get(0).getRange().get(command); + String ruleName = nodes.get(1).getRange().get(command); + String ruleValue = nodes.get(2).getRange().get(command); + if (EssentialClient.INSTANCE.getCarpetClient().isValidRule(ruleName, root)) { + this.sendCommand(root + " setDefault " + ruleName + " " + ruleValue); + } + } + return original; + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/carpet_client/ClientNetworkHandlerMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/carpet_client/ClientNetworkHandlerMixin.java new file mode 100644 index 00000000..dfcb3239 --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/carpet_client/ClientNetworkHandlerMixin.java @@ -0,0 +1,31 @@ +package me.senseiwells.essential_client.mixins.carpet_client; + +import carpet.network.CarpetClient; +import carpet.network.ClientNetworkHandler; +import me.senseiwells.essential_client.EssentialClient; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(value = ClientNetworkHandler.class, remap = false) +public class ClientNetworkHandlerMixin { + @Inject( + method = "lambda$static$1", + at = @At("HEAD") + ) + private static void onSynchronizeRules(LocalPlayer player, Tag tag, CallbackInfo ci) { + EssentialClient.INSTANCE.synchronizeCarpetRules((CompoundTag) tag); + } + + @Inject( + method = "onHi", + at = @At("TAIL") + ) + private static void onCarpetHi(String version, CallbackInfo ci) { + EssentialClient.INSTANCE.setMultiplayerCarpet(CarpetClient.getPlayer().connection); + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/creative_walk_speed/PlayerMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/creative_walk_speed/PlayerMixin.java new file mode 100644 index 00000000..2163358f --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/creative_walk_speed/PlayerMixin.java @@ -0,0 +1,24 @@ +package me.senseiwells.essential_client.mixins.creative_walk_speed; + +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import me.senseiwells.essential_client.EssentialClientConfig; +import net.minecraft.world.entity.player.Player; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(Player.class) +public abstract class PlayerMixin { + @Shadow public abstract boolean isCreative(); + + @ModifyReturnValue( + method = "getSpeed", + at = @At("RETURN") + ) + private float onGetPlayerSpeed(float original) { + if (this.isCreative()) { + return original * EssentialClientConfig.getInstance().getCreativeWalkSpeed(); + } + return original; + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/disable_armor_rendering/HumanoidArmorLayerMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/disable_armor_rendering/HumanoidArmorLayerMixin.java new file mode 100644 index 00000000..e24e495b --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/disable_armor_rendering/HumanoidArmorLayerMixin.java @@ -0,0 +1,22 @@ +package me.senseiwells.essential_client.mixins.disable_armor_rendering; + +import me.senseiwells.essential_client.EssentialClientConfig; +import net.minecraft.client.renderer.entity.layers.HumanoidArmorLayer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(HumanoidArmorLayer.class) +public class HumanoidArmorLayerMixin { + @Inject( + method = "render(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;ILnet/minecraft/world/entity/LivingEntity;FFFFFF)V", + at = @At("HEAD"), + cancellable = true + ) + private void onRenderArmor(CallbackInfo ci) { + if (EssentialClientConfig.getInstance().getDisableArmorRendering()) { + ci.cancel(); + } + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/disable_bossbar_rendering/GuiMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/disable_bossbar_rendering/GuiMixin.java new file mode 100644 index 00000000..8d3f4640 --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/disable_bossbar_rendering/GuiMixin.java @@ -0,0 +1,23 @@ +package me.senseiwells.essential_client.mixins.disable_bossbar_rendering; + +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; +import me.senseiwells.essential_client.EssentialClientConfig; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.BossHealthOverlay; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(Gui.class) +public class GuiMixin { + @WrapWithCondition( + method = "method_55808", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/gui/components/BossHealthOverlay;render(Lnet/minecraft/client/gui/GuiGraphics;)V" + ) + ) + private boolean onRenderBossbar(BossHealthOverlay instance, GuiGraphics guiGraphics) { + return !EssentialClientConfig.getInstance().getDisableBossbarRendering(); + } +} \ No newline at end of file diff --git a/src/main/java/me/senseiwells/essential_client/mixins/disable_damage_tilt/GameRendererMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/disable_damage_tilt/GameRendererMixin.java new file mode 100644 index 00000000..1a6bbad1 --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/disable_damage_tilt/GameRendererMixin.java @@ -0,0 +1,23 @@ +package me.senseiwells.essential_client.mixins.disable_damage_tilt; + +import com.mojang.blaze3d.vertex.PoseStack; +import me.senseiwells.essential_client.EssentialClientConfig; +import net.minecraft.client.renderer.GameRenderer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(GameRenderer.class) +public class GameRendererMixin { + @Inject( + method = "bobHurt", + at = @At("HEAD"), + cancellable = true + ) + private void onDamageTilt(PoseStack poseStack, float partialTicks, CallbackInfo ci) { + if (EssentialClientConfig.getInstance().getDisableDamageTilt()) { + ci.cancel(); + } + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/disable_hotbar_scrolling/MouseHandlerMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/disable_hotbar_scrolling/MouseHandlerMixin.java new file mode 100644 index 00000000..51ecad53 --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/disable_hotbar_scrolling/MouseHandlerMixin.java @@ -0,0 +1,22 @@ +package me.senseiwells.essential_client.mixins.disable_hotbar_scrolling; + +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; +import me.senseiwells.essential_client.EssentialClientConfig; +import net.minecraft.client.MouseHandler; +import net.minecraft.world.entity.player.Inventory; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(MouseHandler.class) +public class MouseHandlerMixin { + @WrapWithCondition( + method = "onScroll", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/entity/player/Inventory;swapPaint(D)V" + ) + ) + private boolean shouldScrollHotbar(Inventory instance, double direction) { + return !EssentialClientConfig.getInstance().getDisableHotbarScrolling(); + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/disable_join_leave_messages/ChatListenerMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/disable_join_leave_messages/ChatListenerMixin.java new file mode 100644 index 00000000..460004a7 --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/disable_join_leave_messages/ChatListenerMixin.java @@ -0,0 +1,33 @@ +package me.senseiwells.essential_client.mixins.disable_join_leave_messages; + +import me.senseiwells.essential_client.EssentialClientConfig; +import net.minecraft.client.multiplayer.chat.ChatListener; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.contents.TranslatableContents; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ChatListener.class) +public class ChatListenerMixin { + @Inject( + method = "handleSystemMessage", + at = @At("HEAD"), + cancellable = true + ) + private void onSystemMessage(Component message, boolean isOverlay, CallbackInfo ci) { + if (!EssentialClientConfig.getInstance().getDisableJoinLeaveMessages()) { + return; + } + + if (message.getContents() instanceof TranslatableContents contents) { + switch (contents.getKey()) { + case "multiplayer.player.left": + case "multiplayer.player.joined": + case "multiplayer.player.joined.renamed": + ci.cancel(); + } + } + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/disable_map_rendering/ItemFrameRendererMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/disable_map_rendering/ItemFrameRendererMixin.java new file mode 100644 index 00000000..4c635d58 --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/disable_map_rendering/ItemFrameRendererMixin.java @@ -0,0 +1,34 @@ +package me.senseiwells.essential_client.mixins.disable_map_rendering; + +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; +import com.mojang.blaze3d.vertex.PoseStack; +import me.senseiwells.essential_client.EssentialClientConfig; +import net.minecraft.client.gui.MapRenderer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.ItemFrameRenderer; +import net.minecraft.world.level.saveddata.maps.MapId; +import net.minecraft.world.level.saveddata.maps.MapItemSavedData; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(ItemFrameRenderer.class) +public class ItemFrameRendererMixin { + @WrapWithCondition( + method = "render(Lnet/minecraft/world/entity/decoration/ItemFrame;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/gui/MapRenderer;render(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;Lnet/minecraft/world/level/saveddata/maps/MapId;Lnet/minecraft/world/level/saveddata/maps/MapItemSavedData;ZI)V" + ) + ) + private boolean onRenderMap( + MapRenderer instance, + PoseStack poseStack, + MultiBufferSource buffer, + MapId mapId, + MapItemSavedData mapData, + boolean active, + int packedLight + ) { + return !EssentialClientConfig.getInstance().getDisableMapRendering(); + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/disable_nametag_rendering/EntityRendererMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/disable_nametag_rendering/EntityRendererMixin.java new file mode 100644 index 00000000..d79d7d6e --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/disable_nametag_rendering/EntityRendererMixin.java @@ -0,0 +1,33 @@ +package me.senseiwells.essential_client.mixins.disable_nametag_rendering; + +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; +import com.mojang.blaze3d.vertex.PoseStack; +import me.senseiwells.essential_client.EssentialClientConfig; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.EntityRenderer; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.Entity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(EntityRenderer.class) +public class EntityRendererMixin { + @WrapWithCondition( + method = "render", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/renderer/entity/EntityRenderer;renderNameTag(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/network/chat/Component;Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;IF)V" + ) + ) + private boolean onRenderNametag( + EntityRenderer instance, + Entity entity, + Component displayName, + PoseStack poseStack, + MultiBufferSource bufferSource, + int packedLight, + float partialTick + ) { + return !EssentialClientConfig.getInstance().getDisableNametagRendering(); + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/disable_night_vision_flashing/GameRendererMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/disable_night_vision_flashing/GameRendererMixin.java new file mode 100644 index 00000000..4aa67b38 --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/disable_night_vision_flashing/GameRendererMixin.java @@ -0,0 +1,24 @@ +package me.senseiwells.essential_client.mixins.disable_night_vision_flashing; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import me.senseiwells.essential_client.EssentialClientConfig; +import net.minecraft.client.renderer.GameRenderer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(GameRenderer.class) +public class GameRendererMixin { + @ModifyExpressionValue( + method = "getNightVisionScale", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/effect/MobEffectInstance;endsWithin(I)Z" + ) + ) + private static boolean isNightVisionEnding(boolean original) { + if (EssentialClientConfig.getInstance().getDisableNightVisionFlashing()) { + return false; + } + return original; + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/disable_screenshot_message/ScreenshotMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/disable_screenshot_message/ScreenshotMixin.java new file mode 100644 index 00000000..6cc80b4c --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/disable_screenshot_message/ScreenshotMixin.java @@ -0,0 +1,24 @@ +package me.senseiwells.essential_client.mixins.disable_screenshot_message; + +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; +import me.senseiwells.essential_client.EssentialClientConfig; +import net.minecraft.client.Screenshot; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import java.util.function.Consumer; + +@Mixin(Screenshot.class) +public class ScreenshotMixin { + @WrapWithCondition( + method = "method_1661", + at = @At( + value = "INVOKE", + target = "Ljava/util/function/Consumer;accept(Ljava/lang/Object;)V", + remap = false + ) + ) + private static boolean onConsumeFeedback(Consumer instance, Object t) { + return !EssentialClientConfig.getInstance().getDisableScreenshotMessages(); + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/disable_toasts/ToastComponentMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/disable_toasts/ToastComponentMixin.java new file mode 100644 index 00000000..9d683148 --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/disable_toasts/ToastComponentMixin.java @@ -0,0 +1,28 @@ +package me.senseiwells.essential_client.mixins.disable_toasts; + +import me.senseiwells.essential_client.EssentialClientConfig; +import net.minecraft.client.gui.components.toasts.*; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ToastComponent.class) +public class ToastComponentMixin { + @Inject( + method = "addToast", + at = @At("HEAD"), + cancellable = true + ) + private void onAddToast(Toast toast, CallbackInfo ci) { + boolean disabled = switch (toast) { + case AdvancementToast ignored -> EssentialClientConfig.getInstance().getDisableAdvancementToasts(); + case RecipeToast ignored -> EssentialClientConfig.getInstance().getDisableRecipeToasts(); + case TutorialToast ignored -> EssentialClientConfig.getInstance().getDisableTutorialToasts(); + default -> false; + }; + if (disabled) { + ci.cancel(); + } + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/display_time_played/PauseScreenMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/display_time_played/PauseScreenMixin.java new file mode 100644 index 00000000..cf2db08a --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/display_time_played/PauseScreenMixin.java @@ -0,0 +1,26 @@ +package me.senseiwells.essential_client.mixins.display_time_played; + +import me.senseiwells.essential_client.features.DisplayStartTime; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.PauseScreen; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(PauseScreen.class) +public class PauseScreenMixin extends Screen { + protected PauseScreenMixin(Component title) { + super(title); + } + + @Inject( + method = "render", + at = @At("TAIL") + ) + private void onRender(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, CallbackInfo ci) { + DisplayStartTime.render(guiGraphics, this.font); + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/essential_client_button/PauseScreenMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/essential_client_button/PauseScreenMixin.java new file mode 100644 index 00000000..2efa1555 --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/essential_client_button/PauseScreenMixin.java @@ -0,0 +1,42 @@ +package me.senseiwells.essential_client.mixins.essential_client_button; + +import com.llamalad7.mixinextras.sugar.Local; +import me.senseiwells.essential_client.EssentialClientConfig; +import me.senseiwells.essential_client.gui.EssentialClientScreen; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.layouts.GridLayout; +import net.minecraft.client.gui.screens.PauseScreen; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(PauseScreen.class) +public class PauseScreenMixin extends Screen { + @Shadow @Final private static int BUTTON_WIDTH_FULL; + + protected PauseScreenMixin(Component title) { + super(title); + } + + @Inject( + method = "createPauseMenu", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/gui/layouts/GridLayout$RowHelper;addChild(Lnet/minecraft/client/gui/layouts/LayoutElement;I)Lnet/minecraft/client/gui/layouts/LayoutElement;" + ) + ) + private void onCreatePauseMenu(CallbackInfo ci, @Local GridLayout.RowHelper rows) { + if (EssentialClientConfig.getInstance().getEssentialClientButton()) { + rows.addChild(Button.builder(Component.translatable("essential-client.menu"), button -> { + if (this.minecraft != null) { + this.minecraft.setScreen(new EssentialClientScreen(this)); + } + }).width(BUTTON_WIDTH_FULL).build(), 2); + } + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/highlight_liquids/LiquidBlockRendererMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/highlight_liquids/LiquidBlockRendererMixin.java new file mode 100644 index 00000000..a10489f6 --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/highlight_liquids/LiquidBlockRendererMixin.java @@ -0,0 +1,227 @@ +package me.senseiwells.essential_client.mixins.highlight_liquids; + +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.llamalad7.mixinextras.sugar.Local; +import com.llamalad7.mixinextras.sugar.Share; +import com.llamalad7.mixinextras.sugar.ref.LocalBooleanRef; +import com.llamalad7.mixinextras.sugar.ref.LocalRef; +import com.mojang.blaze3d.vertex.VertexConsumer; +import it.unimi.dsi.fastutil.floats.FloatArrayList; +import it.unimi.dsi.fastutil.floats.FloatList; +import it.unimi.dsi.fastutil.floats.FloatListIterator; +import me.senseiwells.essential_client.EssentialClientConfig; +import me.senseiwells.essential_client.ducks.TranslucentLiquids; +import me.senseiwells.essential_client.features.HighlightLiquids; +import net.minecraft.client.renderer.block.LiquidBlockRenderer; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.Brightness; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Slice; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +// Apply after the Fabric api mixin +@Mixin(value = LiquidBlockRenderer.class, priority = 1100) +public abstract class LiquidBlockRendererMixin { + @Shadow + private static boolean isNeighborSameFluid(FluidState firstState, FluidState secondState) { + return false; + } + + @Shadow + private static boolean isFaceOccludedBySelf(BlockGetter level, BlockPos pos, BlockState state, Direction face) { + return false; + } + + @Inject( + method = "tesselate", + at = @At("HEAD") + ) + private void onTesselateFluid( + BlockAndTintGetter level, + BlockPos pos, + VertexConsumer buffer, + BlockState blockState, + FluidState fluidState, + CallbackInfo ci, + @Share("vertices") LocalRef ref + ) { + if (fluidState.is(Fluids.LAVA)) { + if (EssentialClientConfig.getInstance().getHighlightLavaSources()) { + ref.set(new FloatArrayList()); + } + } else if (fluidState.is(Fluids.WATER)) { + if (EssentialClientConfig.getInstance().getHighlightWaterSources()) { + ref.set(new FloatArrayList()); + } + } + } + + @WrapOperation( + method = "tesselate", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/renderer/block/LiquidBlockRenderer;shouldRenderFace(Lnet/minecraft/world/level/BlockAndTintGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/material/FluidState;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/Direction;Lnet/minecraft/world/level/material/FluidState;)Z" + ), + slice = @Slice( + from = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/renderer/block/LiquidBlockRenderer;isFaceOccludedByNeighbor(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/Direction;FLnet/minecraft/world/level/block/state/BlockState;)Z" + ) + ) + ) + private boolean shouldRenderFace( + BlockAndTintGetter level, + BlockPos pos, + FluidState fluidState, + BlockState blockState, + Direction side, + FluidState neighborFluid, + Operation original, + @Share("vertices") LocalRef ref + ) { + if (ref.get() == null) { + return original.call(level, pos, fluidState, blockState, side, neighborFluid); + } + return !isFaceOccludedBySelf(level, pos, blockState, side); + } + + @WrapWithCondition( + method = "tesselate", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/renderer/block/LiquidBlockRenderer;vertex(Lcom/mojang/blaze3d/vertex/VertexConsumer;FFFFFFFFI)V" + ), + slice = @Slice( + to = @At( + value = "INVOKE", + target = "Lnet/minecraft/core/Direction;getAxis()Lnet/minecraft/core/Direction$Axis;" + ) + ) + ) + private boolean onVertex( + LiquidBlockRenderer instance, + VertexConsumer buffer, + float x, + float y, + float z, + float red, + float green, + float blue, + float u, + float v, + int packedLight, + @Share("vertices") LocalRef ref + ) { + FloatList vertices = ref.get(); + if (vertices != null) { + vertices.add(x); + vertices.add(y); + vertices.add(z); + } + return true; + } + + @Inject( + method = "tesselate", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/core/Direction;getAxis()Lnet/minecraft/core/Direction$Axis;" + ) + ) + private void onDirection( + BlockAndTintGetter level, + BlockPos pos, + VertexConsumer buffer, + BlockState blockState, + FluidState fluidState, + CallbackInfo ci, + @Local Direction direction, + @Share("shouldRenderLiquid") LocalBooleanRef shouldRenderLiquid, + @Share("shouldRenderHighlight") LocalBooleanRef shouldRenderHighlight + ) { + FluidState neighbor = level.getFluidState(pos.relative(direction)); + boolean isNeighborSameFluid = isNeighborSameFluid(fluidState, neighbor); + shouldRenderLiquid.set(!isNeighborSameFluid); + shouldRenderHighlight.set((isNeighborSameFluid || neighbor.is(Fluids.EMPTY)) && !neighbor.isSource()); + } + + @WrapWithCondition( + method = "tesselate", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/renderer/block/LiquidBlockRenderer;vertex(Lcom/mojang/blaze3d/vertex/VertexConsumer;FFFFFFFFI)V" + ), + slice = @Slice( + from = @At( + value = "INVOKE", + target = "Lnet/minecraft/core/Direction;getAxis()Lnet/minecraft/core/Direction$Axis;" + ) + ) + ) + private boolean onSideVertex( + LiquidBlockRenderer instance, + VertexConsumer buffer, + float x, + float y, + float z, + float red, + float green, + float blue, + float u, + float v, + int packedLight, + @Share("vertices") LocalRef ref, + @Share("shouldRenderLiquid") LocalBooleanRef shouldRenderLiquid, + @Share("shouldRenderHighlight") LocalBooleanRef shouldRenderHighlight + ) { + FloatList vertices = ref.get(); + if (shouldRenderHighlight.get() && vertices != null) { + vertices.add(x); + vertices.add(y); + vertices.add(z); + } + return shouldRenderLiquid.get(); + } + + @Inject( + method = "tesselate", + at = @At("TAIL") + ) + private void afterTesselate( + BlockAndTintGetter level, + BlockPos pos, + VertexConsumer buffer, + BlockState blockState, + FluidState fluidState, + CallbackInfo ci, + @Share("vertices") LocalRef ref + ) { + FloatList vertices = ref.get(); + if (vertices == null) { + return; + } + VertexConsumer consumer = ((TranslucentLiquids) this).essentialclient$getTranslucentConsumer(); + int light = Brightness.FULL_BRIGHT.pack(); + FloatListIterator iterator = vertices.iterator(); + while (iterator.hasNext()) { + for (var uv : HighlightLiquids.getSpriteUVs()) { + consumer.addVertex(iterator.nextFloat(), iterator.nextFloat(), iterator.nextFloat()) + .setColor(0xFFFFFFFF) + .setUv(uv.u(), uv.v()) + .setLight(light) + .setNormal(0.0F, 1.0F, 0.0F); + } + } + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/lava_opacity/BlockRenderDispatcherMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/lava_opacity/BlockRenderDispatcherMixin.java new file mode 100644 index 00000000..2db51a59 --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/lava_opacity/BlockRenderDispatcherMixin.java @@ -0,0 +1,24 @@ +package me.senseiwells.essential_client.mixins.lava_opacity; + +import com.mojang.blaze3d.vertex.VertexConsumer; +import me.senseiwells.essential_client.ducks.TranslucentLiquids; +import net.minecraft.client.renderer.block.BlockRenderDispatcher; +import net.minecraft.client.renderer.block.LiquidBlockRenderer; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(BlockRenderDispatcher.class) +public class BlockRenderDispatcherMixin implements TranslucentLiquids { + @Shadow @Final private LiquidBlockRenderer liquidBlockRenderer; + + @Override + public void essentialclient$setTranslucentConsumer(VertexConsumer consumer) { + ((TranslucentLiquids) this.liquidBlockRenderer).essentialclient$setTranslucentConsumer(consumer); + } + + @Override + public VertexConsumer essentialclient$getTranslucentConsumer() { + return null; + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/lava_opacity/LiquidBlockRendererMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/lava_opacity/LiquidBlockRendererMixin.java new file mode 100644 index 00000000..a755551a --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/lava_opacity/LiquidBlockRendererMixin.java @@ -0,0 +1,62 @@ +package me.senseiwells.essential_client.mixins.lava_opacity; + +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; +import com.llamalad7.mixinextras.sugar.Local; +import com.mojang.blaze3d.vertex.VertexConsumer; +import me.senseiwells.essential_client.EssentialClientConfig; +import me.senseiwells.essential_client.ducks.TranslucentLiquids; +import net.minecraft.client.renderer.block.LiquidBlockRenderer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; + +// This must be loaded *AFTER* highlight liquids, we want the lava +// rendering to happen after our vertex checks in highlight liquids +@Mixin(value = LiquidBlockRenderer.class, priority = 1200) +public abstract class LiquidBlockRendererMixin implements TranslucentLiquids { + @Unique + private final ThreadLocal translucentConsumer = new ThreadLocal<>(); + + @WrapWithCondition( + method = "tesselate", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/renderer/block/LiquidBlockRenderer;vertex(Lcom/mojang/blaze3d/vertex/VertexConsumer;FFFFFFFFI)V" + ) + ) + private boolean onVertex( + LiquidBlockRenderer instance, + VertexConsumer buffer, + float x, + float y, + float z, + float red, + float green, + float blue, + float u, + float v, + int packedLight, + @Local(ordinal = 0) boolean isLava + ) { + if (!isLava) { + return true; + } + VertexConsumer consumer = this.translucentConsumer.get(); + consumer.addVertex(x, y, z) + .setColor(red, green, blue, EssentialClientConfig.getInstance().getLavaOpacity()) + .setUv(u, v) + .setLight(packedLight) + .setNormal(0.0F, 1.0F, 0.0F); + return false; + } + + @Override + public void essentialclient$setTranslucentConsumer(VertexConsumer consumer) { + this.translucentConsumer.set(consumer); + } + + @Override + public VertexConsumer essentialclient$getTranslucentConsumer() { + return this.translucentConsumer.get(); + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/lava_opacity/SectionCompilerMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/lava_opacity/SectionCompilerMixin.java new file mode 100644 index 00000000..e299db6c --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/lava_opacity/SectionCompilerMixin.java @@ -0,0 +1,53 @@ +package me.senseiwells.essential_client.mixins.lava_opacity; + +import com.llamalad7.mixinextras.sugar.Local; +import com.mojang.blaze3d.vertex.*; +import me.senseiwells.essential_client.ducks.TranslucentLiquids; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.SectionBufferBuilderPack; +import net.minecraft.client.renderer.block.BlockRenderDispatcher; +import net.minecraft.client.renderer.chunk.RenderChunkRegion; +import net.minecraft.client.renderer.chunk.SectionCompiler; +import net.minecraft.core.SectionPos; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Map; + +@Mixin(SectionCompiler.class) +public abstract class SectionCompilerMixin { + @Shadow protected abstract BufferBuilder getOrBeginLayer(Map bufferLayers, SectionBufferBuilderPack sectionBufferBuilderPack, RenderType renderType); + + @Shadow @Final private BlockRenderDispatcher blockRenderer; + + @Inject( + method = "compile", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/util/RandomSource;create()Lnet/minecraft/util/RandomSource;" + ) + ) + private void onRenderFluid( + SectionPos sectionPos, + RenderChunkRegion region, + VertexSorting vertexSorting, + SectionBufferBuilderPack sectionBufferBuilderPack, + CallbackInfoReturnable cir, + @Local Map cache + ) { + BufferBuilder translucent = this.getOrBeginLayer(cache, sectionBufferBuilderPack, RenderType.translucent()); + ((TranslucentLiquids) this.blockRenderer).essentialclient$setTranslucentConsumer(translucent); + } + + @Inject( + method = "compile", + at = @At("RETURN") + ) + private void afterRenderFluids(CallbackInfoReturnable cir) { + ((TranslucentLiquids) this.blockRenderer).essentialclient$setTranslucentConsumer(null); + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/persistent_chat_history/GuiMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/persistent_chat_history/GuiMixin.java new file mode 100644 index 00000000..33c750db --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/persistent_chat_history/GuiMixin.java @@ -0,0 +1,22 @@ +package me.senseiwells.essential_client.mixins.persistent_chat_history; + +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; +import me.senseiwells.essential_client.EssentialClientConfig; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.components.ChatComponent; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(Gui.class) +public class GuiMixin { + @WrapWithCondition( + method = "onDisconnected", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/gui/components/ChatComponent;clearMessages(Z)V" + ) + ) + private boolean onClearChat(ChatComponent instance, boolean clearSentMsgHistory) { + return !EssentialClientConfig.getInstance().getPersistentChatHistory(); + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/spectator_scrolling/MouseHandlerMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/spectator_scrolling/MouseHandlerMixin.java new file mode 100644 index 00000000..a0f55f68 --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/spectator_scrolling/MouseHandlerMixin.java @@ -0,0 +1,26 @@ +package me.senseiwells.essential_client.mixins.spectator_scrolling; + +import me.senseiwells.essential_client.EssentialClientConfig; +import net.minecraft.client.MouseHandler; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.Constant; +import org.spongepowered.asm.mixin.injection.ModifyConstant; + +@Mixin(MouseHandler.class) +public class MouseHandlerMixin { + @ModifyConstant( + method = "onScroll", + constant = @Constant(floatValue = 0.005F) + ) + private float getScrollSensitivity(float constant) { + return constant * EssentialClientConfig.getInstance().getSpectatorScrollSensitivity(); + } + + @ModifyConstant( + method = "onScroll", + constant = @Constant(floatValue = 0.2F) + ) + private float getMaxScrollSpeed(float constant) { + return constant * EssentialClientConfig.getInstance().getSpectatorScrollMaxSpeed(); + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/toggle_tab/GuiMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/toggle_tab/GuiMixin.java new file mode 100644 index 00000000..1a5453a3 --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/toggle_tab/GuiMixin.java @@ -0,0 +1,38 @@ +package me.senseiwells.essential_client.mixins.toggle_tab; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import me.senseiwells.essential_client.EssentialClient; +import me.senseiwells.essential_client.EssentialClientConfig; +import net.minecraft.client.KeyMapping; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(Gui.class) +public class GuiMixin { + @Shadow @Final private Minecraft minecraft; + + @Unique private boolean isTabToggled = false; + + @ModifyExpressionValue( + method = "renderTabList", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/KeyMapping;isDown()Z" + ) + ) + private boolean isTabToggled(boolean original) { + if (!EssentialClientConfig.getInstance().getToggleTab()) { + return original; + } + KeyMapping mapping = this.minecraft.options.keyPlayerList; + while (mapping.consumeClick()) { + this.isTabToggled = !this.isTabToggled; + } + return this.isTabToggled; + } +} diff --git a/src/main/java/me/senseiwells/essential_client/mixins/yacl/SimpleOptionFactoryMixin.java b/src/main/java/me/senseiwells/essential_client/mixins/yacl/SimpleOptionFactoryMixin.java new file mode 100644 index 00000000..6229e855 --- /dev/null +++ b/src/main/java/me/senseiwells/essential_client/mixins/yacl/SimpleOptionFactoryMixin.java @@ -0,0 +1,37 @@ +package me.senseiwells.essential_client.mixins.yacl; + +import com.google.common.collect.Sets; +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import dev.isxander.yacl3.api.OptionFlag; +import dev.isxander.yacl3.config.v2.api.ConfigField; +import dev.isxander.yacl3.config.v2.api.autogen.SimpleOptionFactory; +import me.senseiwells.essential_client.utils.yacl.ReloadChunks; +import me.senseiwells.essential_client.utils.yacl.ReloadResources; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import java.lang.annotation.Annotation; +import java.util.HashSet; +import java.util.Set; + +@Mixin(value = SimpleOptionFactory.class, remap = false) +public class SimpleOptionFactoryMixin { + @ModifyReturnValue( + method = "flags", + at = @At("RETURN") + ) + private Set onGetFlags( + Set original, + A annotation, + ConfigField field + ) { + Set additional = new HashSet<>(); + if (field.access().getAnnotation(ReloadChunks.class).isPresent()) { + additional.add(OptionFlag.RELOAD_CHUNKS); + } + if (field.access().getAnnotation(ReloadResources.class).isPresent()) { + additional.add(OptionFlag.ASSET_RELOAD); + } + return Sets.union(original, additional); + } +} diff --git a/src/main/java/me/senseiwells/essentialclient/EssentialClient.java b/src/main/java/me/senseiwells/essentialclient/EssentialClient.java deleted file mode 100644 index 6deb7f4d..00000000 --- a/src/main/java/me/senseiwells/essentialclient/EssentialClient.java +++ /dev/null @@ -1,95 +0,0 @@ -package me.senseiwells.essentialclient; - -import carpet.CarpetExtension; -import carpet.CarpetServer; -import me.senseiwells.essentialclient.clientscript.core.ClientScript; -import me.senseiwells.essentialclient.feature.CarpetClient; -import me.senseiwells.essentialclient.feature.CraftingSharedConstants; -import me.senseiwells.essentialclient.feature.GameRuleNetworkHandler; -import me.senseiwells.essentialclient.feature.chunkdebug.ChunkClientNetworkHandler; -import me.senseiwells.essentialclient.feature.chunkdebug.ChunkGrid; -import me.senseiwells.essentialclient.feature.keybinds.ClientKeyBinds; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.ClientScriptUtils; -import me.senseiwells.essentialclient.utils.clientscript.ClientTickSyncer; -import me.senseiwells.essentialclient.utils.clientscript.MinecraftDeobfuscator; -import me.senseiwells.essentialclient.utils.config.Config; -import me.senseiwells.essentialclient.utils.config.ConfigClientNick; -import me.senseiwells.essentialclient.utils.config.ConfigPlayerClient; -import me.senseiwells.essentialclient.utils.config.ConfigPlayerList; -import me.senseiwells.essentialclient.utils.misc.Scheduler; -import me.senseiwells.essentialclient.utils.network.NetworkHandler; -import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.time.LocalDateTime; -import java.util.LinkedHashSet; -import java.util.Set; - -public class EssentialClient implements ModInitializer, CarpetExtension { - public static final ChunkClientNetworkHandler CHUNK_NET_HANDLER; - public static final GameRuleNetworkHandler GAME_RULE_NET_HANDLER; - - public static final Logger LOGGER; - public static final LocalDateTime START_TIME; - public static final Set NETWORK_HANDLERS; - public static final Set> CONFIG_SET; - public static final String VERSION; - - static { - LOGGER = LogManager.getLogger("EssentialClient"); - CHUNK_NET_HANDLER = new ChunkClientNetworkHandler(); - GAME_RULE_NET_HANDLER = new GameRuleNetworkHandler(); - START_TIME = LocalDateTime.now(); - VERSION = EssentialUtils.getEssentialVersion(); - NETWORK_HANDLERS = new LinkedHashSet<>(); - CONFIG_SET = new LinkedHashSet<>(); - registerConfigs(); - - ClientLifecycleEvents.CLIENT_STOPPING.register(client -> saveConfigs()); - ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> onDisconnect()); - - NETWORK_HANDLERS.add(CHUNK_NET_HANDLER); - NETWORK_HANDLERS.add(GAME_RULE_NET_HANDLER); - } - - @Override - public void onInitialize() { - CarpetServer.manageExtension(CarpetClient.INSTANCE); - NETWORK_HANDLERS.forEach(NetworkHandler::registerCustomPayloads); - - // Run async for faster boot, saves ~2000ms on my machine - new Thread(() -> { - CONFIG_SET.forEach(Config::readConfig); - ClientRules.load(); - ClientKeyBinds.load(); - MinecraftDeobfuscator.load(); - CraftingSharedConstants.load(); - ClientScriptUtils.load(); - Scheduler.load(); - ClientTickSyncer.load(); - }, "EssentialClient Init Thread").start(); - } - - public static void registerConfigs() { - CONFIG_SET.add(ConfigClientNick.INSTANCE); - CONFIG_SET.add(ConfigPlayerClient.INSTANCE); - CONFIG_SET.add(ConfigPlayerList.INSTANCE); - CONFIG_SET.add(ClientRules.INSTANCE); - CONFIG_SET.add(ClientScript.INSTANCE); - CONFIG_SET.add(ClientKeyBinds.INSTANCE); - } - - public static void saveConfigs() { - CONFIG_SET.forEach(Config::saveConfig); - } - - public static void onDisconnect() { - NETWORK_HANDLERS.forEach(NetworkHandler::onDisconnect); - EssentialClient.saveConfigs(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/api/ClientScriptAPI.java b/src/main/java/me/senseiwells/essentialclient/clientscript/api/ClientScriptAPI.java deleted file mode 100644 index a61142a7..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/api/ClientScriptAPI.java +++ /dev/null @@ -1,7 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.api; - -import me.senseiwells.arucas.api.ArucasAPI; - -public interface ClientScriptAPI { - void apply(ArucasAPI.Builder builder); -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/core/ClientScript.java b/src/main/java/me/senseiwells/essentialclient/clientscript/core/ClientScript.java deleted file mode 100644 index f5e491a0..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/core/ClientScript.java +++ /dev/null @@ -1,159 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.core; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import me.senseiwells.arucas.utils.FileUtils; -import me.senseiwells.essentialclient.utils.config.Config; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.io.File; -import java.nio.file.Path; -import java.util.*; - -public enum ClientScript implements Config.CList { - INSTANCE; - - public static final Logger LOGGER = LogManager.getLogger("ClientScript"); - - private final Map scriptInstances; - private final Set selectedScriptNames; - - ClientScript() { - this.scriptInstances = new HashMap<>(); - this.selectedScriptNames = new HashSet<>(); - } - - public ClientScriptInstance getScriptInstance(String name) { - return this.scriptInstances.get(name); - } - - public Collection getScriptInstances() { - return this.scriptInstances.values(); - } - - public List getScriptInstancesInOrder() { - return this.getScriptInstances().stream().sorted(Comparator.comparing(ClientScriptInstance::getName)).toList(); - } - - public Set getScriptInstanceNames() { - return this.scriptInstances.keySet(); - } - - public boolean hasScriptInstance(String name) { - return this.getScriptInstances().stream().anyMatch(i -> i.getName().equals(name)); - } - - public boolean isSelected(String name) { - return this.selectedScriptNames.contains(name); - } - - public void startAllInstances() { - if (this.scriptInstances.isEmpty()) { - return; - } - for (String selected : this.selectedScriptNames) { - ClientScriptInstance instance = this.scriptInstances.get(selected); - if (instance != null) { - instance.toggleScript(); - } - } - } - - public void stopAllInstances() { - for (ClientScriptInstance instance : this.getScriptInstances()) { - instance.stopScript(); - } - } - - public void addInstance(ClientScriptInstance scriptInstance) { - this.scriptInstances.put(scriptInstance.getName(), scriptInstance); - } - - public void addSelectedInstance(String name) { - this.selectedScriptNames.add(name); - this.saveConfig(); - } - - public void removeInstance(ClientScriptInstance clientScriptInstance) { - this.scriptInstances.remove(clientScriptInstance.getName()); - } - - public void removeSelectedInstance(String name) { - this.selectedScriptNames.remove(name); - this.saveConfig(); - } - - public void replaceSelectedInstance(String oldName, String newName) { - if (this.selectedScriptNames.remove(oldName)) { - this.selectedScriptNames.add(newName); - } - this.saveConfig(); - } - - public void refresh() { - File[] files = this.getScriptFiles(); - for (File file : files) { - String fileName = file.getName(); - if (fileName.endsWith(".arucas")) { - fileName = fileName.substring(0, fileName.length() - 7); - if (!this.hasScriptInstance(fileName)) { - new ClientScriptInstance(fileName, file.toPath()); - } - } - } - } - - public Path getScriptDirectory() { - Path scriptDir = this.getConfigRootPath().resolve("Scripts"); - return FileUtils.ensureExists(scriptDir); - } - - public Path getLibraryDirectory() { - Path libDir = this.getScriptDirectory().resolve("libs"); - return FileUtils.ensureExists(libDir); - } - - private File[] getScriptFiles() { - Path scriptPath = this.getScriptDirectory(); - File[] files = scriptPath.toFile().listFiles(); - if (files == null) { - return new File[0]; - } - return files; - } - - @Override - public String getConfigName() { - return "ClientScript"; - } - - @Override - public Path getConfigPath() { - return this.getConfigRootPath().resolve("ScriptConfig.json"); - } - - @Override - public JsonElement getSaveData() { - JsonArray scriptData = new JsonArray(); - this.getScriptInstances().forEach(instance -> { - if (this.selectedScriptNames.contains(instance.getName())) { - JsonObject scriptObject = new JsonObject(); - scriptObject.addProperty("name", instance.getName()); - scriptObject.addProperty("selected", true); - scriptData.add(scriptObject); - } - }); - return scriptData; - } - - @Override - public void readConfig(JsonArray jsonArray) { - jsonArray.forEach(element -> { - JsonObject scriptObject = element.getAsJsonObject(); - this.selectedScriptNames.add(scriptObject.get("name").getAsString()); - }); - this.refresh(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/core/ClientScriptErrorHandler.java b/src/main/java/me/senseiwells/essentialclient/clientscript/core/ClientScriptErrorHandler.java deleted file mode 100644 index ef4bd263..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/core/ClientScriptErrorHandler.java +++ /dev/null @@ -1,115 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.core; - -import me.senseiwells.arucas.Arucas; -import me.senseiwells.arucas.api.ArucasErrorHandler; -import me.senseiwells.arucas.exceptions.ArucasError; -import me.senseiwells.arucas.exceptions.FatalError; -import me.senseiwells.arucas.exceptions.Propagator; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.FileUtils; -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.render.Texts; -import net.minecraft.text.ClickEvent; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.Identifier; -import org.apache.commons.lang3.exception.ExceptionUtils; -import org.jetbrains.annotations.NotNull; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.text.SimpleDateFormat; -import java.util.Date; - -public enum ClientScriptErrorHandler implements ArucasErrorHandler { - INSTANCE; - - private static final String ISSUE_TRACKER = "https://github.com/senseiwells/EssentialClient/issues/new"; - - @Override - public void handleArucasError(@NotNull ArucasError arucasError, @NotNull Interpreter interpreter) { - Identifier identifier = switch (ClientRules.CLIENT_SCRIPT_FONT.getValue()) { - case "Minecraft" -> Texts.MINECRAFT_MONO; - case "Jetbrains" -> Texts.JETBRAINS_MONO; - default -> null; - }; - EssentialUtils.sendMessage(Text.literal(arucasError.format(interpreter)).styled(s -> s.withFont(identifier).withColor(Formatting.RED))); - } - - @Override - public void handleInvalidPropagator(@NotNull Propagator propagator, @NotNull Interpreter interpreter) { - ArucasErrorHandler.getDefault().handleInvalidPropagator(propagator, interpreter); - } - - @Override - public void handleFatalError(@NotNull FatalError fatalError, @NotNull Interpreter interpreter) { - this.handleFatalError((Throwable) fatalError, interpreter); - } - - @Override - public void handleFatalError(@NotNull Throwable throwable, @NotNull Interpreter interpreter) { - Text error = Text.literal("\n").formatted(Formatting.RED).append(Texts.FATAL_ERROR.generate(interpreter.getName())); - EssentialUtils.sendMessage(error); - - String path = this.writeCrashReport(interpreter, throwable).toAbsolutePath().toString(); - Text crashReport = Texts.CRASH_REPORT.generate( - Text.literal("\n" + path + "\n") - .formatted(Formatting.UNDERLINE) - .styled(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_FILE, path))) - ).formatted(Formatting.RED); - EssentialUtils.sendMessage(crashReport); - - EssentialUtils.sendMessage(Texts.CRASH_BUG); - Text issueTracker = Text.literal(ISSUE_TRACKER + "\n") - .formatted(Formatting.UNDERLINE) - .styled((style) -> style.withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, ISSUE_TRACKER))); - - EssentialUtils.sendMessage(issueTracker); - } - - private Path writeCrashReport(Interpreter interpreter, Throwable throwable) { - String stacktrace = ExceptionUtils.getStackTrace(throwable); - String scriptTrace = ""; - if (throwable instanceof FatalError error) { - scriptTrace = """ - ### StackTrace: - ``` - %s - ``` - """.formatted(error.format(interpreter)); - } - String report = """ - ### Minecraft Version: `%s` - ### Essential Client Version: `%s` - ### Arucas Version: `%s` - ### Script: - ```kt - // %s - %s - ``` - %s### Crash: - ``` - %s - ``` - """.formatted( - EssentialUtils.getMinecraftVersion(), - EssentialClient.VERSION, - Arucas.VERSION, - interpreter.getName(), - interpreter.getContent(), - scriptTrace, - stacktrace - ); - String date = new SimpleDateFormat("dd-MM-yyyy_HH-mm-ss").format(new Date()); - Path crashPath = EssentialUtils.getEssentialConfigFile().resolve("script-crashes").resolve("crash-" + date + ".txt"); - try { - Files.writeString(FileUtils.ensureParentExists(crashPath), report); - } catch (IOException e) { - EssentialClient.LOGGER.error("Failed to write script crash report:\n{}\n\n{}", report, e); - } - return crashPath; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/core/ClientScriptIO.java b/src/main/java/me/senseiwells/essentialclient/clientscript/core/ClientScriptIO.java deleted file mode 100644 index 43991eec..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/core/ClientScriptIO.java +++ /dev/null @@ -1,101 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.core; - -import me.senseiwells.arucas.api.ArucasFileHandler; -import me.senseiwells.arucas.api.ArucasInput; -import me.senseiwells.arucas.api.ArucasOutput; -import me.senseiwells.arucas.compiler.LocatableTrace; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.render.ChatColour; -import net.minecraft.util.Util; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.util.concurrent.CompletableFuture; - -public enum ClientScriptIO implements ArucasInput, ArucasOutput, ArucasFileHandler { - INSTANCE; - - private final Logger logger = LogManager.getLogger("ClientScript"); - private CompletableFuture inputFuture; - - public boolean submitInput(String input) { - if (this.inputFuture != null) { - this.inputFuture.complete(input); - this.inputFuture = null; - return true; - } - return false; - } - - @NotNull - @Override - public CompletableFuture takeInput() { - return this.inputFuture = new CompletableFuture<>(); - } - - @NotNull - @Override - public String formatError(@NotNull String s) { - return ChatColour.RED + s + ChatColour.RESET; - } - - @NotNull - @Override - public String formatErrorBold(@NotNull String s) { - return ChatColour.BOLD + this.formatError(s); - } - - @Override - public void print(Object o) { - EssentialUtils.sendMessage(String.valueOf(o)); - } - - @Override - public void println() { - this.println(""); - } - - @Override - public void println(Object o) { - this.print(o); - } - - @Override - public void printError(Object o) { - this.println(this.formatErrorBold(String.valueOf(o))); - } - - @Override - public void log(Object o) { - this.logger.info(o); - } - - @Override - public void logln() { - this.log(""); - } - - @Override - public void logln(Object o) { - this.log(o); - } - - @Override - public void logError(Object o) { - this.logln(this.formatErrorBold(String.valueOf(o))); - } - - @NotNull - @Override - public String formatStackTrace(@NotNull Interpreter interpreter, String message, @NotNull LocatableTrace trace) { - return ArucasOutput.defaultFormatStackTrace(interpreter, message, trace); - } - - @Override - public void open(@NotNull File file) { - Util.getOperatingSystem().open(file); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/core/ClientScriptInstance.java b/src/main/java/me/senseiwells/essentialclient/clientscript/core/ClientScriptInstance.java deleted file mode 100644 index da283e29..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/core/ClientScriptInstance.java +++ /dev/null @@ -1,201 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.core; - -import me.senseiwells.arucas.api.ArucasAPI; -import me.senseiwells.arucas.api.impl.GitHubArucasLibrary; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.interpreter.Properties; -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.clientscript.api.ClientScriptAPI; -import me.senseiwells.essentialclient.clientscript.events.MinecraftScriptEvents; -import me.senseiwells.essentialclient.feature.keybinds.ClientKeyBind; -import me.senseiwells.essentialclient.feature.keybinds.ClientKeyBinds; -import me.senseiwells.essentialclient.feature.keybinds.MultiKeyBind; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.command.CommandHelper; -import me.senseiwells.essentialclient.utils.render.Texts; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.client.util.InputUtil; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; - -public class ClientScriptInstance { - private static List APIS = new LinkedList<>(); - private static ArucasAPI API; - - private final String content; - private Path fileLocation; - private String scriptName; - private MultiKeyBind keyBind; - private Interpreter interpreter; - private boolean isStopping; - - private ClientScriptInstance(String scriptName, String content, Path fileLocation) { - this.scriptName = scriptName; - this.content = content; - this.fileLocation = fileLocation; - this.keyBind = ClientKeyBinds.registerMulti(scriptName, "Script Toggles", client -> this.toggleScript()); - ClientScript.INSTANCE.addInstance(this); - } - - public ClientScriptInstance(String scriptName, Path fileLocation) { - this(scriptName, null, fileLocation); - } - - public Path getFileLocation() { - return this.fileLocation; - } - - public MultiKeyBind getKeyBind() { - return this.keyBind; - } - - public boolean isTemporary() { - return this.fileLocation == null; - } - - public void renameScript(String newName, Path newLocation) { - ClientScript.INSTANCE.replaceSelectedInstance(this.scriptName, newName); - ClientKeyBind old = ClientKeyBinds.unregisterKeyBind(this.scriptName); - Collection keys = old != null ? old.getKeys() : List.of(); - this.keyBind = ClientKeyBinds.registerMulti(newName, "Script Toggles", client -> this.toggleScript(), keys); - this.scriptName = newName; - this.fileLocation = newLocation; - } - - public void delete() throws IOException { - this.stopScript(); - Files.delete(this.fileLocation); - ClientScript.INSTANCE.removeInstance(this); - ClientKeyBinds.unregisterKeyBind(this.scriptName); - } - - public boolean isScriptRunning() { - return this.interpreter != null; - } - - public synchronized void toggleScript() { - if (EssentialUtils.getClient().player == null || this.isScriptRunning()) { - this.stopScript(); - return; - } - this.executeScript(); - } - - public synchronized void stopScript() { - if (!this.isScriptRunning() || this.isStopping) { - return; - } - this.isStopping = true; - MinecraftScriptEvents.ON_SCRIPT_END.run(this.interpreter.getProperties().getId()); - this.interpreter.stop(); - - MinecraftClient client = EssentialUtils.getClient(); - if (CommandHelper.getCommandPacket() != null) { - client.execute(() -> { - ClientPlayNetworkHandler networkHandler = EssentialUtils.getNetworkHandler(); - if (networkHandler != null) { - networkHandler.onCommandTree(CommandHelper.getCommandPacket()); - } - }); - } - - if (ClientRules.CLIENT_SCRIPT_ANNOUNCEMENTS.getValue()) { - EssentialUtils.sendMessage(Texts.SCRIPT_STATUS.generate(this.scriptName, Texts.FINISHED)); - } - this.interpreter = null; - this.isStopping = false; - } - - private synchronized void executeScript() { - String fileContent; - try { - fileContent = this.fileLocation == null ? this.content : Files.readString(this.fileLocation); - if (fileContent == null) { - throw new IOException("File content was null!"); - } - } catch (IOException e) { - EssentialUtils.sendMessage(Texts.READ_ERROR.generate(this.scriptName)); - e.printStackTrace(); - return; - } - - this.interpreter = Interpreter.of(fileContent, this.scriptName, getApi()); - - this.interpreter.addStopEvent(this::stopScript); - this.interpreter.executeAsync(); - - if (ClientRules.CLIENT_SCRIPT_ANNOUNCEMENTS.getValue()) { - EssentialUtils.sendMessage(Texts.SCRIPT_STATUS.generate(this.scriptName, Texts.STARTED)); - } - } - - public String getName() { - return this.scriptName; - } - - public static ArucasAPI getApi() { - if (API == null) { - load(); - } - return API; - } - - @SuppressWarnings("unused") - public static void addApi(ClientScriptAPI api) { - if (APIS == null) { - throw new IllegalStateException("ClientScript API has been locked, register your api earlier"); - } - APIS.add(api); - } - - public static void runFromContent(String scriptName, String scriptContent) { - ClientScriptInstance instance = new ClientScriptInstance(scriptName, scriptContent, null); - instance.toggleScript(); - } - - private static void load() { - ArucasAPI.Builder builder = new ArucasAPI.Builder() - .addDefault() - .addArucasLibrary("ArucasLibraries", new GitHubArucasLibrary(ClientScript.INSTANCE.getLibraryDirectory())) - .setObfuscator(new ClientScriptObfuscator()) - .setInput(ClientScriptIO.INSTANCE) - .setOutput(ClientScriptIO.INSTANCE) - .setErrorHandler(ClientScriptErrorHandler.INSTANCE) - .setFileHandler(ClientScriptIO.INSTANCE) - .setInterpreterProperties(() -> { - Properties properties = new Properties(); - properties.setErrorMaxLength(40); - properties.setLogDeprecated(true); - return properties; - }); - - MinecraftAPI.addMinecraftAPI(builder); - - APIS.forEach(a -> a.apply(builder)); - APIS = null; - - try { - API = builder.build(); - } catch (Exception e) { - EssentialClient.LOGGER.error("Failed to load Script API", e); - EssentialUtils.getClient().scheduleStop(); - throw e; - } - - new Thread(() -> { - try { - API.generateNativeFiles(ClientScript.INSTANCE.getLibraryDirectory()); - } catch (Exception e) { - // This isn't fatal - EssentialClient.LOGGER.error("Failed to generate native files", e); - } - }).start(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/core/ClientScriptObfuscator.java b/src/main/java/me/senseiwells/essentialclient/clientscript/core/ClientScriptObfuscator.java deleted file mode 100644 index 3715af72..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/core/ClientScriptObfuscator.java +++ /dev/null @@ -1,87 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.core; - -import me.senseiwells.arucas.api.ArucasObfuscator; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.MinecraftDeobfuscator; -import org.jetbrains.annotations.NotNull; - -import java.util.Objects; - -public class ClientScriptObfuscator implements ArucasObfuscator { - @Override - public boolean shouldObfuscate() { - return !EssentialUtils.isDev(); - } - - @NotNull - @Override - public String obfuscateClassName(@NotNull String s) { - return this.shouldObfuscate() ? MinecraftDeobfuscator.obfuscate(s) : s; - } - - @NotNull - @Override - public String obfuscateMethodName(@NotNull Class clazz, @NotNull String name) { - if (this.shouldObfuscate()) { - for (Class k = clazz; k != Object.class; k = k.getSuperclass()) { - String result = obfuscateMethod(k, name); - if (result != null) { - return result; - } - } - for (Class k : clazz.getInterfaces()) { - String result = obfuscateMethod(k, name); - if (result != null) { - return result; - } - } - } - return name; - } - - @NotNull - @Override - public String obfuscateFieldName(@NotNull Class clazz, @NotNull String name) { - if (this.shouldObfuscate()) { - for (Class k = clazz; k != Object.class; k = k.getSuperclass()) { - String result = obfuscateField(k, name); - if (result != null) { - return result; - } - } - for (Class k : clazz.getInterfaces()) { - String result = obfuscateField(k, name); - if (result != null) { - return result; - } - } - } - return name; - } - - @NotNull - @Override - public String deobfuscateClass(@NotNull Class aClass) { - return this.shouldObfuscate() ? MinecraftDeobfuscator.deobfuscateClass(aClass.getName()) : aClass.getName(); - } - - private static String obfuscateMethod(Class clazz, String name) { - String deobfuscatedClass = MinecraftDeobfuscator.deobfuscateClass(clazz.getName()); - String deobfuscatedMethod = deobfuscatedClass + "#" + name + "()"; - String obfuscatedMethod = MinecraftDeobfuscator.obfuscate(deobfuscatedMethod); - if (!Objects.equals(obfuscatedMethod, deobfuscatedMethod)) { - return obfuscatedMethod.substring(obfuscatedMethod.lastIndexOf('#') + 1, obfuscatedMethod.length() - 2); - } - return null; - } - - private static String obfuscateField(Class clazz, String name) { - String deobfuscatedClass = MinecraftDeobfuscator.deobfuscateClass(clazz.getName()); - String deobfuscatedMethod = deobfuscatedClass + "#" + name; - String obfuscatedMethod = MinecraftDeobfuscator.obfuscate(deobfuscatedMethod); - if (!Objects.equals(obfuscatedMethod, deobfuscatedMethod)) { - return obfuscatedMethod.substring(obfuscatedMethod.lastIndexOf('#') + 1); - } - return null; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/core/MinecraftAPI.java b/src/main/java/me/senseiwells/essentialclient/clientscript/core/MinecraftAPI.java deleted file mode 100644 index 3b5fb03d..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/core/MinecraftAPI.java +++ /dev/null @@ -1,157 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.core; - -import com.mojang.brigadier.builder.ArgumentBuilder; -import me.senseiwells.arucas.api.ArucasAPI; -import me.senseiwells.arucas.builtin.StringDef; -import me.senseiwells.essentialclient.clientscript.definitions.*; -import me.senseiwells.essentialclient.clientscript.definitions.shapes.*; -import me.senseiwells.essentialclient.clientscript.extensions.ArucasMinecraftExtension; -import me.senseiwells.essentialclient.rule.client.ClientRule; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptBlockState; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptItemStack; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptMaterial; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptPos; -import me.senseiwells.essentialclient.utils.render.FakeInventoryScreen; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.ingame.MerchantScreen; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.network.OtherClientPlayerEntity; -import net.minecraft.command.argument.BlockStateArgument; -import net.minecraft.command.argument.ItemStackArgument; -import net.minecraft.enchantment.Enchantment; -import net.minecraft.entity.Entity; -import net.minecraft.entity.ItemEntity; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.recipe.RecipeEntry; -import net.minecraft.registry.Registries; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; -import net.minecraft.util.math.Vec3i; -import net.minecraft.village.TradeOffer; -import net.minecraft.world.World; -import net.minecraft.world.biome.Biome; -import org.joml.Vector3f; - -public class MinecraftAPI { - public static final String - BIOME = "Biome", - BOX_SHAPE = "BoxShape", - CENTRED_SHAPE = "CentredShape", - CONFIG_HANDLER = "ConfigHandler", - CORNERED_SHAPE = "CorneredShape", - FAKE_BLOCK = "FakeBlock", - FAKE_ENTITY = "FakeEntity", - GAME_EVENT = "GameEvent", - KEY_BIND = "KeyBind", - LINE_SHAPE = "LineShape", - SPHERE_SHAPE = "SphereShape", - BLOCK = "Block", - COMMAND_BUILDER = "CommandBuilder", - CONFIG = "Config", - ENTITY = "Entity", - FAKE_SCREEN = "FakeScreen", - ITEM_ENTITY = "ItemEntity", - ITEM_STACK = "ItemStack", - LIVING_ENTITY = "LivingEntity", - MATERIAL = "Material", - MERCHANT_SCREEN = "MerchantScreen", - MINECRAFT_CLIENT = "MinecraftClient", - MINECRAFT_TASK = "MinecraftTask", - OTHER_PLAYER = "OtherPlayer", - OUTLINED_SHAPE = "OutlinedShape", - PLAYER = "Player", - POS = "Pos", - RECIPE = "Recipe", - SCREEN = "Screen", - SHAPE = "Shape", - TEXT = "Text", - TRADE = "Trade", - WORLD = "World"; - - public static final String IMPORT_NAME = "Minecraft"; - - @SuppressWarnings({"deprecation", "unchecked"}) - public static void addMinecraftAPI(ArucasAPI.Builder builder) { - builder.addClassDefinitions( - IMPORT_NAME, - BiomeDef::new, - BlockDef::new, - BoxShapeDef::new, - CentredShapeDef::new, - CommandBuilderDef::new, - ConfigDef::new, - ConfigHandlerDef::new, - CorneredShapeDef::new, - EntityDef::new, - FakeEntityDef::new, - FakeScreenDef::new, - FakeBlockShapeDef::new, - GameEventDef::new, - ItemEntityDef::new, - ItemStackDef::new, - KeyBindDef::new, - LineShapeDef::new, - LivingEntityDef::new, - MaterialDef::new, - MerchantScreenDef::new, - MinecraftClientDef::new, - MinecraftTaskDef::new, - OtherPlayerDef::new, - OutlinedShapeDef::new, - PlayerDef::new, - PosDef::new, - RecipeDef::new, - ScreenDef::new, - ShapeDef::new, - SphereShapeDef::new, - TextDef::new, - TradeDef::new, - WorldDef::new - ); - builder.addBuiltInExtension(new ArucasMinecraftExtension()); - - builder.addConversion(MinecraftClient.class, (m, i) -> i.getPrimitive(MinecraftClientDef.class).instance); - builder.addConversion(ClientPlayerEntity.class, (p, i) -> i.create(PlayerDef.class, p)); - builder.addConversion(OtherClientPlayerEntity.class, (p, i) -> i.getPrimitive(OtherPlayerDef.class).create(p)); - builder.addConversion(LivingEntity.class, (l, i) -> i.getPrimitive(LivingEntityDef.class).create(l)); - builder.addConversion(ItemEntity.class, (e, i) -> i.getPrimitive(ItemEntityDef.class).create(e)); - builder.addConversion(Entity.class, (e, i) -> i.getPrimitive(EntityDef.class).create(e)); - builder.addConversion(Block.class, (b, i) -> i.create(MaterialDef.class, ScriptMaterial.materialOf(b))); - builder.addConversion(BlockState.class, (b, i) -> i.create(BlockDef.class, new ScriptBlockState(b, null))); - builder.addConversion(Item.class, (m, i) -> i.create(MaterialDef.class, ScriptMaterial.materialOf(m))); - builder.addConversion(ItemStack.class, (s, i) -> i.create(ItemStackDef.class, new ScriptItemStack(s))); - builder.addConversion(World.class, (w, i) -> i.create(WorldDef.class, w)); - builder.addConversion(Biome.class, (b, i) -> i.create(BiomeDef.class, b)); - builder.addConversion(Screen.class, (s, i) -> i.getPrimitive(ScreenDef.class).create(s)); - builder.addConversion(FakeInventoryScreen.class, (s, i) -> i.create(FakeScreenDef.class, s)); - builder.addConversion(MerchantScreen.class, (s, i) -> i.create(MerchantScreenDef.class, s)); - builder.addConversion(MutableText.class, (t, i) -> i.create(TextDef.class, t)); - builder.addConversion(Text.class, (t, i) -> i.create(TextDef.class, t.copy())); - builder.addConversion(Vec3d.class, (p, i) -> i.create(PosDef.class, new ScriptPos(p))); - builder.addConversion(Vector3f.class, (p, i) -> i.create(PosDef.class, new ScriptPos(new Vec3d(p)))); - builder.addConversion(BlockPos.class, (b, i) -> i.create(PosDef.class, new ScriptPos(b))); - builder.addConversion(Vec3i.class, (p, i) -> i.create(PosDef.class, new ScriptPos(new Vec3d(p.getX(), p.getY(), p.getZ())))); - builder.addConversion(ScriptBlockState.class, (s, i) -> i.create(BlockDef.class, s)); - builder.addConversion(ScriptItemStack.class, (s, i) -> i.create(ItemStackDef.class, s)); - builder.addConversion(ScriptPos.class, (p, i) -> i.create(PosDef.class, p)); - builder.addConversion(ScriptMaterial.class, (m, i) -> i.create(MaterialDef.class, m)); - builder.addConversion(RecipeEntry.class, (r, i) -> i.create(RecipeDef.class, r)); - builder.addConversion(TradeOffer.class, (t, i) -> i.create(TradeDef.class, t)); - builder.addConversion(ArgumentBuilder.class, (a, i) -> i.create(CommandBuilderDef.class, a)); - builder.addConversion(ClientRule.class, (c, i) -> i.create(ConfigDef.class, c)); - - builder.addConversion(ItemStackArgument.class, (s, i) -> EssentialUtils.throwAsUnchecked(() -> i.create(ItemStackDef.class, new ScriptItemStack(s.createStack(1, false))))); - builder.addConversion(BlockStateArgument.class, (b, i) -> i.create(BlockDef.class, new ScriptBlockState(b.getBlockState(), null))); - builder.addConversion(Identifier.class, (id, i) -> i.create(StringDef.class, id.toString())); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/BiomeDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/BiomeDef.java deleted file mode 100644 index dc4e7e5c..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/BiomeDef.java +++ /dev/null @@ -1,236 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ParameterDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.BooleanDef; -import me.senseiwells.arucas.builtin.NumberDef; -import me.senseiwells.arucas.builtin.StringDef; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.compiler.LocatableTrace; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.clientscript.core.MinecraftAPI; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptPos; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.biome.Biome; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.BIOME; - -@ClassDoc( - name = BIOME, - desc = "This class represents biomes, and allows you to interact with things inside of them.", - language = Language.Java -) -public class BiomeDef extends CreatableDefinition { - public BiomeDef(Interpreter interpreter) { - super(MinecraftAPI.BIOME, interpreter); - } - - @NotNull - @Override - public String toString(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - Identifier id = EssentialUtils.getRegistryManager().get(RegistryKeys.BIOME).getId(instance.asPrimitive(this)); - return "Biome{id=" + (id == null ? "plains" : id.getPath()) + "}"; - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("canSnow", 3, this::canSnowFull), - MemberFunction.of("canSnow", 1, this::canSnowPos), - MemberFunction.of("isHot", 3, this::isHotFull), - MemberFunction.of("isHot", 1, this::isHotPos), - MemberFunction.of("getFogColor", this::getFogColor), - MemberFunction.of("getTemperature", this::getTemperature), - MemberFunction.of("getWaterColor", this::getWaterColor), - MemberFunction.of("getWaterFogColor", this::getWaterFogColor), - MemberFunction.of("isCold", 1, this::isColdPos), - MemberFunction.of("isCold", 3, this::isColdFull), - MemberFunction.of("getId", this::getId), - MemberFunction.of("getSkyColor", this::getSkyColor) - ); - } - - @FunctionDoc( - name = "canSnow", - desc = "This function calculates whether snow will fall at given coordinates", - params = { - @ParameterDoc(type = NumberDef.class, name = "x", desc = "the x coordinate"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "the y coordinate"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "the z coordinate") - }, - returns = @ReturnDoc(type = BooleanDef.class, desc = "whether snow will fall at given position"), - examples = "biome.canSnow(0, 100, 0);" - ) - private boolean canSnowFull(Arguments arguments) { - Biome biome = arguments.nextPrimitive(this); - int x = arguments.nextPrimitive(NumberDef.class).intValue(); - int y = arguments.nextPrimitive(NumberDef.class).intValue(); - int z = arguments.nextPrimitive(NumberDef.class).intValue(); - BlockPos blockPos = new BlockPos(x, y, z); - return isCold(biome, blockPos); - } - - @FunctionDoc( - name = "canSnow", - desc = "This function calculates whether snow will fall at given coordinates", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "the position")}, - returns = @ReturnDoc(type = BooleanDef.class, desc = "whether snow will fall at given position"), - examples = "biome.canSnow(new Pos(0, 100, 0));" - ) - private boolean canSnowPos(Arguments arguments) { - Biome biome = arguments.nextPrimitive(this); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - return isCold(biome, pos.getBlockPos()); - } - - @FunctionDoc( - name = "isHot", - desc = "This function calculates whether a biome is hot at given position", - params = { - @ParameterDoc(type = NumberDef.class, name = "x", desc = "the x coordinate"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "the y coordinate"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "the z coordinate") - }, - returns = @ReturnDoc(type = BooleanDef.class, desc = "whether temperature is hot at given position"), - examples = "biome.isHot(0, 100, 0);" - ) - private boolean isHotFull(Arguments arguments) { - Biome biome = arguments.nextPrimitive(this); - int x = arguments.nextPrimitive(NumberDef.class).intValue(); - int y = arguments.nextPrimitive(NumberDef.class).intValue(); - int z = arguments.nextPrimitive(NumberDef.class).intValue(); - return isHot(biome, new BlockPos(x, y, z)); - } - - @FunctionDoc( - name = "isHot", - desc = "This function calculates whether a biome is hot at given position", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "the position")}, - returns = @ReturnDoc(type = BooleanDef.class, desc = "whether temperature is hot at given position"), - examples = "biome.isHot(0, 100, 0);" - ) - private boolean isHotPos(Arguments arguments) { - Biome biome = arguments.nextPrimitive(this); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - return isHot(biome, pos.getBlockPos()); - } - - @FunctionDoc( - name = "isCold", - desc = "This function calculates whether biome is cold at given position", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "the position")}, - returns = @ReturnDoc(type = BooleanDef.class, desc = "whether temperature is cold at given position"), - examples = "biome.isCold(0, 100, 0);" - ) - private boolean isColdPos(Arguments arguments) { - Biome biome = arguments.nextPrimitive(this); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - return isCold(biome, pos.getBlockPos()); - } - - @FunctionDoc( - name = "isCold", - desc = "This function calculates whether biome is cold at given position", - params = { - @ParameterDoc(type = NumberDef.class, name = "x", desc = "the x coordinate"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "the y coordinate"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "the z coordinate") - }, - returns = @ReturnDoc(type = BooleanDef.class, desc = "whether temperature is cold at given position"), - examples = "biome.isCold(0, 100, 0);" - ) - private boolean isColdFull(Arguments arguments) { - Biome biome = arguments.nextPrimitive(this); - int x = arguments.nextPrimitive(NumberDef.class).intValue(); - int y = arguments.nextPrimitive(NumberDef.class).intValue(); - int z = arguments.nextPrimitive(NumberDef.class).intValue(); - return isCold(biome, new BlockPos(x, y, z)); - } - - @FunctionDoc( - name = "getFogColor", - desc = "This function returns fog color of the biome", - returns = @ReturnDoc(type = NumberDef.class, desc = "fog color of the biome"), - examples = "biome.getFogColor();" - ) - private int getFogColor(Arguments arguments) { - Biome biome = arguments.nextPrimitive(this); - return biome.getFogColor(); - } - - @FunctionDoc( - name = "getTemperature", - desc = "This function returns temperature of the biome", - returns = @ReturnDoc(type = NumberDef.class, desc = "temperature of the biome"), - examples = "biome.getTemperature();" - ) - private float getTemperature(Arguments arguments) { - Biome biome = arguments.nextPrimitive(this); - return biome.getTemperature(); - } - - @FunctionDoc( - name = "getWaterColor", - desc = "This function returns Fog color of the biome", - returns = @ReturnDoc(type = NumberDef.class, desc = "fog color of the biome"), - examples = "biome.getWaterColor();" - ) - private int getWaterColor(Arguments arguments) { - Biome biome = arguments.nextPrimitive(this); - return biome.getWaterColor(); - } - - @FunctionDoc( - name = "getWaterFogColor", - desc = "This function returns water fog color of the biome", - returns = @ReturnDoc(type = NumberDef.class, desc = "water fog color of the biome"), - examples = "biome.getWaterFogColor();" - ) - private int getWaterFogColor(Arguments arguments) { - Biome biome = arguments.nextPrimitive(this); - return biome.getWaterFogColor(); - } - - @FunctionDoc( - name = "getId", - desc = "This function returns the path id of the biome, e.g. 'plains'", - returns = @ReturnDoc(type = StringDef.class, desc = "id of the biome"), - examples = "biome.getId();" - ) - private String getId(Arguments arguments) { - Biome biome = arguments.nextPrimitive(this); - Identifier id = EssentialUtils.getRegistryManager().get(RegistryKeys.BIOME).getId(biome); - return id == null ? "plains" : id.getPath(); - } - - @FunctionDoc( - name = "getSkyColor", - desc = "This function returns sky color of the biome", - returns = @ReturnDoc(type = NumberDef.class, desc = "sky color of the biome"), - examples = "biome.getSkyColor();" - ) - private int getSkyColor(Arguments arguments) { - Biome biome = arguments.nextPrimitive(this); - return biome.getSkyColor(); - } - - private static boolean isCold(Biome biome, BlockPos pos) { - return biome.isCold(pos); - } - - private static boolean isHot(Biome biome, BlockPos pos) { - return biome.getTemperature() > 1.0F; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/BlockDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/BlockDef.java deleted file mode 100644 index ef36fa1d..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/BlockDef.java +++ /dev/null @@ -1,552 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ParameterDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.*; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.compiler.LocatableTrace; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.BuiltInFunction; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.impl.ArucasList; -import me.senseiwells.arucas.utils.impl.ArucasMap; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.ClientScriptUtils; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptBlockState; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptMaterial; -import net.minecraft.block.BlockEntityProvider; -import net.minecraft.block.BlockState; -import net.minecraft.block.SideShapeType; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityType; -import net.minecraft.item.Item; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.registry.Registries; -import net.minecraft.registry.tag.BlockTags; -import net.minecraft.state.property.EnumProperty; -import net.minecraft.state.property.Property; -import net.minecraft.util.BlockMirror; -import net.minecraft.util.BlockRotation; -import net.minecraft.util.StringIdentifiable; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.world.EmptyBlockView; -import org.jetbrains.annotations.NotNull; - -import java.util.List; -import java.util.Optional; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.BLOCK; -import static me.senseiwells.essentialclient.utils.clientscript.ClientScriptUtils.warnMainThread; - -@ClassDoc( - name = BLOCK, - desc = "This class allows interactions with blocks in Minecraft.", - superclass = MaterialDef.class, - language = Language.Java -) -public class BlockDef extends CreatableDefinition { - public BlockDef(Interpreter interpreter) { - super(BLOCK, interpreter); - } - - @NotNull - @Override - public PrimitiveDefinition superclass() { - return this.getPrimitiveDef(MaterialDef.class); - } - - @Override - public Object asJavaValue(ClassInstance instance) { - return instance.asPrimitive(this).asDefault(); - } - - @Override - public boolean equals(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull ClassInstance other, @NotNull LocatableTrace trace) { - ScriptBlockState state = other.getPrimitive(this); - return state != null && instance.asPrimitive(this).state.equals(state.state); - } - - @Override - public int hashCode(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - return instance.asPrimitive(this).state.hashCode(); - } - - @NotNull - @Override - public String toString(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - return "Block{id=" + instance.asPrimitive(this).getId().getPath() + "}"; - } - - @Override - public List defineStaticMethods() { - return List.of( - BuiltInFunction.of("of", 1, this::of) - ); - } - - @FunctionDoc( - isStatic = true, - name = "of", - desc = "This creates a Block from a material or string", - params = {@ParameterDoc(type = MaterialDef.class, name = "material", desc = "the material, item stack, block, or string to create the Block from")}, - returns = @ReturnDoc(type = BlockDef.class, desc = "the Block created from the material or string"), - examples = "Block.of(Material.STONE);" - ) - private BlockState of(Arguments arguments) { - if (arguments.isNext(StringDef.class)) { - String id = arguments.nextPrimitive(StringDef.class); - return Registries.BLOCK.getOrEmpty(ClientScriptUtils.stringToIdentifier(id)).orElseThrow( - () -> new RuntimeError("'%s' is not a value block".formatted(id)) - ).getDefaultState(); - } - if (arguments.isNext(MaterialDef.class)) { - ScriptMaterial material = arguments.nextPrimitive(MaterialDef.class); - return material.asBlockState(); - } - throw new RuntimeError("Parameter must be of type String or Material"); - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("getMaterial", this::getMaterial), - MemberFunction.of("getDefaultState", this::getDefaultState), - MemberFunction.of("with", 2, this::with), - MemberFunction.of("isBlockEntity", this::isBlockEntity), - MemberFunction.of("isTransparent", this::isTransparent), - MemberFunction.of("getBlastResistance", this::getBlastResistance), - MemberFunction.of("getBlockProperties", this::getBlockProperties), - MemberFunction.of("hasBlockPosition", this::hasBlockPosition), - MemberFunction.of("getPos", this::getPos), - MemberFunction.of("getX", this::getBlockX), - MemberFunction.of("getZ", this::getBlockZ), - MemberFunction.of("getY", this::getBlockY), - MemberFunction.of("offset", 1, this::offset), - MemberFunction.of("offset", 2, this::offset2), - MemberFunction.of("isSolidBlock", this::isSolidBlock), - MemberFunction.of("rotateYClockwise", this::rotateYClockwise), - MemberFunction.of("rotateYCounterClockwise", this::rotateYCounterClockwise), - MemberFunction.of("mirrorFrontBack", this::mirrorFrontBack), - MemberFunction.of("mirrorLeftRight", this::mirrorLeftRight), - MemberFunction.of("isFluid", this::isFluid), - MemberFunction.of("isFluidSource", this::isFluidSource), - MemberFunction.of("isReplaceable", this::isReplaceable), - MemberFunction.of("getHardness", this::getHardness), - MemberFunction.of("sideCoversSmallSquare", 1, this::sideCoversSmallSquare), - MemberFunction.of("isSideSolidFullSquare", 1, this::isSideSolidFullSquare), - MemberFunction.of("isSpawnable", this::allowsSpawning), - MemberFunction.of("isSpawnable", 1, this::allowsSpawningType), - MemberFunction.of("getLuminance", this::getLuminance), - MemberFunction.of("getMapColour", this::getMapColour), - MemberFunction.of("getMapColor", this::getMapColour), - MemberFunction.of("getBlockEntityNbt", this::getBlockNbt) - ); - } - - @FunctionDoc( - name = "getMaterial", - desc = "This gets the material of the Block", - returns = @ReturnDoc(type = MaterialDef.class, desc = "the material of the Block"), - examples = "block.getMaterial();" - ) - private Object getMaterial(Arguments arguments) { - ScriptBlockState blockState = arguments.nextPrimitive(this); - Item item = Item.BLOCK_ITEMS.get(blockState.asBlock()); - return item == null ? blockState.asBlock() : item; - } - - @FunctionDoc( - name = "getDefaultState", - desc = "This gets the default state of the block, it will conserve any positions", - returns = @ReturnDoc(type = BlockDef.class, desc = "default state of the Block"), - examples = "block.getDefaultState();" - ) - private Object getDefaultState(Arguments arguments) { - ScriptBlockState blockState = arguments.nextPrimitive(this); - return new ScriptBlockState(blockState.asBlock().getDefaultState(), blockState.pos); - } - - @FunctionDoc( - name = "with", - desc = "This gets modified block with a property value, conserving positions", - params = { - @ParameterDoc(type = StringDef.class, name = "property", desc = "property name, such as 'facing', 'extended'"), - @ParameterDoc(type = StringDef.class, name = "value", desc = "value name, such as 'north', 'true'") - }, - returns = @ReturnDoc(type = BlockDef.class, desc = "new state of the Block"), - examples = "block.with('facing', 'north');" - ) - private Object with(Arguments arguments) { - ScriptBlockState blockState = arguments.nextPrimitive(this); - String propertyAsString = arguments.nextPrimitive(StringDef.class); - - Property property = blockState.asBlock().getStateManager().getProperty(propertyAsString); - if (property == null) { - throw new RuntimeError("Property %s is not defined in block".formatted(propertyAsString)); - } - - String value = arguments.nextPrimitive(StringDef.class); - BlockState state = this.getStateWith(blockState.state, property, value); - if (state == null) { - throw new RuntimeError("Property %s with value %s is not defined in block".formatted(propertyAsString, value)); - } - - return new ScriptBlockState(state, blockState.pos); - } - - @FunctionDoc( - name = "isBlockEntity", - desc = "This checks if the Block is a BlockEntity", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the Block is a BlockEntity"), - examples = "block.isBlockEntity();" - ) - private Object isBlockEntity(Arguments arguments) { - return arguments.nextPrimitive(this).asBlock() instanceof BlockEntityProvider; - } - - @FunctionDoc( - name = "isTransparent", - desc = "This checks if the Block is transparent", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the Block is transparent"), - examples = "block.isTransparent();" - ) - private Object isTransparent(Arguments arguments) { - return !arguments.nextPrimitive(this).state.isOpaque(); - } - - @FunctionDoc( - name = "getBlastResistance", - desc = "This gets the blast resistance of the Block", - returns = @ReturnDoc(type = NumberDef.class, desc = "the blast resistance of the Block"), - examples = "block.getBlastResistance();" - ) - private Object getBlastResistance(Arguments arguments) { - return arguments.nextPrimitive(this).asBlock().getBlastResistance(); - } - - @FunctionDoc( - name = "getBlockProperties", - desc = { - "This gets the properties of the Block", - "You can find a list of all block properties", - "[here](https://minecraft.fandom.com/wiki/Java_Edition_data_values#Block_states)" - }, - returns = @ReturnDoc(type = MapDef.class, desc = "the properties of the Block, may be empty if there are no properties"), - examples = "block.getBlockProperties();" - ) - private Object getBlockProperties(Arguments arguments) { - ScriptBlockState blockState = arguments.nextPrimitive(this); - ArucasMap propertyMap = new ArucasMap(); - Interpreter interpreter = arguments.getInterpreter(); - blockState.state.getEntries().forEach((p, c) -> { - Object value = p instanceof EnumProperty ? ((StringIdentifiable) c).asString() : c; - propertyMap.put(interpreter, interpreter.create(StringDef.class, p.getName()), interpreter.convertValue(value)); - }); - return propertyMap; - } - - @FunctionDoc( - name = "hasBlockPosition", - desc = "This checks if the Block has a position or not", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the Block has a position"), - examples = "block.hasBlockPosition();" - ) - private Object hasBlockPosition(Arguments arguments) { - return arguments.nextPrimitive(this).pos != null; - } - - @FunctionDoc( - name = "getPos", - desc = "This gets the position of the Block", - returns = @ReturnDoc(type = PosDef.class, desc = "the position of the Block, may be null if the Block has no position"), - examples = "block.getPos();" - ) - private Object getPos(Arguments arguments) { - return arguments.nextPrimitive(this).pos; - } - - @FunctionDoc( - name = "getX", - desc = "This gets the X position of the Block", - returns = @ReturnDoc(type = NumberDef.class, desc = "the X position of the Block, may be null if the Block has no position"), - examples = "block.getX();" - ) - private Object getBlockX(Arguments arguments) { - BlockPos pos = arguments.nextPrimitive(this).pos; - return pos == null ? null : pos.getX(); - } - - @FunctionDoc( - name = "getY", - desc = "This gets the Y position of the Block", - returns = @ReturnDoc(type = NumberDef.class, desc = "the Y position of the Block, may be null if the Block has no position"), - examples = "block.getY();" - ) - private Object getBlockY(Arguments arguments) { - BlockPos pos = arguments.nextPrimitive(this).pos; - return pos == null ? null : pos.getY(); - } - - @FunctionDoc( - name = "offset", - desc = "This gets a block with a given offset, this will throw if the block has no position", - params = {@ParameterDoc(type = PosDef.class, name = "offset", desc = "the position offset to add to the block's current position")}, - returns = @ReturnDoc(type = BlockDef.class, desc = "the block at the offset position"), - examples = "block.offset(new Pos(0, 1, 0));" - ) - private Object offset(Arguments arguments) { - warnMainThread("offset", arguments.getInterpreter()); - ScriptBlockState state = this.ensurePosition(arguments); - BlockPos offset = arguments.nextPrimitive(PosDef.class).getBlockPos(); - BlockPos newPos = state.pos.add(offset); - return new ScriptBlockState(EssentialUtils.getWorld().getBlockState(newPos), newPos); - } - - @FunctionDoc( - name = "offset", - desc = "This gets a block with a given offset, this will throw if the block has no position", - params = { - @ParameterDoc(type = StringDef.class, name = "direction", desc = "the direction of the offset"), - @ParameterDoc(type = NumberDef.class, name = "distance", desc = "the distance of the offset") - }, - returns = @ReturnDoc(type = BlockDef.class, desc = "the block at the offset position"), - examples = "block.offset('north', 5);" - ) - private Object offset2(Arguments arguments) { - warnMainThread("offset", arguments.getInterpreter()); - ScriptBlockState state = this.ensurePosition(arguments); - Direction direction = ClientScriptUtils.stringToDirection(arguments.nextConstant(), null); - int amount = arguments.nextPrimitive(NumberDef.class).intValue(); - BlockPos newPos = state.pos.offset(direction, amount); - return new ScriptBlockState(EssentialUtils.getWorld().getBlockState(newPos), newPos); - } - - @FunctionDoc( - name = "getZ", - desc = "This gets the Z position of the Block", - returns = @ReturnDoc(type = NumberDef.class, desc = "the Z position of the Block, may be null if the Block has no position"), - examples = "block.getZ();" - ) - private Object getBlockZ(Arguments arguments) { - BlockPos pos = arguments.nextPrimitive(this).pos; - return pos == null ? null : pos.getZ(); - } - - @FunctionDoc( - name = "isSolidBlock", - desc = "This checks if the Block is a solid block", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the Block is a solid block"), - examples = "block.isSolidBlock();" - ) - private Object isSolidBlock(Arguments arguments) { - ScriptBlockState blockState = this.ensurePosition(arguments); - return blockState.state.isSolidBlock(EmptyBlockView.INSTANCE, BlockPos.ORIGIN); - } - - @FunctionDoc( - name = "rotateYClockwise", - desc = "This rotates the Block 90 degrees clockwise", - returns = @ReturnDoc(type = BlockDef.class, desc = "the rotated Block"), - examples = "block.rotateYClockwise();" - ) - private Object rotateYClockwise(Arguments arguments) { - ScriptBlockState blockState = arguments.nextPrimitive(this); - return blockState.state.rotate(BlockRotation.CLOCKWISE_90); - } - - @FunctionDoc( - name = "rotateYCounterClockwise", - desc = "This rotates the Block 90 degrees counter-clockwise", - returns = @ReturnDoc(type = BlockDef.class, desc = "the rotated Block"), - examples = "block.rotateYCounterClockwise();" - ) - private Object rotateYCounterClockwise(Arguments arguments) { - ScriptBlockState blockState = arguments.nextPrimitive(this); - return blockState.state.rotate(BlockRotation.COUNTERCLOCKWISE_90); - } - - @FunctionDoc( - name = "mirrorFrontBack", - desc = "This mirrors the Block around the front and back", - returns = @ReturnDoc(type = BlockDef.class, desc = "the mirrored Block"), - examples = "block.mirrorFrontBack();" - ) - private Object mirrorFrontBack(Arguments arguments) { - ScriptBlockState blockState = arguments.nextPrimitive(this); - return blockState.state.mirror(BlockMirror.FRONT_BACK); - } - - @FunctionDoc( - name = "mirrorLeftRight", - desc = "This mirrors the Block around the left and right", - returns = @ReturnDoc(type = BlockDef.class, desc = "the mirrored Block"), - examples = "block.mirrorLeftRight();" - ) - private Object mirrorLeftRight(Arguments arguments) { - ScriptBlockState blockState = arguments.nextPrimitive(this); - return blockState.state.mirror(BlockMirror.LEFT_RIGHT); - } - - @FunctionDoc( - name = "isFluid", - desc = "This checks if the Block is a fluid", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the Block is a fluid"), - examples = "block.isFluid();" - ) - private Object isFluid(Arguments arguments) { - ScriptBlockState blockState = arguments.nextPrimitive(this); - return !blockState.state.getFluidState().isEmpty(); - } - - @FunctionDoc( - name = "isFluidSource", - desc = "This checks if the Block is a fluid source", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the Block is a fluid source"), - examples = "block.isFluidSource();" - ) - private Object isFluidSource(Arguments arguments) { - ScriptBlockState blockState = arguments.nextPrimitive(this); - return blockState.state.getFluidState().isStill(); - } - - @FunctionDoc( - name = "isReplaceable", - desc = "This checks if the Block is replaceable", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the Block is replaceable"), - examples = "block.isReplaceable();" - ) - private Object isReplaceable(Arguments arguments) { - ScriptBlockState blockState = arguments.nextPrimitive(this); - return blockState.state.isReplaceable(); - } - - @FunctionDoc( - name = "getHardness", - desc = "This gets the hardness of the Block", - returns = @ReturnDoc(type = NumberDef.class, desc = "the hardness of the Block"), - examples = "block.getHardness();" - ) - private Object getHardness(Arguments arguments) { - ScriptBlockState blockState = arguments.nextPrimitive(this); - return blockState.state.getHardness(EmptyBlockView.INSTANCE, BlockPos.ORIGIN); - } - - @FunctionDoc( - name = "sideCoversSmallSquare", - desc = "This checks if the Block covers a small square", - params = {@ParameterDoc(type = StringDef.class, name = "side", desc = "the side to check, for example: 'north', 'south', 'east', 'west', 'up', 'down'")}, - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the Block covers a small square"), - examples = "block.sideCoversSmallSquare('north');" - ) - private Object sideCoversSmallSquare(Arguments arguments) { - ScriptBlockState state = arguments.nextPrimitive(this); - String stringDirection = arguments.nextConstant(); - Direction direction = ClientScriptUtils.stringToDirection(stringDirection, Direction.DOWN); - boolean isSmallSquare = direction != Direction.DOWN || !state.state.isIn(BlockTags.UNSTABLE_BOTTOM_CENTER); - return isSmallSquare && state.state.isSideSolid(EmptyBlockView.INSTANCE, BlockPos.ORIGIN, direction, SideShapeType.CENTER); - } - - @FunctionDoc( - name = "isSideSolidFullSquare", - desc = "This checks if the Block is solid on the full square", - params = {@ParameterDoc(type = StringDef.class, name = "side", desc = "the side to check, for example: 'north', 'south', 'east', 'west', 'up', 'down'")}, - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the Block is solid on the full square"), - examples = "block.isSideSolidFullSquare('north');" - ) - private Object isSideSolidFullSquare(Arguments arguments) { - ScriptBlockState state = arguments.nextPrimitive(this); - String stringDirection = arguments.nextConstant(); - Direction direction = ClientScriptUtils.stringToDirection(stringDirection, Direction.DOWN); - return state.state.isSideSolidFullSquare(EmptyBlockView.INSTANCE, BlockPos.ORIGIN, direction); - } - - @FunctionDoc( - name = "isSpawnable", - desc = "This checks if the Block is spawnable in the case of zombies", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the Block is spawnable in the case of zombies"), - examples = "block.isSpawnable();" - ) - private Object allowsSpawning(Arguments arguments) { - ScriptBlockState state = arguments.nextPrimitive(this); - return state.state.allowsSpawning(EmptyBlockView.INSTANCE, BlockPos.ORIGIN, EntityType.ZOMBIE); - } - - @FunctionDoc( - name = "isSpawnable", - desc = "This checks if the Block allows spawning for given entity", - params = {@ParameterDoc(type = EntityDef.class, name = "entity", desc = "the entity to check")}, - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the Block allows spawning for given entity"), - examples = "block.isSpawnable(zombie);" - ) - private Object allowsSpawningType(Arguments arguments) { - ScriptBlockState state = arguments.nextPrimitive(this); - Entity entity = arguments.nextPrimitive(EntityDef.class); - return state.state.allowsSpawning(EmptyBlockView.INSTANCE, BlockPos.ORIGIN, entity.getType()); - } - - @FunctionDoc( - name = "getLuminance", - desc = "This gets the luminance of the Block", - returns = @ReturnDoc(type = NumberDef.class, desc = "the luminance of the Block"), - examples = "block.getLuminance();" - ) - private Object getLuminance(Arguments arguments) { - ScriptBlockState blockState = arguments.nextPrimitive(this); - return blockState.state.getLuminance(); - } - - @FunctionDoc( - name = "getMapColour", - desc = "This gets the map colour of the Block, can also be called with 'getMapColor'", - returns = @ReturnDoc(type = ListDef.class, desc = "a list with the map colour of the Block as RGB values"), - examples = "block.getMapColour();" - ) - private Object getMapColour(Arguments arguments) { - ScriptBlockState blockState = arguments.nextPrimitive(this); - int colour = blockState.state.getMapColor(EmptyBlockView.INSTANCE, BlockPos.ORIGIN).color; - Interpreter interpreter = arguments.getInterpreter(); - return ArucasList.of( - interpreter.create(NumberDef.class, (double) ((colour & 0xFF0000) >> 16)), - interpreter.create(NumberDef.class, (double) ((colour & 0xFF00) >> 8)), - interpreter.create(NumberDef.class, (double) (colour & 0xFF)) - ); - } - - @FunctionDoc( - name = "getBlockEntityNbt", - desc = "This gets the NBT of a block entity", - returns = @ReturnDoc(type = MapDef.class, desc = "the NBT of a block entity, may be null if the block entity has no NBT"), - examples = "block.getBlockEntityNbt();" - ) - private Object getBlockNbt(Arguments arguments) { - ScriptBlockState blockState = this.ensurePosition(arguments); - BlockEntity blockEntity = EssentialUtils.getWorld().getBlockEntity(blockState.pos); - if (blockEntity != null) { - NbtCompound compound = blockEntity.createNbt(EssentialUtils.getWorld().getRegistryManager()); - return ClientScriptUtils.nbtToMap(arguments.getInterpreter(), compound, 10); - } - return null; - } - - private ScriptBlockState ensurePosition(Arguments arguments) { - ScriptBlockState blockState = arguments.nextPrimitive(this); - if (blockState.pos == null) { - throw new RuntimeError("Block does not have position"); - } - return blockState; - } - - private > BlockState getStateWith(BlockState blockState, Property property, String value) { - Optional optional = property.parse(value); - return optional.map(t -> blockState.with(property, t)).orElse(null); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/CommandBuilderDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/CommandBuilderDef.java deleted file mode 100644 index 8b997b62..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/CommandBuilderDef.java +++ /dev/null @@ -1,252 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import com.mojang.brigadier.builder.ArgumentBuilder; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import com.mojang.brigadier.builder.RequiredArgumentBuilder; -import com.mojang.brigadier.context.ParsedArgument; -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ParameterDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.FunctionDef; -import me.senseiwells.arucas.builtin.ListDef; -import me.senseiwells.arucas.builtin.MapDef; -import me.senseiwells.arucas.builtin.StringDef; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.functions.ArucasFunction; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.BuiltInFunction; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.impl.ArucasList; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.clientscript.core.MinecraftAPI; -import me.senseiwells.essentialclient.utils.clientscript.ClientScriptUtils; -import me.senseiwells.essentialclient.utils.command.CommandHelper; -import net.minecraft.server.command.CommandManager; -import net.minecraft.server.command.ServerCommandSource; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.COMMAND_BUILDER; - -@ClassDoc( - name = COMMAND_BUILDER, - desc = "This class allows you to build commands for Minecraft.", - language = Language.Java -) -public class CommandBuilderDef extends CreatableDefinition> { - public CommandBuilderDef(Interpreter interpreter) { - super(MinecraftAPI.COMMAND_BUILDER, interpreter); - } - - @Override - public List defineStaticMethods() { - return List.of( - BuiltInFunction.of("literal", 1, this::literal), - BuiltInFunction.of("argument", 2, this::argument2), - BuiltInFunction.of("argument", 3, this::argument3), - BuiltInFunction.of("fromMap", 1, this::fromMap) - ); - } - - @FunctionDoc( - isStatic = true, - name = "literal", - desc = "Creates a literal argument with just a string", - params = @ParameterDoc(type = StringDef.class, name = "argument", desc = "the literal argument"), - returns = @ReturnDoc(type = CommandBuilderDef.class, desc = "the argument builder"), - examples = "CommandBuilder.literal('test');" - ) - private LiteralArgumentBuilder literal(Arguments arguments) { - String name = arguments.nextPrimitive(StringDef.class); - return CommandManager.literal(name); - } - - @FunctionDoc( - isStatic = true, - name = "argument", - desc = { - "Creates an argument builder with a specific argument type, and a name", - "to see all the different types refer to CommandBuilder.fromMap(...)" - }, - params = { - @ParameterDoc(type = StringDef.class, name = "argumentName", desc = "the name of the argument"), - @ParameterDoc(type = StringDef.class, name = "argumentType", desc = "the type of the argument") - }, - returns = @ReturnDoc(type = CommandBuilderDef.class, desc = "the argument builder"), - examples = "CommandBuilder.argument('test', 'entityid');" - ) - private RequiredArgumentBuilder argument2(Arguments arguments) { - String name = arguments.nextPrimitive(StringDef.class); - String type = arguments.nextPrimitive(StringDef.class); - return this.argument(arguments.getInterpreter(), name, type, null); - } - - @FunctionDoc( - isStatic = true, - name = "argument", - desc = { - "Creates an argument builder with a specific argument type, a name, and a default value", - "to see all the different types refer to CommandBuilder.fromMap(...)" - }, - params = { - @ParameterDoc(type = StringDef.class, name = "argumentName", desc = "the name of the argument"), - @ParameterDoc(type = StringDef.class, name = "argumentType", desc = "the type of the argument"), - @ParameterDoc(type = ListDef.class, name = "suggestions", desc = "a list of strings for the suggestions for the argument") - }, - returns = @ReturnDoc(type = CommandBuilderDef.class, desc = "the argument builder"), - examples = "CommandBuilder.argument('test', 'word', ['wow', 'suggestion']);" - ) - private RequiredArgumentBuilder argument3(Arguments arguments) { - String name = arguments.nextPrimitive(StringDef.class); - String type = arguments.nextPrimitive(StringDef.class); - ArucasList suggestions = arguments.nextPrimitive(ListDef.class); - return this.argument(arguments.getInterpreter(), name, type, suggestions); - } - - @FunctionDoc( - isStatic = true, - name = "fromMap", - desc = { - "Creates an argument builder from a map.", - "The map must contain a 'name' key as a String that is the name of the command,", - "the map then can contain 'subcommands' as a map which contains the subcommands,", - "the key of the subcommands is the name of the subcommand, and the value is a map,", - "if the name is encased in '<' and '>' it will be treated as an argument, otherwise it will be treated as a literal.", - "You can chain arguments by leaving a space in the name like: 'literal '.", - "If the key has no name and is just an empty string the value will be used as the function", - "which will be executed when the command is executed, the function should have the appropriate", - "number of parameters, the number of parameters is determined by the number of arguments.", - "Argument types are defined in the main map under the key 'arguments' with the value of a map", - "the keys of this map should be the names of your arguments used in your subcommands,", - "this should be a map and must have the key 'type' which should be a string that is the type of the argument.", - "Optionally if the type is of 'integer' or 'double' you can also have the key 'min' and 'max' with numbers as the value,", - "and if the type is of 'enum' you must have the key 'enum' with the enum class type as the value: 'enum': MyEnum.type.", - "You can also optionally have 'suggests' which has the value of a list of strings that are suggestions for the argument.", - "You can also optionally have 'suggester' which has the value of a function that will be called to get suggestions for the argument,", - "this function should have arbitrary number of parameters which will be the arguments that the user has entered so far.", - "The possible argument types are: 'PlayerName', 'Word' 'String', 'GreedyString', 'Double', 'Integer', 'Boolean', 'Enum',", - "'ItemStack', 'Block', 'Particle', 'RecipeId', 'EntityId', 'EnchantmentId', 'Entity', 'Entities', 'BlockPos', 'Pos', 'Effect',", - "'BiomeId'." - }, - params = {@ParameterDoc(type = MapDef.class, name = "argumentMap", desc = "the map of arguments")}, - returns = @ReturnDoc(type = CommandBuilderDef.class, desc = "the argument builder"), - examples = """ - effectCommandMap = { - "name" : "effect", - "subcommands" : { - "give" : { - " " : { - "" : fun(target, effect) { - // do something - }, - "" : { - "" : fun(target, effect, second) { - // do something - }, - "" : { - "" : fun(target, effect, second, amplifier) { - // do something - }, - "" : { - "" : fun(target, effect, second, amplifier, hideParticle) { - // do something - } - } - } - } - } - }, - "clear" : { - "" : fun() { - // do something - }, - "" : { - "" : fun(target) { - // do something - }, - "" : { - "" : fun(target, effect) { - // do something - } - } - } - } - }, - "arguments" : { - "targets" : { "type" : "Entity" }, - "effect" : { "type" : "Effect", "suggests" : ["effect1", "effect2"] }, - "seconds" : { "type" : "Integer", "min" : 0, "max" : 1000000 }, - "amplifier" : { "type" : "Integer", "min" : 0, "max" : 255 }, - "hideParticle" : { "type" : "Boolean" } - } - }; - effectCommand = CommandBuilder.fromMap(effectCommandMap); - """ - ) - private ArgumentBuilder fromMap(Arguments arguments) { - return ClientScriptUtils.mapToCommand(arguments.nextPrimitive(MapDef.class), arguments.getInterpreter()); - } - - private RequiredArgumentBuilder argument(Interpreter interpreter, String name, String stringArgType, ArucasList suggestions) { - List suggests = suggestions == null ? null : suggestions.stream().map(i -> i.toString(interpreter)).toList(); - return ClientScriptUtils.parseArgument(name, stringArgType, suggests, null); - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("then", 1, this::then), - MemberFunction.of("executes", 1, this::executes) - ); - } - - @FunctionDoc( - name = "then", - desc = "This adds a child CommandBuilder to your command builder", - params = {@ParameterDoc(type = CommandBuilderDef.class, name = "childBuilder", desc = "the child command builder to add")}, - returns = @ReturnDoc(type = CommandBuilderDef.class, desc = "the parent command builder"), - examples = "commandBuilder.then(CommandBuilder.literal('subcommand'));" - ) - private ClassInstance then(Arguments arguments) { - ClassInstance instance = arguments.next(this); - instance.asPrimitive(this).then(arguments.nextPrimitive(this)); - return instance; - } - - @FunctionDoc( - name = "executes", - desc = { - "This sets the function to be executed when the command is executed,", - "this should have the correct amount of parameters for the command" - }, - params = {@ParameterDoc(type = CommandBuilderDef.class, name = "function", desc = "the function to execute")}, - returns = @ReturnDoc(type = CommandBuilderDef.class, desc = "the parent command builder"), - examples = "commandBuilder.executes(fun() { });" - ) - private ClassInstance executes(Arguments arguments) { - ClassInstance instance = arguments.next(this); - ArucasFunction function = arguments.nextPrimitive(FunctionDef.class); - Interpreter interpreter = arguments.getInterpreter().branch(); - instance.asPrimitive(this).executes(c -> { - Collection> args = CommandHelper.getArguments(c); - if (args == null) { - throw ClientScriptUtils.CommandParser.NO_ARGS.create(); - } - List list = new ArrayList<>(args.size()); - for (ParsedArgument argument : args) { - list.add(ClientScriptUtils.commandArgumentToValue(argument.getResult(), interpreter)); - } - interpreter.runAsync(() -> { - function.invoke(interpreter.branch(), list); - return null; - }); - return 1; - }); - return instance; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/ConfigDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/ConfigDef.java deleted file mode 100644 index a4b9cc57..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/ConfigDef.java +++ /dev/null @@ -1,291 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import com.google.gson.JsonElement; -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ParameterDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.*; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.compiler.LocatableTrace; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.extensions.JsonDef; -import me.senseiwells.arucas.functions.ArucasFunction; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.BuiltInFunction; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.impl.ArucasList; -import me.senseiwells.arucas.utils.impl.ArucasMap; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.clientscript.core.MinecraftAPI; -import me.senseiwells.essentialclient.rule.client.ClientRule; -import me.senseiwells.essentialclient.utils.clientscript.ClientScriptUtils; -import me.senseiwells.essentialclient.utils.interfaces.Rule; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.CONFIG; - -@ClassDoc( - name = CONFIG, - desc = "This class allows you to create configs for your scripts", - language = Language.Java -) -public class ConfigDef extends CreatableDefinition> { - public ConfigDef(Interpreter interpreter) { - super(MinecraftAPI.CONFIG, interpreter); - } - - @NotNull - @Override - public String toString(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - ClientRule rule = instance.asPrimitive(this); - return "Config{name=" + rule.getName() + ", value=" + rule.getValue() + "}"; - } - - @Override - public List defineStaticMethods() { - return List.of( - BuiltInFunction.of("fromMap", 1, this::fromMap), - BuiltInFunction.of("fromListOfMap", 1, this::fromListOfMap) - ); - } - - @FunctionDoc( - isStatic = true, - name = "fromMap", - desc = { - "Creates a config from a map", - "The map must contain the following keys:", - "'type' which is the type of the config which can be 'boolean', 'cycle', 'double', 'double_slider', 'integer', 'integer_slider', 'list', or 'string',", - "'name' which is the name of the config", - "And can optionally contain the following keys:", - "'description' which is a description of the config,", - "'optional_info' which is an optional info for the config,", - "'default_value' which is the default value of the config,", - "'category' which is the category of the config,", - "'value' which is the current value of the config, ", - "'listener' which is a function that will be called when the config changes, this must have 1 parameter which is the rule that was changed,", - "'max_length' which is the max length for the input of the config, this must be an integer > 0, default is 32", - "And 'cycle' types must contain the following keys:", - "'cycle_values' which is a list of values that the config can cycle through.", - "And slider types must contain the following keys:", - "'min' which is the minimum value of the slider,", - "'max' which is the maximum value of the slider" - }, - params = {@ParameterDoc(type = MapDef.class, name = "map", desc = "The map to create the config from")}, - returns = @ReturnDoc(type = ConfigDef.class, desc = "The config created from the map"), - examples = """ - configMap = { - "type": "string", - "name": "My Config", - "description": "This is my config", - "category": "Useful", - "optional_info": "This is an optional info", - "default_value": "foo", - "value": "bar", - "listener": fun(newValue) { }, - "max_length": 64 - }; - config = Config.fromMap(configMap); - """ - ) - private ClassInstance fromMap(Arguments arguments) { - ArucasMap map = arguments.nextPrimitive(MapDef.class); - return ClientScriptUtils.mapToRule(map, arguments.getInterpreter()); - } - - @FunctionDoc( - isStatic = true, - name = "fromListOfMap", - desc = "Creates a config from a list of config maps", - params = {@ParameterDoc(type = ListDef.class, name = "list", desc = "The list of config maps")}, - returns = @ReturnDoc(type = ListDef.class, desc = "A list of configs created from the list of config maps"), - examples = """ - configs = [ - { - "type": "boolean", - "name": "My Config", - "description": "This is my config" - }, - { - "type": "cycle", - "name": "My Cycle Config", - "description": "This is my cycle config", - "cycle_values": ["one", "two", "three"], - "default_value": "two" - } - ]; - configs = Config.fromListOfMap(configs); - """ - ) - private ArucasList fromListOfMap(Arguments arguments) { - ArucasList list = arguments.nextPrimitive(ListDef.class); - ArucasList configList = new ArucasList(); - for (ClassInstance value : list.toArray()) { - ArucasMap configMap = value.getPrimitive(MapDef.class); - if (configMap == null) { - throw new RuntimeError("List must only contains maps"); - } - configList.add(ClientScriptUtils.mapToRule(configMap, arguments.getInterpreter())); - } - return configList; - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("getName", this::getName), - MemberFunction.of("getType", this::getType), - MemberFunction.of("getDescription", this::getDescription), - MemberFunction.of("getCategory", this::getCategory), - MemberFunction.of("getOptionalInfo", this::getOptionalInfo), - MemberFunction.of("getDefaultValue", this::getDefaultValue), - MemberFunction.of("getValue", this::getValue), - MemberFunction.of("toJson", this::toJson), - MemberFunction.of("resetToDefault", this::resetToDefault), - MemberFunction.of("addListener", 1, this::addListener), - MemberFunction.of("setValue", 1, this::setValue) - ); - } - - @FunctionDoc( - name = "getName", - desc = "Gets the name of the config", - returns = @ReturnDoc(type = StringDef.class, desc = "The name of the config"), - examples = "config.getName();" - ) - private String getName(Arguments arguments) { - return arguments.nextPrimitive(this).getName(); - } - - @FunctionDoc( - name = "getType", - desc = "Gets the type of the config", - returns = @ReturnDoc(type = StringDef.class, desc = "The type of the config"), - examples = "config.getType();" - ) - private String getType(Arguments arguments) { - return arguments.nextPrimitive(this).getTypeAsString(); - } - - @FunctionDoc( - name = "getDescription", - desc = "Gets the description of the config", - returns = @ReturnDoc(type = StringDef.class, desc = "The description of the config"), - examples = "config.getDescription();" - ) - private String getDescription(Arguments arguments) { - return arguments.nextPrimitive(this).getDescription(); - } - - @FunctionDoc( - name = "getCategory", - desc = "Gets the category of the config", - returns = @ReturnDoc(type = StringDef.class, desc = "The category of the config"), - examples = "config.getCategory();" - ) - private String getCategory(Arguments arguments) { - return arguments.nextPrimitive(this).getCategory(); - } - - @FunctionDoc( - name = "getOptionalInfo", - desc = "Gets the optional info of the config", - returns = @ReturnDoc(type = StringDef.class, desc = "The optional info of the config"), - examples = "config.getOptionalInfo();" - ) - private String getOptionalInfo(Arguments arguments) { - return arguments.nextPrimitive(this).getOptionalInfo(); - } - - @FunctionDoc( - name = "getDefaultValue", - desc = "Gets the default value of the config", - returns = @ReturnDoc(type = ObjectDef.class, desc = "The default value of the config"), - examples = "config.getDefaultValue();" - ) - private Object getDefaultValue(Arguments arguments) { - return arguments.nextPrimitive(this).getDefaultValue(); - } - - @FunctionDoc( - name = "getValue", - desc = "Gets the value of the config", - returns = @ReturnDoc(type = ObjectDef.class, desc = "The value of the config"), - examples = "config.getValue();" - ) - private Object getValue(Arguments arguments) { - return arguments.nextPrimitive(this).getValue(); - } - - @FunctionDoc( - name = "toJson", - desc = "Converts the config into a json value, this will not keep the listeners", - returns = @ReturnDoc(type = JsonDef.class, desc = "The config as a json value"), - examples = "config.toJson();" - ) - private JsonElement toJson(Arguments arguments) { - return arguments.nextPrimitive(this).serialise(); - } - - @FunctionDoc( - name = "addListener", - desc = { - "Adds a listener to the config, the listener will be called when the config is changed", - "The listener must have one parameter, this is the new value that was set" - }, - params = {@ParameterDoc(type = FunctionDef.class, name = "listener", desc = "The listener to add")}, - examples = """ - config.addListener(function(newValue) { - print(newValue); - }); - """ - ) - private Void addListener(Arguments arguments) { - ClientRule rule = arguments.nextPrimitive(this); - ArucasFunction listener = arguments.nextPrimitive(FunctionDef.class); - Interpreter interpreter = arguments.getInterpreter().branch(); - rule.addListener(object -> { - Interpreter branch = interpreter.branch(); - listener.invoke(branch, List.of(branch.convertValue(object))); - }); - return null; - } - - @FunctionDoc( - name = "resetToDefault", - desc = "Resets the config to the default value", - examples = "config.resetToDefault();" - ) - private Void resetToDefault(Arguments arguments) { - arguments.nextPrimitive(this).resetToDefault(); - return null; - } - - @FunctionDoc( - name = "setValue", - desc = { - "Sets the value of the config, if the value is invalid it will not be changed", - "If you are modifying a list rule you must pass in a list to this method" - }, - params = {@ParameterDoc(type = ObjectDef.class, name = "value", desc = "The new value of the config")}, - examples = "config.setValue(10);" - ) - private Void setValue(Arguments arguments) { - ClientRule rule = arguments.nextPrimitive(this); - if (rule instanceof Rule.ListRule listRule) { - List values = arguments.nextPrimitive(ListDef.class).stream() - .map(e -> e.toString(arguments.getInterpreter())) - .toList(); - listRule.setValue(values); - return null; - } - ClassInstance value = arguments.next(); - rule.setValueFromString(value.toString(arguments.getInterpreter())); - return null; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/ConfigHandlerDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/ConfigHandlerDef.java deleted file mode 100644 index 3b37cdff..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/ConfigHandlerDef.java +++ /dev/null @@ -1,292 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import kotlin.Unit; -import me.senseiwells.arucas.api.docs.annotations.*; -import me.senseiwells.arucas.builtin.BooleanDef; -import me.senseiwells.arucas.builtin.FileDef; -import me.senseiwells.arucas.builtin.ListDef; -import me.senseiwells.arucas.builtin.StringDef; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.ConstructorFunction; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.impl.ArucasList; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.gui.RulesScreen; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptConfigHandler; -import net.minecraft.text.Text; - -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.CONFIG_HANDLER; - -@ClassDoc( - name = CONFIG_HANDLER, - desc = "This class allows you to easily read and write config files.", - language = Language.Java -) -public class ConfigHandlerDef extends CreatableDefinition { - public ConfigHandlerDef(Interpreter interpreter) { - super(CONFIG_HANDLER, interpreter); - } - - @Override - public List defineConstructors() { - return List.of( - ConstructorFunction.of(1, this::constructor1), - ConstructorFunction.of(2, this::constructor2) - ); - } - - @ConstructorDoc( - desc = "Creates a new ConfigHandler, this is used to read and save configs", - params = {@ParameterDoc(type = StringDef.class, name = "name", desc = "The name of the config, this will also be the name of the config file")}, - examples = "new ConfigHandler('MyConfig');" - ) - private Unit constructor1(Arguments arguments) { - ClassInstance instance = arguments.next(); - String name = arguments.nextPrimitive(StringDef.class); - instance.setPrimitive(this, new ScriptConfigHandler(arguments.getInterpreter(), name, true)); - return null; - } - - @ConstructorDoc( - desc = "Creates a new ConfigHandler, this is used to read and save configs", - params = { - @ParameterDoc(type = StringDef.class, name = "name", desc = "The name of the config, this will also be the name of the config file"), - @ParameterDoc(type = BooleanDef.class, name = "read", desc = "Whether or not to read the config on creation") - }, - examples = "new ConfigHandler('MyConfig', false);" - ) - private Unit constructor2(Arguments arguments) { - ClassInstance instance = arguments.next(); - String name = arguments.nextPrimitive(StringDef.class); - boolean read = arguments.nextPrimitive(BooleanDef.class); - instance.setPrimitive(this, new ScriptConfigHandler(arguments.getInterpreter(), name, read)); - return null; - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("getName", this::getName), - MemberFunction.of("read", this::read), - MemberFunction.of("save", this::save), - MemberFunction.of("setSaveOnClose", 1, this::setSaveOnClose), - MemberFunction.of("willSaveOnClose", this::willSaveOnClose), - MemberFunction.of("setSavePath", 1, this::setSavePath), - MemberFunction.of("addConfig", 1, this::addConfig), - MemberFunction.arb("addConfigs", this::addConfigs), - MemberFunction.of("getConfig", 1, this::getConfig), - MemberFunction.of("removeConfig", 1, this::removeConfig), - MemberFunction.of("resetAllToDefault", this::resetAllToDefault), - MemberFunction.of("getAllConfigs", this::getAllConfigs), - MemberFunction.of("createScreen", this::createScreen0), - MemberFunction.of("createScreen", 1, this::createScreen1), - MemberFunction.of("createScreen", 2, this::createScreen2) - ); - } - - @FunctionDoc( - name = "getName", - desc = "Gets the name of the config", - returns = @ReturnDoc(type = StringDef.class, desc = "The name of the config"), - examples = "configHandler.getName();" - ) - private String getName(Arguments arguments) { - return arguments.nextPrimitive(this).getConfigName(); - } - - @FunctionDoc( - name = "read", - desc = { - "Reads the all the configs from the file", - "If configs are already in the handler, only the values", - "will be overwritten" - }, - examples = "configHandler.read();" - ) - private Void read(Arguments arguments) { - arguments.nextPrimitive(this).readConfig(); - return null; - } - - @FunctionDoc( - name = "save", - desc = "Saves the configs to the file", - examples = "configHandler.save();" - ) - private Void save(Arguments arguments) { - arguments.nextPrimitive(this).saveConfig(); - return null; - } - - @FunctionDoc( - name = "setSaveOnClose", - desc = "Sets whether or not the configs should be saved when the script ends, by default this is true", - params = {@ParameterDoc(type = BooleanDef.class, name = "saveOnClose", desc = "Whether or not the configs should be saved when the script ends")}, - examples = "configHandler.setSaveOnClose(false);" - ) - private Void setSaveOnClose(Arguments arguments) { - arguments.nextPrimitive(this).setSaveOnClose(arguments.nextPrimitive(BooleanDef.class)); - return null; - } - - @FunctionDoc( - name = "willSaveOnClose", - desc = "Gets whether or not the configs will be saved when the script ends", - returns = @ReturnDoc(type = BooleanDef.class, desc = "Whether or not the configs will be saved when the script ends"), - examples = "configHandler.willSaveOnClose();" - ) - private boolean willSaveOnClose(Arguments arguments) { - return arguments.nextPrimitive(this).willSaveOnClose(); - } - - @FunctionDoc( - name = "setSavePath", - desc = "Sets the path to save the configs to, this shouldn't include the file name", - params = {@ParameterDoc(type = FileDef.class, name = "savePath", desc = "The path to save the configs to")}, - examples = "configHandler.setSavePath(new File('/home/user/scripts/'));" - ) - private Void setSavePath(Arguments arguments) { - arguments.nextPrimitive(this).setSavePath(arguments.nextPrimitive(FileDef.class).toPath()); - return null; - } - - @FunctionDoc( - name = "addConfig", - desc = "Adds a config to the handler", - params = {@ParameterDoc(type = ConfigDef.class, name = "config", desc = "The config to add")}, - examples = - """ - config = Config.fromMap({ - "type": "boolean", - "name": "My Config", - "description": "This is my config" - }); - configHandler.addConfig(config); - """ - ) - private Void addConfig(Arguments arguments) { - arguments.nextPrimitive(this).addConfig(arguments.next(ConfigDef.class)); - return null; - } - - @FunctionDoc( - name = "addConfigs", - desc = { - "Adds multiple configs to the handler, you can pass in a list of configs", - "or a varargs of configs, this is for compatability with older scripts" - }, - params = @ParameterDoc(type = ConfigDef.class, name = "configs", desc = "The configs to add", isVarargs = true), - examples = - """ - config = Config.fromMap({ - "type": "boolean", - "name": "My Config", - "description": "This is my config" - }); - configHandler.addConfigs(config, config); - """ - ) - private Void addConfigs(Arguments arguments) { - ScriptConfigHandler handler = arguments.nextPrimitive(this); - if (arguments.size() == 2 && arguments.isNext(ListDef.class)) { - ArucasList list = arguments.nextPrimitive(ListDef.class); - for (ClassInstance instance : list) { - handler.addConfig(instance); - } - } else { - for (ClassInstance instance : arguments.getRemaining()) { - handler.addConfig(instance); - } - } - return null; - } - - @FunctionDoc( - name = "getConfig", - desc = "Gets a config from the handler", - params = {@ParameterDoc(type = StringDef.class, name = "name", desc = "The name of the config")}, - returns = @ReturnDoc(type = ConfigDef.class, desc = "The config"), - examples = "configHandler.getConfig('MyConfig');" - ) - private ClassInstance getConfig(Arguments arguments) { - return arguments.nextPrimitive(this).getConfig(arguments.nextPrimitive(StringDef.class)); - } - - @FunctionDoc( - name = "removeConfig", - desc = "Removes a config from the handler", - params = {@ParameterDoc(type = StringDef.class, name = "name", desc = "The name of the config to remove")}, - examples = "configHandler.removeConfig('My Config');" - ) - private Void removeConfig(Arguments arguments) { - arguments.nextPrimitive(this).removeConfig(arguments.nextPrimitive(StringDef.class)); - return null; - } - - @FunctionDoc( - name = "resetAllToDefault", - desc = "Resets all configs to their default values", - examples = "configHandler.resetAllToDefault();" - ) - private Void resetAllToDefault(Arguments arguments) { - arguments.nextPrimitive(this).resetAllToDefault(); - return null; - } - - @FunctionDoc( - name = "getAllConfigs", - desc = "Gets all the configs in the handler", - returns = @ReturnDoc(type = ListDef.class, desc = "All the configs in the handler"), - examples = "configHandler.getAllConfigs();" - ) - private ArucasList getAllConfigs(Arguments arguments) { - return arguments.nextPrimitive(this).getAllConfigs(); - } - - @FunctionDoc( - name = "createScreen", - desc = { - "Creates a new config screen containing all of the configs in the handler, in alphabetical order.", - "The screen name will be the default, the same as the name of the config handler" - }, - returns = @ReturnDoc(type = ScreenDef.class, desc = "The new config screen"), - examples = "configHandler.createScreen();" - ) - private RulesScreen createScreen0(Arguments arguments) { - ScriptConfigHandler handler = arguments.nextPrimitive(this); - return handler.createScreen(Text.literal(handler.getConfigName()), true); - } - - @FunctionDoc( - name = "createScreen", - desc = "Creates a new config screen containing all of the configs in the handler, in alphabetical order", - params = {@ParameterDoc(type = TextDef.class, name = "title", desc = "The title of the screen")}, - returns = @ReturnDoc(type = ScreenDef.class, desc = "The new config screen"), - examples = "configHandler.createScreen(Text.of('wow'));" - ) - private RulesScreen createScreen1(Arguments arguments) { - return arguments.nextPrimitive(this).createScreen(arguments.nextPrimitive(TextDef.class), true); - } - - @FunctionDoc( - name = "createScreen", - desc = "Creates a new config screen containing all of the configs in the handler", - params = { - @ParameterDoc(type = TextDef.class, name = "title", desc = "The title of the screen"), - @ParameterDoc(type = BooleanDef.class, name = "alphabetical", desc = "Whether or not to sort the configs alphabetically") - }, - returns = @ReturnDoc(type = ScreenDef.class, desc = "The new config screen"), - examples = "configHandler.createScreen(Text.of('wow'), false);" - ) - private RulesScreen createScreen2(Arguments arguments) { - return arguments.nextPrimitive(this).createScreen( - arguments.nextPrimitive(TextDef.class), - arguments.nextPrimitive(BooleanDef.class) - ); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/EntityDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/EntityDef.java deleted file mode 100644 index e7c0c85a..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/EntityDef.java +++ /dev/null @@ -1,624 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ParameterDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.*; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.compiler.LocatableTrace; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.BuiltInFunction; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.impl.ArucasList; -import me.senseiwells.arucas.utils.impl.ArucasMap; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.clientscript.core.MinecraftAPI; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.ClientScriptUtils; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptBlockState; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptPos; -import net.minecraft.block.Blocks; -import net.minecraft.client.resource.language.I18n; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityType; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.registry.Registries; -import net.minecraft.text.Text; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.hit.HitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Box; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.RaycastContext; -import net.minecraft.world.biome.Biome; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.ENTITY; - -@ClassDoc( - name = ENTITY, - desc = "This class is mostly used to get data about entities.", - language = Language.Java -) -public class EntityDef extends PrimitiveDefinition { - public EntityDef(Interpreter interpreter) { - super(MinecraftAPI.ENTITY, interpreter); - } - - @Deprecated - @NotNull - @Override - public ClassInstance create(@NotNull Entity value) { - return super.create(value); - } - - @NotNull - @Override - public String toString(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - return "Entity{id=%s}".formatted(Registries.ENTITY_TYPE.getId(instance.asPrimitive(this).getType())); - } - - @Override - public List defineStaticMethods() { - return List.of( - BuiltInFunction.of("of", 1, this::of) - ); - } - - @FunctionDoc( - isStatic = true, - name = "of", - desc = { - "This converts an entityId into an entity instance.", - "This will throw an error if the id is not valid." - }, - params = {@ParameterDoc(type = StringDef.class, name = "entityId", desc = "the entityId to convert to an entity")}, - returns = @ReturnDoc(type = EntityDef.class, desc = "the entity instance from the id"), - examples = "Entity.of('minecraft:pig');" - ) - private ClassInstance of(Arguments arguments) { - ClientWorld world = EssentialUtils.getWorld(); - String string = arguments.nextPrimitive(StringDef.class); - return arguments.getInterpreter().convertValue( - Registries.ENTITY_TYPE.getOrEmpty(ClientScriptUtils.stringToIdentifier(string)).orElseThrow( - () -> new RuntimeError("'%s' is not a valid entity".formatted(string)) - ).create(world) - ); - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("isSneaking", this::isSneaking), - MemberFunction.of("isSprinting", this::isSprinting), - MemberFunction.of("isFalling", this::isFalling), - MemberFunction.of("isOnGround", this::isOnGround), - MemberFunction.of("isTouchingWater", this::isTouchingWater), - MemberFunction.of("isTouchingWaterOrRain", this::isTouchingWaterOrRain), - MemberFunction.of("isSubmergedInWater", this::isSubmergedInWater), - MemberFunction.of("isInLava", this::isInLava), - MemberFunction.of("isOnFire", this::isOnFire), - MemberFunction.of("isGlowing", this::isGlowing), - MemberFunction.of("getLookingAtBlock", this::getLookingAtBlock), - MemberFunction.of("getLookingAtBlock", 1, this::getLookingAtBlock1), - MemberFunction.of("getLookingAtBlock", 2, this::getLookingAtBlock2), - MemberFunction.of("getLookingAtPos", 1, this::getLookingAtPos), - MemberFunction.of("getEntityIdNumber", this::getEntityIdNumber), - MemberFunction.of("getVelocity", this::getVelocity), - MemberFunction.of("getPos", this::getPos), - MemberFunction.of("getX", this::getX), - MemberFunction.of("getY", this::getY), - MemberFunction.of("getZ", this::getZ), - MemberFunction.of("getYaw", this::getYaw), - MemberFunction.of("getPitch", this::getPitch), - MemberFunction.of("getDimension", this::getDimension), - MemberFunction.of("getWorld", this::getWorld), - MemberFunction.of("getBiome", this::getBiome), - MemberFunction.of("getFullId", this::getFullId), - MemberFunction.of("getId", this::getId), - MemberFunction.of("isOf", 1, this::isOf), - MemberFunction.of("getAge", this::getAge), - MemberFunction.of("getCustomName", this::getCustomName), - MemberFunction.of("getEntityUuid", this::getEntityUuid), - MemberFunction.of("setGlowing", 1, this::setGlowing), - MemberFunction.of("getDistanceTo", 1, this::getDistanceTo), - MemberFunction.of("getSquaredDistanceTo", 1, this::getSquaredDistanceTo), - MemberFunction.of("getNbt", this::getNbt), - MemberFunction.of("getTranslatedName", this::getTranslatedName), - MemberFunction.of("getHitbox", this::getHitbox), - MemberFunction.of("collidesWith", 2, this::collidesWithBlockAtPos) - // MemberFunction.of("canSpawnAt", 1, this::canSpawnPos) - ); - } - - @FunctionDoc( - name = "isSneaking", - desc = "Returns true if the player is sneaking", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the player is sneaking, false if not"), - examples = "entity.isSneaking();" - ) - private boolean isSneaking(Arguments arguments) { - return arguments.nextPrimitive(this).isSneaking(); - } - - @FunctionDoc( - name = "isSprinting", - desc = "Returns true if the player is sprinting", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the player is sprinting, false if not"), - examples = "entity.isSprinting();" - ) - private boolean isSprinting(Arguments arguments) { - return arguments.nextPrimitive(this).isSprinting(); - } - - @FunctionDoc( - name = "isFalling", - desc = "Returns true if the entity is falling", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the entity is falling, false if not"), - examples = "entity.isFalling();" - ) - private boolean isFalling(Arguments arguments) { - return arguments.nextPrimitive(this).fallDistance > 0; - } - - @FunctionDoc( - name = "isOnGround", - desc = "Returns true if the entity is on the ground", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the entity is on the ground, false if not"), - examples = "entity.isOnGround();" - ) - private boolean isOnGround(Arguments arguments) { - return arguments.nextPrimitive(this).isOnGround(); - } - - @FunctionDoc( - name = "isTouchingWater", - desc = "Returns true if the entity is touching water", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the entity is touching water, false if not"), - examples = "entity.isTouchingWater();" - ) - private boolean isTouchingWater(Arguments arguments) { - return arguments.nextPrimitive(this).isTouchingWater(); - } - - @FunctionDoc( - name = "isTouchingWaterOrRain", - desc = "Returns true if the entity is touching water or rain", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the entity is touching water or rain, false if not"), - examples = "entity.isTouchingWaterOrRain();" - ) - private boolean isTouchingWaterOrRain(Arguments arguments) { - return arguments.nextPrimitive(this).isTouchingWaterOrRain(); - } - - @FunctionDoc( - name = "isSubmergedInWater", - desc = "Returns true if the entity is submerged in water", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the entity is submerged in water, false if not"), - examples = "entity.isSubmergedInWater();" - ) - private boolean isSubmergedInWater(Arguments arguments) { - return arguments.nextPrimitive(this).isSubmergedInWater(); - } - - @FunctionDoc( - name = "isInLava", - desc = "Returns true if the entity is in lava", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the entity is in lava, false if not"), - examples = "entity.isInLava();" - ) - private boolean isInLava(Arguments arguments) { - return arguments.nextPrimitive(this).isInLava(); - } - - @FunctionDoc( - name = "isOnFire", - desc = "Returns true if the entity is on fire", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the entity is on fire, false if not"), - examples = "entity.isOnFire();" - ) - private boolean isOnFire(Arguments arguments) { - return arguments.nextPrimitive(this).isOnFire(); - } - - @FunctionDoc( - name = "isGlowing", - desc = "Returns true if the entity is glowing", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the entity is glowing, false if not"), - examples = "entity.isGlowing();" - ) - private boolean isGlowing(Arguments arguments) { - return arguments.nextPrimitive(this).isGlowing(); - } - - @FunctionDoc( - name = "getLookingAtBlock", - desc = { - "This gets the block that the entity is currently looking at", - "with a max range of 20 blocks, if there is no block then it will return air" - }, - returns = @ReturnDoc(type = BlockDef.class, desc = "the block that the entity is looking at, containing the position"), - examples = "entity.getLookingAtBlock();" - ) - private ScriptBlockState getLookingAtBlock(Arguments arguments) { - Entity entity = arguments.nextPrimitive(this); - HitResult result = entity.raycast(20D, 0.0F, true); - if (result.getType() == HitResult.Type.BLOCK) { - BlockPos blockPos = ((BlockHitResult) result).getBlockPos(); - return new ScriptBlockState(entity.getEntityWorld().getBlockState(blockPos), blockPos); - } - return new ScriptBlockState(Blocks.AIR.getDefaultState(), EssentialUtils.vec3dToBlockPos(result.getPos())); - } - - @FunctionDoc( - name = "getLookingAtBlock", - desc = { - "This gets the block that the entity is currently looking at", - "with a specific max range, if there is no block then it will return air" - }, - params = {@ParameterDoc(type = NumberDef.class, name = "maxDistance", desc = "the max range to ray cast")}, - returns = @ReturnDoc(type = BlockDef.class, desc = "the block that the entity is looking at, containing the position"), - examples = "entity.getLookingAtBlock(10);" - ) - private ScriptBlockState getLookingAtBlock1(Arguments arguments) { - Entity entity = arguments.nextPrimitive(this); - double maxDistance = arguments.nextPrimitive(NumberDef.class); - HitResult result = entity.raycast(maxDistance, 0.0F, true); - if (result.getType() == HitResult.Type.BLOCK) { - BlockPos blockPos = ((BlockHitResult) result).getBlockPos(); - return new ScriptBlockState(entity.getEntityWorld().getBlockState(blockPos), blockPos); - } - return new ScriptBlockState(Blocks.AIR.getDefaultState(), EssentialUtils.vec3dToBlockPos(result.getPos())); - } - - @FunctionDoc( - name = "getLookingAtBlock", - desc = { - "This gets the block that the entity is currently looking at", - "with a specific max range, and optionally whether fluids should", - "be included, if there is no block then it will return air" - }, - params = { - @ParameterDoc(type = NumberDef.class, name = "maxDistance", desc = "the max range to ray cast"), - @ParameterDoc(type = StringDef.class, name = "fluidType", desc = "the types of fluids to include, either 'none', 'sources', or 'all'") - }, - returns = @ReturnDoc(type = BlockDef.class, desc = "the block that the entity is looking at, containing the position"), - examples = "entity.getLookingAtBlock(10, 'sources');" - ) - private ScriptBlockState getLookingAtBlock2(Arguments arguments) { - Entity entity = arguments.nextPrimitive(this); - double maxDistance = arguments.nextPrimitive(NumberDef.class); - String fluidString = arguments.nextConstant(); - RaycastContext.FluidHandling fluidType = ClientScriptUtils.stringToFluidType(fluidString); - Vec3d camera = entity.getCameraPosVec(0.0F); - Vec3d rotation = entity.getRotationVec(0.0F); - Vec3d end = camera.add(rotation.x * maxDistance, rotation.y * maxDistance, rotation.z * maxDistance); - BlockHitResult result = entity.getEntityWorld().raycast(new RaycastContext(camera, end, RaycastContext.ShapeType.OUTLINE, fluidType, entity)); - if (result.getType() == HitResult.Type.BLOCK) { - BlockPos blockPos = result.getBlockPos(); - return new ScriptBlockState(entity.getEntityWorld().getBlockState(blockPos), blockPos); - } - return new ScriptBlockState(Blocks.AIR.getDefaultState(), EssentialUtils.vec3dToBlockPos(result.getPos())); - } - - @FunctionDoc( - name = "getLookingAtPos", - desc = "This gets the position that the entity is currently looking at with a specific max range", - params = {@ParameterDoc(type = NumberDef.class, name = "maxDistance", desc = "the max range to ray cast")}, - returns = @ReturnDoc(type = PosDef.class, desc = "the position that the entity is looking at, containing the x, y, and z"), - examples = "entity.getLookingAtPos(10);" - ) - private Vec3d getLookingAtPos(Arguments arguments) { - Entity entity = arguments.nextPrimitive(this); - double maxDistance = arguments.nextPrimitive(NumberDef.class); - return entity.raycast(maxDistance, 0.0F, true).getPos(); - } - - @FunctionDoc( - name = "getEntityIdNumber", - desc = "This gets the entity id number of the entity", - returns = @ReturnDoc(type = NumberDef.class, desc = "the entity id number"), - examples = "entity.getEntityIdNumber();" - ) - private int getEntityIdNumber(Arguments arguments) { - return arguments.nextPrimitive(this).getId(); - } - - @FunctionDoc( - name = "getVelocity", - desc = "This gets the velocity of the entity in a list in the form [x, y, z]", - returns = @ReturnDoc(type = ListDef.class, desc = "the velocity of the entity"), - examples = "entity.getVelocity();" - ) - private ArucasList getVelocity(Arguments arguments) { - Entity entity = arguments.nextPrimitive(this); - Vec3d velocity = entity.getVelocity(); - NumberDef numberDef = arguments.getInterpreter().getPrimitive(NumberDef.class); - return ArucasList.of( - numberDef.create(velocity.x), - numberDef.create(velocity.y), - numberDef.create(velocity.z) - ); - } - - @FunctionDoc( - name = "getPos", - desc = "This gets the position of the entity", - returns = @ReturnDoc(type = PosDef.class, desc = "the position of the entity"), - examples = "entity.getPos();" - ) - private Vec3d getPos(Arguments arguments) { - return arguments.nextPrimitive(this).getPos(); - } - - @FunctionDoc( - name = "getX", - desc = "This gets the x position of the entity", - returns = @ReturnDoc(type = NumberDef.class, desc = "the x position of the entity"), - examples = "entity.getX();" - ) - private double getX(Arguments arguments) { - return arguments.nextPrimitive(this).getX(); - } - - @FunctionDoc( - name = "getY", - desc = "This gets the y position of the entity", - returns = @ReturnDoc(type = NumberDef.class, desc = "the y position of the entity"), - examples = "entity.getY();" - ) - private double getY(Arguments arguments) { - return arguments.nextPrimitive(this).getY(); - } - - @FunctionDoc( - name = "getZ", - desc = "This gets the z position of the entity", - returns = @ReturnDoc(type = NumberDef.class, desc = "the z position of the entity"), - examples = "entity.getZ();" - ) - private double getZ(Arguments arguments) { - return arguments.nextPrimitive(this).getZ(); - } - - @FunctionDoc( - name = "getYaw", - desc = "This gets the yaw of the entity (horizontal head rotation)", - returns = @ReturnDoc(type = NumberDef.class, desc = "the yaw of the entity, between -180 and 180"), - examples = "entity.getYaw();" - ) - private float getYaw(Arguments arguments) { - Entity entity = arguments.nextPrimitive(this); - float yaw = entity.getYaw() % 360; - return yaw < -180 ? 360 + yaw : yaw; - } - - @FunctionDoc( - name = "getPitch", - desc = "This gets the pitch of the entity (vertical head rotation)", - returns = @ReturnDoc(type = NumberDef.class, desc = "the pitch of the entity, between -90 and 90"), - examples = "entity.getPitch();" - ) - private float getPitch(Arguments arguments) { - return arguments.nextPrimitive(this).getPitch(); - } - - @FunctionDoc( - name = "getDimension", - desc = "This gets the dimension of the entity", - returns = @ReturnDoc(type = StringDef.class, desc = "the dimension id of dimension the entity is in"), - examples = "entity.getDimension();" - ) - private String getDimension(Arguments arguments) { - return arguments.nextPrimitive(this).getEntityWorld().getRegistryKey().getValue().getPath(); - } - - @FunctionDoc( - name = "getWorld", - desc = "This gets the world the entity is in", - returns = @ReturnDoc(type = WorldDef.class, desc = "the world the entity is in"), - examples = "entity.getWorld();" - ) - private ClientWorld getWorld(Arguments arguments) { - Entity entity = arguments.nextPrimitive(this); - if (entity.getEntityWorld() instanceof ClientWorld world) { - return world; - } - throw new RuntimeError("Could not get entity '%s's world".formatted(entity)); - } - - @FunctionDoc( - name = "getBiome", - desc = "This gets the biome of the entity", - returns = @ReturnDoc(type = BiomeDef.class, desc = "the biome the entity is in"), - examples = "entity.getBiome();" - ) - private Biome getBiome(Arguments arguments) { - Entity entity = arguments.nextPrimitive(this); - return entity.getEntityWorld().getBiome(entity.getBlockPos()).value(); - } - - @FunctionDoc( - name = "getFullId", - desc = { - "This gets the full id of the entity, this returns the full id, so for example", - "'minecraft:cow' you can find all entityNames on", - "[Joa's Entity Property Encyclopedia](https://joakimthorsen.github.io/MCPropertyEncyclopedia/entities.html)" - }, - returns = @ReturnDoc(type = StringDef.class, desc = "the full id of the entity"), - examples = "entity.getFullId();" - ) - private String getFullId(Arguments arguments) { - return Registries.ENTITY_TYPE.getId(arguments.nextPrimitive(this).getType()).toString(); - } - - @FunctionDoc( - name = "getId", - desc = "This gets the id of the entity, this returns the id, so for examples 'cow'", - returns = @ReturnDoc(type = StringDef.class, desc = "the id of the entity"), - examples = "entity.getId();" - ) - private String getId(Arguments arguments) { - return Registries.ENTITY_TYPE.getId(arguments.nextPrimitive(this).getType()).getPath(); - } - - @FunctionDoc( - name = "isOf", - desc = "This checks if the entity is of the given entity id", - params = {@ParameterDoc(type = StringDef.class, name = "entityId", desc = "the entity id to check")}, - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the entity is of the given entity id"), - examples = "entity.isOf('cow');" - ) - private boolean isOf(Arguments arguments) { - Entity entity = arguments.nextPrimitive(this); - String id = arguments.nextPrimitive(StringDef.class); - EntityType type = Registries.ENTITY_TYPE.getOrEmpty(ClientScriptUtils.stringToIdentifier(id)).orElse(null); - return entity.getType() == type; - } - - @FunctionDoc( - name = "getAge", - desc = "This gets the age of the entity in ticks", - returns = @ReturnDoc(type = NumberDef.class, desc = "the age of the entity in ticks"), - examples = "entity.getAge();" - ) - private int getAge(Arguments arguments) { - return arguments.nextPrimitive(this).age; - } - - @FunctionDoc( - name = "getCustomName", - desc = "This gets the custom name of the entity if it has one", - returns = @ReturnDoc(type = StringDef.class, desc = "the custom name of the entity if it has one, otherwise null"), - examples = "entity.getCustomName();" - ) - private String getCustomName(Arguments arguments) { - Entity entity = arguments.nextPrimitive(this); - Text customName = entity.getCustomName(); - return customName == null ? null : customName.getString(); - } - - @FunctionDoc( - name = "getEntityUuid", - desc = "This gets the uuid of the entity", - returns = @ReturnDoc(type = StringDef.class, desc = "the uuid of the entity"), - examples = "entity.getEntityUuid();" - ) - private String getEntityUuid(Arguments arguments) { - return arguments.nextPrimitive(this).getUuidAsString(); - } - - @FunctionDoc( - name = "setGlowing", - desc = "This sets the entity to either start glowing or stop glowing on the client", - params = {@ParameterDoc(type = BooleanDef.class, name = "glowing", desc = "the glowing state")}, - examples = "entity.setGlowing(true);" - ) - private Void setGlowing(Arguments arguments) { - Entity entity = arguments.nextPrimitive(this); - entity.setGlowing(arguments.nextPrimitive(BooleanDef.class)); - return null; - } - - @FunctionDoc( - name = "getDistanceTo", - desc = "This gets the distance between the entity and the other entity", - params = {@ParameterDoc(type = EntityDef.class, name = "otherEntity", desc = "the other entity")}, - returns = @ReturnDoc(type = NumberDef.class, desc = "the distance between the entities"), - examples = "entity.getDistanceTo(Player.get());" - ) - private double getDistanceTo(Arguments arguments) { - Entity entity = arguments.nextPrimitive(this); - return entity.distanceTo(arguments.nextPrimitive(this)); - } - - @FunctionDoc( - name = "getSquaredDistanceTo", - desc = "This gets the squared distance between the entity and the other entity", - params = {@ParameterDoc(type = EntityDef.class, name = "otherEntity", desc = "the other entity")}, - returns = @ReturnDoc(type = NumberDef.class, desc = "the squared distance between the entities"), - examples = "entity.getSquaredDistanceTo(Player.get());" - ) - private double getSquaredDistanceTo(Arguments arguments) { - Entity entity = arguments.nextPrimitive(this); - return entity.squaredDistanceTo(arguments.nextPrimitive(this)); - } - - @FunctionDoc( - name = "getNbt", - desc = "This gets the nbt of the entity as a map", - returns = @ReturnDoc(type = MapDef.class, desc = "the nbt of the entity"), - examples = "entity.getNbt();" - ) - private ArucasMap getNbt(Arguments arguments) { - Entity entity = arguments.nextPrimitive(this); - NbtCompound nbtCompound = entity.writeNbt(new NbtCompound()); - return ClientScriptUtils.nbtToMap(arguments.getInterpreter(), nbtCompound, 10); - } - - @FunctionDoc( - name = "getTranslatedName", - desc = "This gets the translated name of the entity, for examples 'minecraft:pig' would return 'Pig' if your language is in english", - returns = @ReturnDoc(type = StringDef.class, desc = "the translated name of the entity"), - examples = "entity.getTranslatedName();" - ) - private String getTranslatedName(Arguments arguments) { - Entity entity = arguments.nextPrimitive(this); - return I18n.translate(entity.getType().getTranslationKey()); - } - - @FunctionDoc( - name = "getHitbox", - desc = "This gets the hitbox of the entity in a list containing the two corners of the hitbox, the minimum point and the maximum point", - returns = @ReturnDoc(type = ListDef.class, desc = "the hitbox of the entity"), - examples = "entity.getHitbox();" - ) - private ArucasList getHitbox(Arguments arguments) { - Entity entity = arguments.nextPrimitive(this); - Box box = entity.getBoundingBox(); - PosDef posDef = arguments.getInterpreter().getPrimitive(PosDef.class); - return ArucasList.of( - posDef.create(new ScriptPos(box.minX, box.minY, box.minZ)), - posDef.create(new ScriptPos(box.maxX, box.maxY, box.maxZ)) - ); - } - - @FunctionDoc( - name = "collidesWith", - desc = "This checks whether the entity collides with a block at a given position", - params = { - @ParameterDoc(type = PosDef.class, name = "pos", desc = "the position to check"), - @ParameterDoc(type = BlockDef.class, name = "block", desc = "the block to check") - }, - returns = @ReturnDoc(type = BooleanDef.class, desc = "whether the entity collides with the block"), - examples = "entity.collidesWith(Pos.get(0, 0, 0), Block.of('minecraft:stone'));" - ) - private boolean collidesWithBlockAtPos(Arguments arguments) { - Entity entity = arguments.nextPrimitive(this); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - ScriptBlockState block = arguments.nextPrimitive(BlockDef.class); - return entity.collidesWithStateAtPos(pos.getBlockPos(), block.state); - } - - // @FunctionDoc( - // name = "canSpawnAt", - // desc = "This checks whether the entity can spawn at given position with regard to light and hitbox", - // params = { - // @ParameterDoc(type = PosDef.class, name = "pos", desc = "the position to check") - // }, - // returns = @ReturnDoc(type = BooleanDef.class, desc = "whether entity type can spawn at given position"), - // examples = "entity.canSpawnAt(new Pos(0,0,0));" - // ) - // private boolean canSpawnPos(Arguments arguments) { - // Entity entity = arguments.nextPrimitive(this); - // ScriptPos pos = arguments.nextPrimitive(PosDef.class); - // return EssentialUtils.canSpawn(EssentialUtils.getWorld(), pos.getBlockPos(), entity.getType()); - // } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/FakeEntityDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/FakeEntityDef.java deleted file mode 100644 index eaddf122..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/FakeEntityDef.java +++ /dev/null @@ -1,334 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import kotlin.Unit; -import me.senseiwells.arucas.api.docs.annotations.*; -import me.senseiwells.arucas.builtin.NumberDef; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.ConstructorFunction; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptFakeEntity; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptPos; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.entity.Entity; -import net.minecraft.world.World; - -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.FAKE_ENTITY; - -@ClassDoc( - name = FAKE_ENTITY, - desc = "This allows you to create a fake entity which can be rendered in the world.", - language = Language.Java -) -public class FakeEntityDef extends CreatableDefinition { - public FakeEntityDef(Interpreter interpreter) { - super(FAKE_ENTITY, interpreter); - } - - @Override - public List defineConstructors() { - return List.of( - ConstructorFunction.of(2, this::construct) - ); - } - - @ConstructorDoc( - desc = "Creates a new fake entity", - params = { - @ParameterDoc(type = EntityDef.class, name = "entity", desc = "The entity that you want to create into a fake entity"), - @ParameterDoc(type = WorldDef.class, name = "world", desc = "The world that the entity is being rendered in") - }, - examples = "fakeEntity = new FakeEntity();" - ) - private Unit construct(Arguments arguments) { - ClassInstance instance = arguments.next(); - Entity entity = arguments.nextPrimitive(EntityDef.class); - World world = arguments.nextPrimitive(WorldDef.class); - if (!(world instanceof ClientWorld clientWorld)) { - throw new RuntimeError("World must be a client world"); - } - instance.setPrimitive(this, new ScriptFakeEntity(arguments.getInterpreter(), entity, clientWorld)); - return null; - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("setWorld", 1, this::setWorld), - MemberFunction.of("getWorld", this::getWorld), - MemberFunction.of("setPos", 1, this::setPos1), - MemberFunction.of("setPos", 2, this::setPos2), - MemberFunction.of("getPos", this::getPos), - MemberFunction.of("setYaw", 1, this::setYaw1), - MemberFunction.of("setYaw", 2, this::setYaw2), - MemberFunction.of("getYaw", this::getYaw), - MemberFunction.of("setBodyYaw", 1, this::setBodyYaw1), - MemberFunction.of("setBodyYaw", 2, this::setBodyYaw2), - MemberFunction.of("getBodyYaw", this::getBodyYaw), - MemberFunction.of("setPitch", 1, this::setPitch1), - MemberFunction.of("setPitch", 2, this::setPitch2), - MemberFunction.of("getPitch", this::getPitch), - MemberFunction.of("updatePosAndRotation", 3, this::updatePosAndRotation3), - MemberFunction.of("updatePosAndRotation", 4, this::updatePosAndRotation4), - MemberFunction.of("spawn", this::spawn), - MemberFunction.of("despawn", this::despawn) - ); - } - - @FunctionDoc( - name = "setWorld", - desc = "Sets the world that the entity is being rendered in", - params = {@ParameterDoc(type = WorldDef.class, name = "world", desc = "The world that the entity is being rendered in")}, - examples = "fakeEntity.setWorld(MinecraftClient.getClient().getWorld());" - ) - private Void setWorld(Arguments arguments) { - ScriptFakeEntity entity = arguments.nextPrimitive(this); - World world = arguments.nextPrimitive(WorldDef.class); - if (!(world instanceof ClientWorld clientWorld)) { - throw new RuntimeError("World must be a client world"); - } - entity.setWorld(clientWorld); - return null; - } - - @FunctionDoc( - name = "getWorld", - desc = "Gets the world that the entity is being rendered in", - returns = @ReturnDoc(type = WorldDef.class, desc = "The world that the entity is being rendered in"), - examples = "world = fakeEntity.getWorld();" - ) - private World getWorld(Arguments arguments) { - ScriptFakeEntity entity = arguments.nextPrimitive(this); - return entity.getWorld(); - } - - @FunctionDoc( - name = "setPos", - desc = "Sets the position of the entity with no interpolation", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "The new position of the entity")}, - examples = "fakeEntity.setPos(new Pos(0, 0, 0));" - ) - private Void setPos1(Arguments arguments) { - ScriptFakeEntity entity = arguments.nextPrimitive(this); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - entity.setPos(pos.getVec3d()); - return null; - } - - @FunctionDoc( - name = "setPos", - desc = "Sets the position of the entity", - params = { - @ParameterDoc(type = PosDef.class, name = "pos", desc = "The new position of the entity"), - @ParameterDoc(type = NumberDef.class, name = "interpolationSteps", desc = "The number of interpolation steps to take") - }, - examples = "fakeEntity.setPos(new Pos(0, 0, 0), 0);" - ) - private Void setPos2(Arguments arguments) { - ScriptFakeEntity entity = arguments.nextPrimitive(this); - int interpolationSteps = arguments.nextPrimitive(NumberDef.class).intValue(); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - entity.setPos(pos.getVec3d(), interpolationSteps); - return null; - } - - @FunctionDoc( - name = "getPos", - desc = "Gets the position of the entity", - returns = @ReturnDoc(type = PosDef.class, desc = "The position of the entity"), - examples = "pos = fakeEntity.getPos();" - ) - private ScriptPos getPos(Arguments arguments) { - ScriptFakeEntity entity = arguments.nextPrimitive(this); - return new ScriptPos(entity.getPos()); - } - - @FunctionDoc( - name = "setYaw", - desc = "Sets the yaw of the entity with no interpolation", - params = {@ParameterDoc(type = NumberDef.class, name = "yaw", desc = "The new yaw of the entity")}, - examples = "fakeEntity.setYaw(0);" - ) - private Void setYaw1(Arguments arguments) { - ScriptFakeEntity entity = arguments.nextPrimitive(this); - float yaw = arguments.nextPrimitive(NumberDef.class).floatValue(); - entity.setYaw(yaw); - return null; - } - - @FunctionDoc( - name = "setYaw", - desc = "Sets the yaw of the entity", - params = { - @ParameterDoc(type = NumberDef.class, name = "yaw", desc = "The new yaw of the entity"), - @ParameterDoc(type = NumberDef.class, name = "interpolationSteps", desc = "The number of interpolation steps to take") - }, - examples = "fakeEntity.setYaw(0, 10);" - ) - private Void setYaw2(Arguments arguments) { - ScriptFakeEntity entity = arguments.nextPrimitive(this); - int interpolationSteps = arguments.nextPrimitive(NumberDef.class).intValue(); - float yaw = arguments.nextPrimitive(NumberDef.class).floatValue(); - entity.setYaw(yaw, interpolationSteps); - return null; - } - - @FunctionDoc( - name = "getYaw", - desc = "Gets the yaw of the entity", - returns = @ReturnDoc(type = NumberDef.class, desc = "The yaw of the entity"), - examples = "yaw = fakeEntity.getYaw();" - ) - private float getYaw(Arguments arguments) { - ScriptFakeEntity entity = arguments.nextPrimitive(this); - return entity.getYaw(); - } - - @FunctionDoc( - name = "setBodyYaw", - desc = "Sets the body yaw of the entity with no interpolation", - params = {@ParameterDoc(type = NumberDef.class, name = "bodyYaw", desc = "The new body yaw of the entity")}, - examples = "fakeEntity.setBodyYaw(0);" - ) - private Void setBodyYaw1(Arguments arguments) { - ScriptFakeEntity entity = arguments.nextPrimitive(this); - float bodyYaw = arguments.nextPrimitive(NumberDef.class).floatValue(); - entity.setBodyYaw(bodyYaw); - return null; - } - - @FunctionDoc( - name = "setBodyYaw", - desc = "Sets the body yaw of the entity", - params = { - @ParameterDoc(type = NumberDef.class, name = "bodyYaw", desc = "The new body yaw of the entity"), - @ParameterDoc(type = NumberDef.class, name = "interpolationSteps", desc = "The number of interpolation steps to take") - }, - examples = "fakeEntity.setBodyYaw(0, 10);" - ) - private Void setBodyYaw2(Arguments arguments) { - ScriptFakeEntity entity = arguments.nextPrimitive(this); - int interpolationSteps = arguments.nextPrimitive(NumberDef.class).intValue(); - float bodyYaw = arguments.nextPrimitive(NumberDef.class).floatValue(); - entity.setBodyYaw(bodyYaw, interpolationSteps); - return null; - } - - @FunctionDoc( - name = "getBodyYaw", - desc = "Gets the body yaw of the entity", - returns = @ReturnDoc(type = NumberDef.class, desc = "The body yaw of the entity"), - examples = "bodyYaw = fakeEntity.getBodyYaw();" - ) - private float getBodyYaw(Arguments arguments) { - ScriptFakeEntity entity = arguments.nextPrimitive(this); - return entity.getBodyYaw(); - } - - @FunctionDoc( - name = "setPitch", - desc = "Sets the pitch of the entity with no interpolation", - params = {@ParameterDoc(type = NumberDef.class, name = "pitch", desc = "The new pitch of the entity")}, - examples = "fakeEntity.setPitch(0);" - ) - private Void setPitch1(Arguments arguments) { - ScriptFakeEntity entity = arguments.nextPrimitive(this); - float pitch = arguments.nextPrimitive(NumberDef.class).floatValue(); - entity.setPitch(pitch); - return null; - } - - @FunctionDoc( - name = "setPitch", - desc = "Sets the pitch of the entity", - params = { - @ParameterDoc(type = NumberDef.class, name = "pitch", desc = "The new pitch of the entity"), - @ParameterDoc(type = NumberDef.class, name = "interpolationSteps", desc = "The number of interpolation steps to take") - }, - examples = "fakeEntity.setPitch(0, 10);" - ) - private Void setPitch2(Arguments arguments) { - ScriptFakeEntity entity = arguments.nextPrimitive(this); - int interpolationSteps = arguments.nextPrimitive(NumberDef.class).intValue(); - float pitch = arguments.nextPrimitive(NumberDef.class).floatValue(); - entity.setPitch(pitch, interpolationSteps); - return null; - } - - @FunctionDoc( - name = "getPitch", - desc = "Gets the pitch of the entity", - returns = @ReturnDoc(type = NumberDef.class, desc = "The pitch of the entity"), - examples = "pitch = fakeEntity.getPitch();" - ) - private float getPitch(Arguments arguments) { - ScriptFakeEntity entity = arguments.nextPrimitive(this); - return entity.getPitch(); - } - - @FunctionDoc( - name = "updatePosAndRotation", - desc = "Updates the position and rotation of the entity with no interpolation", - params = { - @ParameterDoc(type = PosDef.class, name = "pos", desc = "The new position of the entity"), - @ParameterDoc(type = NumberDef.class, name = "yaw", desc = "The new yaw of the entity"), - @ParameterDoc(type = NumberDef.class, name = "pitch", desc = "The new pitch of the entity") - }, - examples = "fakeEntity.updatePosAndRotation(new Pos(100, 0, 100), 0, 0);" - ) - private Void updatePosAndRotation3(Arguments arguments) { - ScriptFakeEntity entity = arguments.nextPrimitive(this); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - float yaw = arguments.nextPrimitive(NumberDef.class).floatValue(); - float pitch = arguments.nextPrimitive(NumberDef.class).floatValue(); - entity.updatePosAndRotation(pos.getVec3d(), yaw, pitch); - return null; - } - - @FunctionDoc( - name = "updatePosAndRotation", - desc = "Updates the position and rotation of the entity", - params = { - @ParameterDoc(type = PosDef.class, name = "pos", desc = "The new position of the entity"), - @ParameterDoc(type = NumberDef.class, name = "yaw", desc = "The new yaw of the entity"), - @ParameterDoc(type = NumberDef.class, name = "pitch", desc = "The new pitch of the entity"), - @ParameterDoc(type = NumberDef.class, name = "interpolationSteps", desc = "The number of interpolation steps to take") - }, - examples = "fakeEntity.updatePosAndRotation(new Pos(100, 0, 100), 0, 0, 10);" - ) - private Void updatePosAndRotation4(Arguments arguments) { - ScriptFakeEntity entity = arguments.nextPrimitive(this); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - float yaw = arguments.nextPrimitive(NumberDef.class).floatValue(); - float pitch = arguments.nextPrimitive(NumberDef.class).floatValue(); - int interpolationSteps = arguments.nextPrimitive(NumberDef.class).intValue(); - entity.updatePosAndRotation(pos.getVec3d(), yaw, pitch, interpolationSteps); - return null; - } - - @FunctionDoc( - name = "spawn", - desc = "Spawns the entity (makes it render in the world)", - examples = "fakeEntity.spawn();" - ) - private Void spawn(Arguments arguments) { - arguments.nextPrimitive(this).spawn(); - return null; - } - - @FunctionDoc( - name = "despawn", - desc = "Despawns the entity (makes it not render in the world)", - examples = "fakeEntity.despawn();" - ) - private Void despawn(Arguments arguments) { - arguments.nextPrimitive(this).despawn(); - return null; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/FakeScreenDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/FakeScreenDef.java deleted file mode 100644 index b81b4102..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/FakeScreenDef.java +++ /dev/null @@ -1,155 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import kotlin.Unit; -import me.senseiwells.arucas.api.docs.annotations.*; -import me.senseiwells.arucas.builtin.FunctionDef; -import me.senseiwells.arucas.builtin.NumberDef; -import me.senseiwells.arucas.builtin.StringDef; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.functions.ArucasFunction; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.ConstructorFunction; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.clientscript.core.MinecraftAPI; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.ClientScriptUtils; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptItemStack; -import me.senseiwells.essentialclient.utils.render.FakeInventoryScreen; -import net.minecraft.item.ItemStack; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.FAKE_SCREEN; - -@ClassDoc( - name = FAKE_SCREEN, - desc = { - "This class extends Screen and so inherits all of their methods too,", - "this class is used to create client side inventory screens." - }, - superclass = ScreenDef.class, - language = Language.Java -) -public class FakeScreenDef extends CreatableDefinition { - public FakeScreenDef(Interpreter interpreter) { - super(MinecraftAPI.FAKE_SCREEN, interpreter); - } - - @NotNull - @Override - public PrimitiveDefinition superclass() { - return this.getPrimitiveDef(ScreenDef.class); - } - - @Override - public List defineConstructors() { - return List.of( - ConstructorFunction.of(2, this::construct) - ); - } - - @ConstructorDoc( - desc = { - "Creates a FakeScreen instance with given name and given amount of rows,", - "this will throw an error if the rows are not between 1 and 6" - }, - params = { - @ParameterDoc(type = StringDef.class, name = "name", desc = "the name of the screen"), - @ParameterDoc(type = NumberDef.class, name = "rows", desc = "the number of rows between 1 - 6") - }, - examples = "new FakeScreen('MyScreen', 6);" - ) - private Unit construct(Arguments arguments) { - ClassInstance instance = arguments.next(); - String name = arguments.nextPrimitive(StringDef.class); - int rows = arguments.nextPrimitive(NumberDef.class).intValue(); - if (rows < 1 || rows > 6) { - throw new RuntimeError("Rows must be between 1 and 6"); - } - FakeInventoryScreen screen = new FakeInventoryScreen( - arguments.getInterpreter(), - EssentialUtils.getPlayer().getInventory(), - name, - rows - ); - instance.setPrimitive(this, screen); - return null; - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("onClick", 1, this::onClick), - MemberFunction.of("setStackForSlot", 2, this::setStackForSlot), - MemberFunction.of("getStackForSlot", 1, this::getStackForSlot) - ); - } - - @FunctionDoc( - name = "onClick", - desc = { - "This sets the callback for when a slot is clicked in the inventory.", - "The callback must have 3 parameters, the first is the item stack that was clicked,", - "then second is the slot number, third is the action as a string, fourth is the", - "button string: right, left, middle." - }, - params = { - @ParameterDoc(type = FunctionDef.class, name = "function", desc = "the callback function") - }, - examples = - """ - fakeScreen.onClick(fun(item, slotNum, action, button) { - // Action can be any of the following: - // 'PICKUP', 'QUICK_MOVE', 'SWAP', 'CLONE', 'THROW', 'QUICK_CRAFT', or 'PICKUP_ALL' - // Button can be any of the follinwg: - // 'right', 'left', 'middle', or 'unknown' - print(action); - }); - """ - ) - private Void onClick(Arguments arguments) { - FakeInventoryScreen fakeScreen = arguments.nextPrimitive(FakeScreenDef.class); - ArucasFunction function = arguments.nextPrimitive(FunctionDef.class); - fakeScreen.setFunctionValue(arguments.getInterpreter(), function); - return null; - } - - @FunctionDoc( - name = "setStackForSlot", - desc = "Sets the stack for the given slot, if the slot is out of bounds it won't be set", - params = { - @ParameterDoc(type = NumberDef.class, name = "slotNum", desc = "the slot number"), - @ParameterDoc(type = ItemStackDef.class, name = "stack", desc = "the stack to set") - }, - examples = "fakeScreen.setStackForSlot(0, Material.DIAMOND_BLOCK.asItemStack());" - ) - private Void setStackForSlot(Arguments arguments) { - FakeInventoryScreen fakeScreen = arguments.nextPrimitive(FakeScreenDef.class); - int slotNum = arguments.nextPrimitive(NumberDef.class).intValue(); - ScriptItemStack itemStack = arguments.nextPrimitive(ItemStackDef.class); - ClientScriptUtils.ensureMainThread("setStackForSlot", arguments.getInterpreter(), () -> { - fakeScreen.setStack(slotNum, itemStack.stack); - }); - return null; - } - - @FunctionDoc( - name = "getStackForSlot", - desc = "Gets the stack for the given slot, if the slot is out of bounds it returns null", - params = {@ParameterDoc(type = NumberDef.class, name = "slotNum", desc = "the slot number")}, - returns = @ReturnDoc(type = ItemStackDef.class, desc = "the stack for the given slot"), - examples = "fakeScreen.getStackForSlot(0);" - ) - private ScriptItemStack getStackForSlot(Arguments arguments) { - FakeInventoryScreen fakeScreen = arguments.nextPrimitive(FakeScreenDef.class); - int slotNum = arguments.nextPrimitive(NumberDef.class).intValue(); - ItemStack stack = fakeScreen.getStack(slotNum); - return stack == null ? null : new ScriptItemStack(stack); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/GameEventDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/GameEventDef.java deleted file mode 100644 index afe0cb32..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/GameEventDef.java +++ /dev/null @@ -1,178 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import kotlin.Unit; -import me.senseiwells.arucas.api.docs.annotations.*; -import me.senseiwells.arucas.builtin.BooleanDef; -import me.senseiwells.arucas.builtin.FunctionDef; -import me.senseiwells.arucas.builtin.FutureDef; -import me.senseiwells.arucas.builtin.StringDef; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.BuiltInFunction; -import me.senseiwells.arucas.functions.builtin.ConstructorFunction; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.clientscript.events.CancelEvent; -import me.senseiwells.essentialclient.clientscript.events.MinecraftScriptEvent; -import me.senseiwells.essentialclient.clientscript.events.MinecraftScriptEvents; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptEvent; - -import java.util.List; -import java.util.concurrent.Future; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.GAME_EVENT; - -@ClassDoc( - name = GAME_EVENT, - desc = "This class allows you to register listeners for game events in Minecraft.", - language = Language.Java -) -public class GameEventDef extends CreatableDefinition { - public GameEventDef(Interpreter interpreter) { - super(GAME_EVENT, interpreter); - } - - @Override - public List defineConstructors() { - return List.of( - ConstructorFunction.of(2, this::construct2), - ConstructorFunction.of(3, this::construct3) - ); - } - - @ConstructorDoc( - desc = "This creates a new GameEvent, that is not cancellable", - params = { - @ParameterDoc(type = StringDef.class, name = "eventName", desc = "The name of the event, you can find these on the GameEvents page"), - @ParameterDoc(type = FunctionDef.class, name = "onEvent", desc = "The function to run when the event is called, some events may have parameters") - }, - examples = "new GameEvent('onClientTick', fun() { });" - ) - private Unit construct2(Arguments arguments) { - ClassInstance instance = arguments.next(); - String eventName = arguments.nextConstant(); - MinecraftScriptEvent event = MinecraftScriptEvents.getEvent(eventName); - if (event == null) { - throw new RuntimeError("No such event '%s'".formatted(eventName)); - } - ClassInstance function = arguments.next(FunctionDef.class); - ScriptEvent scriptEvent = new ScriptEvent(arguments.getInterpreter(), event, function, false); - instance.setPrimitive(this, scriptEvent); - scriptEvent.register(); - return null; - } - - @ConstructorDoc( - desc = "This creates a new GameEvent", - params = { - @ParameterDoc(type = StringDef.class, name = "eventName", desc = "The name of the event, you can find these on the GameEvents page"), - @ParameterDoc(type = FunctionDef.class, name = "onEvent", desc = "The function to run when the event is called, some events may have parameters"), - @ParameterDoc(type = BooleanDef.class, name = "cancellable", desc = "Whether or not the event is cancellable, if it is then it will run on the main thread") - }, - examples = "new GameEvent('onClientTick', fun() { }, true);" - ) - private Unit construct3(Arguments arguments) { - ClassInstance instance = arguments.next(); - String eventName = arguments.nextConstant(); - MinecraftScriptEvent event = MinecraftScriptEvents.getEvent(eventName); - if (event == null) { - throw new RuntimeError("No such event '%s'".formatted(eventName)); - } - ClassInstance function = arguments.next(FunctionDef.class); - boolean cancellable = arguments.nextPrimitive(BooleanDef.class); - ScriptEvent scriptEvent = new ScriptEvent(arguments.getInterpreter(), event, function, cancellable); - instance.setPrimitive(this, scriptEvent); - scriptEvent.register(); - return null; - } - - @Override - public List defineStaticMethods() { - return List.of( - BuiltInFunction.of("cancel", this::cancel), - BuiltInFunction.of("unregisterAll", this::unregisterAll), - BuiltInFunction.of("future", 1, this::future) - ); - } - - @FunctionDoc( - isStatic = true, - name = "cancel", - desc = { - "If called on a cancellable event, this will stop execution and cancel the event,", - "if called on a non-cancellable event, or not on an event, this will throw an error" - }, - examples = "GameEvent.cancel();" - ) - private Void cancel(Arguments arguments) { - throw CancelEvent.INSTANCE; - } - - @FunctionDoc( - isStatic = true, - name = "unregisterAll", - desc = "This unregisters all events registered by this script", - examples = "GameEvent.unregisterAll();" - ) - private Void unregisterAll(Arguments arguments) { - MinecraftScriptEvents.clearEventFunctions(arguments.getInterpreter().getProperties().getId()); - return null; - } - - @FunctionDoc( - isStatic = true, - name = "future", - desc = "This returns a future that allows you to wait for an event to occur", - returns = @ReturnDoc(type = FutureDef.class, desc = "the future, will complete once the event has occurred"), - examples = "GameEvent.future('onClientTick').await();" - ) - private Future future(Arguments arguments) { - String eventName = arguments.nextConstant(); - MinecraftScriptEvent event = MinecraftScriptEvents.getEvent(eventName); - if (event == null) { - throw new RuntimeError("No such event '%s'".formatted(eventName)); - } - return event.registerWaitingEvent(arguments.getInterpreter()); - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("isRegistered", this::isRegistered), - MemberFunction.of("register", this::register), - MemberFunction.of("unregister", this::unregister) - ); - } - - @FunctionDoc( - name = "isRegistered", - desc = "This returns whether or not the event is registered", - returns = @ReturnDoc(type = BooleanDef.class, desc = "Whether or not the event is registered"), - examples = "gameEvent.isRegistered();" - ) - private boolean isRegistered(Arguments arguments) { - return arguments.nextPrimitive(this).isRegistered(); - } - - @FunctionDoc( - name = "register", - desc = "This registers the event", - examples = "gameEvent.register();" - ) - private Void register(Arguments arguments) { - arguments.nextPrimitive(this).register(); - return null; - } - - @FunctionDoc( - name = "unregister", - desc = "This unregisters the event", - examples = "gameEvent.unregister();" - ) - private boolean unregister(Arguments arguments) { - return arguments.nextPrimitive(this).unregister(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/ItemEntityDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/ItemEntityDef.java deleted file mode 100644 index 0950d2aa..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/ItemEntityDef.java +++ /dev/null @@ -1,110 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.NumberDef; -import me.senseiwells.arucas.builtin.StringDef; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.compiler.LocatableTrace; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.clientscript.core.MinecraftAPI; -import me.senseiwells.essentialclient.mixins.clientScript.ItemEntityAccessor; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.ThreadSafeUtils; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptItemStack; -import net.minecraft.entity.ItemEntity; -import net.minecraft.item.ItemStack; -import org.jetbrains.annotations.NotNull; - -import java.util.List; -import java.util.UUID; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.ITEM_ENTITY; - -@ClassDoc( - name = ITEM_ENTITY, - desc = { - "This class extends Entity and so inherits all of their methods too,", - "ItemEntities are entities that are dropped items." - }, - superclass = EntityDef.class, - language = Language.Java -) -public class ItemEntityDef extends CreatableDefinition { - public ItemEntityDef(Interpreter interpreter) { - super(MinecraftAPI.ITEM_ENTITY, interpreter); - } - - @NotNull - @Override - public PrimitiveDefinition superclass() { - return this.getPrimitiveDef(EntityDef.class); - } - - @NotNull - @Override - public String toString(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - ItemStack stack = instance.asPrimitive(this).getStack(); - return "ItemEntity{id=" + stack.getItem().toString() + ", count=" + stack.getCount() + "}"; - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("getItemStack", this::getItemStack), - MemberFunction.of("getCustomName", this::getCustomName), - MemberFunction.of("getItemAge", this::getItemAge), - MemberFunction.of("getThrower", this::getThrower) - ); - } - - @FunctionDoc( - name = "getItemStack", - desc = "This method returns the ItemStack that is held in the ItemEntity", - returns = @ReturnDoc(type = ItemStackDef.class, desc = "the ItemStack that the entity holds"), - examples = "itemEntity.getItemStack();" - ) - private ScriptItemStack getItemStack(Arguments arguments) { - return new ScriptItemStack(arguments.nextPrimitive(this).getStack()); - } - - @FunctionDoc( - name = "getCustomName", - desc = "This method returns the custom name of the ItemEntity", - returns = @ReturnDoc(type = StringDef.class, desc = "the custom name of the entity"), - examples = "itemEntity.getCustomName();" - ) - private String getCustomName(Arguments arguments) { - return arguments.nextPrimitive(this).getName().getString(); - } - - @FunctionDoc( - name = "getItemAge", - desc = { - "This method returns the age of the ItemEntity", - "this is increased every tick and the item entity despawns after 6000 ticks" - }, - returns = @ReturnDoc(type = NumberDef.class, desc = "the age of the entity"), - examples = "itemEntity.getItemAge();" - ) - private double getItemAge(Arguments arguments) { - return arguments.nextPrimitive(this).getItemAge(); - } - - @FunctionDoc( - name = "getThrower", - desc = "This method returns the player that threw the ItemEntity, null if not thrown by a player or player not found", - returns = @ReturnDoc(type = PlayerDef.class, desc = "the player that threw the entity"), - examples = "itemEntity.getThrower();" - ) - private Object getThrower(Arguments arguments) { - UUID throwerUuid = ((ItemEntityAccessor) arguments.nextPrimitive(this)).getThrower(); - return throwerUuid == null ? null : ThreadSafeUtils.getPlayerByUuid(EssentialUtils.getWorld(), throwerUuid); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/ItemStackDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/ItemStackDef.java deleted file mode 100644 index 834259b7..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/ItemStackDef.java +++ /dev/null @@ -1,497 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ParameterDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.*; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.compiler.LocatableTrace; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.BuiltInFunction; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.impl.ArucasList; -import me.senseiwells.arucas.utils.impl.ArucasMap; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.mixins.clientScript.NbtListMixin; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.ClientScriptUtils; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptBlockState; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptItemStack; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptMaterial; -import net.minecraft.client.resource.language.I18n; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.EnchantmentHelper; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.ItemEntity; -import net.minecraft.item.*; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtElement; -import net.minecraft.nbt.NbtList; -import net.minecraft.nbt.NbtString; -import net.minecraft.registry.Registries; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.ITEM_STACK; - -@ClassDoc( - name = ITEM_STACK, - desc = "This class represents an item stack. It can be used to create new item stacks, or to modify existing ones.", - superclass = MaterialDef.class, - language = Language.Java -) -public class ItemStackDef extends CreatableDefinition { - public ItemStackDef(Interpreter interpreter) { - super(ITEM_STACK, interpreter); - } - - @NotNull - @Override - public PrimitiveDefinition superclass() { - return this.getPrimitiveDef(MaterialDef.class); - } - - @Override - public Object asJavaValue(ClassInstance instance) { - return instance.asPrimitive(this).asDefault(); - } - - @Override - public boolean equals(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull ClassInstance other, @NotNull LocatableTrace trace) { - ScriptItemStack stack = other.getPrimitive(this); - return stack != null && instance.asPrimitive(this).stack.getItem() == stack.stack.getItem(); - } - - @Override - public int hashCode(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - return this.toString(instance, interpreter, trace).hashCode(); - } - - @NotNull - @Override - public String toString(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - ScriptItemStack stack = instance.asPrimitive(this); - return "ItemStack{id=" + stack.getId() + ", count=" + stack.stack.getCount() + "}"; - } - - @Override - public @NotNull ClassInstance copy(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - return this.create(new ScriptItemStack(instance.asPrimitive(this).stack.copy())); - } - - @Override - public List defineStaticMethods() { - return List.of( - BuiltInFunction.of("of", 1, this::of) - // BuiltInFunction.of("parse", 1, this::parse) - ); - } - - @FunctionDoc( - isStatic = true, - name = "of", - desc = "This creates an ItemStack from a material or a string", - params = {@ParameterDoc(type = MaterialDef.class, name = "material", desc = "the material, item stack, block, or string to create the ItemStack from")}, - returns = @ReturnDoc(type = ItemStackDef.class, desc = "the new ItemStack instance"), - examples = "ItemStack.of('dirt');" - ) - private ItemStack of(Arguments arguments) { - if (arguments.isNext(StringDef.class)) { - String id = arguments.nextPrimitive(StringDef.class); - Identifier identifier = ClientScriptUtils.stringToIdentifier(id); - return Registries.ITEM.getOrEmpty(identifier).orElseThrow( - () -> new RuntimeError("'%s' is not a valid item stack".formatted(id)) - ).getDefaultStack(); - } - if (arguments.isNext(MaterialDef.class)) { - ScriptMaterial material = arguments.nextPrimitive(MaterialDef.class); - return material.asItemStack(); - } - throw new RuntimeError("Parameter must be of type String or Material"); - } - - // @FunctionDoc( - // isStatic = true, - // name = "parse", - // desc = { - // "This creates an ItemStack from a NBT string, this can be in the form of a map", - // "or an ItemStack NBT, or like the item stack command format" - // }, - // params = {@ParameterDoc(type = StringDef.class, name = "nbtString", desc = "the NBT string to create the ItemStack from")}, - // returns = @ReturnDoc(type = ItemStackDef.class, desc = "the new ItemStack instance"), - // examples = "ItemStack.parse('{id:\"minecraft:dirt\",Count:64}')" - // ) - // private ItemStack parse(Arguments arguments) { - // if (arguments.isNext(StringDef.class)) { - // String nbt = arguments.nextPrimitive(StringDef.class); - // return ClientScriptUtils.stringToItemStack(nbt); - // } - // if (arguments.isNext(MapDef.class)) { - // ArucasMap map = arguments.nextPrimitive(MapDef.class); - // return ItemStack.fromNbt(ClientScriptUtils.mapToNbt(arguments.getInterpreter(), map, 100)); - // } - // throw new RuntimeError("Argument must be able to convert to NBT"); - // } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("getMaterial", this::getMaterial), - MemberFunction.of("getCount", this::getCount), - MemberFunction.of("getDurability", this::getDurability), - MemberFunction.of("getMaxDurability", this::getMaxDurability), - // MemberFunction.of("getEnchantments", this::getEnchantments), - MemberFunction.of("isBlockItem", this::isBlockItem), - MemberFunction.of("isStackable", this::isStackable), - MemberFunction.of("getMaxCount", this::getMaxCount), - MemberFunction.of("asEntity", this::asEntity), - MemberFunction.of("getCustomName", this::getCustomName), - // MemberFunction.of("isNbtEqual", 1, this::isNbtEqual), - // MemberFunction.of("getNbt", this::getNbt), - // MemberFunction.of("getNbtAsString", this::getNbtAsString), - MemberFunction.of("getTranslatedName", this::getTranslatedName), - MemberFunction.of("getMiningSpeedMultiplier", 1, this::getMiningSpeedMultiplier), - // MemberFunction.of("setCustomName", 1, this::setCustomName), - MemberFunction.of("setStackSize", 1, this::setStackSize), - MemberFunction.of("increment", 1, this::increment), - MemberFunction.of("decrement", 1, this::decrement) - // MemberFunction.of("setItemLore", 1, this::setLore), - // MemberFunction.of("setNbtFromString", 1, this::setNbtFromString), - // MemberFunction.of("setNbt", 1, this::setNbt) - ); - } - - @FunctionDoc( - name = "getMaterial", - desc = "This gets the material of the ItemStack", - returns = @ReturnDoc(type = MaterialDef.class, desc = "the material of the ItemStack"), - examples = "itemStack.getMaterial();" - ) - private Item getMaterial(Arguments arguments) { - return arguments.nextPrimitive(this).asItem(); - } - - @FunctionDoc( - name = "getCount", - desc = "This gets the count of the ItemStack, the amount of items in the stack", - returns = @ReturnDoc(type = NumberDef.class, desc = "the count of the ItemStack"), - examples = "itemStack.getCount();" - ) - private double getCount(Arguments arguments) { - return arguments.nextPrimitive(this).stack.getCount(); - } - - @FunctionDoc( - name = "getDurability", - desc = "This gets the durability of the item", - returns = @ReturnDoc(type = NumberDef.class, desc = "the durability of the item"), - examples = "itemStack.getDurability();" - ) - private double getDurability(Arguments arguments) { - ItemStack stack = arguments.nextPrimitive(this).stack; - return stack.getMaxDamage() - stack.getDamage(); - } - - @FunctionDoc( - name = "getMaxDurability", - desc = "This gets the max durability of the item", - returns = @ReturnDoc(type = NumberDef.class, desc = "the max durability of the item"), - examples = "itemStack.getMaxDurability();" - ) - private double getMaxDurability(Arguments arguments) { - return arguments.nextPrimitive(this).stack.getMaxDamage(); - } - - // @FunctionDoc( - // name = "getEnchantments", - // desc = { - // "This gets the enchantments of the item, in a map containing the", - // "id of the enchantment as the key and the level of the enchantment as the value" - // }, - // returns = @ReturnDoc(type = MapDef.class, desc = "the enchantments of the item, map may be empty"), - // examples = "itemStack.getEnchantments();" - // ) - // private ArucasMap getEnchantments(Arguments arguments) { - // ItemStack itemStack = arguments.nextPrimitive(this).stack; - // NbtList nbtList = itemStack.getItem() == Items.ENCHANTED_BOOK ? EnchantedBookItem.getEnchantmentNbt(itemStack) : itemStack.getEnchantments(); - // Interpreter interpreter = arguments.getInterpreter(); - // ArucasMap enchantmentMap = new ArucasMap(); - // for (Map.Entry entry : EnchantmentHelper.fromNbt(nbtList).entrySet()) { - // Identifier enchantmentId = Registries.ENCHANTMENT.getId(entry.getKey()); - // enchantmentMap.put( - // interpreter, - // enchantmentId == null ? interpreter.getNull() : interpreter.create(StringDef.class, enchantmentId.getPath()), - // interpreter.create(NumberDef.class, entry.getValue().doubleValue()) - // ); - // } - // return enchantmentMap; - // } - - @FunctionDoc( - name = "isBlockItem", - desc = "This checks if the ItemStack can be placed as a block", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the ItemStack can be placed as a block, false otherwise"), - examples = "itemStack.isBlockItem();" - ) - private boolean isBlockItem(Arguments arguments) { - return arguments.nextPrimitive(this).asItem() instanceof BlockItem; - } - - @FunctionDoc( - name = "isStackable", - desc = "This checks if the ItemStack is stackable", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the ItemStack is stackable, false otherwise"), - examples = "itemStack.isStackable();" - ) - private boolean isStackable(Arguments arguments) { - return arguments.nextPrimitive(this).stack.isStackable(); - } - - @FunctionDoc( - name = "getMaxCount", - desc = "This gets the max stack size of the ItemStack", - returns = @ReturnDoc(type = NumberDef.class, desc = "the max stack size of the ItemStack"), - examples = "itemStack.getMaxCount();" - ) - private double getMaxCount(Arguments arguments) { - return arguments.nextPrimitive(this).stack.getMaxCount(); - } - - @FunctionDoc( - name = "asEntity", - desc = "This creates an item entity with the item", - returns = @ReturnDoc(type = ItemEntityDef.class, desc = "the entity of the ItemStack"), - examples = "itemStack.asEntity();" - ) - private ItemEntity asEntity(Arguments arguments) { - ItemStack itemStack = arguments.nextPrimitive(this).stack; - ClientWorld world = EssentialUtils.getWorld(); - ItemEntity itemEntity = EntityType.ITEM.create(world); - if (itemEntity == null) { - throw new RuntimeError("'%s' cannot be converted into ItemEntity".formatted(itemStack)); - } - itemEntity.setStack(itemStack); - return itemEntity; - } - - @FunctionDoc( - name = "getCustomName", - desc = "This gets the custom name of the ItemStack", - returns = @ReturnDoc(type = StringDef.class, desc = "the custom name of the ItemStack"), - examples = "itemStack.getCustomName();" - ) - private String getCustomName(Arguments arguments) { - return arguments.nextPrimitive(this).stack.getName().getString(); - } - - // @FunctionDoc( - // name = "isNbtEqual", - // desc = "This checks if the ItemStack has the same NBT data as the other given ItemStack", - // params = {@ParameterDoc(type = ItemStackDef.class, name = "itemStack", desc = "the other ItemStack to compare to")}, - // returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the ItemStack has the same NBT data as the other given ItemStack"), - // examples = "itemStack.isNbtEqual(Material.GOLD_INGOT.asItemStack());" - // ) - // private boolean isNbtEqual(Arguments arguments) { - // ItemStack itemStack = arguments.nextPrimitive(this).stack; - // ItemStack otherItemStack = arguments.nextPrimitive(this).stack; - // return ItemStack.canCombine(itemStack, otherItemStack); - // } - // - // @FunctionDoc( - // name = "getNbt", - // desc = "This gets the NBT data of the ItemStack as a Map", - // returns = @ReturnDoc(type = MapDef.class, desc = "the NBT data of the ItemStack"), - // examples = "itemStack.getNbt();" - // ) - // private ArucasMap getNbt(Arguments arguments) { - // ItemStack itemStack = arguments.nextPrimitive(this).stack; - // NbtCompound nbtCompound = itemStack.getNbt(); - // return ClientScriptUtils.nbtToMap(arguments.getInterpreter(), nbtCompound, 10); - // } - - // @FunctionDoc( - // name = "getNbtAsString", - // desc = "This gets the NBT data of the ItemStack as a String", - // returns = @ReturnDoc(type = StringDef.class, desc = "the NBT data of the ItemStack"), - // examples = "itemStack.getNbtAsString();" - // ) - // private String getNbtAsString(Arguments arguments) { - // ItemStack itemStack = arguments.nextPrimitive(this).stack; - // NbtCompound nbtCompound = itemStack.getNbt(); - // return nbtCompound == null ? "" : itemStack.getNbt().toString(); - // } - - @FunctionDoc( - name = "getTranslatedName", - desc = { - "This gets the translated name of the ItemStack, for example", - "'diamond_sword' would return 'Diamond Sword' if your language is English" - }, - returns = @ReturnDoc(type = StringDef.class, desc = "the translated name of the ItemStack"), - examples = "itemStack.getTranslatedName();" - ) - private String getTranslatedName(Arguments arguments) { - ItemStack itemStack = arguments.nextPrimitive(this).stack; - return I18n.translate(itemStack.getItem().getTranslationKey()); - } - - @FunctionDoc( - name = "getMiningSpeedMultiplier", - desc = { - "This gets the mining speed multiplier of the ItemStack for the given Block,", - "for example a diamond pickaxe on stone would have a higher multiplier than air on stone" - }, - params = {@ParameterDoc(type = BlockDef.class, name = "block", desc = "the Block to get the mining speed multiplier for")}, - returns = @ReturnDoc(type = NumberDef.class, desc = "the mining speed multiplier of the ItemStack for the given Block"), - examples = """ - pickaxe = Material.DIAMOND_PICKAXE.asItemStack(); - goldBlock = Material.GOLD_BLOCK.asBlock(); - - pickaxe.getMiningSpeedMultiplier(goldBlock); - """ - ) - private double getMiningSpeedMultiplier(Arguments arguments) { - ItemStack itemStack = arguments.nextPrimitive(this).stack; - ScriptBlockState blockState = arguments.nextPrimitive(BlockDef.class); - return itemStack.getMiningSpeedMultiplier(blockState.state); - } - - // @FunctionDoc( - // name = "setCustomName", - // desc = "This sets the custom name of the ItemStack", - // params = {@ParameterDoc(type = TextDef.class, name = "customName", desc = "the custom name of the ItemStack, this can be text or string")}, - // returns = @ReturnDoc(type = ItemStackDef.class, desc = "the ItemStack with the new custom name"), - // examples = "itemStack.setCustomName('My Pickaxe');" - // ) - // private ClassInstance setCustomName(Arguments arguments) { - // ClassInstance instance = arguments.next(this); - // ItemStack itemStack = instance.asPrimitive(this).stack; - // Text text; - // if (arguments.isNext(TextDef.class)) { - // text = arguments.nextPrimitive(TextDef.class); - // } else { - // text = Text.literal(arguments.next().toString(arguments.getInterpreter())); - // } - // itemStack.setCustomName(text); - // return instance; - // } - - @FunctionDoc( - name = "setStackSize", - desc = "This sets the stack size of the ItemStack", - params = {@ParameterDoc(type = NumberDef.class, name = "stackSize", desc = "the stack size of the ItemStack")}, - returns = @ReturnDoc(type = ItemStackDef.class, desc = "the ItemStack with the new stack size"), - examples = "itemStack.setStackSize(5);" - ) - private ClassInstance setStackSize(Arguments arguments) { - ClassInstance instance = arguments.next(this); - ItemStack itemStack = instance.asPrimitive(this).stack; - double count = arguments.nextPrimitive(NumberDef.class); - itemStack.setCount((int) count); - return instance; - } - - @FunctionDoc( - name = "increment", - desc = "This increments the stack size of the ItemStack by number", - params = {@ParameterDoc(type = NumberDef.class, name = "count", desc = "number to increase")}, - returns = @ReturnDoc(type = ItemStackDef.class, desc = "the ItemStack with the new stack size"), - examples = "itemStack.increment(5);" - ) - private ClassInstance increment(Arguments arguments) { - ClassInstance instance = arguments.next(this); - ItemStack itemStack = instance.asPrimitive(this).stack; - double count = arguments.nextPrimitive(NumberDef.class); - itemStack.increment((int) count); - return instance; - } - - @FunctionDoc( - name = "decrement", - desc = "This decrements the stack size of the ItemStack by number", - params = {@ParameterDoc(type = NumberDef.class, name = "count", desc = "number to decrease")}, - returns = @ReturnDoc(type = ItemStackDef.class, desc = "the ItemStack with the new stack size"), - examples = "itemStack.decrement(5);" - ) - private ClassInstance decrement(Arguments arguments) { - ClassInstance instance = arguments.next(this); - ItemStack itemStack = instance.asPrimitive(this).stack; - double count = arguments.nextPrimitive(NumberDef.class); - itemStack.decrement((int) count); - return instance; - } - - // @FunctionDoc( - // name = "setItemLore", - // desc = "This sets the lore of the ItemStack", - // params = {@ParameterDoc(type = ListDef.class, name = "lore", desc = "the lore of the ItemStack as a list of Text")}, - // returns = @ReturnDoc(type = ItemStackDef.class, desc = "the ItemStack with the new lore"), - // examples = """ - // itemStack = Material.DIAMOND_PICKAXE.asItemStack(); - // itemStack.setItemLore([ - // Text.of('This is a pickaxe'), - // Text.of('It is made of diamond') - // ]); - // """ - // ) - // private ClassInstance setLore(Arguments arguments) { - // ClassInstance instance = arguments.next(this); - // ArucasList list = arguments.nextPrimitive(ListDef.class); - // List textList = new ArrayList<>(); - // for (ClassInstance value : list) { - // Text text = value.getPrimitive(TextDef.class); - // if (text == null) { - // throw new RuntimeError("List must contain only Text"); - // } - // textList.add(NbtString.of(Text.Serialization.toJsonString(text))); - // } - // ItemStack itemStack = instance.asPrimitive(this).stack; - // itemStack.getOrCreateSubNbt("display").put("Lore", NbtListMixin.createNbtList(textList, (byte) 8)); - // return instance; - // } - - // @FunctionDoc( - // name = "setNbtFromString", - // desc = "This sets the NBT data of the ItemStack from an NBT string", - // params = {@ParameterDoc(type = StringDef.class, name = "nbtString", desc = "the NBT data of the ItemStack as a string")}, - // returns = @ReturnDoc(type = ItemStackDef.class, desc = "the ItemStack with the new NBT data"), - // examples = "itemStack.setNbtFromString(\"{\\\"Lore\\\": []}\");" - // ) - // private ClassInstance setNbtFromString(Arguments arguments) { - // ClassInstance instance = arguments.next(this); - // ItemStack itemStack = instance.asPrimitive(this).stack; - // String nbtString = arguments.nextPrimitive(StringDef.class); - // NbtElement nbt = ClientScriptUtils.stringToNbt(nbtString); - // if (!(nbt instanceof NbtCompound compound)) { - // throw new RuntimeError("'%s' cannot be converted into an nbt compound".formatted(nbtString)); - // } - // itemStack.setNbt(compound); - // return instance; - // } - // - // @FunctionDoc( - // name = "setNbt", - // desc = "This sets the NBT data of the ItemStack", - // params = {@ParameterDoc(type = MapDef.class, name = "nbtMap", desc = "the NBT data of the ItemStack as a map")}, - // returns = @ReturnDoc(type = ItemStackDef.class, desc = "the ItemStack with the new NBT data"), - // examples = "itemStack.setNbt({'Lore': []});" - // ) - // private ClassInstance setNbt(Arguments arguments) { - // ClassInstance instance = arguments.next(this); - // ItemStack itemStack = instance.asPrimitive(this).stack; - // ArucasMap map = arguments.nextPrimitive(MapDef.class); - // itemStack.setNbt(ClientScriptUtils.mapToNbt(arguments.getInterpreter(), map, 10)); - // return instance; - // } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/KeyBindDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/KeyBindDef.java deleted file mode 100644 index 5e69467d..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/KeyBindDef.java +++ /dev/null @@ -1,157 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import kotlin.Unit; -import me.senseiwells.arucas.api.docs.annotations.*; -import me.senseiwells.arucas.builtin.FunctionDef; -import me.senseiwells.arucas.builtin.ListDef; -import me.senseiwells.arucas.builtin.StringDef; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.ConstructorFunction; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.impl.ArucasList; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.feature.keybinds.MultiKeyBind; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptKeyBind; -import me.senseiwells.essentialclient.utils.keyboard.KeyboardHelper; -import net.minecraft.client.util.InputUtil; - -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.KEY_BIND; - -@ClassDoc( - name = KEY_BIND, - desc = { - "This class allows you to create key binds that can be used, everything is", - "handled for you internally so you just need to regers the key bind and", - "the function you want to run when it is pressed." - }, - language = Language.Java -) -public class KeyBindDef extends CreatableDefinition { - public KeyBindDef(Interpreter interpreter) { - super(KEY_BIND, interpreter); - } - - @Override - public Object asJavaValue(ClassInstance instance) { - return instance.asPrimitive(this).getKeyBind(); - } - - @Override - public List defineConstructors() { - return List.of( - ConstructorFunction.of(1, this::construct) - ); - } - - @ConstructorDoc( - desc = "Creates a new key bind", - params = {@ParameterDoc(type = StringDef.class, name = "keyName", desc = "the name of the key")}, - examples = "new KeyBind('MyKey');" - ) - private Unit construct(Arguments arguments) { - ClassInstance instance = arguments.next(); - String keyName = arguments.nextPrimitive(StringDef.class); - instance.setPrimitive(this, new ScriptKeyBind(arguments.getInterpreter(), keyName)); - return null; - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("setKey", 1, this::setKey), - MemberFunction.arb("setKeys", this::setKeys), - MemberFunction.of("getKey", this::getKey), - MemberFunction.of("getKeys", this::getKeys), - MemberFunction.of("setCallback", 1, this::setCallback) - ); - } - - @FunctionDoc( - name = "setKey", - desc = "Sets the key bind to a new key", - params = {@ParameterDoc(type = StringDef.class, name = "keyName", desc = "the name of the key")}, - examples = "keyBind.setKey('f');" - ) - private Void setKey(Arguments arguments) { - MultiKeyBind keyBind = arguments.nextPrimitive(this).getKeyBind(); - int keyCode = KeyboardHelper.translateStringToKey(arguments.nextPrimitive(StringDef.class)); - keyBind.clearKey(); - keyBind.addKeys(keyCode); - return null; - } - - @FunctionDoc( - name = "setKeys", - desc = { - "Sets the key bind to new keys, you may also pass", - "in a list as the parameter, this is to keep compatability" - }, - params = @ParameterDoc(type = StringDef.class, name = "keyNames...", desc = "the names of keys", isVarargs = true), - examples = "keyBind.setKeys('control', 'f');" - ) - private Void setKeys(Arguments arguments) { - MultiKeyBind keyBind = arguments.nextPrimitive(this).getKeyBind(); - List keys; - if (arguments.size() == 2 && arguments.isNext(ListDef.class)) { - keys = arguments.nextPrimitive(ListDef.class); - } else { - keys = arguments.getRemaining(); - } - int[] inputKeys = new int[keys.size()]; - for (int i = 0; i < keys.size(); i++) { - String keyAsString = keys.get(i).toString(arguments.getInterpreter()); - int key = KeyboardHelper.translateStringToKey(keyAsString); - if (key < 0) { - throw new RuntimeError("Invalid key: " + keyAsString); - } - inputKeys[i] = key; - } - keyBind.clearKey(); - keyBind.addKeys(inputKeys); - return null; - } - - @FunctionDoc( - name = "getKey", - desc = "Gets the key bind's first key", - returns = @ReturnDoc(type = StringDef.class, desc = "the key bind's key"), - examples = "keyBind.getKey();" - ) - private String getKey(Arguments arguments) { - MultiKeyBind keyBind = arguments.nextPrimitive(this).getKeyBind(); - return KeyboardHelper.translateKeyToString(keyBind.getFirstKey().getCode()); - } - - @FunctionDoc( - name = "getKeys", - desc = "Gets the all of the keys in the key bind", - returns = @ReturnDoc(type = ListDef.class, desc = "list of strings of all the keys"), - examples = "keybind.getKeys();" - ) - private ArucasList getKeys(Arguments arguments) { - MultiKeyBind keyBind = arguments.nextPrimitive(this).getKeyBind(); - ArucasList list = new ArucasList(); - for (InputUtil.Key key : keyBind.getKeys()) { - list.add(arguments.getInterpreter().create(StringDef.class, KeyboardHelper.translateKeyToString(key.getCode()))); - } - return list; - } - - @FunctionDoc( - name = "setCallback", - desc = "Sets the callback function for the key bind", - params = {@ParameterDoc(type = FunctionDef.class, name = "callback", desc = "the callback function")}, - examples = "keyBind.setCallback(fun() { print('My key was pressed'); });" - ) - private Void setCallback(Arguments arguments) { - ScriptKeyBind keyBind = arguments.nextPrimitive(this); - keyBind.setFunction(arguments.nextPrimitive(FunctionDef.class)); - return null; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/LivingEntityDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/LivingEntityDef.java deleted file mode 100644 index df5f614e..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/LivingEntityDef.java +++ /dev/null @@ -1,109 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.BooleanDef; -import me.senseiwells.arucas.builtin.ListDef; -import me.senseiwells.arucas.builtin.NumberDef; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.compiler.LocatableTrace; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.impl.ArucasList; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.clientscript.core.MinecraftAPI; -import net.minecraft.entity.LivingEntity; -import net.minecraft.registry.Registries; -import net.minecraft.util.Identifier; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.LIVING_ENTITY; - -@ClassDoc( - name = LIVING_ENTITY, - desc = { - "This class extends Entity and so inherits all of their methods too,", - "LivingEntities are any entities that are alive, so all mobs" - }, - superclass = EntityDef.class, - language = Language.Java -) -public class LivingEntityDef extends PrimitiveDefinition { - public LivingEntityDef(Interpreter interpreter) { - super(MinecraftAPI.LIVING_ENTITY, interpreter); - } - - @Deprecated - @NotNull - @Override - public ClassInstance create(@NotNull LivingEntity value) { - return super.create(value); - } - - @NotNull - @Override - public PrimitiveDefinition superclass() { - return this.getInterpreter().getPrimitive(EntityDef.class); - } - - @NotNull - @Override - public String toString(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - return "LivingEntity{id=%s}".formatted(Registries.ENTITY_TYPE.getId(instance.asPrimitive(this).getType()).getPath()); - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("getStatusEffects", this::getStatusEffects), - MemberFunction.of("getHealth", this::getHealth), - MemberFunction.of("isFlyFalling", this::isFlyFalling) - ); - } - - @FunctionDoc( - name = "getStatusEffects", - desc = { - "This gets the LivingEntity's status effects, you can find", - "a list of all the ids of the status effects", - "[here](https://minecraft.fandom.com/wiki/Java_Edition_data_values#Effects)" - }, - returns = @ReturnDoc(type = ListDef.class, desc = "a list of status effects, may be empty"), - examples = "livingEntity.getStatusEffects();" - ) - private ArucasList getStatusEffects(Arguments arguments) { - LivingEntity livingEntity = arguments.nextPrimitive(this); - ArucasList potionList = new ArucasList(); - Interpreter interpreter = arguments.getInterpreter(); - livingEntity.getStatusEffects().forEach(s -> { - Identifier effectId = Registries.STATUS_EFFECT.getId(s.getEffectType().value()); - potionList.add(effectId == null ? interpreter.getNull() : interpreter.convertValue(effectId.getPath())); - }); - return potionList; - } - - @FunctionDoc( - name = "getHealth", - desc = "This gets the LivingEntity's current health", - returns = @ReturnDoc(type = NumberDef.class, desc = "the LivingEntity's health"), - examples = "livingEntity.getHealth();" - ) - private double getHealth(Arguments arguments) { - return arguments.nextPrimitive(this).getHealth(); - } - - @FunctionDoc( - name = "isFlyFalling", - desc = "This checks if the LivingEntity is fly falling (gliding with elytra)", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the LivingEntity is fly falling"), - examples = "livingEntity.isFlyFalling();" - ) - private boolean isFlyFalling(Arguments arguments) { - return arguments.nextPrimitive(this).isFallFlying(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/MaterialDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/MaterialDef.java deleted file mode 100644 index 956e18ef..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/MaterialDef.java +++ /dev/null @@ -1,190 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ParameterDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.StringDef; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.compiler.LocatableTrace; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.BuiltInFunction; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.utils.clientscript.ClientScriptUtils; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptMaterial; -import net.minecraft.block.Block; -import net.minecraft.client.resource.language.I18n; -import net.minecraft.item.Item; -import net.minecraft.registry.Registries; -import net.minecraft.util.Identifier; -import org.jetbrains.annotations.NotNull; - -import java.util.*; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.MATERIAL; - -@ClassDoc( - name = MATERIAL, - desc = { - "This class represents all possible item and block types", - "and allows you to convert them into instances of ItemStacks and Blocks" - }, - language = Language.Java -) -public class MaterialDef extends CreatableDefinition { - public MaterialDef(Interpreter interpreter) { - super(MATERIAL, interpreter); - } - - @Override - public Object asJavaValue(ClassInstance instance) { - return instance.asPrimitive(this).asDefault(); - } - - @Override - public boolean equals(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull ClassInstance other, @NotNull LocatableTrace trace) { - ScriptMaterial material = other.getPrimitive(this); - return material != null && instance.asPrimitive(this).asDefault().equals(material.asDefault()); - } - - @Override - public int hashCode(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - return instance.asPrimitive(this).asDefault().hashCode(); - } - - @NotNull - @Override - public String toString(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - return instance.asPrimitive(this).asString(); - } - - @Override - public List defineStaticFields() { - SortedMap map = new TreeMap<>(); - - for (Item item : Registries.ITEM) { - map.put(item.toString().toUpperCase(), this.create(ScriptMaterial.materialOf(item))); - } - for (Block block : Registries.BLOCK) { - Identifier identifier = Registries.BLOCK.getId(block); - map.computeIfAbsent(identifier.getPath().toUpperCase(), s -> { - return this.create(ScriptMaterial.materialOf(block)); - }); - } - - List fields = new ArrayList<>(map.size()); - map.forEach((key, value) -> fields.add(new PrimitiveField(key, value, false))); - fields.add(new PrimitiveField("ALL", map.values().stream().toList(), false)); - return fields; - } - - @Override - public List defineStaticMethods() { - return List.of( - BuiltInFunction.of("of", 1, this::of) - ); - } - - @FunctionDoc( - isStatic = true, - name = "of", - desc = { - "This converts a block or item id into a Material.", - "This method will throw an error if the id is invalid" - }, - params = {@ParameterDoc(type = StringDef.class, name = "id", desc = "the id of the block or item")}, - returns = @ReturnDoc(type = MaterialDef.class, desc = "the material instance from the id"), - examples = "Material.of('diamond');" - ) - private Object of(Arguments arguments) { - String id = arguments.nextPrimitive(StringDef.class); - Identifier identifier = ClientScriptUtils.stringToIdentifier(id); - Optional item = Registries.ITEM.getOrEmpty(identifier); - if (item.isEmpty()) { - Optional block = Registries.BLOCK.getOrEmpty(identifier); - if (block.isPresent()) { - return block.get(); - } - } - return item.orElseThrow(() -> new RuntimeError("'%s' is not a valid Material".formatted(id))); - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("getFullId", this::getFullId), - MemberFunction.of("getId", this::getId), - MemberFunction.of("asItemStack", this::asItemStack), - MemberFunction.of("asBlock", this::asBlock), - MemberFunction.of("getTranslatedName", this::getTranslatedName) - ); - } - - @FunctionDoc( - name = "getFullId", - desc = "This returns the full id of the material, for example: 'minecraft:diamond'", - returns = @ReturnDoc(type = StringDef.class, desc = "the full id representation of the material"), - examples = "material.getFullId();" - ) - private Object getFullId(Arguments arguments) { - ScriptMaterial material = arguments.nextPrimitive(this); - return material.getId().toString(); - } - - @FunctionDoc( - name = "getId", - desc = "This returns the id of the material, for example: 'diamond'", - returns = @ReturnDoc(type = StringDef.class, desc = "the id representation of the material"), - examples = "material.getId();" - ) - private Object getId(Arguments arguments) { - ScriptMaterial material = arguments.nextPrimitive(this); - return material.getId().getPath(); - } - - @FunctionDoc( - name = "asItemStack", - desc = { - "This converts the material into an ItemStack.", - "If it cannot be converted an error will be thrown" - }, - returns = @ReturnDoc(type = ItemStackDef.class, desc = "the ItemStack representation of the material"), - examples = "material.asItemStack();" - ) - private Object asItemStack(Arguments arguments) { - ScriptMaterial material = arguments.nextPrimitive(this); - return material.asItemStack(); - } - - @FunctionDoc( - name = "asBlock", - desc = { - "This converts the material into a Block.", - "If it cannot be converted an error will be thrown" - }, - returns = @ReturnDoc(type = BlockDef.class, desc = "the Block representation of the material"), - examples = "material.asBlock();" - ) - private Object asBlock(Arguments arguments) { - ScriptMaterial material = arguments.nextPrimitive(this); - return material.asBlockState(); - } - - @FunctionDoc( - name = "getTranslatedName", - desc = { - "This gets the translated name of the ItemStack, for example: ", - "Material.DIAMOND_SWORD would return 'Diamond Sword' if your language is English" - }, - returns = @ReturnDoc(type = StringDef.class, desc = "the translated name of the Material"), - examples = "material.getTranslatedName();" - ) - private Object getTranslatedName(Arguments arguments) { - ScriptMaterial material = arguments.nextPrimitive(this); - return I18n.translate(material.getTranslationKey()); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/MerchantScreenDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/MerchantScreenDef.java deleted file mode 100644 index 04673419..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/MerchantScreenDef.java +++ /dev/null @@ -1,311 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ParameterDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.BooleanDef; -import me.senseiwells.arucas.builtin.ListDef; -import me.senseiwells.arucas.builtin.NumberDef; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.impl.ArucasList; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptItemStack; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptMaterial; -import me.senseiwells.essentialclient.utils.inventory.InventoryUtils; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.ingame.MerchantScreen; -import net.minecraft.screen.MerchantScreenHandler; -import net.minecraft.village.TradeOffer; -import net.minecraft.village.TradeOfferList; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.MERCHANT_SCREEN; -import static me.senseiwells.essentialclient.utils.clientscript.ClientScriptUtils.ensureMainThread; -import static me.senseiwells.essentialclient.utils.clientscript.ClientScriptUtils.warnMainThread; - -@ClassDoc( - name = MERCHANT_SCREEN, - desc = { - "This class extends Screen and so inherits all of their methods too,", - "this class is used to add functionality to trading screens." - }, - superclass = ScreenDef.class, - language = Language.Java -) -public class MerchantScreenDef extends CreatableDefinition { - public MerchantScreenDef(Interpreter interpreter) { - super(MERCHANT_SCREEN, interpreter); - } - - @NotNull - @Override - public PrimitiveDefinition superclass() { - return this.getPrimitiveDef(ScreenDef.class); - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("getTradeList", this::getTradeList), - MemberFunction.of("getTradeListSize", this::getTradeListSize), - MemberFunction.of("getVillagerLevel", this::getVillagerLevel), - MemberFunction.of("getVillagerXpBar", this::getVillagerXpBar), - MemberFunction.of("tradeIndex", 1, this::tradeIndex), - MemberFunction.of("getIndexOfTradeItem", 1, this::getIndexOfTradeItem), - MemberFunction.of("getTradeItemForIndex", 1, this::getTradeItemForIndex), - MemberFunction.of("doesVillagerHaveTrade", 1, this::doesVillagerHaveTrade), - MemberFunction.of("isTradeDisabled", 1, this::isTradeDisabled), - MemberFunction.of("getPriceForIndex", 1, this::getPriceForIndex), - MemberFunction.of("selectTrade", 1, this::selectTrade), - MemberFunction.of("clearTrade", this::clearTrade), - MemberFunction.of("isTradeSelected", this::isTradeSelected), - MemberFunction.of("tradeSelected", this::tradeSelected), - MemberFunction.of("tradeSelectedAndThrow", this::tradeSelectedAndThrow) - ); - } - - @FunctionDoc( - name = "getTradeListSize", - desc = "This gets the size of all the trades available", - returns = @ReturnDoc(type = NumberDef.class, desc = "the size of the trade list"), - examples = "screen.getTradeListSize();" - ) - private int getTradeListSize(Arguments arguments) { - MerchantScreen merchantScreen = this.checkIsCurrentScreen(arguments); - TradeOfferList tradeOfferList = merchantScreen.getScreenHandler().getRecipes(); - return tradeOfferList.size(); - } - - @FunctionDoc( - name = "getTradeList", - desc = "This gets a list of all the merchant's trades", - returns = @ReturnDoc(type = ListDef.class, desc = "the list of all the Trades"), - examples = "screen.getTradeList();" - ) - private ArucasList getTradeList(Arguments arguments) { - MerchantScreen merchantScreen = this.checkIsCurrentScreen(arguments); - ArucasList valueList = new ArucasList(); - TradeOfferList tradeOfferList = merchantScreen.getScreenHandler().getRecipes(); - for (TradeOffer tradeOffers : tradeOfferList) { - valueList.add(arguments.getInterpreter().convertValue(tradeOffers)); - } - return valueList; - } - - @FunctionDoc( - name = "getVillagerLevel", - desc = { - "This gets the level of the villager, this will", - "throw an error if you are not trading with a villager.", - "The level can be between 1 - 5 from Novice to Master" - }, - returns = @ReturnDoc(type = NumberDef.class, desc = "the level of the villager"), - examples = "screen.getVillagerLevel();" - ) - private int getVillagerLevel(Arguments arguments) { - MerchantScreenHandler handler = this.checkIsCurrentScreen(arguments).getScreenHandler(); - if (handler.isLeveled()) { - return handler.getLevelProgress(); - } - throw new RuntimeError("Merchant isn't a villager"); - } - - @FunctionDoc( - name = "getVillagerXp", - desc = { - "This gets the amount of xp in the villagers xp bar,", - "The total amount of xp is hardcoded for each level.", - "Level 2 requires 10 xp, 3 requires 70 (60 xp from 2 -> 3),", - "4 requires 150 (80 xp from 3 -> 4), 5 requires 250", - "(100 xp from 4 -> 5). 250 is the max xp a villager can have" - }, - returns = @ReturnDoc(type = NumberDef.class, desc = "the amount of xp"), - examples = "screen.getVillagerXpBar" - ) - private int getVillagerXpBar(Arguments arguments) { - MerchantScreenHandler handler = this.checkIsCurrentScreen(arguments).getScreenHandler(); - if (handler.isLeveled()) { - return handler.getExperience(); - } - throw new RuntimeError("Merchant isn't a villager"); - } - - @FunctionDoc( - name = "tradeIndex", - desc = { - "This makes your player trade with the merchant at a certain index.", - "You must be inside the merchant GUI or an error will be thrown" - }, - params = {@ParameterDoc(type = NumberDef.class, name = "index", desc = "the index of the trade")}, - examples = "screen.tradeIndex(0);" - ) - private Void tradeIndex(Arguments arguments) { - int index = arguments.skip().nextPrimitive(NumberDef.class).intValue(); - ensureMainThread("tradeIndex", arguments.getInterpreter(), () -> { - InventoryUtils.tradeAllItems(index, false); - }); - return null; - } - - @FunctionDoc( - name = "getIndexOfTradeItem", - desc = { - "This gets the index of a trade for a certain item.", - "You must be inside the merchant GUI or an error will be thrown" - }, - params = {@ParameterDoc(type = MaterialDef.class, name = "material", desc = "the item to get the index of")}, - returns = @ReturnDoc(type = NumberDef.class, desc = "the index of the trade"), - examples = "screen.getIndexOfTradeItem(Material.DIAMOND_PICKAXE);" - ) - private int getIndexOfTradeItem(Arguments arguments) { - warnMainThread("getIndexOfTradeItem", arguments.getInterpreter()); - ScriptMaterial material = arguments.skip().nextPrimitive(MaterialDef.class); - return InventoryUtils.getIndexOfItemInMerchant(material.asItem()); - } - - @FunctionDoc( - name = "getTradeItemForIndex", - desc = { - "This gets the item stack of a trade at a certain index.", - "You must be inside the merchant GUI or an error will be thrown" - }, - params = {@ParameterDoc(type = NumberDef.class, name = "index", desc = "the index of the trade")}, - returns = @ReturnDoc(type = ItemStackDef.class, desc = "the item stack of the trade"), - examples = "screen.getTradeItemForIndex(0);" - ) - private ScriptItemStack getTradeItemForIndex(Arguments arguments) { - warnMainThread("getTradeItemForIndex", arguments.getInterpreter()); - int index = arguments.skip().nextPrimitive(NumberDef.class).intValue(); - return new ScriptItemStack(InventoryUtils.getTrade(index)); - } - - @FunctionDoc( - name = "doesVillagerHaveTrade", - desc = { - "This checks if the villager has a trade for a certain item.", - "You must be inside the merchant GUI or an error will be thrown" - }, - params = {@ParameterDoc(type = MaterialDef.class, name = "materialLike", desc = "the item or material to check for")}, - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the villager has a trade for the item, false otherwise"), - examples = "screen.doesVillagerHaveTrade(Material.DIAMOND_PICKAXE);" - ) - private boolean doesVillagerHaveTrade(Arguments arguments) { - warnMainThread("doesVillagerHaveTrade", arguments.getInterpreter()); - ScriptMaterial material = arguments.skip().nextPrimitive(MaterialDef.class); - return InventoryUtils.checkHasTrade(material.asItem()); - } - - @FunctionDoc( - name = "selectTrade", - desc = { - "This selects the currently selected trade, as if you were to click it.", - "You must be inside the merchant GUI or an error will be thrown" - }, - params = {@ParameterDoc(type = NumberDef.class, name = "index", desc = "the index of the trade")}, - examples = "screen.selectTrade(0);" - ) - private Void selectTrade(Arguments arguments) { - int index = arguments.skip().nextPrimitive(NumberDef.class).intValue(); - ensureMainThread("selectTrade", arguments.getInterpreter(), () -> { - InventoryUtils.selectTrade(index); - }); - return null; - } - - @FunctionDoc( - name = "clearTrade", - desc = { - "This clears the currently selected trade.", - "You must be inside the merchant GUI or an error will be thrown" - }, - examples = "screen.clearTrade();" - ) - private Void clearTrade(Arguments arguments) { - ensureMainThread("clearTrade", arguments.getInterpreter(), InventoryUtils::clearTrade); - return null; - } - - @FunctionDoc( - name = "tradeSelected", - desc = { - "This trades the currently selected trade.", - "You must be inside the merchant GUI or an error will be thrown" - }, - examples = "screen.tradeSelected();" - ) - private Void tradeSelected(Arguments arguments) { - ensureMainThread("tradeSelected", arguments.getInterpreter(), () -> InventoryUtils.tradeSelectedRecipe(false)); - return null; - } - - @FunctionDoc( - name = "tradeSelectedAndThrow", - desc = { - "This trades the currently selected trade and throws the items that were traded.", - "You must be inside the merchant GUI or an error will be thrown" - }, - examples = "screen.tradeSelectedAndThrow();" - ) - private Void tradeSelectedAndThrow(Arguments arguments) { - ensureMainThread("tradeSelectedAndThrow", arguments.getInterpreter(), () -> InventoryUtils.tradeSelectedRecipe(true)); - return null; - } - - @FunctionDoc( - name = "isTradeSelected", - desc = "This returns true if a trade is selected", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if a trade is selected"), - examples = "screen.isTradeSelected();" - ) - private boolean isTradeSelected(Arguments arguments) { - warnMainThread("isTradeSelected", arguments.getInterpreter()); - return InventoryUtils.isTradeSelected(); - } - - @FunctionDoc( - name = "isTradeDisabled", - desc = "This returns true if a trade is disabled at an index", - params = {@ParameterDoc(type = NumberDef.class, name = "index", desc = "the index of the trade")}, - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if a trade is disabled"), - examples = "screen.isTradeDisabled(1);" - ) - private boolean isTradeDisabled(Arguments arguments) { - warnMainThread("isTradeDisabled", arguments.getInterpreter()); - int index = arguments.skip().nextPrimitive(NumberDef.class).intValue(); - return InventoryUtils.checkTradeDisabled(index); - } - - @FunctionDoc( - name = "getPriceForIndex", - desc = { - "This gets the price of a trade at a certain index.", - "You must be inside the merchant GUI or an error will be thrown" - }, - params = {@ParameterDoc(type = NumberDef.class, name = "index", desc = "the index of the trade")}, - returns = @ReturnDoc(type = NumberDef.class, desc = "the price of the trade"), - examples = "screen.getPriceForIndex(0);" - ) - private int getPriceForIndex(Arguments arguments) { - warnMainThread("getPriceForIndex", arguments.getInterpreter()); - int index = arguments.skip().nextPrimitive(NumberDef.class).intValue(); - return InventoryUtils.checkPriceForTrade(index); - } - - public MerchantScreen checkIsCurrentScreen(Arguments arguments) { - MinecraftClient client = EssentialUtils.getClient(); - MerchantScreen screen = arguments.nextPrimitive(this); - if (client.currentScreen != screen) { - throw new RuntimeError("Currently not in that screen"); - } - return screen; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/MinecraftClientDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/MinecraftClientDef.java deleted file mode 100644 index 10e6c2d9..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/MinecraftClientDef.java +++ /dev/null @@ -1,868 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import com.mojang.authlib.GameProfile; -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.ParseResults; -import com.mojang.brigadier.suggestion.Suggestion; -import com.mojang.brigadier.suggestion.Suggestions; -import com.mojang.brigadier.tree.CommandNode; -import com.mojang.brigadier.tree.LiteralCommandNode; -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ParameterDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.*; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.compiler.LocatableTrace; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.functions.ArucasFunction; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.BuiltInFunction; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.impl.ArucasList; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.clientscript.core.ClientScript; -import me.senseiwells.essentialclient.clientscript.core.MinecraftAPI; -import me.senseiwells.essentialclient.mixins.clientScript.MinecraftClientAccessor; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.rule.client.ClientRule; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.ClientScriptUtils; -import me.senseiwells.essentialclient.utils.clientscript.ClientTickSyncer; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptItemStack; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptMaterial; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptPos; -import me.senseiwells.essentialclient.utils.command.CommandHelper; -import me.senseiwells.essentialclient.utils.interfaces.ChatHudAccessor; -import me.senseiwells.essentialclient.utils.inventory.InventoryUtils; -import me.senseiwells.essentialclient.utils.keyboard.KeyboardHelper; -import me.senseiwells.essentialclient.utils.misc.Scheduler; -import me.senseiwells.essentialclient.utils.network.MojangAPI; -import me.senseiwells.essentialclient.utils.render.FakeInventoryScreen; -import net.fabricmc.loader.api.FabricLoader; -import net.fabricmc.loader.api.ModContainer; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.hud.ChatHudLine; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.client.network.ServerInfo; -import net.minecraft.client.util.ScreenshotRecorder; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.command.CommandSource; -import net.minecraft.item.ItemStack; -import net.minecraft.network.packet.c2s.play.UpdateSignC2SPacket; -import net.minecraft.registry.Registries; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.sound.SoundCategory; -import net.minecraft.sound.SoundEvent; -import net.minecraft.text.Text; -import net.minecraft.util.math.MathHelper; -import org.jetbrains.annotations.NotNull; -import org.lwjgl.glfw.GLFW; - -import java.io.File; -import java.util.List; -import java.util.UUID; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.MINECRAFT_CLIENT; - -@ClassDoc( - name = MINECRAFT_CLIENT, - desc = "This allows for many core interactions with the MinecraftClient", - language = Language.Java -) -public class MinecraftClientDef extends PrimitiveDefinition { - public final ClassInstance instance = this.create(EssentialUtils.getClient()); - - public MinecraftClientDef(Interpreter interpreter) { - super(MinecraftAPI.MINECRAFT_CLIENT, interpreter); - } - - @Override - public boolean canExtend() { - return false; - } - - @NotNull - @Override - public String toString(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - return "MinecraftClient"; - } - - @Override - public List defineStaticMethods() { - return List.of( - BuiltInFunction.of("getClient", this::getClientStatic), - BuiltInFunction.of("get", this::getClientStaticShort) - ); - } - - @FunctionDoc( - isStatic = true, - name = "getClient", - desc = "Returns the MinecraftClient instance", - returns = @ReturnDoc(type = MinecraftClientDef.class, desc = "the MinecraftClient instance"), - examples = "MinecraftClient.getClient();" - ) - private ClassInstance getClientStatic(Arguments arguments) { - return this.instance; - } - - @FunctionDoc( - isStatic = true, - name = "get", - desc = "Returns the MinecraftClient instance", - returns = @ReturnDoc(type = MinecraftClientDef.class, desc = "the MinecraftClient instance"), - examples = "MinecraftClient.get();" - ) - private ClassInstance getClientStaticShort(Arguments arguments) { - return this.instance; - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("syncToTick", this::syncToTick), - MemberFunction.of("getRunDirectory", this::getRunDirectory), - MemberFunction.of("screenshot", this::screenshot), - MemberFunction.of("screenshot", 1, this::screenshotNamed), - MemberFunction.of("pressKey", 1, this::pressKey), - MemberFunction.of("releaseKey", 1, this::releaseKey), - MemberFunction.of("holdKey", 2, this::holdKey), - MemberFunction.arb("editSign", this::editSignFull), - MemberFunction.of("clearChat", this::clearChat), - MemberFunction.of("getLatestChatMessage", this::getLatestChatMessage), - MemberFunction.of("addCommand", 1, this::addCommand), - MemberFunction.of("completionsForCommand", 1, this::completionsForCommand), - MemberFunction.of("isInSinglePlayer", this::isInSinglePlayer), - MemberFunction.of("getOnlinePlayerNames", this::getOnlinePlayerNames), - MemberFunction.of("getOnlinePlayerUuids", this::getOnlinePlayerUuids), - MemberFunction.of("getOnlinePlayerNamesAndUuids", this::getOnlinePlayerNamesAndUuids), - MemberFunction.of("playerNameFromUuid", 1, this::playerNameFromUuid), - MemberFunction.of("uuidFromPlayerName", 1, this::uuidFromPlayerName), - MemberFunction.of("getServerIp", this::getServerIp), - MemberFunction.of("getServerName", this::getServerName), - MemberFunction.of("getPing", this::getPing), - MemberFunction.of("getScriptsPath", this::getScriptsPath), - MemberFunction.of("setEssentialClientRule", 2, this::setEssentialClientRule), - MemberFunction.of("resetEssentialClientRule", 1, this::resetEssentialClientRule), - MemberFunction.of("getEssentialClientValue", 1, this::getEssentialClientRuleValue), - MemberFunction.of("getModList", this::getModList), - MemberFunction.of("getFps", this::getFps), - - MemberFunction.of("getPlayer", this::getPlayer), - MemberFunction.of("getWorld", this::getWorld), - MemberFunction.of("getVersion", this::getVersion), - - MemberFunction.of("parseStringToNbt", 1, this::parseStringToNbt), - MemberFunction.of("playSound", 3, this::playSound), - MemberFunction.of("renderFloatingItem", 1, this::renderFloatingItem), - MemberFunction.of("stripFormatting", 1, this::stripFormatting), - MemberFunction.of("getCursorStack", this::getCursorStack), - MemberFunction.of("setCursorStack", 1, this::setCursorStack), - MemberFunction.of("getClientRenderDistance", this::getClientRenderDistance), - MemberFunction.of("setClientRenderDistance", 1, this::setClientRenderDistance), - MemberFunction.of("runOnMainThread", 1, this::runOnMainThread, "Use 'client.run(func)'"), - MemberFunction.of("run", 1, this::run), - MemberFunction.of("tick", this::tick), - - MemberFunction.of("canSendScriptPacket", this::canSendScriptPacket), - MemberFunction.arb("sendScriptPacket", this::sendScriptPacket) - ); - } - - @FunctionDoc( - deprecated = "This function is unstable, it should not be used", - name = "syncToTick", - desc = "Synchronizes the current thread in Arucas to the next game tick", - examples = "client.syncToTick();" - ) - private Object syncToTick(Arguments arguments) { - ClientTickSyncer.syncToTick(); - return null; - } - - @FunctionDoc( - name = "getRunDirectory", - desc = "Returns the directory where the client is running", - returns = @ReturnDoc(type = FileDef.class, desc = "the Minecraft run directory"), - examples = "client.getRunDirectory();" - ) - private File getRunDirectory(Arguments arguments) { - MinecraftClient client = arguments.nextPrimitive(this); - return client.runDirectory; - } - - @FunctionDoc( - name = "screenshot", - desc = "This makes the client take a screenshot", - examples = "client.screenshot();" - ) - private Object screenshot(Arguments arguments) { - MinecraftClient client = arguments.nextPrimitive(this); - ScreenshotRecorder.saveScreenshot( - client.runDirectory, - client.getFramebuffer(), - text -> client.execute(() -> client.inGameHud.getChatHud().addMessage(text)) - ); - return null; - } - - @FunctionDoc( - name = "screenshot", - desc = "This makes the client take a screenshot and saves it with a given name", - params = {@ParameterDoc(type = StringDef.class, name = "name", desc = "the name of the file")}, - examples = "client.screenshot('screenshot.png');" - ) - private Void screenshotNamed(Arguments arguments) { - MinecraftClient client = arguments.nextPrimitive(this); - String name = arguments.nextPrimitive(StringDef.class); - ScreenshotRecorder.saveScreenshot( - client.runDirectory, - name.endsWith(".png") ? name : name + ".png", - client.getFramebuffer(), - text -> client.execute(() -> client.inGameHud.getChatHud().addMessage(text)) - ); - return null; - } - - @FunctionDoc( - name = "pressKey", - desc = { - "This allows you to simulate a key press inside of Minecraft, this will only press the key down.", - "This will throw an error if the key is unknown" - }, - params = {@ParameterDoc(type = StringDef.class, name = "key", desc = "the key to press")}, - examples = "client.pressKey('f');" - ) - private Void pressKey(Arguments arguments) { - MinecraftClient client = arguments.nextPrimitive(this); - String key = arguments.nextPrimitive(StringDef.class); - final int keyCode = KeyboardHelper.translateStringToKey(key); - if (keyCode == -1) { - throw new RuntimeError("Tried to press unknown key"); - } - ClientScriptUtils.ensureMainThread("pressKey", arguments.getInterpreter(), () -> { - long handler = client.getWindow().getHandle(); - int scanCode = GLFW.glfwGetKeyScancode(keyCode); - client.keyboard.onKey(handler, keyCode, scanCode, 1, 0); - }); - return null; - } - - @FunctionDoc( - name = "releaseKey", - desc = { - "This allows you to simulate a key release inside of Minecraft, this", - "is useful for keys that only work on release, for example `F3`, this", - "will throw an error if the key is unknown" - }, - params = {@ParameterDoc(type = StringDef.class, name = "key", desc = "the key to release")}, - examples = "client.releaseKey('f');" - ) - private Void releaseKey(Arguments arguments) { - MinecraftClient client = arguments.nextPrimitive(this); - String key = arguments.nextPrimitive(StringDef.class); - final int keyCode = KeyboardHelper.translateStringToKey(key); - if (keyCode == -1) { - throw new RuntimeError("Tried to press unknown key"); - } - ClientScriptUtils.ensureMainThread("releaseKey", arguments.getInterpreter(), () -> { - long handler = client.getWindow().getHandle(); - int scanCode = GLFW.glfwGetKeyScancode(keyCode); - client.keyboard.onKey(handler, keyCode, scanCode, 0, 0); - }); - return null; - } - - @FunctionDoc( - name = "holdKey", - desc = { - "This allows you to simulate a key being held inside of Minecraft, this will press, hold, and release.", - "This will throw an error if the given key is unknown" - }, - params = { - @ParameterDoc(type = StringDef.class, name = "key", desc = "the key to hold"), - @ParameterDoc(type = NumberDef.class, name = "milliseconds", desc = "the number of milliseconds you want it held for") - }, - examples = "client.holdKey('f', 100);" - ) - private Void holdKey(Arguments arguments) { - MinecraftClient client = arguments.nextPrimitive(this); - String key = arguments.nextPrimitive(StringDef.class); - int milliseconds = arguments.nextPrimitive(NumberDef.class).intValue(); - int keyCode = KeyboardHelper.translateStringToKey(key); - if (keyCode == -1) { - throw new RuntimeError("Tried to press unknown key"); - } - long handler = client.getWindow().getHandle(); - int scanCode = GLFW.glfwGetKeyScancode(keyCode); - Function keyPartial = action -> () -> client.keyboard.onKey(handler, keyCode, scanCode, action, 0); - - int ticks = MathHelper.ceil(milliseconds / 50.0F); - if (ticks < 0) { - throw new RuntimeError("Ticks cannot be negative"); - } - ClientScriptUtils.ensureMainThread("holdKey", arguments.getInterpreter(), keyPartial.apply(GLFW.GLFW_PRESS)); - Scheduler.scheduleLoop(1, 5, ticks, keyPartial.apply(GLFW.GLFW_REPEAT)); - Scheduler.schedule(ticks, keyPartial.apply(GLFW.GLFW_RELEASE)); - return null; - } - - @FunctionDoc( - name = "editSign", - desc = { - "This allows you to edit sign at certain position with given string(lines), up to 4 lines.", - "This function does not check if sign is editable / is in position." - }, - params = { - @ParameterDoc(type = PosDef.class, name = "position", desc = "the position of sign"), - @ParameterDoc(type = StringDef.class, name = "strings", desc = "the lines for the sign, requires 1 string and up to 4 strings", isVarargs = true) - }, - examples = "client.editSign(new Pos(0,0,0), '100', '101', 'this is third line', 'last line');" - ) - private Void editSignFull(Arguments arguments) { - ScriptPos pos = arguments.skip().nextPrimitive(PosDef.class); - String first = arguments.nextPrimitive(StringDef.class); - String second = arguments.hasNext() ? arguments.nextPrimitive(StringDef.class) : ""; - String third = arguments.hasNext() ? arguments.nextPrimitive(StringDef.class) : ""; - String fourth = arguments.hasNext() ? arguments.nextPrimitive(StringDef.class) : ""; - EssentialUtils.getNetworkHandler().sendPacket(new UpdateSignC2SPacket( - pos.getBlockPos(), - true, - first, - second, - third, - fourth - )); - return null; - } - - @FunctionDoc( - name = "clearChat", - desc = "This will clear the chat hud", - examples = "client.clearChat();" - ) - private Object clearChat(Arguments arguments) { - arguments.nextPrimitive(this).inGameHud.getChatHud().clear(true); - return null; - } - - @FunctionDoc( - name = "getLatestChatMessage", - desc = "This will return the latest chat message", - returns = @ReturnDoc(type = TextDef.class, desc = "the latest chat message, null if there is none"), - examples = "client.getLatestChatMessage();" - ) - private Text getLatestChatMessage(Arguments arguments) { - MinecraftClient client = arguments.nextPrimitive(this); - - ChatHudLine[] chat = ((ChatHudAccessor) client.inGameHud.getChatHud()).essentialclient$getMessages().toArray(ChatHudLine[]::new); - - if (chat.length == 0) { - return null; - } - - return chat[0].content(); - } - - @FunctionDoc( - name = "addCommand", - desc = "This allows you to register your own client side command in game", - params = {@ParameterDoc(type = MapDef.class, name = "command", desc = "a command map or a command builder")}, - examples = """ - client.addCommand({ - "name": "example", - "subcommands": { }, - "arguments": { } - }); - """ - ) - private Void addCommand(Arguments arguments) { - arguments.skip(); - CommandNode commandNode; - if (arguments.isNext(CommandBuilderDef.class)) { - commandNode = arguments.nextPrimitive(CommandBuilderDef.class).build(); - } else if (arguments.isNext(MapDef.class)) { - commandNode = ClientScriptUtils.mapToCommand(arguments.nextPrimitive(MapDef.class), arguments.getInterpreter()).build(); - } else { - throw new RuntimeError("Expected CommandBuilder or command map"); - } - if (!(commandNode instanceof LiteralCommandNode literalCommandNode)) { - throw new RuntimeError("Expected a literal command builder as root"); - } - CommandHelper.addComplexCommand(arguments.getInterpreter(), literalCommandNode); - ClientScriptUtils.ensureMainThread("addCommand", arguments.getInterpreter(), () -> { - EssentialUtils.getPlayer().networkHandler.onCommandTree(CommandHelper.getCommandPacket()); - }); - return null; - } - - @FunctionDoc( - name = "completionsForCommand", - desc = "This gets a list of completions for a given command", - params = @ParameterDoc(type = StringDef.class, name = "command", desc = "The command to get suggestions for."), - returns = @ReturnDoc(type = ListDef.class, desc = "A list of all the suggestions as strings."), - examples = "client.completionsForCommand('/gamemode '); // ['adventure', 'creative', 'spectator', 'survival']" - ) - private ArucasList completionsForCommand(Arguments arguments) { - arguments.skip(); - String command = arguments.nextPrimitive(StringDef.class); - if (command.startsWith("/")) { - command = command.substring(1); - } - CommandDispatcher dispatcher = EssentialUtils.getNetworkHandler().getCommandDispatcher(); - CommandSource source = EssentialUtils.getNetworkHandler().getCommandSource(); - ParseResults result = dispatcher.parse(command, source); - Suggestions suggestions = arguments.getInterpreter().canInterrupt((Supplier) () -> - EssentialUtils.throwAsUnchecked(() -> dispatcher.getCompletionSuggestions(result).get()) - ); - ArucasList list = new ArucasList(); - for (Suggestion suggestion : suggestions.getList()) { - list.add(arguments.getInterpreter().convertValue(suggestion.getText())); - } - return list; - } - - @FunctionDoc( - name = "isInSinglePlayer", - desc = "This will return true if the client is in single player mode", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the client is in single player mode"), - examples = "client.isInSinglePlayer();" - ) - private boolean isInSinglePlayer(Arguments arguments) { - return arguments.nextPrimitive(this).isInSingleplayer(); - } - - @FunctionDoc( - name = "getOnlinePlayerNames", - desc = "This will get a list of all the online player's names.", - returns = @ReturnDoc(type = ListDef.class, desc = "The list of online player names."), - examples = "client.getOnlinePlayerNames();" - ) - private List getOnlinePlayerNames(Arguments arguments) { - return EssentialUtils.getNetworkHandler().getPlayerList() - .stream() - .map(e -> e.getProfile().getName()) - .toList(); - } - - @FunctionDoc( - name = "getOnlinePlayerNamesAndUuids", - desc = "This will get a map of all the online player's names to their uuids.", - returns = @ReturnDoc(type = MapDef.class, desc = "The map of online player names to uuids."), - examples = "client.getOnlinePlayerNamesAndUuids();" - ) - private Object getOnlinePlayerNamesAndUuids(Arguments arguments) { - return EssentialUtils.getNetworkHandler().getPlayerList() - .stream() - .map(PlayerListEntry::getProfile) - .collect(Collectors.toMap(GameProfile::getName, GameProfile::getId)); - } - - @FunctionDoc( - name = "getOnlinePlayerUuids", - desc = "This will get a list of all the online player's uuids.", - returns = @ReturnDoc(type = ListDef.class, desc = "The list of online player uuids."), - examples = "client.getOnlinePlayerUuids();" - ) - private List getOnlinePlayerUuids(Arguments arguments) { - return EssentialUtils.getNetworkHandler().getPlayerList() - .stream() - .map(e -> e.getProfile().getId().toString()) - .toList(); - } - - @FunctionDoc( - name = "playerNameFromUuid", - desc = { - "This will return the player name from the given uuid.", - "The player name is fetched from the Mojang API, this is", - "intended for use to get a player's name who is not online" - }, - params = {@ParameterDoc(type = StringDef.class, name = "uuid", desc = "the uuid as a string")}, - returns = @ReturnDoc(type = StringDef.class, desc = "the player name, null if the uuid is not found"), - examples = "client.playerNameFromUuid('d4fca8c4-e083-4300-9a73-bf438847861c');" - ) - private Object playerNameFromUuid(Arguments arguments) { - String uuidAsString = arguments.skip().nextPrimitive(StringDef.class); - return MojangAPI.getNameFromUuid(UUID.fromString(uuidAsString)); - } - - @FunctionDoc( - name = "uuidFromPlayerName", - desc = { - "This will return the uuid from the given player name.", - "The player uuid is fetched from the Mojang API, this is", - "intended for use to get a player's uuid who is not online" - }, - params = {@ParameterDoc(type = StringDef.class, name = "name", desc = "the player name")}, - returns = @ReturnDoc(type = StringDef.class, desc = "the uuid, null if the player name is not found"), - examples = "client.uuidFromPlayerName('senseiwells');" - ) - private String uuidFromPlayerName(Arguments arguments) { - String name = arguments.skip().nextPrimitive(StringDef.class); - UUID uuid = MojangAPI.getUuidFromName(name); - return uuid == null ? null : uuid.toString(); - } - - @FunctionDoc( - name = "getServerIp", - desc = "This will return the server ip", - returns = @ReturnDoc(type = StringDef.class, desc = "The server ip, null if in single player"), - examples = "client.getServerIp();" - ) - private String getServerIp(Arguments arguments) { - MinecraftClient client = arguments.nextPrimitive(this); - ServerInfo serverInfo = client.getCurrentServerEntry(); - return serverInfo == null ? null : serverInfo.address; - } - - @FunctionDoc( - name = "getServerName", - desc = "This gets the current connected server's name that you have set it to in the multiplayer screen", - returns = @ReturnDoc(type = StringDef.class, desc = "the server name"), - examples = "client.getServerName();" - ) - private String getServerName(Arguments arguments) { - MinecraftClient client = arguments.nextPrimitive(this); - ServerInfo serverInfo = client.getCurrentServerEntry(); - if (serverInfo == null) { - throw new RuntimeError("Failed to get server name"); - } - return serverInfo.name; - } - - @FunctionDoc( - name = "getPing", - desc = { - "This gets the current connected server's ping.", - "This will throw an error if the client is not connected to a server" - }, - returns = @ReturnDoc(type = NumberDef.class, desc = "the server ping in milliseconds"), - examples = "client.getPing();" - ) - private double getPing(Arguments arguments) { - MinecraftClient client = arguments.nextPrimitive(this); - ServerInfo serverInfo = client.getCurrentServerEntry(); - if (serverInfo == null) { - throw new RuntimeError("Failed to get server ping"); - } - return serverInfo.ping; - } - - @FunctionDoc( - name = "getScriptsPath", - desc = "This gets the script directory path, this is where all scripts are stored", - returns = @ReturnDoc(type = StringDef.class, desc = "the script directory path"), - examples = "client.getScriptPath();" - ) - private String getScriptsPath(Arguments arguments) { - return ClientScript.INSTANCE.getScriptDirectory().toString(); - } - - @FunctionDoc( - name = "setEssentialClientRule", - desc = { - "This sets the given client rule to the given value.", - "This may throw an error if the name is invalid or the rule cannot be set" - }, - params = { - @ParameterDoc(type = StringDef.class, name = "ruleName", desc = "the client rule"), - @ParameterDoc(type = ObjectDef.class, name = "value", desc = "the new value for the rule") - }, - examples = "client.setEssentialClientRule('highlightLavaSources', false);" - ) - private Void setEssentialClientRule(Arguments arguments) { - String ruleName = arguments.skip().nextPrimitive(StringDef.class); - String clientRuleValue = arguments.next().toString(arguments.getInterpreter()); - ClientRule clientRule = ClientRules.ruleFromString(ruleName); - if (clientRule == null) { - throw new RuntimeError("Invalid ClientRule name"); - } - ClientScriptUtils.ensureMainThread( - "setEssentialClientRule", arguments.getInterpreter(), () -> clientRule.setValueFromString(clientRuleValue) - ); - return null; - } - - @FunctionDoc( - name = "resetEssentialClientRule", - desc = { - "This resets the given client rule to its default value.", - "This will throw an error if the rule name is invalid" - }, - params = {@ParameterDoc(type = StringDef.class, name = "ruleName", desc = "the client rule")}, - examples = "client.resetEssentialClientRule('highlightLavaSources');" - ) - private Void resetEssentialClientRule(Arguments arguments) { - String clientRuleName = arguments.skip().nextPrimitive(StringDef.class); - ClientRule clientRule = ClientRules.ruleFromString(clientRuleName); - if (clientRule == null) { - throw new RuntimeError("Invalid ClientRule name"); - } - ClientScriptUtils.ensureMainThread( - "resetEssentialClientRule", arguments.getInterpreter(), clientRule::resetToDefault - ); - return null; - } - - @FunctionDoc( - name = "getEssentialClientValue", - desc = { - "This gets the value of the given client rule.", - "This will throw an error if the rule name is invalid" - }, - params = {@ParameterDoc(type = StringDef.class, name = "ruleName", desc = "the client rule")}, - returns = @ReturnDoc(type = ObjectDef.class, desc = "the value of the client rule"), - examples = "client.getEssentialClientValue('overrideCreativeWalkSpeed');" - ) - private Object getEssentialClientRuleValue(Arguments arguments) { - String ruleName = arguments.skip().nextPrimitive(StringDef.class); - ClientRule clientRule = ClientRules.ruleFromString(ruleName); - if (clientRule == null) { - throw new RuntimeError("Invalid ClientRule name"); - } - return clientRule.getValue(); - } - - @FunctionDoc( - name = "getModList", - desc = "This gets a list of all the mod ids of the mods installed", - returns = @ReturnDoc(type = ListDef.class, desc = "the mod ids"), - examples = "client.getModList();" - ) - private ArucasList getModList(Arguments arguments) { - ArucasList modList = new ArucasList(); - for (ModContainer modContainer : FabricLoader.getInstance().getAllMods()) { - modList.add(arguments.getInterpreter().create(StringDef.class, modContainer.getMetadata().getId())); - } - return modList; - } - - @FunctionDoc( - name = "getFps", - desc = "This gets the current fps", - returns = @ReturnDoc(type = NumberDef.class, desc = "the fps"), - examples = "client.getFps();" - ) - private double getFps(Arguments arguments) { - return MinecraftClientAccessor.getFps(); - } - - @FunctionDoc( - name = "parseStringToNbt", - desc = "This parses a string and turns it into a Nbt compound", - params = {@ParameterDoc(type = StringDef.class, name = "string", desc = "the string to parse")}, - returns = @ReturnDoc(type = ObjectDef.class, desc = "the nbt compound as a value"), - examples = "client.parseStringToNbt('{\"test\":\"test\"}');" - ) - private ClassInstance parseStringToNbt(Arguments arguments) { - String nbt = arguments.nextPrimitive(StringDef.class); - return ClientScriptUtils.nbtToValue(arguments.getInterpreter(), ClientScriptUtils.stringToNbt(nbt), 10); - } - - @FunctionDoc( - name = "playSound", - desc = { - "This plays the given sound with the given volume and pitch around the player", - "sound id's can be found [here](https://minecraft.fandom.com/wiki/Sounds.json#Sound_events)" - }, - params = { - @ParameterDoc(type = StringDef.class, name = "soundId", desc = "the sound id you want to play"), - @ParameterDoc(type = NumberDef.class, name = "volume", desc = "the volume of the sound"), - @ParameterDoc(type = NumberDef.class, name = "pitch", desc = "the pitch of the sound") - }, - examples = "client.playSound('entity.lightning_bolt.thunder', 1, 1);" - ) - private Void playSound(Arguments arguments) { - ClientPlayerEntity player = EssentialUtils.getPlayer(); - String soundId = arguments.skip().nextPrimitive(StringDef.class); - Double volume = arguments.nextPrimitive(NumberDef.class); - Double pitch = arguments.nextPrimitive(NumberDef.class); - SoundEvent soundEvent = Registries.SOUND_EVENT.get(ClientScriptUtils.stringToIdentifier(soundId)); - ClientScriptUtils.ensureMainThread("playSound", arguments.getInterpreter(), () -> { - player.playSoundToPlayer(soundEvent, SoundCategory.MASTER, volume.floatValue(), pitch.floatValue()); - }); - return null; - } - - @FunctionDoc( - name = "renderFloatingItem", - desc = "This renders an item in front of the player using the totem of undying animation", - params = {@ParameterDoc(type = MaterialDef.class, name = "material", desc = "the material to render")}, - examples = "client.renderFloatingItem(Material.DIAMOND);" - ) - private Void renderFloatingItem(Arguments arguments) { - MinecraftClient client = arguments.nextPrimitive(this); - ScriptMaterial material = arguments.nextPrimitive(MaterialDef.class); - client.gameRenderer.showFloatingItem(material.asItemStack()); - return null; - } - - @FunctionDoc( - name = "stripFormatting", - desc = "This strips the formatting from the given string", - params = {@ParameterDoc(type = StringDef.class, name = "string", desc = "the string to strip")}, - returns = @ReturnDoc(type = StringDef.class, desc = "the stripped string"), - examples = "client.stripFormatting('§cHello§r');" - ) - private String stripFormatting(Arguments arguments) { - String string = arguments.skip().nextPrimitive(StringDef.class); - return string.replaceAll("§[0-9a-gk-or]", ""); - } - - @FunctionDoc( - name = "getCursorStack", - desc = "This returns the item stack that is currently being held by the cursor", - returns = @ReturnDoc(type = ItemStackDef.class, desc = "the item stack, will be Air if there is nothing"), - examples = "client.getCursorStack();" - ) - private ItemStack getCursorStack(Arguments arguments) { - return InventoryUtils.getCursorStack(); - } - - @FunctionDoc( - deprecated = "You should use 'fakeInventoryScreen.setCursorStack(item)' instead", - name = "setCursorStack", - desc = { - "This sets the item stack that is currently being held by the cursor, this does not work", - "in normal screens only in FakeScreens, this does not actually pick up an item just display like you have" - }, - params = @ParameterDoc(type = ItemStackDef.class, name = "itemStack", desc = "the item stack to set"), - examples = "client.setCursorStack(Material.DIAMOND.asItemStack());" - ) - private boolean setCursorStack(Arguments arguments) { - MinecraftClient client = arguments.nextPrimitive(this); - if (client.currentScreen instanceof FakeInventoryScreen) { - ScriptItemStack itemStack = arguments.nextPrimitive(ItemStackDef.class); - return InventoryUtils.setCursorStack(itemStack.stack); - } - return false; - } - - @FunctionDoc( - name = "getClientRenderDistance", - desc = "This returns the current render distance set on the client", - returns = @ReturnDoc(type = NumberDef.class, desc = "the render distance"), - examples = "client.getClientRenderDistance();" - ) - private double getClientRenderDistance(Arguments arguments) { - MinecraftClient client = arguments.nextPrimitive(this); - return client.options.getViewDistance().getValue(); - } - - @FunctionDoc( - name = "setClientRenderDistance", - desc = "This sets the render distance on the client", - params = {@ParameterDoc(type = NumberDef.class, name = "number", desc = "the render distance")}, - examples = "client.setClientRenderDistance(10);" - ) - private Void setClientRenderDistance(Arguments arguments) { - MinecraftClient client = arguments.nextPrimitive(this); - int distance = arguments.nextPrimitive(NumberDef.class).intValue(); - client.options.getViewDistance().setValue(distance); - client.worldRenderer.scheduleTerrainUpdate(); - return null; - } - - @FunctionDoc( - deprecated = "Use 'client.run(task)' instead", - name = "runOnMainThread", - desc = "This runs the given function on the main thread", - params = {@ParameterDoc(type = FunctionDef.class, name = "function", desc = "the function to run")}, - examples = "client.runOnMainThread(fun() { print('Do something'); });" - ) - private Void runOnMainThread(Arguments arguments) { - return this.run(arguments); - } - - @FunctionDoc( - name = "run", - desc = "This runs the given function on the main thread", - params = {@ParameterDoc(type = FunctionDef.class, name = "function", desc = "the function to run")}, - examples = "client.run(fun() { print('Do something'); });" - ) - private Void run(Arguments arguments) { - ArucasFunction function = arguments.skip().nextPrimitive(FunctionDef.class); - Interpreter branch = arguments.getInterpreter().branch(); - ClientScriptUtils.ensureMainThread("run", arguments.getInterpreter(), () -> { - function.invoke(branch, List.of()); - }); - return null; - } - - @FunctionDoc( - name = "tick", - desc = "This ticks the client", - examples = "client.tick();" - ) - private Void tick(Arguments arguments) { - MinecraftClient client = arguments.nextPrimitive(this); - client.execute(client::tick); - return null; - } - - @FunctionDoc( - name = "getPlayer", - desc = "This returns the current player on the client", - returns = @ReturnDoc(type = PlayerDef.class, desc = "the main player"), - examples = "client.getPlayer();" - ) - private ClientPlayerEntity getPlayer(Arguments arguments) { - return EssentialUtils.getPlayer(); - } - - @FunctionDoc( - name = "getWorld", - desc = "This returns the world that is currently being played on", - returns = @ReturnDoc(type = WorldDef.class, desc = "the world"), - examples = "client.getWorld();" - ) - private ClientWorld getWorld(Arguments arguments) { - return EssentialUtils.getWorld(); - } - - @FunctionDoc( - name = "getVersion", - desc = "This returns the current version of Minecraft you are playing", - returns = @ReturnDoc(type = StringDef.class, desc = "the version for example: '1.17.1'"), - examples = "client.getVersion();" - ) - private String getVersion(Arguments arguments) { - return EssentialUtils.getMinecraftVersion(); - } - - @FunctionDoc( - deprecated = "This features is no longer supported", - name = "canSendScriptPacket", - desc = "Returns whether the server supports client script packets", - returns = @ReturnDoc(type = BooleanDef.class, desc = "Whether the client can send packets to the server"), - examples = "client.canSendScriptPacket()" - ) - private boolean canSendScriptPacket(Arguments arguments) { - return false; - } - - @FunctionDoc( - deprecated = "This features is no longer supported", - name = "sendScriptPacket", - desc = { - "This sends a script packet to the server", - "You can send the follow types of values:", - "Boolean, Number, String, List (of numbers), Text, ItemStack, Pos, and NbtMaps", - "You can send byte, int, and long arrays by using the strings 'b', 'i', and 'l' at the start of the list" - }, - params = @ParameterDoc(type = ObjectDef.class, name = "values...", desc = "the data you want to send to the server", isVarargs = true), - examples = "client.sendScriptPacket('test', false, ['l', 9999, 0, 45]);" - ) - private Void sendScriptPacket(Arguments arguments) { - return null; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/MinecraftTaskDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/MinecraftTaskDef.java deleted file mode 100644 index b1582e58..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/MinecraftTaskDef.java +++ /dev/null @@ -1,127 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import kotlin.Unit; -import me.senseiwells.arucas.api.docs.annotations.*; -import me.senseiwells.arucas.builtin.FunctionDef; -import me.senseiwells.arucas.builtin.FutureDef; -import me.senseiwells.arucas.builtin.NumberDef; -import me.senseiwells.arucas.builtin.TaskDef; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.functions.ArucasFunction; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.ConstructorFunction; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptTask; -import org.jetbrains.annotations.NotNull; - -import java.util.List; -import java.util.concurrent.Future; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.MINECRAFT_TASK; - -@ClassDoc( - name = MINECRAFT_TASK, - desc = { - "This class is used to create tasks that can be chained and", - "run on the main Minecraft thread. This ensures that all", - "behaviors work as intended." - }, - superclass = TaskDef.class, - language = Language.Java -) -public class MinecraftTaskDef extends CreatableDefinition { - public MinecraftTaskDef(Interpreter interpreter) { - super(MINECRAFT_TASK, interpreter); - } - - @NotNull - @Override - public PrimitiveDefinition superclass() { - return this.getPrimitiveDef(TaskDef.class); - } - - @Override - public List defineConstructors() { - return List.of( - ConstructorFunction.of(this::construct) - ); - } - - @ConstructorDoc( - desc = "This creates a new empty Minecraft task", - examples = "task = new MinecraftTask();" - ) - private Unit construct(Arguments arguments) { - ClassInstance instance = arguments.next(); - instance.setPrimitive(this, new ScriptTask(arguments.getInterpreter())); - return null; - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("waitThen", 2, this::waitThen), - MemberFunction.of("run", this::run) - ); - } - - @FunctionDoc( - name = "waitThen", - desc = { - "This adds a delay (in ticks) then runs the given task.", - "This delay is will also affect all following chained function", - "delays. If this is the last function in the chain, then the", - "return value will be determined by this function" - }, - params = { - @ParameterDoc(type = NumberDef.class, name = "ticks", desc = "the amount of ticks delay before the function runs"), - @ParameterDoc(type = FunctionDef.class, name = "function", desc = "the function to run after the delay") - }, - returns = @ReturnDoc(type = MinecraftTaskDef.class, desc = "the task, this allows for chaining"), - examples = - """ - task = new MinecraftTask() - .then(fun() print("hello")) - .waitThen(5, fun() print("world")); - task.run(); // prints 'hello', waits 5 ticks, prints 'world' - """ - ) - private ClassInstance waitThen(Arguments arguments) { - ClassInstance instance = arguments.next(); - int ticks = arguments.nextPrimitive(NumberDef.class).intValue(); - if (ticks < 0) { - throw new RuntimeError("Cannot have a negative delay"); - } - ArucasFunction function = arguments.nextPrimitive(FunctionDef.class); - instance.asPrimitive(this).addTask(ticks, function); - return instance; - } - - @FunctionDoc( - name = "run", - desc = { - "This runs the task on the main Minecraft thread. It returns a future", - "which can be awaited, the last function in the chain will be used as", - "the return value for the future" - }, - returns = @ReturnDoc(type = FutureDef.class, desc = "the future value that can be awaited"), - examples = - """ - task = new MinecraftTask() - .then(fun() print("hello")) - .then(fun() print(" ")) - .then(fun() print("world")) - .then(fun() 10); - f = task.run(); // prints 'hello world' - print(f.await()); // prints 10 - """ - ) - private Future run(Arguments arguments) { - return arguments.nextPrimitive(this).run(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/OtherPlayerDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/OtherPlayerDef.java deleted file mode 100644 index 3432a946..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/OtherPlayerDef.java +++ /dev/null @@ -1,407 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ParameterDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.*; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.compiler.LocatableTrace; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.impl.ArucasList; -import me.senseiwells.arucas.utils.impl.ArucasMap; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptMaterial; -import net.minecraft.client.network.AbstractClientPlayerEntity; -import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.entity.player.PlayerAbilities; -import net.minecraft.entity.player.PlayerInventory; -import net.minecraft.entity.projectile.FishingBobberEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.screen.ScreenHandler; -import net.minecraft.screen.slot.Slot; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.OTHER_PLAYER; - -@ClassDoc( - name = OTHER_PLAYER, - desc = { - "This class is used to represent all players, mainly other players,", - "this class extends LivingEntity and so inherits all of their methods too" - }, - language = Language.Java -) -public class OtherPlayerDef extends PrimitiveDefinition { - public OtherPlayerDef(Interpreter interpreter) { - super(OTHER_PLAYER, interpreter); - } - - @Deprecated - @NotNull - @Override - public ClassInstance create(@NotNull AbstractClientPlayerEntity value) { - return super.create(value); - } - - @NotNull - @Override - public PrimitiveDefinition superclass() { - return this.getPrimitiveDef(LivingEntityDef.class); - } - - @NotNull - @Override - public String toString(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - return "OtherPlayer{name=%s}".formatted(instance.asPrimitive(this).getNameForScoreboard()); - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("getCurrentSlot", this::getCurrentSlot), - MemberFunction.of("getHeldItem", this::getHeldItem), - MemberFunction.of("isInventoryFull", this::isInventoryFull), - MemberFunction.of("getEmptySlots", this::getEmptySlots), - MemberFunction.of("getPlayerName", this::getPlayerName), - MemberFunction.of("getGamemode", this::getGamemode), - MemberFunction.of("getTotalSlots", this::getTotalSlots), - MemberFunction.of("isPlayerSlot", 1, this::isPlayerSlot), - MemberFunction.of("getItemForSlot", 1, this::getItemForSlot), - MemberFunction.of("getItemForPlayerSlot", 1, this::getItemForPlayerSlot), - MemberFunction.of("getSlotFor", 1, this::getSlotFor), - MemberFunction.of("getAllSlotsFor", 1, this::getAllSlotsFor), - MemberFunction.of("getAllSlotsFor", 2, this::getAllSlotsForWithOption), - MemberFunction.of("getAbilities", this::getAbilities), - MemberFunction.of("getLevels", this::getLevels), - MemberFunction.of("getXpProgress", this::getXpProgress), - MemberFunction.of("getNextLevelExperience", this::getNextLevelExperience), - MemberFunction.of("getHunger", this::getHunger), - MemberFunction.of("getSaturation", this::getSaturation), - MemberFunction.of("getFishingBobber", this::getFishingBobber) - ); - } - - @FunctionDoc( - name = "getCurrentSlot", - desc = "This gets the players currently selected slot", - returns = @ReturnDoc(type = NumberDef.class, desc = "the currently selected slot number"), - examples = "otherPlayer.getCurrentSlot();" - ) - private double getCurrentSlot(Arguments arguments) { - return arguments.nextPrimitive(this).getInventory().selectedSlot; - } - - @FunctionDoc( - name = "getHeldItem", - desc = "This gets the players currently selected item, in their main hand", - returns = @ReturnDoc(type = ItemStackDef.class, desc = "the currently selected item"), - examples = "otherPlayer.getHeldItem();" - ) - private ItemStack getHeldItem(Arguments arguments) { - return arguments.nextPrimitive(this).getInventory().getMainHandStack(); - } - - @FunctionDoc( - name = "isInventoryFull", - desc = { - "This gets whether the players inventory is full.", - "More specifically whether the player has no empty slots" - }, - returns = @ReturnDoc(type = BooleanDef.class, desc = "whether the inventory is full"), - examples = "otherPlayer.isInventoryFull();" - ) - private boolean isInventoryFull(Arguments arguments) { - return arguments.nextPrimitive(this).getInventory().getEmptySlot() == -1; - } - - @FunctionDoc( - name = "getEmptySlots", - desc = "This gets all the empty slots in the player inventory", - returns = @ReturnDoc(type = ListDef.class, desc = "a list of all the slot numbers that are empty"), - examples = "otherPlayer.getEmptySlots();" - ) - private ArucasList getEmptySlots(Arguments arguments) { - PlayerInventory inventory = arguments.nextPrimitive(this).getInventory(); - ArucasList list = new ArucasList(); - for (int i = 0; i < inventory.main.size(); ++i) { - if (inventory.main.get(i).isEmpty()) { - list.add(arguments.getInterpreter().convertValue(i)); - } - } - return list; - } - - @FunctionDoc( - name = "getPlayerName", - desc = "This gets the players name", - returns = @ReturnDoc(type = StringDef.class, desc = "the players name"), - examples = "otherPlayer.getPlayerName();" - ) - private String getPlayerName(Arguments arguments) { - return arguments.nextPrimitive(this).getNameForScoreboard(); - } - - @FunctionDoc( - name = "getGamemode", - desc = "This gets the players gamemode, may be null if not known", - returns = @ReturnDoc(type = StringDef.class, desc = "the players gamemode as a string, for example 'creative', 'survival', 'spectator'"), - examples = "otherPlayer.getGamemode();" - ) - private String getGamemode(Arguments arguments) { - AbstractClientPlayerEntity playerEntity = arguments.nextPrimitive(this); - PlayerListEntry playerInfo = EssentialUtils.getNetworkHandler().getPlayerListEntry(playerEntity.getUuid()); - if (playerInfo == null || playerInfo.getGameMode() == null) { - return null; - } - return playerInfo.getGameMode().getName(); - } - - @FunctionDoc( - name = "getTotalSlots", - desc = "This gets the players total inventory slots", - returns = @ReturnDoc(type = NumberDef.class, desc = "the players total inventory slots"), - examples = "otherPlayer.getTotalSlots();" - ) - private double getTotalSlots(Arguments arguments) { - ScreenHandler screenHandler = arguments.nextPrimitive(this).currentScreenHandler; - return screenHandler.slots.size(); - } - - @FunctionDoc( - name = "getItemForSlot", - desc = { - "This gets the item in the specified slot, in the total players inventory, including inventories of open containers.", - "This will throw an error if the index is out of bounds" - }, - params = {@ParameterDoc(type = NumberDef.class, name = "slotNum", desc = "the slot number you want to get")}, - returns = @ReturnDoc(type = ItemStackDef.class, desc = "the item in the specified slot"), - examples = "otherPlayer.getItemForSlot(0);" - ) - private ItemStack getItemForSlot(Arguments arguments) { - AbstractClientPlayerEntity playerEntity = arguments.nextPrimitive(this); - int index = arguments.nextPrimitive(NumberDef.class).intValue(); - ScreenHandler screenHandler = playerEntity.currentScreenHandler; - if (index > screenHandler.slots.size() || index < 0) { - throw new RuntimeError("That slot is out of bounds"); - } - return screenHandler.slots.get(index).getStack(); - } - - @FunctionDoc( - name = "isPlayerSlot", - desc = { - "This gets inventory type (player / other) for given slot numbers.", - "This will throw an error if the index is out of bounds" - }, - params = {@ParameterDoc(type = NumberDef.class, name = "slotNum", desc = "the slot number you want to get")}, - returns = @ReturnDoc(type = BooleanDef.class, desc = "whether slot was player inventory or not"), - examples = "otherPlayer.isPlayerSlot(0);" - ) - private boolean isPlayerSlot(Arguments arguments) { - AbstractClientPlayerEntity playerEntity = arguments.nextPrimitive(this); - int index = arguments.nextPrimitive(NumberDef.class).intValue(); - ScreenHandler screenHandler = playerEntity.currentScreenHandler; - if (index > screenHandler.slots.size() || index < 0) { - throw new RuntimeError("That slot is out of bounds"); - } - Slot slot = screenHandler.slots.get(index); - return slot.inventory instanceof PlayerInventory; - } - - @FunctionDoc( - name = "getItemForPlayerSlot", - desc = { - "This gets the item in the specified slot, in the players inventory, not including inventories of open containers.", - "This will throw an error if the slot is out of bounds" - }, - params = {@ParameterDoc(type = NumberDef.class, name = "slotNum", desc = "the slot number you want to get")}, - returns = @ReturnDoc(type = ItemStackDef.class, desc = "the item in the specified slot"), - examples = "otherPlayer.getItemForPlayerSlot(0);" - ) - private ItemStack getItemForPlayerSlot(Arguments arguments) { - // This gets the item for a slot in the player's inventory (no screen inventories) - AbstractClientPlayerEntity player = arguments.nextPrimitive(this); - PlayerInventory inventory = player.getInventory(); - int slot = arguments.nextPrimitive(NumberDef.class).intValue(); - if (slot < 0 || slot > inventory.main.size()) { - throw new RuntimeError("That slot is out of bounds"); - } - return inventory.main.get(slot); - } - - @FunctionDoc( - name = "getSlotFor", - desc = "This gets the slot number of the specified item in the players combined inventory", - params = {@ParameterDoc(type = MaterialDef.class, name = "materialLike", desc = "the item or material you want to get the slot of")}, - returns = @ReturnDoc(type = NumberDef.class, desc = "the slot number of the item, null if not found"), - examples = "otherPlayer.getSlotFor(Material.DIAMOND.asItemStack());" - ) - private Double getSlotFor(Arguments arguments) { - AbstractClientPlayerEntity playerEntity = arguments.nextPrimitive(this); - ScriptMaterial materialLike = arguments.nextPrimitive(MaterialDef.class); - ScreenHandler screenHandler = playerEntity.currentScreenHandler; - for (Slot slot : screenHandler.slots) { - if (slot.getStack().getItem() == materialLike.asItem()) { - return (double) slot.id; - } - } - return null; - } - - @FunctionDoc( - name = "getAllSlotsFor", - desc = "This gets all the slot numbers of the specified item in the players combined inventory", - params = {@ParameterDoc(type = MaterialDef.class, name = "materialLike", desc = "the item or material you want to get the slot of")}, - returns = @ReturnDoc(type = ListDef.class, desc = "the slot numbers of the item, empty list if not found"), - examples = "otherPlayer.getAllSlotsFor(Material.DIAMOND);" - ) - private ArucasList getAllSlotsFor(Arguments arguments) { - AbstractClientPlayerEntity playerEntity = arguments.nextPrimitive(this); - ScriptMaterial materialLike = arguments.nextPrimitive(MaterialDef.class); - ScreenHandler screenHandler = playerEntity.currentScreenHandler; - ArucasList slotList = new ArucasList(); - for (Slot slot : screenHandler.slots) { - if (slot.getStack().getItem() == materialLike.asItem()) { - slotList.add(arguments.getInterpreter().create(NumberDef.class, (double) slot.id)); - } - } - return slotList; - } - - @FunctionDoc( - name = "getAllSlotsFor", - desc = "This gets all the slot numbers of the specified item in the players combined inventory", - params = { - @ParameterDoc(type = MaterialDef.class, name = "materialLike", desc = "the item or material you want to get the slot of"), - @ParameterDoc(type = StringDef.class, name = "inventoryType", desc = "all/combined -> includes external, player/main -> player slots, external/other -> excludes player inventory") - }, - returns = @ReturnDoc(type = ListDef.class, desc = "the slot numbers of the item, empty list if not found"), - examples = "otherPlayer.getAllSlotsFor(Material.DIAMOND, 'player');" - ) - private ArucasList getAllSlotsForWithOption(Arguments arguments) { - AbstractClientPlayerEntity playerEntity = arguments.nextPrimitive(this); - ScriptMaterial materialLike = arguments.nextPrimitive(MaterialDef.class); - String inventoryArgument = arguments.nextPrimitive(StringDef.class); - ScreenHandler screenHandler = playerEntity.currentScreenHandler; - ArucasList slotList = new ArucasList(); - for (Slot slot : screenHandler.slots) { - switch (inventoryArgument) { - case "all", "combined" -> { - } - case "player", "main" -> { - if (!(slot.inventory instanceof PlayerInventory)) { - continue; - } - } - case "external", "other" -> { - if (slot.inventory instanceof PlayerInventory) { - continue; - } - } - default -> throw new RuntimeError("String argument was not either one of combined / player / other"); - } - if (slot.getStack().getItem() == materialLike.asItem()) { - slotList.add(arguments.getInterpreter().create(NumberDef.class, (double) slot.id)); - } - } - return slotList; - } - - @FunctionDoc( - name = "getAbilities", - desc = { - "This gets the abilities of the player in a map", - "For example:", - "`{\"invulnerable\": false, \"canFly\": true, \"canBreakBlocks\": true, \"isCreative\": true, \"walkSpeed\": 1.0, \"flySpeed\": 1.2}`" - }, - returns = @ReturnDoc(type = MapDef.class, desc = "the abilities of the player"), - examples = "otherPlayer.getAbilities();" - ) - private ArucasMap getAbilities(Arguments arguments) { - AbstractClientPlayerEntity playerEntity = arguments.nextPrimitive(this); - PlayerAbilities playerAbilities = playerEntity.getAbilities(); - Interpreter interpreter = arguments.getInterpreter(); - ArucasMap map = new ArucasMap(); - map.put(interpreter, interpreter.create(StringDef.class, "invulnerable"), interpreter.createBool(playerAbilities.invulnerable)); - map.put(interpreter, interpreter.create(StringDef.class, "canFly"), interpreter.createBool(playerAbilities.allowFlying)); - map.put(interpreter, interpreter.create(StringDef.class, "canBreakBlocks"), interpreter.createBool(playerAbilities.allowModifyWorld)); - map.put(interpreter, interpreter.create(StringDef.class, "isCreative"), interpreter.createBool(playerAbilities.creativeMode)); - map.put(interpreter, interpreter.create(StringDef.class, "walkSpeed"), interpreter.create(NumberDef.class, (double) playerAbilities.getWalkSpeed())); - map.put(interpreter, interpreter.create(StringDef.class, "flySpeed"), interpreter.create(NumberDef.class, (double) playerAbilities.getFlySpeed())); - return map; - } - - @FunctionDoc( - name = "getLevels", - desc = "This gets the number of experience levels the player has", - returns = @ReturnDoc(type = NumberDef.class, desc = "the number of experience levels"), - examples = "otherPlayer.getLevels();" - ) - private double getLevels(Arguments arguments) { - AbstractClientPlayerEntity playerEntity = arguments.nextPrimitive(this); - return playerEntity.experienceLevel; - } - - @FunctionDoc( - name = "getXpProgress", - desc = "This gets the number of experience progress the player has", - returns = @ReturnDoc(type = NumberDef.class, desc = "the number of experience progress"), - examples = "otherPlayer.getXpProgress();" - ) - private double getXpProgress(Arguments arguments) { - AbstractClientPlayerEntity playerEntity = arguments.nextPrimitive(this); - return playerEntity.experienceProgress; - } - - @FunctionDoc( - name = "getNextLevelExperience", - desc = "This gets the number of experience required to level up for the player", - returns = @ReturnDoc(type = NumberDef.class, desc = "the number required to next level"), - examples = "otherPlayer.getNextLevelExperience();" - ) - private double getNextLevelExperience(Arguments arguments) { - AbstractClientPlayerEntity playerEntity = arguments.nextPrimitive(this); - return playerEntity.getNextLevelExperience(); - } - - @FunctionDoc( - name = "getHunger", - desc = "This gets the hunger level of the player", - returns = @ReturnDoc(type = NumberDef.class, desc = "the hunger level"), - examples = "otherPlayer.getHunger();" - ) - private double getHunger(Arguments arguments) { - AbstractClientPlayerEntity playerEntity = arguments.nextPrimitive(this); - return playerEntity.getHungerManager().getFoodLevel(); - } - - @FunctionDoc( - name = "getSaturation", - desc = "This gets the saturation level of the player", - returns = @ReturnDoc(type = NumberDef.class, desc = "the saturation level"), - examples = "otherPlayer.getSaturation();" - ) - private double getSaturation(Arguments arguments) { - AbstractClientPlayerEntity playerEntity = arguments.nextPrimitive(this); - return playerEntity.getHungerManager().getSaturationLevel(); - } - - @FunctionDoc( - name = "getFishingBobber", - desc = "This gets the fishing bobber that the player has", - returns = @ReturnDoc(type = EntityDef.class, desc = "the fishing bobber entity, null if the player isn't fishing"), - examples = "otherPlayer.getFishingBobber();" - ) - private FishingBobberEntity getFishingBobber(Arguments arguments) { - AbstractClientPlayerEntity playerEntity = arguments.nextPrimitive(this); - return playerEntity.fishHook; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/PlayerDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/PlayerDef.java deleted file mode 100644 index 081895d1..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/PlayerDef.java +++ /dev/null @@ -1,1495 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ParameterDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.*; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.compiler.LocatableTrace; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.functions.ArucasFunction; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.BuiltInFunction; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.impl.ArucasList; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.feature.BetterAccurateBlockPlacement; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.ClientScriptUtils; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptItemStack; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptMaterial; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptPos; -import me.senseiwells.essentialclient.utils.interfaces.MinecraftClientInvoker; -import me.senseiwells.essentialclient.utils.inventory.InventoryUtils; -import me.senseiwells.essentialclient.utils.render.FakeInventoryScreen; -import net.minecraft.block.BlockState; -import net.minecraft.block.ShapeContext; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.ingame.CraftingScreen; -import net.minecraft.client.gui.screen.ingame.HandledScreen; -import net.minecraft.client.gui.screen.ingame.InventoryScreen; -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.network.ClientPlayerInteractionManager; -import net.minecraft.command.argument.EntityAnchorArgumentType; -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.PlayerInventory; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.network.DisconnectionInfo; -import net.minecraft.network.packet.c2s.play.PickFromInventoryC2SPacket; -import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; -import net.minecraft.network.packet.c2s.play.SpectatorTeleportC2SPacket; -import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket; -import net.minecraft.recipe.RecipeEntry; -import net.minecraft.recipe.StonecuttingRecipe; -import net.minecraft.screen.ScreenHandler; -import net.minecraft.screen.slot.SlotActionType; -import net.minecraft.text.Text; -import net.minecraft.util.Hand; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.Vec3d; -import org.jetbrains.annotations.NotNull; - -import java.util.List; -import java.util.Locale; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Future; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.PLAYER; - -@ClassDoc( - name = PLAYER, - desc = { - "This class is used to interact with the main player, this extends OtherPlayer", - "and so inherits all methods from that class." - }, - superclass = OtherPlayerDef.class, - language = Language.Java -) -public class PlayerDef extends CreatableDefinition { - public PlayerDef(Interpreter interpreter) { - super(PLAYER, interpreter); - } - - @NotNull - @Override - public PrimitiveDefinition superclass() { - return this.getPrimitiveDef(OtherPlayerDef.class); - } - - @NotNull - @Override - public String toString(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - return "Player{name=" + instance.asPrimitive(this).getNameForScoreboard() + "}"; - } - - @Override - public List defineStaticMethods() { - return List.of( - BuiltInFunction.of("get", this::get) - ); - } - - @FunctionDoc( - isStatic = true, - name = "get", - desc = "This gets the main player", - returns = @ReturnDoc(type = PlayerDef.class, desc = "The main player"), - examples = "player = Player.get();" - ) - private ClassInstance get(Arguments arguments) { - return this.create(EssentialUtils.getPlayer()); - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("use", 1, this::use), - MemberFunction.of("attack", 1, this::attack), - MemberFunction.of("setSelectedSlot", 1, this::setSelectedSlot), - MemberFunction.of("getSelectedSlot", this::getSelectedSlot), - MemberFunction.of("say", 1, this::say), - MemberFunction.of("message", 1, this::message), - MemberFunction.of("messageActionBar", 1, this::messageActionBar), - MemberFunction.of("showTitle", 2, this::showTitle), - MemberFunction.of("openInventory", this::openInventory), - MemberFunction.of("openScreen", 1, this::openScreen), - MemberFunction.of("closeScreen", this::closeScreen), - MemberFunction.of("setWalking", 1, this::setWalking), - MemberFunction.of("setSneaking", 1, this::setSneaking), - MemberFunction.of("setSprinting", 1, this::setSprinting), - MemberFunction.of("dropItemInHand", 1, this::dropItemInHand), - MemberFunction.of("dropAll", 1, this::dropAll), - MemberFunction.of("dropAllExact", 1, this::dropAllExact), - MemberFunction.of("look", 2, this::look), - MemberFunction.of("lookAtPos", 3, this::lookAtPos), - MemberFunction.of("lookAtPos", 1, this::lookAtPosPos), - MemberFunction.of("jump", this::jump), - MemberFunction.of("getLookingAtEntity", this::getLookingAtEntity), - MemberFunction.of("swapSlots", 2, this::swapSlots), - MemberFunction.of("shiftClickSlot", 1, this::shiftClickSlot), - MemberFunction.of("dropSlot", 1, this::dropSlot), - MemberFunction.of("getCurrentScreen", this::getCurrentScreen), - MemberFunction.of("craft", 1, this::craft), - MemberFunction.of("craftRecipe", 1, this::craftRecipe), - MemberFunction.of("craftRecipe", 2, this::craftRecipeDrop), - MemberFunction.of("craftRecipe", 3, this::craftRecipeDropAll), - MemberFunction.of("clickRecipe", 1, this::clickRecipe1), - MemberFunction.of("clickRecipe", 2, this::clickRecipe2), - MemberFunction.of("clickStonecuttingRecipe", 1, this::clickCuttingRecipe), - MemberFunction.of("clickStonecuttingRecipe", 2, this::clickCuttingRecipe2), - MemberFunction.of("logout", 1, this::logout), - MemberFunction.of("attackEntity", 1, this::attackEntity), - MemberFunction.of("interactWithEntity", 1, this::interactWithEntity), - MemberFunction.of("anvil", 2, this::anvil2), - MemberFunction.of("anvil", 3, this::anvil3), - MemberFunction.of("anvilRename", 2, this::anvilRename), - MemberFunction.of("stonecutter", 2, this::stonecutter), - MemberFunction.of("fakeLook", 4, this::fakeLook), - MemberFunction.of("swapPlayerSlotWithHotbar", 1, this::swapPlayerSlotWithHotbar), - MemberFunction.of("breakBlock", 1, this::breakBlock), - MemberFunction.of("updateBreakingBlock", 3, this::updateBreakingBlock, "Use .breakBlock(pos)"), - MemberFunction.of("updateBreakingBlock", 1, this::updateBreakingBlockPos, "Use .breakBlock(pos)"), - MemberFunction.of("attackBlock", 4, this::attackBlock), - MemberFunction.of("attackBlock", 2, this::attackBlockPos), - MemberFunction.of("interactItem", 2, this::interactItem), - MemberFunction.of("interactBlock", 2, this::interactBlockPos), - MemberFunction.of("interactBlock", 3, this::interactBlockPosHand), - MemberFunction.of("interactBlock", 8, this::interactBlockFull), - MemberFunction.of("interactBlock", 4, this::interactBlockFullPos), - MemberFunction.of("interactBlock", 5, this::interactBlockFullPosHand), - MemberFunction.of("getBlockBreakingSpeed", 2, this::getBlockBreakingSpeed), - MemberFunction.of("swapHands", this::swapHands), - MemberFunction.of("swingHand", 1, this::swingHand), - MemberFunction.of("clickSlot", 3, this::clickSlot), - MemberFunction.of("clickCreativeStack", 2, this::clickCreativeStack), - MemberFunction.of("getSwappableHotbarSlot", this::getSwappableHotbarSlot), - MemberFunction.of("spectatorTeleport", 1, this::spectatorTeleport), - MemberFunction.of("canPlaceBlockAt", 2, this::canPlaceBlockAtPos), - MemberFunction.of("canPlaceBlockAt", 4, this::canPlaceBlockAtPos1) - ); - } - - @FunctionDoc( - name = "use", - desc = { - "This allows you to make your player use, you must", - "pass 'hold', 'stop', or 'once' otherwise an error will be thrown" - }, - params = {@ParameterDoc(type = StringDef.class, name = "action", desc = "the type of action, either 'hold', 'stop', or 'once'")}, - examples = "player.use('hold');" - ) - private Void use(Arguments arguments) { - String action = arguments.skip().nextPrimitive(StringDef.class); - MinecraftClient client = EssentialUtils.getClient(); - switch (action.toLowerCase()) { - case "hold" -> ClientScriptUtils.holdKey(arguments.getInterpreter(), client.options.useKey, 3); - case "stop" -> ClientScriptUtils.releaseKey(client.options.useKey); - case "once" -> ((MinecraftClientInvoker) client).essentialclient$rightClick(); - default -> throw new RuntimeError("Must pass 'hold', 'stop' or 'once' into use()"); - } - return null; - } - - @FunctionDoc( - name = "attack", - desc = { - "This allows you to make your player attack, you must", - "pass 'hold', 'stop', or 'once' otherwise an error will be thrown" - }, - params = {@ParameterDoc(type = StringDef.class, name = "action", desc = "the type of action, either 'hold', 'stop', or 'once'")}, - examples = "player.attack('once');" - ) - private Void attack(Arguments arguments) { - String action = arguments.skip().nextPrimitive(StringDef.class); - MinecraftClient client = EssentialUtils.getClient(); - switch (action.toLowerCase()) { - case "hold" -> ClientScriptUtils.holdKey(arguments.getInterpreter(), client.options.attackKey, 1); - case "stop" -> ClientScriptUtils.releaseKey(client.options.attackKey); - case "once" -> ((MinecraftClientInvoker) client).essentialclient$leftClick(); - default -> throw new RuntimeError("Must pass 'hold', 'stop' or 'once' into attack()"); - } - return null; - } - - @FunctionDoc( - name = "setSelectedSlot", - desc = { - "This allows you to set the slot number your player is holding.", - "If the number is not between 0 and 8 an error will be thrown" - }, - params = {@ParameterDoc(type = NumberDef.class, name = "slot", desc = "the slot number, must be between 0 - 8")}, - examples = "player.setSelectedSlot(0);" - ) - private Void setSelectedSlot(Arguments arguments) { - int index = arguments.skip().nextPrimitive(NumberDef.class).intValue(); - if (index < 0 || index > 8) { - throw new RuntimeError("Number must be between 0 - 8"); - } - ClientScriptUtils.ensureMainThread("setSelectedSlot", arguments.getInterpreter(), () -> { - EssentialUtils.getPlayer().getInventory().selectedSlot = index; - EssentialUtils.getNetworkHandler().sendPacket(new UpdateSelectedSlotC2SPacket(index)); - }); - return null; - } - - @FunctionDoc( - name = "getSelectedSlot", - desc = "This gets the current selected slot number your player is holding", - returns = @ReturnDoc(type = NumberDef.class, desc = "the selected slot"), - examples = "player.getSelectedSlot" - ) - private int getSelectedSlot(Arguments arguments) { - return EssentialUtils.getPlayer().getInventory().selectedSlot; - } - - @FunctionDoc( - name = "say", - desc = "This allows you to make your player send a message in chat, this includes commands", - params = {@ParameterDoc(type = StringDef.class, name = "message", desc = "the message to send")}, - examples = "player.say('/help');" - ) - private Void say(Arguments arguments) { - EssentialUtils.sendChatMessage(arguments.skip().next().toString(arguments.getInterpreter())); - return null; - } - - @FunctionDoc( - name = "message", - desc = "This allows you to send a message to your player, only they will see this, purely client side", - params = {@ParameterDoc(type = TextDef.class, name = "message", desc = "the message to send, can also be string")}, - examples = "player.message('Hello World!');" - ) - private Void message(Arguments arguments) { - ClassInstance value = arguments.skip().next(); - Text text = ClientScriptUtils.instanceToText(value, arguments.getInterpreter()); - ClientScriptUtils.ensureMainThread("message", arguments.getInterpreter(), () -> { - EssentialUtils.getPlayer().sendMessage(text, false); - }); - return null; - } - - @FunctionDoc( - name = "messageActionBar", - desc = "This allows you to set the current memssage displaying on the action bar", - params = {@ParameterDoc(type = TextDef.class, name = "message", desc = "the message to send, can also be string")}, - examples = "player.messageActionBar('Hello World!');" - ) - private Void messageActionBar(Arguments arguments) { - ClassInstance value = arguments.skip().next(); - Text text = ClientScriptUtils.instanceToText(value, arguments.getInterpreter()); - ClientScriptUtils.ensureMainThread("messageActionBar", arguments.getInterpreter(), () -> { - EssentialUtils.getPlayer().sendMessage(text, true); - }); - return null; - } - - @FunctionDoc( - name = "showTitle", - desc = "THis allows you to show a title and subtitle to the player", - params = { - @ParameterDoc(type = TextDef.class, name = "title", desc = "the title to show, can be string or null"), - @ParameterDoc(type = TextDef.class, name = "subtitle", desc = "the subtitle to show, can be string or null") - }, - examples = "player.showTitle('Title!', 'Subtitle!');" - ) - private Void showTitle(Arguments arguments) { - ClassInstance titleInstance = arguments.skip().next(); - ClassInstance subTitleInstance = arguments.next(); - Text title = ClientScriptUtils.instanceToText(titleInstance, arguments.getInterpreter()); - Text subTitle = ClientScriptUtils.instanceToText(subTitleInstance, arguments.getInterpreter()); - ClientScriptUtils.ensureMainThread("showTitle", arguments.getInterpreter(), () -> { - MinecraftClient client = EssentialUtils.getClient(); - client.inGameHud.setTitle(title); - client.inGameHud.setSubtitle(subTitle); - }); - return null; - } - - @FunctionDoc( - name = "openInventory", - desc = "This opens the player's inventory", - examples = "player.openInventory();" - ) - private Void openInventory(Arguments arguments) { - ClientScriptUtils.ensureMainThread("openInventory", arguments.getInterpreter(), () -> { - EssentialUtils.getClient().setScreen(new InventoryScreen(EssentialUtils.getPlayer())); - }); - return null; - } - - @FunctionDoc( - name = "openScreen", - desc = { - "This opens a screen for the player, this cannot open server side screens.", - "This will throw an error if you are trying to open a handled screen" - }, - params = {@ParameterDoc(type = ScreenDef.class, name = "screen", desc = "the screen to open")}, - examples = "player.openScreen(new FakeScreen('MyScreen', 4));" - ) - private Void openScreen(Arguments arguments) { - Screen screen = arguments.skip().nextPrimitive(ScreenDef.class); - if (screen instanceof HandledScreen && !(screen instanceof FakeInventoryScreen)) { - throw new RuntimeError("Opening handled screens is unsafe"); - } - ClientScriptUtils.ensureMainThread("openScreen", arguments.getInterpreter(), () -> { - EssentialUtils.getClient().setScreen(screen); - }); - return null; - } - - @FunctionDoc( - name = "closeScreen", - desc = "This closes the current screen", - examples = "player.closeScreen();" - ) - private Void closeScreen(Arguments arguments) { - ClientScriptUtils.ensureMainThread("closeScreen", arguments.getInterpreter(), () -> { - EssentialUtils.getPlayer().closeHandledScreen(); - }); - return null; - } - - @FunctionDoc( - name = "setWalking", - desc = "This sets the player's walking state", - params = {@ParameterDoc(type = BooleanDef.class, name = "walking", desc = "the walking state")}, - examples = "player.setWalking(true);" - ) - private Void setWalking(Arguments arguments) { - ClientScriptUtils.modifyKey(arguments.getInterpreter(), arguments.skip().nextPrimitive(BooleanDef.class), EssentialUtils.getClient().options.forwardKey); - return null; - } - - @FunctionDoc( - name = "setSneaking", - desc = "This sets the player's sneaking state", - params = {@ParameterDoc(type = BooleanDef.class, name = "sneaking", desc = "the sneaking state")}, - examples = "player.setSneaking(true);" - ) - private Void setSneaking(Arguments arguments) { - ClientScriptUtils.modifyKey(arguments.getInterpreter(), arguments.skip().nextPrimitive(BooleanDef.class), EssentialUtils.getClient().options.sneakKey); - return null; - } - - @FunctionDoc( - name = "setSprinting", - desc = "This sets the player's sprinting state", - params = {@ParameterDoc(type = BooleanDef.class, name = "sprinting", desc = "the sprinting state")}, - examples = "player.setSprinting(true);" - ) - private Void setSprinting(Arguments arguments) { - boolean shouldSprint = arguments.skip().nextPrimitive(BooleanDef.class); - ClientScriptUtils.ensureMainThread("setSprinting", arguments.getInterpreter(), () -> { - EssentialUtils.getPlayer().setSprinting(shouldSprint); - }); - return null; - } - - @FunctionDoc( - name = "dropItemInHand", - desc = "This drops the item(s) in the player's main hand", - params = {@ParameterDoc(type = BooleanDef.class, name = "dropAll", desc = "if true, all items in the player's main hand will be dropped")}, - examples = "player.dropItemInHand(true);" - ) - private Void dropItemInHand(Arguments arguments) { - boolean dropAll = arguments.skip().nextPrimitive(BooleanDef.class); - ClientScriptUtils.ensureMainThread("dropItemInHand", arguments.getInterpreter(), () -> { - EssentialUtils.getPlayer().dropSelectedItem(dropAll); - }); - return null; - } - - @FunctionDoc( - name = "dropAll", - desc = "This drops all items of a given type in the player's inventory", - params = {@ParameterDoc(type = MaterialDef.class, name = "material", desc = "the item stack, or material type to drop")}, - examples = "player.dropAll(Material.DIRT.asItemStack());" - ) - private Void dropAll(Arguments arguments) { - Item item = arguments.skip().nextPrimitive(MaterialDef.class).asItem(); - ClientScriptUtils.ensureMainThread("dropAll", arguments.getInterpreter(), () -> { - InventoryUtils.dropAllItemType(item); - }); - return null; - } - - @FunctionDoc( - name = "dropAllExact", - desc = "This drops all the items that have the same nbt as a given stack", - params = {@ParameterDoc(type = ItemStackDef.class, name = "itemStack", desc = "the stack with nbt to drop")}, - examples = "player.dropAllExact(Material.GOLD_INGOT.asItemStack());" - ) - private Void dropAllExact(Arguments arguments) { - ItemStack stack = arguments.skip().nextPrimitive(ItemStackDef.class).stack; - ClientScriptUtils.ensureMainThread("dropAllExact", arguments.getInterpreter(), () -> { - InventoryUtils.dropAllItemExact(stack); - }); - return null; - } - - @FunctionDoc( - name = "look", - desc = "This sets the player's look direction", - params = { - @ParameterDoc(type = NumberDef.class, name = "yaw", desc = "the yaw of the player's look direction"), - @ParameterDoc(type = NumberDef.class, name = "pitch", desc = "the pitch of the player's look direction") - }, - examples = "player.look(0, 0);" - ) - private Void look(Arguments arguments) { - float yaw = arguments.skip().nextPrimitive(NumberDef.class).floatValue(); - float pitch = arguments.nextPrimitive(NumberDef.class).floatValue(); - ClientScriptUtils.ensureMainThread("look", arguments.getInterpreter(), () -> { - ClientPlayerEntity player = EssentialUtils.getPlayer(); - player.setYaw(yaw); - player.setPitch(pitch); - }); - return null; - } - - @FunctionDoc( - name = "lookAtPos", - desc = "This makes your player look towards a position", - params = { - @ParameterDoc(type = NumberDef.class, name = "x", desc = "the x coordinate of the position"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "the y coordinate of the position"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "the z coordinate of the position") - }, - examples = "player.lookAtPos(0, 0, 0);" - ) - private Void lookAtPos(Arguments arguments) { - double x = arguments.skip().nextPrimitive(NumberDef.class); - double y = arguments.nextPrimitive(NumberDef.class); - double z = arguments.nextPrimitive(NumberDef.class); - ClientScriptUtils.ensureMainThread("lookAtPos", arguments.getInterpreter(), () -> { - EssentialUtils.getPlayer().lookAt(EntityAnchorArgumentType.EntityAnchor.EYES, new Vec3d(x, y, z)); - }); - return null; - } - - @FunctionDoc( - name = "lookAtPos", - desc = "This makes your player look towards a position", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "the position to look at")}, - examples = "player.lookAtPos(pos);" - ) - private Void lookAtPosPos(Arguments arguments) { - Vec3d pos = arguments.skip().nextPrimitive(PosDef.class).getVec3d(); - ClientScriptUtils.ensureMainThread("lookAtPos", arguments.getInterpreter(), () -> { - EssentialUtils.getPlayer().lookAt(EntityAnchorArgumentType.EntityAnchor.EYES, pos); - }); - return null; - } - - @FunctionDoc( - name = "canPlaceBlockAt", - desc = "Checks block can be placed at given position", - params = { - @ParameterDoc(type = BlockDef.class, name = "block", desc = "the block to check for"), - @ParameterDoc(type = PosDef.class, name = "pos", desc = "the position to check") - }, - examples = "player.canPlaceBlockAt(block, pos);" - ) - private boolean canPlaceBlockAtPos(Arguments arguments) { - ClientScriptUtils.warnMainThread("canPlaceBlockAt", arguments.getInterpreter()); - BlockState state = arguments.skip().nextPrimitive(BlockDef.class).state; - BlockPos pos = arguments.nextPrimitive(PosDef.class).getBlockPos(); - boolean canPlace = state.canPlaceAt(EssentialUtils.getWorld(), pos); - canPlace = canPlace && EssentialUtils.getWorld().canPlace(state, pos, ShapeContext.of(EssentialUtils.getPlayer())); - return canPlace; - } - - @FunctionDoc( - name = "canPlaceBlockAt", - desc = "Checks block can be placed at given position", - params = { - @ParameterDoc(type = BlockDef.class, name = "block", desc = "the block to check for"), - @ParameterDoc(type = NumberDef.class, name = "x", desc = "the x coordinate of the position"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "the y coordinate of the position"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "the z coordinate of the position") - }, - examples = "player.canPlaceBlockAt(block, 0, 0, 0);" - ) - private boolean canPlaceBlockAtPos1(Arguments arguments) { - ClientScriptUtils.warnMainThread("canPlaceBlockAt", arguments.getInterpreter()); - BlockState state = arguments.skip().nextPrimitive(BlockDef.class).state; - int x = arguments.nextPrimitive(NumberDef.class).intValue(); - int y = arguments.nextPrimitive(NumberDef.class).intValue(); - int z = arguments.nextPrimitive(NumberDef.class).intValue(); - BlockPos pos = new BlockPos(x, y, z); - boolean canPlace = state.canPlaceAt(EssentialUtils.getWorld(), pos); - canPlace = canPlace && EssentialUtils.getWorld().canPlace(state, pos, ShapeContext.of(EssentialUtils.getPlayer())); - return canPlace; - } - - @FunctionDoc( - name = "jump", - desc = "This will make the player jump if they are on the ground", - examples = "player.jump();" - ) - private Void jump(Arguments arguments) { - ClientScriptUtils.ensureMainThread("jump", arguments.getInterpreter(), () -> { - ClientPlayerEntity player = EssentialUtils.getPlayer(); - if (player.isOnGround()) { - player.jump(); - player.setOnGround(false); - } - }); - return null; - } - - @FunctionDoc( - name = "getLookingAtEntity", - desc = "This gets the entity that the player is currently looking at", - returns = @ReturnDoc(type = EntityDef.class, desc = "the entity that the player is looking at"), - examples = "player.getLookingAtEntity();" - ) - private Entity getLookingAtEntity(Arguments arguments) { - ClientScriptUtils.warnMainThread("getLookingAtEntity", arguments.getInterpreter()); - if (EssentialUtils.getClient().crosshairTarget instanceof EntityHitResult hitResult) { - return hitResult.getEntity(); - } - return null; - } - - @FunctionDoc( - name = "swapSlots", - desc = { - "The allows you to swap two slots with one another.", - "A note about slot order is that slots go from top to bottom.", - "This will throw an errof if the slots are out of bounds" - }, - params = { - @ParameterDoc(type = NumberDef.class, name = "slot1", desc = "the slot to swap with slot2"), - @ParameterDoc(type = NumberDef.class, name = "slot2", desc = "the slot to swap with slot1") - }, - examples = "player.swapSlots(13, 14);" - ) - private Void swapSlots(Arguments arguments) { - ClientPlayerEntity player = EssentialUtils.getPlayer(); - int slot1 = arguments.skip().nextPrimitive(NumberDef.class).intValue(); - int slot2 = arguments.nextPrimitive(NumberDef.class).intValue(); - ClientScriptUtils.ensureMainThread("swapSlots", arguments.getInterpreter(), () -> { - ScreenHandler screenHandler = player.currentScreenHandler; - int size = screenHandler.slots.size(); - if (slot1 >= size || slot1 < 0 || slot2 >= size || slot2 < 0) { - throw new RuntimeError("That slot is out of bounds"); - } - int firstMapped = InventoryUtils.isSlotInHotbar(screenHandler, slot1); - int secondMapped = InventoryUtils.isSlotInHotbar(screenHandler, slot2); - if (firstMapped == -1) { - if (secondMapped == -1) { - ClientPlayerInteractionManager interactionManager = EssentialUtils.getInteractionManager(); - interactionManager.clickSlot(screenHandler.syncId, slot1, 0, SlotActionType.SWAP, player); - interactionManager.clickSlot(screenHandler.syncId, slot2, 0, SlotActionType.SWAP, player); - interactionManager.clickSlot(screenHandler.syncId, slot1, 0, SlotActionType.SWAP, player); - player.getInventory().updateItems(); - } else { - InventoryUtils.swapSlot(screenHandler, slot1, secondMapped); - } - } else { - InventoryUtils.swapSlot(screenHandler, slot2, firstMapped); - } - }); - return null; - } - - @FunctionDoc( - name = "getSwappableHotbarSlot", - desc = { - "This will get the next empty slot in the hotbar starting from the current slot", - "going right, and if it reaches the end of the hotbar it will start from the beginning.", - "If there is no empty slot it will return any slot that doesn't have an item with", - "an enchantment that is in the hotbar, again going from the current slot", - "if there is no such slot it will return the current selected slot" - }, - returns = @ReturnDoc(type = NumberDef.class, desc = "the slot that is swappable"), - examples = "player.getSwappableHotbarSlot();" - ) - private int getSwappableHotbarSlot(Arguments arguments) { - // Return predicted current swappable hotbar slot - return EssentialUtils.getPlayer().getInventory().getSwappableHotbarSlot(); - } - - @FunctionDoc( - name = "spectatorTeleport", - desc = "This allows you to teleport to any entity as long as you are in spectator mode", - params = {@ParameterDoc(type = EntityDef.class, name = "entity", desc = "the entity to teleport to, this can also be a string (UUID of entity)")}, - examples = "player.spectatorTeleport(player.getLookingAtEntity());" - ) - private boolean spectatorTeleport(Arguments arguments) { - ClientPlayerEntity player = EssentialUtils.getPlayer(); - if (!player.isSpectator()) { - return false; - } - arguments.skip(); - - UUID uuid; - if (arguments.isNext(StringDef.class)) { - String uuidAsString = arguments.nextPrimitive(StringDef.class); - uuid = RuntimeError.wrap(() -> UUID.fromString(uuidAsString)); - } else { - uuid = arguments.nextPrimitive(EntityDef.class).getUuid(); - } - EssentialUtils.getNetworkHandler().sendPacket(new SpectatorTeleportC2SPacket(uuid)); - return true; - } - - @FunctionDoc( - name = "swapHands", - desc = "This will swap the player's main hand with the off hand", - examples = "player.swapHands();" - ) - private boolean swapHands(Arguments arguments) { - ClientPlayerEntity player = EssentialUtils.getPlayer(); - if (player.isSpectator()) { - return false; - } - ClientScriptUtils.ensureMainThread("swapHands", arguments.getInterpreter(), () -> { - EssentialUtils.getNetworkHandler().sendPacket( - new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.SWAP_ITEM_WITH_OFFHAND, BlockPos.ORIGIN, Direction.DOWN) - ); - }); - return true; - } - - @FunctionDoc( - name = "swingHand", - desc = "This will play the player's hand swing animation for a given hand", - params = {@ParameterDoc(type = StringDef.class, name = "hand", desc = "the hand to swing, this should be either 'main_hand' or 'off_hand'")}, - examples = "player.swingHand('main_hand');" - ) - private Void swingHand(Arguments arguments) { - String handAsString = arguments.skip().nextConstant(); - Hand hand = ClientScriptUtils.stringToHand(handAsString); - ClientScriptUtils.ensureMainThread("swingHand", arguments.getInterpreter(), () -> { - EssentialUtils.getPlayer().swingHand(hand); - }); - return null; - } - - @FunctionDoc( - name = "clickSlot", - desc = { - "This allows you to click a slot with either right or left click", - "and a slot action, the click must be either 'left' or 'right' or a number (for swap).", - "The action must be either 'click', 'shift_click', 'swap', 'middle_click',", - "'throw', 'drag', or 'double_click' or an error will be thrown" - }, - params = { - @ParameterDoc(type = NumberDef.class, name = "slot", desc = "the slot to click"), - @ParameterDoc(type = StringDef.class, name = "click", desc = "the click type, this should be either 'left' or 'right'"), - @ParameterDoc(type = StringDef.class, name = "action", desc = "the action to perform") - }, - examples = "player.clickSlot(9, 'left', 'double_click');" - ) - private Void clickSlot(Arguments arguments) { - int slot = arguments.skip().nextPrimitive(NumberDef.class).intValue(); - int clickData; - if (arguments.isNext(StringDef.class)) { - clickData = switch (arguments.nextPrimitive(StringDef.class).toLowerCase()) { - case "right" -> 1; - case "left" -> 0; - default -> throw new RuntimeError("Invalid clickData must be 'left' or 'right' or a number"); - }; - } else if (arguments.isNext(NumberDef.class)) { - clickData = arguments.nextPrimitive(NumberDef.class).intValue(); - } else { - throw new RuntimeError("Invalid clickData must be 'left' or 'right' or a number"); - } - String action = arguments.nextConstant(); - SlotActionType slotActionType = ClientScriptUtils.stringToSlotActionType(action); - ClientScriptUtils.ensureMainThread("clickSlot", arguments.getInterpreter(), () -> { - ClientPlayerEntity player = EssentialUtils.getPlayer(); - ScreenHandler screenHandler = player.currentScreenHandler; - int size = screenHandler.slots.size(); - if (slot != -999 && slot >= size || slot < 0) { - throw new RuntimeError("That slot is out of bounds"); - } - EssentialUtils.getInteractionManager().clickSlot(screenHandler.syncId, slot, clickData, slotActionType, player); - }); - return null; - } - - @FunctionDoc( - name = "clickCreativeStack", - desc = "This allows you to click Creative stack, but requires sync with server", - params = { - @ParameterDoc(type = ItemStackDef.class, name = "itemStack", desc = "Stack to click"), - @ParameterDoc(type = NumberDef.class, name = "slot", desc = "the slot to click")}, - examples = "player.clickCreativeStack(Material.DIAMOND_SWORD.asItemStack(), 9);" - ) - private Void clickCreativeStack(Arguments arguments) { - ScriptItemStack stackValue = arguments.skip().nextPrimitive(ItemStackDef.class); - int index = arguments.nextPrimitive(NumberDef.class).intValue(); - ClientScriptUtils.ensureMainThread("clickCreativeStack", arguments.getInterpreter(), () -> { - ClientPlayerEntity player = EssentialUtils.getPlayer(); - ScreenHandler screenHandler = player.currentScreenHandler; - int size = screenHandler.slots.size(); - if (index >= size || index < 0) { - throw new RuntimeError("That slot is out of bounds"); - } - EssentialUtils.getInteractionManager().clickCreativeStack(stackValue.stack, index); - }); - return null; - } - - @FunctionDoc( - name = "shiftClickSlot", - desc = "This allows you to shift click a slot", - params = {@ParameterDoc(type = NumberDef.class, name = "slot", desc = "the slot to click")}, - examples = "player.shiftClickSlot(9);" - ) - private Void shiftClickSlot(Arguments arguments) { - int index = arguments.skip().nextPrimitive(NumberDef.class).intValue(); - ClientScriptUtils.ensureMainThread("shiftClickSlot", arguments.getInterpreter(), () -> { - ClientPlayerEntity player = EssentialUtils.getPlayer(); - ScreenHandler screenHandler = player.currentScreenHandler; - int size = screenHandler.slots.size(); - if (index >= size || index < 0) { - throw new RuntimeError("That slot is out of bounds"); - } - InventoryUtils.shiftClickSlot(screenHandler, index); - }); - return null; - } - - @FunctionDoc( - name = "dropSlot", - desc = "This allows you to drop the items in a slot", - params = {@ParameterDoc(type = NumberDef.class, name = "slot", desc = "the slot to drop")}, - examples = "player.dropSlot(9);" - ) - private Void dropSlot(Arguments arguments) { - int index = arguments.skip().nextPrimitive(NumberDef.class).intValue(); - ClientScriptUtils.ensureMainThread("shiftClickSlot", arguments.getInterpreter(), () -> { - ClientPlayerEntity player = EssentialUtils.getPlayer(); - ScreenHandler screenHandler = player.currentScreenHandler; - int size = screenHandler.slots.size(); - if (index >= size || index < 0) { - throw new RuntimeError("That slot is out of bounds"); - } - EssentialUtils.getInteractionManager().clickSlot(screenHandler.syncId, index, 1, SlotActionType.THROW, player); - }); - return null; - } - - @FunctionDoc( - name = "getCurrentScreen", - desc = "This gets the current screen the player is in", - returns = @ReturnDoc(type = ScreenDef.class, desc = "the screen the player is in, if the player is not in a screen it will return null"), - examples = "screen = player.getCurrentScreen();" - ) - private Screen getCurrentScreen(Arguments arguments) { - ClientScriptUtils.warnMainThread("getCurrentScreen", arguments.getInterpreter()); - return EssentialUtils.getClient().currentScreen; - } - - @FunctionDoc( - name = "craft", - desc = { - "This allows you to craft a recipe, this can be 2x2 or 3x3", - "The list you pass in must contain Materials or ItemStacks", - "Most of the time you should use craftRecipe instead. You must", - "be in an appropriate gui for the crafting recipe or an error will be thrown" - }, - params = {@ParameterDoc(type = ListDef.class, name = "recipe", desc = "a list of materials making up the recipe you want to craft including air")}, - examples = { - """ - chestRecipe = [ - Material.OAK_PLANKS, Material.OAK_PLANKS, Material.OAK_PLANKS, - Material.OAK_PLANKS, Material.AIR , Material.OAK_PLANKS, - Material.OAK_PLANKS, Material.OAK_PLANKS, Material.OAK_PLANKS - ]; - player.craft(chestRecipe); - """ - } - ) - private Void craft(Arguments arguments) { - ArucasList listValue = arguments.skip().nextPrimitive(ListDef.class); - if (listValue.size() != 4 && listValue.size() != 9) { - throw new RuntimeError("Recipe must either be 3x3 or 2x2"); - } - ItemStack[] itemStacks = new ItemStack[listValue.size()]; - for (int i = 0; i < listValue.size(); i++) { - ScriptMaterial value = listValue.get(i).getPrimitive(MaterialDef.class); - if (value != null) { - itemStacks[i] = value.asItemStack(); - continue; - } - throw new RuntimeError("The recipe must only include items or materials"); - } - - ClientScriptUtils.ensureMainThread("craft", arguments.getInterpreter(), () -> { - MinecraftClient client = EssentialUtils.getClient(); - if (!(client.currentScreen instanceof HandledScreen handledScreen)) { - throw new RuntimeError("Must be in a crafting GUI"); - } - if (itemStacks.length == 9 && !(handledScreen instanceof CraftingScreen)) { - throw new RuntimeError("3x3 recipes require crafting table GUI"); - } - ScreenHandler handler = handledScreen.getScreenHandler(); - InventoryUtils.tryMoveItemsToCraftingGridSlots(itemStacks, handler); - InventoryUtils.shiftClickSlot(handler, 0); - }); - return null; - } - - @FunctionDoc( - name = "craftRecipe", - desc = "This allows you to craft a predefined recipe", - params = {@ParameterDoc(type = RecipeDef.class, name = "recipe", desc = "the recipe you want to craft")}, - examples = "player.craftRecipe(Recipe.CHEST);" - ) - private Void craftRecipe(Arguments arguments) { - RecipeEntry recipe = arguments.skip().nextPrimitive(RecipeDef.class); - ClientScriptUtils.ensureMainThread("craftRecipe", arguments.getInterpreter(), () -> { - InventoryUtils.craftRecipe(recipe, false, true); - }); - return null; - } - - @FunctionDoc( - name = "craftRecipe", - desc = "This allows you to craft a predefined recipe", - params = { - @ParameterDoc(type = RecipeDef.class, name = "recipe", desc = "the recipe you want to craft"), - @ParameterDoc(type = BooleanDef.class, name = "boolean", desc = "whether result should be dropped or not") - }, - examples = "player.craftRecipe(Recipe.CHEST, true);" - ) - private Void craftRecipeDrop(Arguments arguments) { - RecipeEntry recipe = arguments.skip().nextPrimitive(RecipeDef.class); - boolean shouldDrop = arguments.nextPrimitive(BooleanDef.class); - ClientScriptUtils.ensureMainThread("craftRecipe", arguments.getInterpreter(), () -> { - InventoryUtils.craftRecipe(recipe, shouldDrop, true); - }); - return null; - } - - @FunctionDoc( - name = "craftRecipe", - desc = "This allows you to craft a predefined recipe", - params = { - @ParameterDoc(type = RecipeDef.class, name = "recipe", desc = "the recipe you want to craft"), - @ParameterDoc(type = BooleanDef.class, name = "boolean", desc = "whether result should be dropped or not"), - @ParameterDoc(type = BooleanDef.class, name = "boolean", desc = "whether whole stack should be crafted or not") - }, - examples = "player.craftRecipe(Recipe.CHEST, true, false);" - ) - private Void craftRecipeDropAll(Arguments arguments) { - RecipeEntry recipe = arguments.skip().nextPrimitive(RecipeDef.class); - boolean shouldDrop = arguments.nextPrimitive(BooleanDef.class); - boolean shouldCraftAll = arguments.nextPrimitive(BooleanDef.class); - ClientScriptUtils.ensureMainThread("craftRecipe", arguments.getInterpreter(), () -> { - InventoryUtils.craftRecipe(recipe, shouldDrop, shouldCraftAll); - }); - return null; - } - - @FunctionDoc( - name = "clickRecipe", - desc = "This allows you to click a predefined recipe", - params = {@ParameterDoc(type = RecipeDef.class, name = "recipe", desc = "the recipe you want to select")}, - examples = "player.clickRecipe(Recipe.CHEST);" - ) - private Void clickRecipe1(Arguments arguments) { - RecipeEntry recipe = arguments.skip().nextPrimitive(RecipeDef.class); - ClientScriptUtils.ensureMainThread("clickRecipe", arguments.getInterpreter(), () -> { - InventoryUtils.clickRecipe(recipe, false); - }); - return null; - } - - @FunctionDoc( - name = "clickRecipe", - desc = "This allows you to click a predefined recipe", - params = { - @ParameterDoc(type = RecipeDef.class, name = "recipe", desc = "the recipe you want to select"), - @ParameterDoc(type = BooleanDef.class, name = "boolean", desc = "whether to shift click the recipe") - }, - examples = "player.clickRecipe(Recipe.CHEST, true);" - ) - private Void clickRecipe2(Arguments arguments) { - RecipeEntry recipe = arguments.skip().nextPrimitive(RecipeDef.class); - boolean craftAll = arguments.nextPrimitive(BooleanDef.class); - ClientScriptUtils.ensureMainThread("clickRecipe", arguments.getInterpreter(), () -> { - InventoryUtils.clickRecipe(recipe, craftAll); - }); - return null; - } - - @FunctionDoc( - name = "logout", - desc = "This forces the player to leave the world", - params = {@ParameterDoc(type = StringDef.class, name = "message", desc = "the message to display to the player on the logout screen")}, - examples = "player.logout('You've been lazy!');" - ) - private Void logout(Arguments arguments) { - String reason = arguments.skip().nextPrimitive(StringDef.class); - ClientScriptUtils.ensureMainThread("logout", arguments.getInterpreter(), () -> { - EssentialUtils.getNetworkHandler().onDisconnected(new DisconnectionInfo(Text.literal(reason))); - }); - return null; - } - - @FunctionDoc( - name = "attackEntity", - desc = { - "This makes your player attack an entity without", - "having to be looking at it or clicking on the entity" - }, - params = {@ParameterDoc(type = EntityDef.class, name = "entity", desc = "the entity to attack")}, - examples = """ - allEntities = client.getWorld().getAllEntities(); - foreach (entity : allEntities) { - if (entity.getId() == "villager" && player.getSquaredDistanceTo(entity) < 5) { - player.attackEntity(entity); - break; - } - } - """ - ) - private Void attackEntity(Arguments arguments) { - Entity entity = arguments.skip().nextPrimitive(EntityDef.class); - ClientScriptUtils.ensureMainThread("interactWithEntity", arguments.getInterpreter(), () -> { - EssentialUtils.getInteractionManager().attackEntity(EssentialUtils.getPlayer(), entity); - }); - return null; - } - - @FunctionDoc( - name = "interactWithEntity", - desc = { - "This allows your player to interact with an entity without", - "having to be looking at it or clicking on the entity" - }, - params = {@ParameterDoc(type = EntityDef.class, name = "entity", desc = "the entity to interact with")}, - examples = """ - allEntities = client.getWorld().getAllEntities(); - foreach (entity : allEntities) { - if (entity.getId() == "villager" && player.getSquaredDistanceTo(entity) < 5) { - player.interactWithEntity(entity); - break; - } - } - """ - ) - private Void interactWithEntity(Arguments arguments) { - Entity entity = arguments.skip().nextPrimitive(EntityDef.class); - ClientScriptUtils.ensureMainThread("interactWithEntity", arguments.getInterpreter(), () -> { - EssentialUtils.getInteractionManager().interactEntity(EssentialUtils.getPlayer(), entity, Hand.MAIN_HAND); - }); - return null; - } - - @FunctionDoc( - name = "anvil", - desc = "This allows you to combine two items in an anvil", - params = { - @ParameterDoc(type = FunctionDef.class, name = "predicate1", desc = "a function determining whether the first ItemStack meets a criteria"), - @ParameterDoc(type = FunctionDef.class, name = "predicate2", desc = "a function determining whether the second ItemStack meets a criteria") - }, - returns = @ReturnDoc(type = FutureDef.class, desc = "whether the anvilling was successful, if the player doesn't have enough levels it will return the xp cost"), - examples = """ - // Enchant a pickaxe with mending - player.anvil( - // Predicate for pick - fun(item) { - // We want a netherite pickaxe without mending - if (item.getItemId() == "netherite_pickaxe") { - hasMending = item.getEnchantments().getKeys().contains("mending"); - return !hasMending; - } - return false; - }, - // Predicate for book - fun(item) { - // We want a book with mending - if (item.getItemId() == "enchanted_book") { - hasMending = item.getEnchantments().getKeys().contains("mending"); - return hasMending; - } - return false; - } - ); - """ - ) - private Future anvil2(Arguments arguments) { - ArucasFunction predicate1 = arguments.skip().nextPrimitive(FunctionDef.class); - ArucasFunction predicate2 = arguments.nextPrimitive(FunctionDef.class); - Interpreter interpreter = arguments.getInterpreter(); - return ClientScriptUtils.ensureMainThread("anvil", interpreter, () -> { - return InventoryUtils.anvil(interpreter, predicate1, predicate2, false); - }); - } - - @FunctionDoc( - name = "anvil", - desc = "This allows you to combine two items in an anvil", - params = { - @ParameterDoc(type = FunctionDef.class, name = "predicate1", desc = "a function determining whether the first ItemStack meets a criteria"), - @ParameterDoc(type = FunctionDef.class, name = "predicate2", desc = "a function determining whether the second ItemStack meets a criteria"), - @ParameterDoc(type = BooleanDef.class, name = "take", desc = "whether you should take the item after putting items in the anvil") - }, - returns = @ReturnDoc(type = FutureDef.class, desc = "whether the anvilling was successful, if the player doesn't have enough levels it will return the xp cost"), - examples = { - """ - // Enchant a pickaxe with mending - player.anvil( - // Predicate for pick - fun(item) { - // We want a netherite pickaxe without mending - if (item.getItemId() == "netherite_pickaxe") { - hasMending = item.getEnchantments().getKeys().contains("mending"); - return !hasMending; - } - return false; - }, - // Predicate for book - fun(item) { - // We want a book with mending - if (item.getItemId() == "enchanted_book") { - hasMending = item.getEnchantments().getKeys().contains("mending"); - return hasMending; - } - return false; - }, - false - ); - """ - } - ) - private Future anvil3(Arguments arguments) { - ArucasFunction predicate1 = arguments.skip().nextPrimitive(FunctionDef.class); - ArucasFunction predicate2 = arguments.nextPrimitive(FunctionDef.class); - boolean take = arguments.nextPrimitive(BooleanDef.class); - Interpreter interpreter = arguments.getInterpreter(); - return ClientScriptUtils.ensureMainThread("anvil", interpreter, () -> { - return InventoryUtils.anvil(interpreter, predicate1, predicate2, take); - }); - } - - @FunctionDoc( - name = "anvilRename", - desc = "This allows you to name an item in an anvil", - params = { - @ParameterDoc(type = StringDef.class, name = "name", desc = "the name you want to give the item"), - @ParameterDoc(type = FunctionDef.class, name = "predicate", desc = "whether the ItemStack meets a certain criteria") - }, - returns = @ReturnDoc(type = FutureDef.class, desc = "whether the anvilling was successful, if the player doesn't have enough levels it will return the xp cost"), - examples = { - """ - // Rename any shulker box - player.anvilRename("Rocket Box", - fun(item) { - isShulker = item.getItemId().containsString("shulker_box")); - return isShulker; - } - ); - """ - } - ) - private Future anvilRename(Arguments arguments) { - String newName = arguments.skip().nextPrimitive(StringDef.class); - ArucasFunction function = arguments.nextPrimitive(FunctionDef.class); - Interpreter interpreter = arguments.getInterpreter(); - return ClientScriptUtils.ensureMainThread("anvilRename", interpreter, () -> { - return InventoryUtils.anvilRename(interpreter, newName, function); - }); - } - - @FunctionDoc( - name = "stonecutter", - desc = "This allows you to use the stonecutter", - params = { - @ParameterDoc(type = MaterialDef.class, name = "itemInput", desc = "the item or material you want to input"), - @ParameterDoc(type = MaterialDef.class, name = "itemOutput", desc = "the item or material you want to craft") - }, - returns = @ReturnDoc(type = FutureDef.class, desc = "whether the result was successful"), - examples = "player.stonecutter(Material.STONE.asItemstack(), Material.STONE_BRICKS.asItemStack());" - ) - private Future stonecutter(Arguments arguments) { - Item itemInput = arguments.skip().nextPrimitive(MaterialDef.class).asItem(); - Item itemOutput = arguments.nextPrimitive(MaterialDef.class).asItem(); - return ClientScriptUtils.ensureMainThread("stonecutter", arguments.getInterpreter(), () -> { - return InventoryUtils.stonecutter(itemInput, itemOutput); - }); - } - - // Try casting recipe to CuttingRecipe, then execute stonecutter - @FunctionDoc( - name = "clickStonecuttingRecipe", - desc = "This allows you to click the stonecutter recipe. Unlike clickRecipe, stonecutter wants you to manually send input items.", - params = { - @ParameterDoc(type = RecipeDef.class, name = "cuttingRecipe", desc = "Stone cutting recipe") - }, - examples = "player.clickCuttingRecipe(cuttingRecipe);" - ) - private Void clickCuttingRecipe(Arguments arguments) { - RecipeEntry recipe = arguments.skip().nextPrimitive(RecipeDef.class); - if (recipe.value() instanceof StonecuttingRecipe cuttingRecipe) { - ClientScriptUtils.ensureMainThread("clickCuttingRecipe", arguments.getInterpreter(), () -> { - InventoryUtils.clickCuttingRecipe(cuttingRecipe); - return null; - }); - } - return null; - } - - @FunctionDoc( - name = "clickStonecuttingRecipe", - desc = "This allows you to click the stonecutter recipe. Unlike clickRecipe, stonecutter wants you to manually send input items.", - params = { - @ParameterDoc(type = MaterialDef.class, name = "inputItem", desc = "Stone cutting recipe input item"), - @ParameterDoc(type = MaterialDef.class, name = "outputItem", desc = "Stone cutting recipe output item") - }, - examples = "player.clickCuttingRecipe(ItemStack.of('cobblestone'), ItemStack.of('cobblestone_slab');" - ) - private Void clickCuttingRecipe2(Arguments arguments) { - Item inputItem = arguments.skip().nextPrimitive(MaterialDef.class).asItem(); - Item outputItem = arguments.nextPrimitive(MaterialDef.class).asItem(); - ClientScriptUtils.ensureMainThread("clickCuttingRecipe", arguments.getInterpreter(), () -> { - InventoryUtils.clickCuttingRecipe(inputItem, outputItem); - return null; - }); - return null; - } - - @FunctionDoc( - name = "fakeLook", - desc = { - "This makes the player 'fake' looking in a direction, this can be", - "used to place blocks in unusual orientations without moving the camera" - }, - params = { - @ParameterDoc(type = NumberDef.class, name = "yaw", desc = "the yaw to look at"), - @ParameterDoc(type = NumberDef.class, name = "pitch", desc = "the pitch to look at"), - @ParameterDoc(type = StringDef.class, name = "direction", desc = "the direction to look at"), - @ParameterDoc(type = NumberDef.class, name = "duration", desc = "the duration of the look in ticks") - }, - examples = "player.fakeLook(90, 0, 'up', 100);" - ) - private Void fakeLook(Arguments arguments) { - float yaw = arguments.skip().nextPrimitive(NumberDef.class).floatValue(); - float pitch = arguments.nextPrimitive(NumberDef.class).floatValue(); - String directionAsString = arguments.nextConstant(); - int ticks = arguments.nextPrimitive(NumberDef.class).intValue(); - Direction direction = ClientScriptUtils.stringToDirection(directionAsString, Direction.DOWN); - ClientScriptUtils.ensureMainThread("fakeLook", arguments.getInterpreter(), () -> { - BetterAccurateBlockPlacement.fakeYaw = yaw; - BetterAccurateBlockPlacement.fakePitch = pitch; - BetterAccurateBlockPlacement.fakeDirection = direction; - BetterAccurateBlockPlacement.requestedTicks = Math.max(20, ticks); - BetterAccurateBlockPlacement.sendLookPacket(EssentialUtils.getPlayer()); - }); - return null; - } - - @FunctionDoc( - name = "swapPlayerSlotWithHotbar", - desc = "This allows you to swap a slot in the player's inventory with the hotbar", - params = {@ParameterDoc(type = NumberDef.class, name = "slot", desc = "the slot to swap")}, - examples = "player.swapPlayerSlotWithHotbar(15);" - ) - private Void swapPlayerSlotWithHotbar(Arguments arguments) { - int slotToSwap = arguments.skip().nextPrimitive(NumberDef.class).intValue(); - ClientScriptUtils.ensureMainThread("swapPlayerSlotWithHotbar", arguments.getInterpreter(), () -> { - PlayerInventory inventory = EssentialUtils.getPlayer().getInventory(); - if (slotToSwap < 0 || slotToSwap > inventory.main.size()) { - throw new RuntimeError("That slot is out of bounds"); - } - ClientPlayNetworkHandler networkHandler = EssentialUtils.getNetworkHandler(); - int prepareSlot = inventory.getSwappableHotbarSlot(); - networkHandler.sendPacket(new UpdateSelectedSlotC2SPacket(prepareSlot)); - inventory.swapSlotWithHotbar(slotToSwap); - networkHandler.sendPacket(new PickFromInventoryC2SPacket(slotToSwap)); - }); - return null; - } - - @FunctionDoc( - name = "breakBlock", - desc = "This breaks a block at a given position, if it is able to be broken", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "the position of the block")}, - returns = @ReturnDoc(type = FutureDef.class, desc = "the future will be completed when the block is broken"), - examples = "player.breakBlock(new Pos(0, 0, 0));" - ) - private Future breakBlock(Arguments arguments) { - BlockPos blockPos = arguments.skip().nextPrimitive(PosDef.class).getBlockPos(); - CompletableFuture future = new CompletableFuture<>(); - ClientScriptUtils.ensureMainThread("breakBlock", arguments.getInterpreter(), () -> { - EssentialUtils.mineBlock(blockPos, () -> arguments.getInterpreter().isRunning(), future); - }); - return future; - } - - @FunctionDoc( - deprecated = "Consider using other alternatives for breaking blocks, e.g. .breakBlock", - name = "updateBreakingBlock", - desc = "This allows you to update your block breaking progress at a position", - params = { - @ParameterDoc(type = NumberDef.class, name = "x", desc = "the x position"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "the y position"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "the z position") - }, - examples = "player.updateBreakingBlock(0, 0, 0);" - ) - private Void updateBreakingBlock(Arguments arguments) { - double x = arguments.skip().nextPrimitive(NumberDef.class).intValue(); - double y = arguments.nextPrimitive(NumberDef.class).intValue(); - double z = arguments.nextPrimitive(NumberDef.class).intValue(); - BlockPos blockPos = EssentialUtils.vec3dToBlockPos(x, y, z); - ClientScriptUtils.ensureMainThread("updateBreakingBlock", arguments.getInterpreter(), () -> { - EssentialUtils.getInteractionManager().updateBlockBreakingProgress(blockPos, Direction.UP); - EssentialUtils.getPlayer().swingHand(Hand.MAIN_HAND); - }); - return null; - } - - @FunctionDoc( - deprecated = "Consider using other alternatives for breaking blocks, e.g. .breakBlock", - name = "updateBreakingBlock", - desc = "This allows you to update your block breaking progress at a position", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "the position of the block")}, - examples = "player.updateBreakingBlock(new Pos(0, 0, 0));" - ) - private Void updateBreakingBlockPos(Arguments arguments) { - BlockPos blockPos = arguments.skip().nextPrimitive(PosDef.class).getBlockPos(); - ClientScriptUtils.ensureMainThread("updateBreakingBlock", arguments.getInterpreter(), () -> { - EssentialUtils.getInteractionManager().updateBlockBreakingProgress(blockPos, Direction.UP); - EssentialUtils.getPlayer().swingHand(Hand.MAIN_HAND); - }); - return null; - } - - @FunctionDoc( - name = "attackBlock", - desc = "This allows you to attack a block at a position and direction", - params = { - @ParameterDoc(type = NumberDef.class, name = "x", desc = "the x position"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "the y position"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "the z position"), - @ParameterDoc(type = StringDef.class, name = "direction", desc = "the direction of the attack, e.g. 'up', 'north', 'east', etc.") - }, - examples = "player.attackBlock(0, 0, 0, 'up');" - ) - private Void attackBlock(Arguments arguments) { - double x = arguments.skip().nextPrimitive(NumberDef.class).intValue(); - double y = arguments.nextPrimitive(NumberDef.class).intValue(); - double z = arguments.nextPrimitive(NumberDef.class).intValue(); - String stringDirection = arguments.nextConstant(); - Direction direction = ClientScriptUtils.stringToDirection(stringDirection, Direction.DOWN); - ClientScriptUtils.ensureMainThread("attackBlock", arguments.getInterpreter(), () -> { - EssentialUtils.getInteractionManager().attackBlock(EssentialUtils.vec3dToBlockPos(x, y, z), direction); - }); - return null; - } - - @FunctionDoc( - name = "attackBlock", - desc = "This allows you to attack a block at a position and direction", - params = { - @ParameterDoc(type = PosDef.class, name = "pos", desc = "the position of the block"), - @ParameterDoc(type = StringDef.class, name = "direction", desc = "the direction of the attack, e.g. 'up', 'north', 'east', etc.") - }, - examples = "player.attackBlock(new Pos(0, 0, 0), 'up');" - ) - private Void attackBlockPos(Arguments arguments) { - BlockPos pos = arguments.skip().nextPrimitive(PosDef.class).getBlockPos(); - String stringDirection = arguments.nextConstant(); - Direction direction = ClientScriptUtils.stringToDirection(stringDirection, Direction.DOWN); - ClientScriptUtils.ensureMainThread("attackBlock", arguments.getInterpreter(), () -> { - EssentialUtils.getInteractionManager().attackBlock(pos, direction); - }); - return null; - } - - @FunctionDoc( - name = "interactItem", - desc = "This allows you to interact item with given Hand", - params = {@ParameterDoc(type = StringDef.class, name = "hand", desc = " Hand to use, either 'main' or 'offhand'")}, - examples = "player.interactItem('main');" - ) - private Void interactItem(Arguments arguments) { - String handAsString = arguments.skip().nextConstant(); - Hand hand = ClientScriptUtils.stringToHand(handAsString); - ClientScriptUtils.ensureMainThread("interactItem", arguments.getInterpreter(), () -> { - EssentialUtils.getInteractionManager().interactItem(EssentialUtils.getPlayer(), hand); - }); - return null; - } - - @FunctionDoc( - name = "interactBlock", - desc = "This allows you to interact with a block at a position and direction", - params = { - @ParameterDoc(type = PosDef.class, name = "pos", desc = "the position of the block"), - @ParameterDoc(type = StringDef.class, name = "direction", desc = "the direction of the interaction, e.g. 'up', 'north', 'east', etc.") - }, - returns = @ReturnDoc(type = FutureDef.class, desc = "the result of the placement as a string; this can be: 'success', 'pass', 'fail'"), - examples = "player.interactBlock(new Pos(0, 0, 0), 'up');" - ) - private Future interactBlockPos(Arguments arguments) { - ScriptPos pos = arguments.skip().nextPrimitive(PosDef.class); - String direction = arguments.nextConstant(); - return this.interactInternal( - arguments.getInterpreter(), - direction, - EssentialUtils.getPlayer().getActiveHand(), - pos.getVec3d(), - pos.getBlockPos(), - false - ); - } - - @FunctionDoc( - name = "interactBlock", - desc = "This allows you to interact with a block at a position, direction, and hand", - params = { - @ParameterDoc(type = PosDef.class, name = "pos", desc = "the position of the block"), - @ParameterDoc(type = StringDef.class, name = "direction", desc = "the direction of the interaction, e.g. 'up', 'north', 'east', etc."), - @ParameterDoc(type = StringDef.class, name = "hand", desc = "the hand to use, e.g. 'main_hand', 'off_hand'") - }, - returns = @ReturnDoc(type = FutureDef.class, desc = "the result of the placement as a string; this can be: 'success', 'pass', 'fail'"), - examples = "player.interactBlock(new Pos(0, 0, 0), 'up', 'off_hand');" - ) - private Future interactBlockPosHand(Arguments arguments) { - ScriptPos pos = arguments.skip().nextPrimitive(PosDef.class); - String direction = arguments.nextConstant(); - String handAsString = arguments.nextConstant(); - Hand hand = ClientScriptUtils.stringToHand(handAsString); - return this.interactInternal( - arguments.getInterpreter(), - direction, - hand, - pos.getVec3d(), - pos.getBlockPos(), - false - ); - } - - @FunctionDoc( - name = "interactBlock", - desc = { - "This allows you to interact with a block at a position and direction", - "This function is for very specific cases where there needs to be extra precision", - "like when placing stairs or slabs in certain directions, so the first set of", - "coords is the exact position of the block, and the second set of coords is the position" - }, - params = { - @ParameterDoc(type = NumberDef.class, name = "x", desc = "the exact x position"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "the exact y position"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "the exact z position"), - @ParameterDoc(type = StringDef.class, name = "direction", desc = "the direction of the interaction, e.g. 'up', 'north', 'east', etc."), - @ParameterDoc(type = NumberDef.class, name = "blockX", desc = "the x position of the block"), - @ParameterDoc(type = NumberDef.class, name = "blockY", desc = "the y position of the block"), - @ParameterDoc(type = NumberDef.class, name = "blockZ", desc = "the z position of the block"), - @ParameterDoc(type = BooleanDef.class, name = "insideBlock", desc = "whether the player is inside the block") - }, - returns = @ReturnDoc(type = FutureDef.class, desc = "the result of the placement as a string; this can be: 'success', 'pass', 'fail'"), - examples = "player.interactBlock(0, 100.5, 0, 'up', 0, 100, 0, true);" - ) - private Future interactBlockFull(Arguments arguments) { - double px = arguments.skip().nextPrimitive(NumberDef.class); - double py = arguments.nextPrimitive(NumberDef.class); - double pz = arguments.nextPrimitive(NumberDef.class); - String direction = arguments.nextConstant(); - double bx = arguments.nextPrimitive(NumberDef.class); - double by = arguments.nextPrimitive(NumberDef.class); - double bz = arguments.nextPrimitive(NumberDef.class); - boolean bool = arguments.nextPrimitive(BooleanDef.class); - return this.interactInternal( - arguments.getInterpreter(), - direction, - EssentialUtils.getPlayer().getActiveHand(), - new Vec3d(px, py, pz), - EssentialUtils.vec3dToBlockPos(bx, by, bz), - bool - ); - } - - @FunctionDoc( - name = "interactBlock", - desc = { - "This allows you to interact with a block at a position and direction", - "This function is for very specific cases where there needs to be extra precision", - "like when placing stairs or slabs in certain directions, so the first set of", - "coords is the exact position of the block, and the second set of coords is the position" - }, - params = { - @ParameterDoc(type = PosDef.class, name = "pos", desc = "the exact position of the block"), - @ParameterDoc(type = StringDef.class, name = "direction", desc = "the direction of the interaction, e.g. 'up', 'north', 'east', etc."), - @ParameterDoc(type = PosDef.class, name = "blockPos", desc = "the position of the block"), - @ParameterDoc(type = BooleanDef.class, name = "insideBlock", desc = "whether the player is inside the block") - }, - returns = @ReturnDoc(type = FutureDef.class, desc = "the result of the placement as a string; this can be: 'success', 'pass', 'fail'"), - examples = "player.interactBlock(new Pos(0, 15.5, 0), 'up', new Pos(0, 15, 0), true);" - ) - private Future interactBlockFullPos(Arguments arguments) { - Vec3d pos = arguments.skip().nextPrimitive(PosDef.class).getVec3d(); - String direction = arguments.nextConstant(); - BlockPos blockPos = arguments.nextPrimitive(PosDef.class).getBlockPos(); - return this.interactInternal(arguments.getInterpreter(), direction, EssentialUtils.getPlayer().getActiveHand(), pos, blockPos, false); - } - - @FunctionDoc( - name = "interactBlock", - desc = { - "This allows you to interact with a block at a position and direction", - "This function is for very specific cases where there needs to be extra precision", - "like when placing stairs or slabs in certain directions, so the first set of", - "coords is the exact position of the block, and the second set of coords is the position" - }, - params = { - @ParameterDoc(type = PosDef.class, name = "pos", desc = "the exact position of the block"), - @ParameterDoc(type = StringDef.class, name = "direction", desc = "the direction of the interaction, e.g. 'up', 'north', 'east', etc."), - @ParameterDoc(type = StringDef.class, name = "hand", desc = "the hand to use, e.g. 'main_hand', 'off_hand'"), - @ParameterDoc(type = PosDef.class, name = "blockPos", desc = "the position of the block"), - @ParameterDoc(type = BooleanDef.class, name = "insideBlock", desc = "whether the player is inside the block") - }, - returns = @ReturnDoc(type = FutureDef.class, desc = "the result of the placement as a string; this can be: 'success', 'pass', 'fail'"), - examples = "player.interactBlock(new Pos(0, 15.5, 0), 'up', new Pos(0, 15, 0), true, 'off_hand');" - ) - private Future interactBlockFullPosHand(Arguments arguments) { - Vec3d pos = arguments.nextPrimitive(PosDef.class).getVec3d(); - String direction = arguments.nextConstant(); - String handAsString = arguments.nextConstant(); - BlockPos blockPos = arguments.nextPrimitive(PosDef.class).getBlockPos(); - Hand hand = ClientScriptUtils.stringToHand(handAsString); - return this.interactInternal(arguments.getInterpreter(), direction, hand, pos, blockPos, false); - } - - @FunctionDoc( - name = "getBlockBreakingSpeed", - desc = "This returns the block breaking speed of the player on a block including enchanements and effects", - params = {@ParameterDoc(type = ItemStackDef.class, name = "itemStack", desc = "item to test with"), @ParameterDoc(type = BlockDef.class, name = "block", desc = "the block to get the speed of")}, - examples = "speed = player.getBlockBreakingSpeed(Material.NETHERITE_PICKAXE.asItem(), Material.GOLD_BLOCK.asBlock());" - ) - private float getBlockBreakingSpeed(Arguments arguments) { - ClientPlayerEntity player = EssentialUtils.getPlayer(); - ItemStack itemStack = arguments.skip().nextPrimitive(ItemStackDef.class).stack; - BlockState state = arguments.nextPrimitive(BlockDef.class).state; - return EssentialUtils.getBlockBreakingSpeed(itemStack, state, player); - } - - private Future interactInternal(Interpreter interpreter, String directionAsString, Hand hand, Vec3d pos, BlockPos blockPos, boolean insideBlock) { - Hand finalHand = hand == null ? Hand.MAIN_HAND : hand; - Direction direction = ClientScriptUtils.stringToDirection(directionAsString, Direction.DOWN); - BlockHitResult hitResult = new BlockHitResult(pos, direction, blockPos, insideBlock); - return ClientScriptUtils.ensureMainThread("interactBlock", interpreter, () -> { - return EssentialUtils.getInteractionManager().interactBlock(EssentialUtils.getPlayer(), finalHand, hitResult).toString().toLowerCase(Locale.ROOT); - }); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/PosDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/PosDef.java deleted file mode 100644 index 03be21dd..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/PosDef.java +++ /dev/null @@ -1,607 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import kotlin.Unit; -import me.senseiwells.arucas.api.docs.annotations.*; -import me.senseiwells.arucas.builtin.BooleanDef; -import me.senseiwells.arucas.builtin.ListDef; -import me.senseiwells.arucas.builtin.NumberDef; -import me.senseiwells.arucas.builtin.StringDef; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.compiler.LocatableTrace; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.ConstructorFunction; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.impl.ArucasList; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.utils.clientscript.ClientScriptUtils; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptPos; -import net.minecraft.entity.Entity; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.Vec3d; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.POS; - -@ClassDoc( - name = POS, - desc = "This class is a wrapper for 3 coordinate points in Minecraft", - language = Language.Java -) -public class PosDef extends CreatableDefinition { - public PosDef(Interpreter interpreter) { - super(POS, interpreter); - } - - @Override - public Object asJavaValue(ClassInstance instance) { - return instance.asPrimitive(this).getVec3d(); - } - - @Override - public boolean equals(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull ClassInstance other, @NotNull LocatableTrace trace) { - ScriptPos pos = other.getPrimitive(this); - return pos != null && instance.asPrimitive(this).getVec3d().equals(pos.getVec3d()); - } - - @Override - public int hashCode(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - return instance.asPrimitive(this).getVec3d().hashCode(); - } - - @NotNull - @Override - public String toString(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - return instance.asPrimitive(this).getVec3d().toString(); - } - - @Override - public List defineConstructors() { - return List.of( - ConstructorFunction.of(1, this::construct1), - ConstructorFunction.of(3, this::construct3) - ); - } - - @ConstructorDoc( - desc = "Creates a new Pos object with the given coordinates in a list", - params = {@ParameterDoc(type = ListDef.class, name = "list", desc = "the list containing three coordinates")}, - examples = "new Pos([1, 2, 3])" - ) - private Unit construct1(Arguments arguments) { - ClassInstance instance = arguments.next(); - ArucasList list = arguments.nextPrimitive(ListDef.class); - if (list.size() != 3) { - throw new RuntimeError("Expected a list with 3 coordinates"); - } - double[] coords = new double[3]; - for (int i = 0; i < 3; i++) { - Double value = list.get(i).getPrimitive(NumberDef.class); - if (value == null) { - throw new RuntimeError("Expected a number at index " + i); - } - coords[i] = value; - } - instance.setPrimitive(this, new ScriptPos(coords[0], coords[1], coords[2])); - return null; - } - - @ConstructorDoc( - desc = "This creates a new Pos with the given x, y, and z", - params = { - @ParameterDoc(type = NumberDef.class, name = "x", desc = "the x position"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "the y position"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "the z position") - }, - examples = "new Pos(100, 0, 96);" - ) - private Unit construct3(Arguments arguments) { - ClassInstance instance = arguments.next(); - double x = arguments.nextPrimitive(NumberDef.class); - double y = arguments.nextPrimitive(NumberDef.class); - double z = arguments.nextPrimitive(NumberDef.class); - instance.setPrimitive(this, new ScriptPos(x, y, z)); - return null; - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("getX", this::getX), - MemberFunction.of("getY", this::getY), - MemberFunction.of("getZ", this::getZ), - MemberFunction.of("multiply", 3, this::multiply), - MemberFunction.of("multiply", 1, this::multiply1), - MemberFunction.of("add", 3, this::add), - MemberFunction.of("add", 1, this::add1), - MemberFunction.of("subtract", 3, this::subtract), - MemberFunction.of("subtract", 1, this::subtract1), - MemberFunction.of("dotProduct", 1, this::dotProduct), - MemberFunction.of("crossProduct", 1, this::crossProduct), - MemberFunction.of("toBlockPos", this::toBlockPos), - MemberFunction.of("toList", this::toList), - MemberFunction.of("offset", 1, this::offset), - MemberFunction.of("offset", 2, this::offset1), - MemberFunction.of("up", this::up), - MemberFunction.of("up", 1, this::up1), - MemberFunction.of("down", this::down), - MemberFunction.of("down", 1, this::down1), - MemberFunction.of("north", this::north), - MemberFunction.of("north", 1, this::north1), - MemberFunction.of("south", this::south), - MemberFunction.of("south", 1, this::south1), - MemberFunction.of("east", this::east), - MemberFunction.of("east", 1, this::east1), - MemberFunction.of("west", this::west), - MemberFunction.of("west", 1, this::west1), - MemberFunction.of("getSidePos", 1, this::getSidePos), - MemberFunction.of("asCentre", this::asCentre), - MemberFunction.of("isNear", 1, this::isNear), - MemberFunction.of("isWithin", 2, this::isWithin), - MemberFunction.of("distanceTo", 1, this::distanceTo), - MemberFunction.of("distanceTo", 3, this::distanceTo1), - MemberFunction.of("normalize", 0, this::normalize) - ); - } - - @FunctionDoc( - name = "getX", - desc = "This returns the x position of the Pos", - returns = @ReturnDoc(type = NumberDef.class, desc = "the x position"), - examples = "pos.getX();" - ) - private double getX(Arguments arguments) { - return arguments.nextPrimitive(this).getX(); - } - - @FunctionDoc( - name = "getY", - desc = "This returns the y position of the Pos", - returns = @ReturnDoc(type = NumberDef.class, desc = "the y position"), - examples = "pos.getY();" - ) - private double getY(Arguments arguments) { - return arguments.nextPrimitive(this).getY(); - } - - @FunctionDoc( - name = "getZ", - desc = "This returns the z position of the Pos", - returns = @ReturnDoc(type = NumberDef.class, desc = "the z position"), - examples = "pos.getZ();" - ) - private double getZ(Arguments arguments) { - return arguments.nextPrimitive(this).getZ(); - } - - @FunctionDoc( - name = "multiply", - desc = "This returns a new Pos with the current pos x, y, and z multiplied by the given x, y, and z", - params = { - @ParameterDoc(type = NumberDef.class, name = "x", desc = "the x multiplier"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "the y multiplier"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "the z multiplier") - }, - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.multiply(2, 3, 5);" - ) - private Vec3d multiply(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - double x = arguments.nextPrimitive(NumberDef.class); - double y = arguments.nextPrimitive(NumberDef.class); - double z = arguments.nextPrimitive(NumberDef.class); - return pos.getVec3d().multiply(x, y, z); - } - - @FunctionDoc( - name = "multiply", - desc = "This returns a new Pos with the current pos x, y, and z multiplied by the given pos x, y, and z", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "the Pos to multiply by")}, - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.multiply(new Pos(2, 3, 5));" - ) - private Vec3d multiply1(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - ScriptPos other = arguments.nextPrimitive(this); - return pos.getVec3d().multiply(other.getVec3d()); - } - - @FunctionDoc( - name = "subtract", - desc = "This returns a new Pos with the current pos x, y, and z subtracted by the given x, y, and z", - params = { - @ParameterDoc(type = NumberDef.class, name = "x", desc = "the x subtractor"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "the y subtractor"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "the z subtractor") - }, - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.subtract(2, 3, 5);" - ) - private Vec3d subtract(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - double x = arguments.nextPrimitive(NumberDef.class); - double y = arguments.nextPrimitive(NumberDef.class); - double z = arguments.nextPrimitive(NumberDef.class); - return pos.getVec3d().subtract(x, y, z); - } - - @FunctionDoc( - name = "subtract", - desc = "This returns a new Pos with the current pos x, y, and z subtracted by the given pos x, y, and z", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "the Pos to subtract by")}, - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.subtract(new Pos(2, 3, 5));" - ) - private Vec3d subtract1(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - ScriptPos other = arguments.nextPrimitive(this); - return pos.getVec3d().subtract(other.getVec3d()); - } - - @FunctionDoc( - name = "add", - desc = "This returns a new Pos with the current pos x, y, and z added by the given x, y, and z", - params = { - @ParameterDoc(type = NumberDef.class, name = "x", desc = "the x adder"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "the y adder"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "the z adder") - }, - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.add(2, 3, 5);" - ) - private Vec3d add(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - double x = arguments.nextPrimitive(NumberDef.class); - double y = arguments.nextPrimitive(NumberDef.class); - double z = arguments.nextPrimitive(NumberDef.class); - return pos.getVec3d().add(x, y, z); - } - - @FunctionDoc( - name = "add", - desc = "This returns a new Pos with the current pos x, y, and z added by the given pos x, y, and z", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "the Pos to add by")}, - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.add(new Pos(2, 3, 5));" - ) - private Vec3d add1(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - ScriptPos other = arguments.nextPrimitive(this); - return pos.getVec3d().add(other.getVec3d()); - } - - @FunctionDoc( - name = "dotProduct", - desc = "This returns the dot product of the current pos and the given pos", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "the Pos to dot product with")}, - returns = @ReturnDoc(type = NumberDef.class, desc = "the dot product"), - examples = "pos.dotProduct(new Pos(2, 3, 5));" - ) - private double dotProduct(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - ScriptPos other = arguments.nextPrimitive(this); - return pos.getVec3d().dotProduct(other.getVec3d()); - } - - @FunctionDoc( - name = "crossProduct", - desc = "This returns the cross product of the current pos and the given pos", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "the Pos to cross product with")}, - returns = @ReturnDoc(type = PosDef.class, desc = "the cross product"), - examples = "pos.crossProduct(new Pos(2, 3, 5));" - ) - private Vec3d crossProduct(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - ScriptPos other = arguments.nextPrimitive(this); - return pos.getVec3d().crossProduct(other.getVec3d()); - } - - @FunctionDoc( - name = "toBlockPos", - desc = "This floors all of the positions values to the nearest block", - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.toBlockPos();" - ) - private BlockPos toBlockPos(Arguments arguments) { - return arguments.nextPrimitive(this).getBlockPos(); - } - - @FunctionDoc( - name = "toList", - desc = "This returns the Pos as a List containing the x, y, and z positions in order", - returns = @ReturnDoc(type = ListDef.class, desc = "the Pos as a List"), - examples = "x, y, z = pos.toList();" - ) - private ArucasList toList(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - NumberDef numberDef = arguments.getInterpreter().getPrimitive(NumberDef.class); - return ArucasList.of( - numberDef.create(pos.getX()), - numberDef.create(pos.getY()), - numberDef.create(pos.getZ()) - ); - } - - @FunctionDoc( - name = "offset", - desc = "This returns a new Pos with the current pos x, y, and z offset by a direction", - params = {@ParameterDoc(type = StringDef.class, name = "direction", desc = "the direction to offset by, must be one of: north, south, east, west, up, down")}, - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.offset('north');" - ) - private Vec3d offset(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - String string = arguments.nextConstant(); - Direction direction = ClientScriptUtils.stringToDirection(string, null); - return pos.getVec3d().add(direction.getOffsetX(), direction.getOffsetY(), direction.getOffsetZ()); - } - - @FunctionDoc( - name = "offset", - desc = "This returns a new Pos with the current pos x, y, and z offset by a direction and a distance", - params = { - @ParameterDoc(type = StringDef.class, name = "direction", desc = "the direction to offset by, must be one of: north, south, east, west, up, down"), - @ParameterDoc(type = NumberDef.class, name = "distance", desc = "the distance to offset by") - }, - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.offset('north', 2);" - ) - private Vec3d offset1(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - String string = arguments.nextConstant(); - double distance = arguments.nextPrimitive(NumberDef.class); - Direction direction = ClientScriptUtils.stringToDirection(string, null); - return pos.getVec3d().add( - direction.getOffsetX() * distance, - direction.getOffsetY() * distance, - direction.getOffsetZ() * distance - ); - } - - @FunctionDoc( - name = "up", - desc = "This returns a new Pos with the current pos y incremented by 1", - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.up();" - ) - private Vec3d up(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - return pos.getVec3d().add(0, 1, 0); - } - - @FunctionDoc( - name = "up", - desc = "This returns a new Pos with the current pos y incremented by the given number", - params = {@ParameterDoc(type = NumberDef.class, name = "number", desc = "the number to increment by")}, - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.up(2);" - ) - private Vec3d up1(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - double number = arguments.nextPrimitive(NumberDef.class); - return pos.getVec3d().add(0, number, 0); - } - - @FunctionDoc( - name = "down", - desc = "This returns a new Pos with the current pos y decremented by 1", - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.down();" - ) - private Vec3d down(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - return pos.getVec3d().add(0, -1, 0); - } - - @FunctionDoc( - name = "down", - desc = "This returns a new Pos with the current pos y decremented by the given number", - params = {@ParameterDoc(type = NumberDef.class, name = "number", desc = "the number to decrement by")}, - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.down(2);" - ) - private Vec3d down1(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - double number = arguments.nextPrimitive(NumberDef.class); - return pos.getVec3d().add(0, -number, 0); - } - - @FunctionDoc( - name = "north", - desc = "This returns a new Pos with the current pos z incremented by 1", - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.north();" - ) - private Vec3d north(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - return pos.getVec3d().add(0, 0, -1); - } - - @FunctionDoc( - name = "north", - desc = "This returns a new Pos with the current pos z incremented by the given number", - params = {@ParameterDoc(type = NumberDef.class, name = "number", desc = "the number to increment by")}, - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.north(2);" - ) - private Vec3d north1(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - double number = arguments.nextPrimitive(NumberDef.class); - return pos.getVec3d().add(0, 0, -number); - } - - @FunctionDoc( - name = "south", - desc = "This returns a new Pos with the current pos z decremented by 1", - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.south();" - ) - private Vec3d south(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - return pos.getVec3d().add(0, 0, 1); - } - - @FunctionDoc( - name = "south", - desc = "This returns a new Pos with the current pos z decremented by the given number", - params = {@ParameterDoc(type = NumberDef.class, name = "number", desc = "the number to decrement by")}, - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.south(2);" - ) - private Vec3d south1(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - double number = arguments.nextPrimitive(NumberDef.class); - return pos.getVec3d().add(0, 0, number); - } - - @FunctionDoc( - name = "east", - desc = "This returns a new Pos with the current pos x incremented by 1", - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.east();" - ) - private Vec3d east(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - return pos.getVec3d().add(1, 0, 0); - } - - @FunctionDoc( - name = "east", - desc = "This returns a new Pos with the current pos x incremented by the given number", - params = {@ParameterDoc(type = NumberDef.class, name = "number", desc = "the number to increment by")}, - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.east(2);" - ) - private Vec3d east1(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - double number = arguments.nextPrimitive(NumberDef.class); - return pos.getVec3d().add(number, 0, 0); - } - - @FunctionDoc( - name = "west", - desc = "This returns a new Pos with the current pos x decremented by 1", - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.west();" - ) - private Vec3d west(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - return pos.getVec3d().add(-1, 0, 0); - } - - @FunctionDoc( - name = "west", - desc = "This returns a new Pos with the current pos x decremented by the given number", - params = {@ParameterDoc(type = NumberDef.class, name = "number", desc = "the number to decrement by")}, - returns = @ReturnDoc(type = PosDef.class, desc = "the new Pos"), - examples = "pos.west(2);" - ) - private Vec3d west1(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - double number = arguments.nextPrimitive(NumberDef.class); - return pos.getVec3d().add(-number, 0, 0); - } - - @FunctionDoc( - name = "getSidePos", - desc = "This returns side position value of position", - params = {@ParameterDoc(type = StringDef.class, name = "direction", desc = "the direction, can be: north, south, east, west, up, down")}, - returns = @ReturnDoc(type = PosDef.class, desc = "the side of the position"), - examples = "pos.getSidePos('east');" - ) - private Vec3d getSidePos(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - String string = arguments.nextConstant(); - Direction direction = ClientScriptUtils.stringToDirection(string, null); - return Vec3d.ofCenter(pos.getBlockPos()).add(Vec3d.of(direction.getVector()).multiply(0.5)); - } - - @FunctionDoc( - name = "asCentre", - desc = "This returns center value of the position", - returns = @ReturnDoc(type = PosDef.class, desc = "the center of the position"), - examples = "pos.asCentre();" - ) - private Vec3d asCentre(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - return Vec3d.ofCenter(pos.getBlockPos()); - } - - @FunctionDoc( - name = "isNear", - desc = "This returns whether position to entity is less than 4.5", - params = {@ParameterDoc(type = EntityDef.class, name = "entity", desc = "the entity you want to check")}, - returns = @ReturnDoc(type = BooleanDef.class, desc = "whether entity is within 4.5 block distance"), - examples = "pos.isNear(Player.get());" - ) - private boolean isNear(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - Entity entity = arguments.nextPrimitive(EntityDef.class); - return entity.squaredDistanceTo(pos.getVec3d()) <= 4.5 * 4.5; - } - - @FunctionDoc( - name = "isWithin", - desc = "This returns whether position to entity is less than given distance", - params = { - @ParameterDoc(type = EntityDef.class, name = "entity", desc = "the entity you want to check"), - @ParameterDoc(type = NumberDef.class, name = "distance", desc = "the distance you want to check") - }, - returns = @ReturnDoc(type = BooleanDef.class, desc = "whether entity is within given distance"), - examples = "pos.isNear(player, 8);" - ) - private boolean isWithin(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - Entity entity = arguments.nextPrimitive(EntityDef.class); - double distance = arguments.nextPrimitive(NumberDef.class); - return entity.squaredDistanceTo(pos.getVec3d()) <= distance * distance; - } - - @FunctionDoc( - name = "distanceTo", - desc = "This returns distance to other position", - params = {@ParameterDoc(type = PosDef.class, name = "other", desc = "other position")}, - returns = @ReturnDoc(type = NumberDef.class, desc = "distance to other position"), - examples = "pos.distanceTo(new Pos(0, 0, 0));" - ) - private double distanceTo(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - ScriptPos other = arguments.nextPrimitive(this); - return pos.getVec3d().distanceTo(other.getVec3d()); - } - - @FunctionDoc( - name = "distanceTo", - desc = "This returns distance to other x, y, z position", - params = { - @ParameterDoc(type = NumberDef.class, name = "x", desc = "other position x"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "other position y"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "other position z") - }, - returns = @ReturnDoc(type = NumberDef.class, desc = "distance to other position"), - examples = "pos.distanceTo(0, 0, 0);" - ) - private double distanceTo1(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - double x = arguments.nextPrimitive(NumberDef.class); - double y = arguments.nextPrimitive(NumberDef.class); - double z = arguments.nextPrimitive(NumberDef.class); - return pos.getVec3d().distanceTo(new Vec3d(x, y, z)); - } - - @FunctionDoc( - name = "normalize", - desc = "Normalizes the vector to have a magnitude of 1", - returns = @ReturnDoc(type = PosDef.class, desc = "the normalized position"), - examples = "pos.normalize();" - ) - private Vec3d normalize(Arguments arguments) { - ScriptPos pos = arguments.nextPrimitive(this); - return pos.getVec3d().normalize(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/RecipeDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/RecipeDef.java deleted file mode 100644 index b516f5d3..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/RecipeDef.java +++ /dev/null @@ -1,179 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ParameterDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.ListDef; -import me.senseiwells.arucas.builtin.StringDef; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.compiler.LocatableTrace; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.BuiltInFunction; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.impl.ArucasList; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.ClientScriptUtils; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptItemStack; -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.item.ItemStack; -import net.minecraft.recipe.Ingredient; -import net.minecraft.recipe.Recipe; -import net.minecraft.recipe.RecipeEntry; -import net.minecraft.registry.Registries; -import net.minecraft.util.Identifier; -import org.jetbrains.annotations.NotNull; - -import java.util.*; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.RECIPE; - -@ClassDoc( - name = RECIPE, - desc = "This class represents recipes in Minecraft.", - language = Language.Java -) -public class RecipeDef extends CreatableDefinition>> { - public RecipeDef(Interpreter interpreter) { - super(RECIPE, interpreter); - } - - @NotNull - @Override - public String toString(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - return "Recipe{id=" + instance.asPrimitive(this).id() + "}"; - } - - @Override - public List defineStaticFields() { - ClientPlayNetworkHandler networkHandler = EssentialUtils.getNetworkHandler(); - if (networkHandler == null) { - return super.defineStaticFields(); - } - - SortedMap map = new TreeMap<>(); - for (RecipeEntry recipe : networkHandler.getRecipeManager().values()) { - @SuppressWarnings("unchecked") - ClassInstance instance = this.create((RecipeEntry>) recipe); - map.put(recipe.toString().toUpperCase(), instance); - } - - ArucasList list = new ArucasList(); - List fields = new ArrayList<>(map.size()); - map.forEach((key, value) -> { - list.add(value); - fields.add(new PrimitiveField(key, value, false)); - }); - fields.add(new PrimitiveField("ALL", list, false)); - return fields; - } - - @Override - public List defineStaticMethods() { - return List.of( - BuiltInFunction.of("of", 1, this::of) - ); - } - - @FunctionDoc( - isStatic = true, - name = "of", - desc = { - "This converts a recipe id into a Recipe if it's valid,", - "otherwise an error will be thrown" - }, - params = {@ParameterDoc(type = StringDef.class, name = "recipeId", desc = "the id of the recipe to convert to a Recipe")}, - returns = @ReturnDoc(type = RecipeDef.class, desc = "the recipe instance from the id"), - examples = "Recipe.of('redstone_block')" - ) - private RecipeEntry of(Arguments arguments) { - String id = arguments.nextPrimitive(StringDef.class); - ClientPlayNetworkHandler networkHandler = EssentialUtils.getNetworkHandler(); - Identifier identifier = ClientScriptUtils.stringToIdentifier(id); - Optional> recipe = networkHandler.getRecipeManager().get(identifier); - if (recipe.isEmpty()) { - throw new RuntimeError("Recipe with id '%s' doesn't exist".formatted(id)); - } - return recipe.get(); - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("getFullId", this::getFullId), - MemberFunction.of("getId", this::getId), - MemberFunction.of("getCraftingType", this::getCraftingType), - MemberFunction.of("getOutput", this::getOutput), - MemberFunction.of("getIngredients", this::getIngredients) - ); - } - - @FunctionDoc( - name = "getFullId", - desc = "This returns the full id of the recipe", - returns = @ReturnDoc(type = StringDef.class, desc = "the full id of the recipe"), - examples = "recipe.getFullId()" - ) - private String getFullId(Arguments arguments) { - RecipeEntry recipe = arguments.nextPrimitive(this); - return recipe.id().toString(); - } - - @FunctionDoc( - name = "getId", - desc = "This returns the id of the recipe", - returns = @ReturnDoc(type = StringDef.class, desc = "the id of the recipe"), - examples = "recipe.getId()" - ) - private String getId(Arguments arguments) { - RecipeEntry recipe = arguments.nextPrimitive(this); - return recipe.id().toString(); - } - - @FunctionDoc( - name = "getCraftingType", - desc = "This returns the crafting type of the recipe", - returns = @ReturnDoc(type = StringDef.class, desc = "the crafting type of the recipe, for example: 'crafting', 'smelting', 'blasting'"), - examples = "recipe.getCraftingType()" - ) - private String getCraftingType(Arguments arguments) { - RecipeEntry recipe = arguments.nextPrimitive(this); - Identifier identifier = Registries.RECIPE_TYPE.getId(recipe.value().getType()); - return identifier == null ? null : identifier.getPath(); - } - - @FunctionDoc( - name = "getOutput", - desc = "This returns the output of the recipe", - returns = @ReturnDoc(type = ItemStackDef.class, desc = "the output of the recipe"), - examples = "recipe.getOutput()" - ) - private ScriptItemStack getOutput(Arguments arguments) { - RecipeEntry recipe = arguments.nextPrimitive(this); - return new ScriptItemStack(recipe.value().getResult(EssentialUtils.getRegistryManager())); - } - - @FunctionDoc( - name = "getIngredients", - desc = "This returns all the possible ingredients of the recipe", - returns = @ReturnDoc(type = ListDef.class, desc = "list of lists, each inner lists contains possible recipe items"), - examples = "recipe.getIngredients()" - ) - private ArucasList getIngredients(Arguments arguments) { - RecipeEntry recipe = arguments.nextPrimitive(this); - ArucasList recipeIngredients = new ArucasList(); - Interpreter interpreter = arguments.getInterpreter(); - for (Ingredient ingredient : recipe.value().getIngredients()) { - ArucasList slotIngredients = new ArucasList(); - for (ItemStack itemStack : ingredient.getMatchingStacks()) { - slotIngredients.add(interpreter.create(ItemStackDef.class, new ScriptItemStack(itemStack))); - } - recipeIngredients.add(interpreter.create(ListDef.class, slotIngredients)); - } - return recipeIngredients; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/ScreenDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/ScreenDef.java deleted file mode 100644 index aeebc403..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/ScreenDef.java +++ /dev/null @@ -1,77 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.StringDef; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.compiler.LocatableTrace; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.clientscript.core.MinecraftAPI; -import me.senseiwells.essentialclient.utils.clientscript.ScreenRemapper; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.SCREEN; - -@ClassDoc( - name = SCREEN, - desc = "This allows you to get information about the player's current screen.", - language = Language.Java -) -public class ScreenDef extends PrimitiveDefinition { - public ScreenDef(Interpreter interpreter) { - super(MinecraftAPI.SCREEN, interpreter); - } - - @Deprecated - @NotNull - @Override - public ClassInstance create(@NotNull Screen value) { - return super.create(value); - } - - @NotNull - @Override - public String toString(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - return "Screen{screen=" + ScreenRemapper.getScreenName(instance.asPrimitive(this).getClass()) + "}"; - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("getName", this::getName), - MemberFunction.of("getTitle", this::getTitle) - ); - } - - @FunctionDoc( - name = "getName", - desc = "Gets the name of the specific screen", - returns = @ReturnDoc(type = StringDef.class, desc = "the screen name, if you are in the creative menu it will return the name of the tab you are on"), - examples = "screen.getName()" - ) - private String getName(Arguments arguments) { - return ScreenRemapper.getScreenName(arguments.nextPrimitive(this).getClass()); - } - - @FunctionDoc( - name = "getTitle", - desc = "Gets the title of the specific screen", - returns = @ReturnDoc(type = StringDef.class, desc = "the screen title as text, this may include formatting, and custom names for the screen if applicable"), - examples = "screen.getTitle()" - ) - private MutableText getTitle(Arguments arguments) { - Screen screen = arguments.nextPrimitive(this); - Text title = screen.getTitle(); - return title == null ? null : title.copy(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/TextDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/TextDef.java deleted file mode 100644 index 9998973d..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/TextDef.java +++ /dev/null @@ -1,200 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ParameterDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.ObjectDef; -import me.senseiwells.arucas.builtin.StringDef; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.compiler.LocatableTrace; -import me.senseiwells.arucas.extensions.JsonDef; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.BuiltInFunction; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.JsonUtils; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.clientscript.core.MinecraftAPI; -import me.senseiwells.essentialclient.utils.clientscript.ClientScriptUtils; -import net.fabricmc.fabric.impl.biome.modification.BuiltInRegistryKeys; -import net.minecraft.registry.BuiltinRegistries; -import net.minecraft.text.ClickEvent; -import net.minecraft.text.HoverEvent; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.TEXT; - -@ClassDoc( - name = TEXT, - desc = "This class is used to create formatted strings used inside Minecraft.", - language = Language.Java -) -public class TextDef extends CreatableDefinition { - public TextDef(Interpreter interpreter) { - super(MinecraftAPI.TEXT, interpreter); - } - - @NotNull - @Override - public String toString(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - return "Text{text=" + instance.asPrimitive(this).getString() + "}"; - } - - @Override - public List defineStaticMethods() { - return List.of( - BuiltInFunction.of("of", 1, this::of), - BuiltInFunction.of("parse", 1, this::parse) - ); - } - - @FunctionDoc( - isStatic = true, - name = "of", - desc = "This converts a string into a text instance", - params = {@ParameterDoc(type = StringDef.class, name = "string", desc = "The string to convert into a text instance")}, - returns = @ReturnDoc(type = TextDef.class, desc = "the text instance from the string"), - examples = "Text.of('Hello World!');" - ) - private Text of(Arguments arguments) { - return Text.literal(arguments.nextPrimitive(StringDef.class)); - } - - @FunctionDoc( - isStatic = true, - name = "parse", - desc = "This converts a text json into a text instance", - params = {@ParameterDoc(type = StringDef.class, name = "textJson", desc = "The string in json format, or a Json value itself")}, - returns = @ReturnDoc(type = TextDef.class, desc = "the text instance from the json"), - examples = "Text.parse('{\"text\":\"Hello World!\",\"color\":\"white\",\"italic\":\"true\"}');" - ) - private Object parse(Arguments arguments) { - if (arguments.isNext(JsonDef.class)) { - return Text.Serialization.fromJson( - JsonUtils.GSON.toJson(arguments.nextPrimitive(JsonDef.class)), - BuiltinRegistries.createWrapperLookup() - ); - } - return Text.Serialization.fromJson( - arguments.nextPrimitive(StringDef.class), - BuiltinRegistries.createWrapperLookup() - ); - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("withClickEvent", 2, this::withClickEvent), - MemberFunction.of("withHoverEvent", 2, this::withHoverEvent), - MemberFunction.of("format", 1, this::formatText), - MemberFunction.of("append", 1, this::appendText) - ); - } - - @FunctionDoc( - name = "withClickEvent", - desc = { - "This allows you to add a click event to a text instance.", - "The possible events are: 'open_url', 'open_file', 'run_command', 'suggest_command', 'copy_to_clipboard', 'run_function'.", - "This will throw an error if the action is invalid" - }, - params = { - @ParameterDoc(type = StringDef.class, name = "event", desc = "the name of the event"), - @ParameterDoc(type = StringDef.class, name = "value", desc = "the value associated with the event") - }, - returns = @ReturnDoc(type = TextDef.class, desc = "the text instance with the click event"), - examples = """ - text = Text.of("Hello World!"); - - // Examples of click events - text.withClickEvent("open_url", "https://youtu.be/dQw4w9WgXcQ"); - text.withClickEvent("open_file", "C:/Users/user/Desktop/thing.txt"); - text.withClickEvent("run_command", "/gamemode creative"); - text.withClickEvent("suggest_command", "/gamemode survival"); - text.withClickEvent("copy_to_clipboard", "Ooops!"); - text.withClickEvent("run_function", fun() { - print("Text was clicked!"); - }); - """ - ) - private ClassInstance withClickEvent(Arguments arguments) { - ClassInstance instance = arguments.next(this); - MutableText text = instance.asPrimitive(this); - String actionAsString = arguments.nextConstant(); - ClickEvent clickEvent = ClientScriptUtils.stringToClickEvent(arguments.getInterpreter(), actionAsString, arguments.next()); - text.styled(style -> style.withClickEvent(clickEvent)); - return instance; - } - - @FunctionDoc( - name = "withHoverEvent", - desc = { - "This allows you to add a hover event to a text instance.", - "The possible events are: 'show_text', 'show_item', 'show_entity'.", - "This will throw an error if the event is invalid" - }, - params = { - @ParameterDoc(type = StringDef.class, name = "event", desc = "the name of the event"), - @ParameterDoc(type = ObjectDef.class, name = "value", desc = "the value associated with the event") - }, - returns = @ReturnDoc(type = TextDef.class, desc = "the text instance with the hover event"), - examples = """ - text = Text.of("Hello World!"); - - // Examples of hover events - text.withHoverEvent("show_text", Text.of("Hello world!")); - text.withHoverEvent("show_item", Material.DIAMOND_SWORD.asItemStack()); - text.withHoverEvent("show_entity", Player.get()); - """ - ) - private ClassInstance withHoverEvent(Arguments arguments) { - ClassInstance instance = arguments.next(this); - MutableText text = instance.asPrimitive(this); - String action = arguments.nextConstant(); - HoverEvent hoverEvent = ClientScriptUtils.stringToHoverEvent(action, arguments.next()); - text.styled(style -> style.withHoverEvent(hoverEvent)); - return instance; - } - - @FunctionDoc( - name = "format", - desc = { - "This allows you to add a formatting to a text instance.", - "A list of formatting names can be found [here](https://minecraft.fandom.com/wiki/Formatting_codes).", - "This will throw an error if the formatting is invalid" - }, - params = {@ParameterDoc(type = StringDef.class, name = "formatting", desc = "the name of the formatting")}, - returns = @ReturnDoc(type = TextDef.class, desc = "the text instance with the formatting added"), - examples = "text.format('DARK_RED').format('BOLD');" - ) - private ClassInstance formatText(Arguments arguments) { - ClassInstance instance = arguments.next(this); - MutableText text = instance.asPrimitive(this); - String string = arguments.nextConstant(); - Formatting formatting = ClientScriptUtils.stringToFormatting(string); - text.formatted(formatting); - return instance; - } - - @FunctionDoc( - name = "append", - desc = "This allows you to append a text instance to another text instance", - params = {@ParameterDoc(type = TextDef.class, name = "otherText", desc = "the text instance to append to")}, - returns = @ReturnDoc(type = TextDef.class, desc = "the text instance with the appended text"), - examples = "Text.of('Hello').append(Text.of(' world!'));" - ) - private ClassInstance appendText(Arguments arguments) { - ClassInstance instance = arguments.next(this); - MutableText text = instance.asPrimitive(this); - MutableText other = arguments.nextPrimitive(this); - text.append(other); - return instance; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/TradeDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/TradeDef.java deleted file mode 100644 index 3fd968f3..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/TradeDef.java +++ /dev/null @@ -1,160 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.NumberDef; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.compiler.LocatableTrace; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.clientscript.core.MinecraftAPI; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptItemStack; -import me.senseiwells.essentialclient.utils.inventory.InventoryUtils; -import net.minecraft.item.ItemStack; -import net.minecraft.village.TradeOffer; -import net.minecraft.village.TradedItem; -import org.jetbrains.annotations.NotNull; - -import java.util.List; -import java.util.Optional; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.TRADE; - -@ClassDoc( - name = TRADE, - desc = "This class represents a trade offer, and allows you to get information about it.", - language = Language.Java -) -public class TradeDef extends CreatableDefinition { - public TradeDef(Interpreter interpreter) { - super(MinecraftAPI.TRADE, interpreter); - } - - @Override - public boolean equals(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull ClassInstance other, @NotNull LocatableTrace trace) { - TradeOffer otherOffer = other.getPrimitive(this); - return otherOffer != null && InventoryUtils.areTradesEqual(instance.asPrimitive(this), otherOffer); - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("getSellItem", this::getSellItem), - MemberFunction.of("getFirstBuyItem", this::getFirstBuyItem), - MemberFunction.of("getAdjustedFirstBuyItem", this::getAdjustedFirstBuyItem), - MemberFunction.of("getSecondBuyItem", this::getSecondBuyItem), - MemberFunction.of("getMaxUses", this::getMaxUses), - MemberFunction.of("getUses", this::getUses), - MemberFunction.of("getSpecialPrice", this::getSpecialPrice), - MemberFunction.of("getPriceMultiplier", this::getPriceMultiplier), - MemberFunction.of("getXpReward", this::getXpReward) - ); - } - - @FunctionDoc( - name = "getSellItem", - desc = "Gets the item that is being sold by the merchant", - returns = @ReturnDoc(type = ItemStackDef.class, desc = "the item for sale"), - examples = "trade.getSellItem();" - ) - public ScriptItemStack getSellItem(Arguments arguments) { - TradeOffer offer = arguments.nextPrimitive(this); - return new ScriptItemStack(offer.getSellItem()); - } - - @FunctionDoc( - name = "getFirstBuyItem", - desc = "Gets the first item that the merchant will buy", - returns = @ReturnDoc(type = ItemStackDef.class, desc = "the first item to buy"), - examples = "trade.getFirstBuyItem();" - ) - public ScriptItemStack getFirstBuyItem(Arguments arguments) { - TradeOffer offer = arguments.nextPrimitive(this); - return new ScriptItemStack(offer.getOriginalFirstBuyItem()); - } - - @FunctionDoc( - name = "getAdjustedFirstBuyItem", - desc = "Gets the first item that the merchant will buy, adjusted by the price multiplier", - returns = @ReturnDoc(type = ItemStackDef.class, desc = "the first item to buy"), - examples = "trade.getAdjustedFirstBuyItem();" - ) - public ScriptItemStack getAdjustedFirstBuyItem(Arguments arguments) { - TradeOffer offer = arguments.nextPrimitive(this); - return new ScriptItemStack(offer.getDisplayedFirstBuyItem()); - } - - @FunctionDoc( - name = "getSecondBuyItem", - desc = "Gets the second item that the merchant will buy", - returns = @ReturnDoc(type = ItemStackDef.class, desc = "the second item to buy"), - examples = "trade.getSecondBuyItem();" - ) - public ScriptItemStack getSecondBuyItem(Arguments arguments) { - TradeOffer offer = arguments.nextPrimitive(this); - Optional traded = offer.getSecondBuyItem(); - return traded.map(item -> new ScriptItemStack(item.itemStack())).orElseGet(() -> new ScriptItemStack(ItemStack.EMPTY)); - } - - @FunctionDoc( - name = "getMaxUses", - desc = "Gets the maximum number of times the trade can be used", - returns = @ReturnDoc(type = NumberDef.class, desc = "the maximum number of uses"), - examples = "trade.getMaxUses();" - ) - public int getMaxUses(Arguments arguments) { - TradeOffer offer = arguments.nextPrimitive(this); - return offer.getMaxUses(); - } - - @FunctionDoc( - name = "getUses", - desc = "Gets the number of times the trade has been used", - returns = @ReturnDoc(type = NumberDef.class, desc = "the number of uses"), - examples = "trade.getUses();" - ) - public int getUses(Arguments arguments) { - TradeOffer offer = arguments.nextPrimitive(this); - return offer.getUses(); - } - - @FunctionDoc( - name = "getSpecialPrice", - desc = "This gets the special price which is used to adjust the price of the first buy item", - returns = @ReturnDoc(type = NumberDef.class, desc = "the special price"), - examples = "trade.getSpecialPrice();" - ) - public int getSpecialPrice(Arguments arguments) { - TradeOffer offer = arguments.nextPrimitive(this); - return offer.getSpecialPrice(); - } - - @FunctionDoc( - name = "getPriceMultiplier", - desc = "Gets the price multiplier which is used to adjust the price of the first buy item", - returns = @ReturnDoc(type = NumberDef.class, desc = "the price multiplier"), - examples = "trade.getPriceMultiplier();" - ) - public float getPriceMultiplier(Arguments arguments) { - TradeOffer offer = arguments.nextPrimitive(this); - return offer.getPriceMultiplier(); - } - - @FunctionDoc( - name = "getXpReward", - desc = { - "Returns the amount of xp the villager will get, which", - "goes towards them levelling up, from trading this offer" - }, - returns = @ReturnDoc(type = NumberDef.class, desc = "the amount of xp"), - examples = "trade.getXpReward" - ) - private int getXpReward(Arguments arguments) { - TradeOffer offer = arguments.nextPrimitive(this); - return offer.getMerchantExperience(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/WorldDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/WorldDef.java deleted file mode 100644 index 77f37b19..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/WorldDef.java +++ /dev/null @@ -1,800 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions; - -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ParameterDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.*; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.compiler.LocatableTrace; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.impl.ArucasIterable; -import me.senseiwells.arucas.utils.impl.ArucasList; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.ClientScriptUtils; -import me.senseiwells.essentialclient.utils.clientscript.PosIterator; -import me.senseiwells.essentialclient.utils.clientscript.ThreadSafeUtils; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptBlockState; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptPos; -import net.minecraft.block.BlockState; -import net.minecraft.client.network.OtherClientPlayerEntity; -import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.particle.ParticleType; -import net.minecraft.particle.SimpleParticleType; -import net.minecraft.registry.Registries; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.world.LightType; -import net.minecraft.world.World; -import net.minecraft.world.biome.Biome; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.WORLD; -import static me.senseiwells.essentialclient.utils.clientscript.ClientScriptUtils.warnMainThread; - -@ClassDoc( - name = WORLD, - desc = "This class represents worlds, and allows you to interact with things inside of them.", - language = Language.Java -) -public class WorldDef extends CreatableDefinition { - public WorldDef(Interpreter interpreter) { - super(WORLD, interpreter); - } - - @NotNull - @Override - public String toString(@NotNull ClassInstance instance, @NotNull Interpreter interpreter, @NotNull LocatableTrace trace) { - World world = instance.asPrimitive(this); - return "World{level=" + world + "dimension=" + world.getRegistryKey().getValue().getPath() + "}"; - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("getBlockAt", 3, this::getBlockAt), - MemberFunction.of("getBlockAt", 1, this::getBlockAtPos), - MemberFunction.of("isLoaded", 1, this::isLoaded), - MemberFunction.of("getBiomeAt", 3, this::getBiomeAt), - MemberFunction.of("getBiomeAt", 1, this::getBiomeAtPos), - MemberFunction.of("getPlayer", 1, this::getPlayer), - MemberFunction.of("getAllPlayers", this::getAllPlayers), - MemberFunction.of("getOtherPlayer", 1, this::getOtherPlayer, "Use '.getPlayer()' instead"), - MemberFunction.of("getAllOtherPlayers", this::getAllOtherPlayers, "Use '.getAllPlayers()' instead"), - MemberFunction.of("getClosestPlayer", 2, this::getClosestPlayer), - MemberFunction.of("getAllEntities", this::getAllEntities), - MemberFunction.of("getEntityFromId", 1, this::getEntityFromId), - MemberFunction.of("getFullId", this::getFullId), - MemberFunction.of("getId", this::getId), - MemberFunction.of("getDimensionName", this::getDimensionName), - MemberFunction.of("isRaining", this::isRaining), - MemberFunction.of("isThundering", this::isThundering), - MemberFunction.of("getTimeOfDay", this::getTimeOfDay), - MemberFunction.of("renderParticle", 4, this::renderParticle), - MemberFunction.of("renderParticle", 2, this::renderParticlePos), - MemberFunction.of("renderParticle", 5, this::renderParticleVel), - MemberFunction.of("setGhostBlock", 4, this::setGhostBlock, "This function is dangerous, be careful!"), - MemberFunction.of("setGhostBlock", 2, this::setGhostBlockPos, "This function is dangerous, be careful!"), - MemberFunction.of("isAir", 3, this::isAir), - MemberFunction.of("isAir", 1, this::isAirPos), - MemberFunction.of("getEmittedRedstonePower", 4, this::getEmittedRedstonePower), - MemberFunction.of("getEmittedRedstonePower", 2, this::getEmittedRedstonePowerPos), - MemberFunction.of("getLight", 3, this::getLight), - MemberFunction.of("getLight", 1, this::getLightPos), - MemberFunction.of("getSkyLight", 1, this::getSkyLight), - MemberFunction.of("getBlockLight", 1, this::getBlockLight), - MemberFunction.of("getArea", 2, this::getArea, "This function is memory intensive, use ''.getPositions(pos1, pos2)"), - MemberFunction.of("getAreaOfBlocks", 2, this::getAreaOfBlocks, "This function is memory intensive, use '.getBlocks(pos1, pos2)'"), - MemberFunction.of("getPositions", 2, this::getPositions), - MemberFunction.of("getBlocks", 2, this::getBlocks), - MemberFunction.of("getPositionsFromCentre", 4, this::getPositionsFromCentre), - MemberFunction.of("getBlocksFromCentre", 4, this::getBlocksFromCentre), - MemberFunction.of("reloadChunks", this::reloadChunks) - ); - } - - @FunctionDoc( - name = "getBlockAt", - desc = "This function gets the block at the given coordinates", - params = { - @ParameterDoc(type = NumberDef.class, name = "x", desc = "the x coordinate"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "the y coordinate"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "the z coordinate") - }, - returns = @ReturnDoc(type = BlockDef.class, desc = "the block at the given coordinates"), - examples = "world.getBlockAt(0, 100, 0);" - ) - private ScriptBlockState getBlockAt(Arguments arguments) { - warnMainThread("getBlockAt", arguments.getInterpreter()); - World world = arguments.nextPrimitive(this); - int x = arguments.nextPrimitive(NumberDef.class).intValue(); - int y = arguments.nextPrimitive(NumberDef.class).intValue(); - int z = arguments.nextPrimitive(NumberDef.class).intValue(); - BlockPos blockPos = new BlockPos(x, y, z); - return new ScriptBlockState(world.getBlockState(blockPos), blockPos); - } - - @FunctionDoc( - name = "getBlockAt", - desc = "This function gets the block at the given coordinates", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "the position")}, - returns = @ReturnDoc(type = BlockDef.class, desc = "the block at the given coordinates"), - examples = "world.getBlockAt(new Pos(0, 100, 0));" - ) - private ScriptBlockState getBlockAtPos(Arguments arguments) { - warnMainThread("getBlockAt", arguments.getInterpreter()); - World world = arguments.nextPrimitive(this); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - BlockPos blockPos = pos.getBlockPos(); - return new ScriptBlockState(world.getBlockState(blockPos), blockPos); - } - - @FunctionDoc( - name = "isLoaded", - desc = "This function returns loaded state of given coordinates(client side)", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "the position")}, - returns = @ReturnDoc(type = BooleanDef.class, desc = "whether the block is loaded at the given coordinates"), - examples = "world.isLoaded(new Pos(0, 100, 0));" - ) - private boolean isLoaded(Arguments arguments) { - warnMainThread("isLoaded", arguments.getInterpreter()); - World world = arguments.nextPrimitive(this); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - BlockPos blockPos = pos.getBlockPos(); - return world.getChunkManager().isChunkLoaded(blockPos.getX() >> 4, blockPos.getZ() >> 4); - } - - @FunctionDoc( - name = "getBiomeAt", - desc = "This function gets the biome at the given coordinates", - params = { - @ParameterDoc(type = NumberDef.class, name = "x", desc = "the x coordinate"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "the y coordinate"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "the z coordinate") - }, - returns = @ReturnDoc(type = BiomeDef.class, desc = "the biome at the given coordinates"), - examples = "world.getBiomeAt(0, 100, 0);" - ) - private Biome getBiomeAt(Arguments arguments) { - warnMainThread("getBiomeAt", arguments.getInterpreter()); - World world = arguments.nextPrimitive(this); - int x = arguments.nextPrimitive(NumberDef.class).intValue(); - int y = arguments.nextPrimitive(NumberDef.class).intValue(); - int z = arguments.nextPrimitive(NumberDef.class).intValue(); - BlockPos blockPos = new BlockPos(x, y, z); - return world.getBiome(blockPos).value(); - } - - @FunctionDoc( - name = "getBiomeAt", - desc = "This function gets the biome at the given coordinates", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "the position")}, - returns = @ReturnDoc(type = BiomeDef.class, desc = "the biome at the given coordinates"), - examples = "world.getBiomeAt(new Pos(0, 100, 0));" - ) - private Biome getBiomeAtPos(Arguments arguments) { - warnMainThread("getBiomeAt", arguments.getInterpreter()); - World world = arguments.nextPrimitive(this); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - BlockPos blockPos = pos.getBlockPos(); - return world.getBiome(blockPos).value(); - } - - @FunctionDoc( - name = "getPlayer", - desc = "This function gets the player with the given name", - params = {@ParameterDoc(type = StringDef.class, name = "name", desc = "the name of the player")}, - returns = @ReturnDoc(type = PlayerDef.class, desc = "the player with the given name"), - examples = "world.getPlayer('player');" - ) - private PlayerEntity getPlayer(Arguments arguments) { - warnMainThread("getPlayer", arguments.getInterpreter()); - World world = arguments.nextPrimitive(this); - String playerName = arguments.nextPrimitive(StringDef.class); - PlayerListEntry playerInfo = EssentialUtils.getNetworkHandler().getPlayerListEntry(playerName); - if (playerInfo != null) { - return ThreadSafeUtils.getPlayerByUuid(world, playerInfo.getProfile().getId()); - } - return null; - } - - @FunctionDoc( - name = "getAllPlayers", - desc = "This function gets all players in the world that are loaded", - returns = @ReturnDoc(type = ListDef.class, desc = "all players in the world"), - examples = "world.getAllPlayers();" - ) - private ArucasList getAllPlayers(Arguments arguments) { - warnMainThread("getAllPlayers", arguments.getInterpreter()); - World world = arguments.nextPrimitive(this); - ArucasList players = new ArucasList(); - for (PlayerEntity playerEntity : ThreadSafeUtils.getPlayersSafe(world)) { - players.add(arguments.getInterpreter().convertValue(playerEntity)); - } - return players; - } - - @FunctionDoc( - deprecated = "Use '.getPlayer(name)' instead", - name = "getOtherPlayer", - desc = "This gets another player from the given username", - params = {@ParameterDoc(type = StringDef.class, name = "username", desc = "the username of the other player")}, - returns = @ReturnDoc(type = PlayerDef.class, desc = "the other player, null if not found"), - examples = "world.getOtherPlayer('senseiwells');" - ) - private PlayerEntity getOtherPlayer(Arguments arguments) { - warnMainThread("getOtherPlayer", arguments.getInterpreter()); - World world = arguments.nextPrimitive(this); - String playerName = arguments.nextPrimitive(StringDef.class); - PlayerListEntry playerInfo = EssentialUtils.getNetworkHandler().getPlayerListEntry(playerName); - if (playerInfo != null) { - PlayerEntity player = ThreadSafeUtils.getPlayerByUuid(world, playerInfo.getProfile().getId()); - if (player instanceof OtherClientPlayerEntity otherClientPlayerEntity) { - return otherClientPlayerEntity; - } - } - return null; - } - - @FunctionDoc( - deprecated = "Use '.getAllPlayers()' instead", - name = "getAllOtherPlayers", - desc = "This will get all other players in the world", - returns = @ReturnDoc(type = ListDef.class, desc = "a list of all other players"), - examples = "world.getAllOtherPlayers();" - ) - private ArucasList getAllOtherPlayers(Arguments arguments) { - warnMainThread("getAllOtherPlayers", arguments.getInterpreter()); - World world = arguments.nextPrimitive(this); - ArucasList otherPlayerValueList = new ArucasList(); - for (PlayerEntity playerEntity : ThreadSafeUtils.getPlayersSafe(world)) { - if (playerEntity instanceof OtherClientPlayerEntity otherClientPlayerEntity) { - otherPlayerValueList.add(arguments.getInterpreter().convertValue(otherClientPlayerEntity)); - } - } - return otherPlayerValueList; - } - - @FunctionDoc( - name = "getClosestPlayer", - desc = "This will get the closest player to another entity in the world", - params = { - @ParameterDoc(type = EntityDef.class, name = "entity", desc = "the entity to get the closest player to"), - @ParameterDoc(type = NumberDef.class, name = "maxDistance", desc = "the maximum distance to search for a player in blocks") - }, - returns = @ReturnDoc(type = PlayerDef.class, desc = "the closest player, null if not found"), - examples = "world.getClosestPlayer(Player.get(), 100);" - ) - private PlayerEntity getClosestPlayer(Arguments arguments) { - warnMainThread("getClosestPlayer", arguments.getInterpreter()); - World world = arguments.nextPrimitive(this); - Entity entity = arguments.nextPrimitive(EntityDef.class); - double distance = arguments.nextPrimitive(NumberDef.class); - return ThreadSafeUtils.getClosestPlayer(world, entity, distance); - } - - @FunctionDoc( - name = "getAllEntities", - desc = "This will get all entities in the world", - returns = @ReturnDoc(type = ListDef.class, desc = "a list of all entities"), - examples = "world.getAllEntities();" - ) - private ArucasList getAllEntities(Arguments arguments) { - warnMainThread("getAllEntities", arguments.getInterpreter()); - World world = arguments.nextPrimitive(this); - ArucasList valueList = new ArucasList(); - if (world instanceof ClientWorld clientWorld) { - for (Entity entity : ThreadSafeUtils.getEntitiesSafe(clientWorld)) { - valueList.add(arguments.getInterpreter().convertValue(entity)); - } - } - return valueList; - } - - @FunctionDoc( - name = "getEntityFromId", - desc = "This will get an entity from the given entity id", - params = {@ParameterDoc(type = NumberDef.class, name = "entityId", desc = "the entity id")}, - returns = @ReturnDoc(type = EntityDef.class, desc = "the entity, null if not found"), - examples = "world.getEntityFromId(1);" - ) - private Object getEntityFromId(Arguments arguments) { - World world = arguments.nextPrimitive(this); - int id = arguments.nextPrimitive(NumberDef.class).intValue(); - return world.getEntityById(id); - } - - @FunctionDoc( - name = "getFullId", - desc = "This will get the full id of the world", - returns = @ReturnDoc(type = StringDef.class, desc = "the full id of the world, for example: 'minecraft:overworld'"), - examples = "world.getFullId();" - ) - private String getFullId(Arguments arguments) { - return arguments.nextPrimitive(this).getRegistryKey().getValue().toString(); - } - - @FunctionDoc( - name = "getId", - desc = "This will get the id of the world", - returns = @ReturnDoc(type = StringDef.class, desc = "the id of the world, for example: 'overworld'"), - examples = "world.getId();" - ) - private String getId(Arguments arguments) { - return arguments.nextPrimitive(this).getRegistryKey().getValue().getPath(); - } - - @FunctionDoc( - deprecated = "You should use 'world.getId()' instead", - name = "getDimensionName", - desc = "This will get the id of the world", - returns = @ReturnDoc(type = StringDef.class, desc = "the id of the world, for example: 'overworld'"), - examples = "world.getDimensionName();" - ) - private String getDimensionName(Arguments arguments) { - return arguments.nextPrimitive(this).getRegistryKey().getValue().getPath(); - } - - @FunctionDoc( - name = "isRaining", - desc = "This will check if the world is currently raining", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the world is currently raining"), - examples = "world.isRaining();" - ) - private boolean isRaining(Arguments arguments) { - return arguments.nextPrimitive(this).isRaining(); - } - - @FunctionDoc( - name = "isThundering", - desc = "This will check if the world is currently thundering", - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the world is currently thundering"), - examples = "world.isThundering();" - ) - private boolean isThundering(Arguments arguments) { - return arguments.nextPrimitive(this).isThundering(); - } - - @FunctionDoc( - name = "getTimeOfDay", - desc = { - "This will get the time of day of the world", - "info on the time of day [here](https://minecraft.fandom.com/wiki/Daylight_cycle)" - }, - returns = @ReturnDoc(type = NumberDef.class, desc = "the time of day of the world, between 0 and 24000"), - examples = "world.getTimeOfDay();" - ) - private long getTimeOfDay(Arguments arguments) { - return arguments.nextPrimitive(this).getTimeOfDay(); - } - - @FunctionDoc( - name = "renderParticle", - desc = { - "This will render a particle in the world, you can find a list of all", - "the particle ids [here](https://minecraft.fandom.com/wiki/Java_Edition_data_values#Particles),", - "if the id is invalid it will throw an error" - }, - params = { - @ParameterDoc(type = StringDef.class, name = "particleId", desc = "the id of the particle"), - @ParameterDoc(type = NumberDef.class, name = "x", desc = "the x position of the particle"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "the y position of the particle"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "the z position of the particle") - }, - examples = "world.renderParticle('end_rod', 10, 10, 10);" - ) - private Void renderParticle(Arguments arguments) { - World world = arguments.nextPrimitive(this); - String particleName = arguments.nextPrimitive(StringDef.class); - ParticleType particleType = Registries.PARTICLE_TYPE.get(ClientScriptUtils.stringToIdentifier(particleName)); - if (!(particleType instanceof SimpleParticleType defaultParticleType)) { - throw new RuntimeError("Particle Invalid"); - } - double x = arguments.nextPrimitive(NumberDef.class); - double y = arguments.nextPrimitive(NumberDef.class); - double z = arguments.nextPrimitive(NumberDef.class); - ClientScriptUtils.ensureMainThread("renderParticle", arguments.getInterpreter(), () -> { - world.addParticle(defaultParticleType, x, y, z, 0, 0, 0); - }); - return null; - } - - @FunctionDoc( - name = "renderParticle", - desc = { - "This will render a particle in the world, you can find a list of all", - "the particle ids [here](https://minecraft.fandom.com/wiki/Java_Edition_data_values#Particles),", - "this will throw an error if the id is invalid" - }, - params = { - @ParameterDoc(type = StringDef.class, name = "particleId", desc = "the id of the particle"), - @ParameterDoc(type = PosDef.class, name = "pos", desc = "the position of the particle") - }, - examples = "world.renderParticle('end_rod', pos);" - ) - private Void renderParticlePos(Arguments arguments) { - World world = arguments.nextPrimitive(this); - String particleName = arguments.nextPrimitive(StringDef.class); - ParticleType particleType = Registries.PARTICLE_TYPE.get(ClientScriptUtils.stringToIdentifier(particleName)); - if (!(particleType instanceof SimpleParticleType defaultParticleType)) { - throw new RuntimeError("Particle Invalid"); - } - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - ClientScriptUtils.ensureMainThread("renderParticle", arguments.getInterpreter(), () -> { - world.addParticle(defaultParticleType, pos.getX(), pos.getY(), pos.getZ(), 0, 0, 0); - }); - return null; - } - - @FunctionDoc( - name = "renderParticle", - desc = { - "This will render a particle in the world with a velocity, you can find a list of all", - "the particle ids [here](https://minecraft.fandom.com/wiki/Java_Edition_data_values#Particles),", - "this will throw an error if the id is invalid" - }, - params = { - @ParameterDoc(type = StringDef.class, name = "particleId", desc = "the id of the particle"), - @ParameterDoc(type = PosDef.class, name = "pos", desc = "the position of the particle"), - @ParameterDoc(type = NumberDef.class, name = "velX", desc = "the velocity of the particle on the x axis"), - @ParameterDoc(type = NumberDef.class, name = "velY", desc = "the velocity of the particle on the y axis"), - @ParameterDoc(type = NumberDef.class, name = "velZ", desc = "the velocity of the particle on the z axis") - }, - examples = "world.renderParticle('end_rod', pos, 0.5, 0.5, 0.5);" - ) - private Void renderParticleVel(Arguments arguments) { - World world = arguments.nextPrimitive(this); - String particleName = arguments.nextPrimitive(StringDef.class); - ParticleType particleType = Registries.PARTICLE_TYPE.get(ClientScriptUtils.stringToIdentifier(particleName)); - if (!(particleType instanceof SimpleParticleType defaultParticleType)) { - throw new RuntimeError("Particle Invalid"); - } - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - double velX = arguments.nextPrimitive(NumberDef.class); - double velY = arguments.nextPrimitive(NumberDef.class); - double velZ = arguments.nextPrimitive(NumberDef.class); - ClientScriptUtils.ensureMainThread("renderParticle", arguments.getInterpreter(), () -> { - world.addParticle(defaultParticleType, pos.getX(), pos.getY(), pos.getZ(), velX, velY, velZ); - }); - return null; - } - - @FunctionDoc( - deprecated = "This function is dangerous, use at your own risk", - name = "setGhostBlock", - desc = "This sets a ghost block in the world as if it were a real block, may cause issues", - params = { - @ParameterDoc(type = BlockDef.class, name = "block", desc = "the block to set"), - @ParameterDoc(type = NumberDef.class, name = "x", desc = "the x position of the block"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "the y position of the block"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "the z position of the block") - }, - examples = "world.setGhostBlock(Material.BEDROCK.asBlock(), 0, 100, 0);" - ) - private Void setGhostBlock(Arguments arguments) { - World world = arguments.nextPrimitive(this); - ScriptBlockState blockState = arguments.nextPrimitive(BlockDef.class); - int x = arguments.nextPrimitive(NumberDef.class).intValue(); - int y = arguments.nextPrimitive(NumberDef.class).intValue(); - int z = arguments.nextPrimitive(NumberDef.class).intValue(); - BlockPos blockPos = new BlockPos(x, y, z); - ClientScriptUtils.ensureMainThread("setGhostBlock", arguments.getInterpreter(), () -> { - world.setBlockState(blockPos, blockState.state); - }); - return null; - } - - @FunctionDoc( - deprecated = "This function is dangerous, use at your own risk", - name = "setGhostBlock", - desc = "This sets a ghost block in the world as if it were a real block, may cause issues", - params = { - @ParameterDoc(type = BlockDef.class, name = "block", desc = "the block to set"), - @ParameterDoc(type = PosDef.class, name = "pos", desc = "the position of the block") - }, - examples = "world.setGhostBlock(Material.BEDROCK.asBlock(), new Pos(0, 100, 0));" - ) - private Void setGhostBlockPos(Arguments arguments) { - World world = arguments.nextPrimitive(this); - ScriptBlockState blockState = arguments.nextPrimitive(BlockDef.class); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - ClientScriptUtils.ensureMainThread("setGhostBlock", arguments.getInterpreter(), () -> { - world.setBlockState(pos.getBlockPos(), blockState.state); - }); - return null; - } - - @FunctionDoc( - name = "isAir", - desc = "Returns true if the block at the given position is air", - params = { - @ParameterDoc(type = NumberDef.class, name = "x", desc = "the x position of the block"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "the y position of the block"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "the z position of the block") - }, - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the block is air"), - examples = "world.isAir(0, 100, 0);" - ) - private boolean isAir(Arguments arguments) { - warnMainThread("isAir", arguments.getInterpreter()); - World world = arguments.nextPrimitive(this); - int x = arguments.nextPrimitive(NumberDef.class).intValue(); - int y = arguments.nextPrimitive(NumberDef.class).intValue(); - int z = arguments.nextPrimitive(NumberDef.class).intValue(); - return world.isAir(new BlockPos(x, y, z)); - } - - @FunctionDoc( - name = "isAir", - desc = "Returns true if the block at the given position is air", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "the position of the block")}, - returns = @ReturnDoc(type = BooleanDef.class, desc = "true if the block is air"), - examples = "world.isAir(new Pos(0, 100, 0));" - ) - private boolean isAirPos(Arguments arguments) { - warnMainThread("isAir", arguments.getInterpreter()); - World world = arguments.nextPrimitive(this); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - return world.isAir(pos.getBlockPos()); - } - - @FunctionDoc( - name = "getEmittedRedstonePower", - desc = "Gets the emitted restone power at the given position and direction", - params = { - @ParameterDoc(type = NumberDef.class, name = "x", desc = "the x position of the block"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "the y position of the block"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "the z position of the block"), - @ParameterDoc(type = StringDef.class, name = "direction", desc = "the direction to check, for example 'north', 'east', 'up', etc.") - }, - returns = @ReturnDoc(type = NumberDef.class, desc = "the emitted redstone power"), - examples = "world.getEmittedRedstonePower(0, 100, 0, 'north');" - ) - private int getEmittedRedstonePower(Arguments arguments) { - warnMainThread("getEmittedRedstonePower", arguments.getInterpreter()); - World world = arguments.nextPrimitive(this); - int x = arguments.nextPrimitive(NumberDef.class).intValue(); - int y = arguments.nextPrimitive(NumberDef.class).intValue(); - int z = arguments.nextPrimitive(NumberDef.class).intValue(); - String stringDirection = arguments.nextConstant(); - BlockPos blockPos = new BlockPos(x, y, z); - Direction direction = ClientScriptUtils.stringToDirection(stringDirection, Direction.DOWN); - return world.getEmittedRedstonePower(blockPos, direction); - } - - @FunctionDoc( - name = "getEmittedRedstonePower", - desc = "Gets the emitted restone power at the given position and direction", - params = { - @ParameterDoc(type = PosDef.class, name = "pos", desc = "the position of the block"), - @ParameterDoc(type = StringDef.class, name = "direction", desc = "the direction to check, for example 'north', 'east', 'up', etc.") - }, - returns = @ReturnDoc(type = NumberDef.class, desc = "the emitted redstone power"), - examples = "world.getEmittedRedstonePower(new Pos(0, 100, 0), 'north');" - ) - private int getEmittedRedstonePowerPos(Arguments arguments) { - warnMainThread("getEmittedRedstonePower", arguments.getInterpreter()); - World world = arguments.nextPrimitive(this); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - String stringDirection = arguments.nextConstant(); - Direction direction = ClientScriptUtils.stringToDirection(stringDirection, Direction.DOWN); - return world.getEmittedRedstonePower(pos.getBlockPos(), direction); - } - - @FunctionDoc( - name = "getLight", - desc = "Gets the light level at the given position, takes the max of either sky light of block light", - params = { - @ParameterDoc(type = NumberDef.class, name = "x", desc = "the x position of the block"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "the y position of the block"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "the z position of the block") - }, - returns = @ReturnDoc(type = NumberDef.class, desc = "the light level between 0 - 15"), - examples = "world.getLight(0, 100, 0);" - ) - private int getLight(Arguments arguments) { - warnMainThread("getLight", arguments.getInterpreter()); - World world = arguments.nextPrimitive(this); - int x = arguments.nextPrimitive(NumberDef.class).intValue(); - int y = arguments.nextPrimitive(NumberDef.class).intValue(); - int z = arguments.nextPrimitive(NumberDef.class).intValue(); - return world.getLightLevel(new BlockPos(x, y, z)); - } - - @FunctionDoc( - name = "getLight", - desc = "Gets the light level at the given position, takes the max of either sky light of block light", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "the position of the block")}, - returns = @ReturnDoc(type = NumberDef.class, desc = "the light level between 0 - 15"), - examples = "world.getLight(new Pos(0, 100, 0));" - ) - private int getLightPos(Arguments arguments) { - warnMainThread("getLight", arguments.getInterpreter()); - World world = arguments.nextPrimitive(this); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - return world.getLightLevel(pos.getBlockPos()); - } - - @FunctionDoc( - name = "getSkyLight", - desc = "Gets the sky light at the given position ignoring block light", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "the position of the block")}, - returns = @ReturnDoc(type = NumberDef.class, desc = "the light level between 0 - 15"), - examples = "world.getSkyLight(new Pos(0, 0, 0));" - ) - private int getSkyLight(Arguments arguments) { - warnMainThread("getSkyLight", arguments.getInterpreter()); - World world = arguments.nextPrimitive(this); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - return world.getLightLevel(LightType.SKY, pos.getBlockPos()); - } - - @FunctionDoc( - name = "getBlockLight", - desc = "Gets the block light at the given position ignoring sky light", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "the position of the block")}, - returns = @ReturnDoc(type = NumberDef.class, desc = "the light level between 0 - 15"), - examples = "world.getBlockLight(new Pos(0, 0, 0));" - ) - private int getBlockLight(Arguments arguments) { - warnMainThread("getBlockLight", arguments.getInterpreter()); - World world = arguments.nextPrimitive(this); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - return world.getLightLevel(LightType.BLOCK, pos.getBlockPos()); - } - - @FunctionDoc( - deprecated = "This function is memory intensive, you should use `.getPositions(pos1, pos2)`", - name = "getArea", - desc = "This gets a list of all block positions between the two positions", - params = { - @ParameterDoc(type = PosDef.class, name = "pos1", desc = "the first position"), - @ParameterDoc(type = PosDef.class, name = "pos2", desc = "the second position") - }, - returns = @ReturnDoc(type = ListDef.class, desc = "the list of positions"), - examples = "world.getArea(new Pos(0, 100, 0), new Pos(0, 100, 0));" - ) - private ArucasList getArea(Arguments arguments) { - warnMainThread("getArea", arguments.getInterpreter()); - BlockPos posA = arguments.skip().nextPrimitive(PosDef.class).getBlockPos(); - BlockPos posB = arguments.nextPrimitive(PosDef.class).getBlockPos(); - ArucasList list = new ArucasList(); - Interpreter interpreter = arguments.getInterpreter(); - for (BlockPos pos : BlockPos.iterate(posA, posB)) { - list.add(interpreter.create(PosDef.class, new ScriptPos(pos))); - } - return list; - } - - @FunctionDoc( - deprecated = "This function is memory intensive, you should use `.getBlocks(pos1, pos2)`", - name = "getAreaOfBlocks", - desc = "This gets a list of all blocks (with positions) between the two positions", - params = { - @ParameterDoc(type = PosDef.class, name = "pos1", desc = "the first position"), - @ParameterDoc(type = PosDef.class, name = "pos2", desc = "the second position") - }, - returns = @ReturnDoc(type = ListDef.class, desc = "the list of blocks"), - examples = "world.getAreaOfBlocks(new Pos(0, 100, 0), new Pos(0, 100, 0));" - ) - private Object getAreaOfBlocks(Arguments arguments) { - warnMainThread("getAreaOfBlocks", arguments.getInterpreter()); - World world = arguments.nextPrimitive(this); - BlockPos posA = arguments.nextPrimitive(PosDef.class).getBlockPos(); - BlockPos posB = arguments.nextPrimitive(PosDef.class).getBlockPos(); - - ArucasList list = new ArucasList(); - Interpreter interpreter = arguments.getInterpreter(); - for (BlockPos pos : BlockPos.iterate(posA, posB)) { - BlockState state = world.getBlockState(pos); - list.add(interpreter.create(BlockDef.class, new ScriptBlockState(state, pos))); - } - return list; - } - - @FunctionDoc( - name = "getPositions", - desc = "This gets an iterator for all positions between two positions", - params = { - @ParameterDoc(type = PosDef.class, name = "pos1", desc = "the first position"), - @ParameterDoc(type = PosDef.class, name = "pos2", desc = "the second position") - }, - returns = @ReturnDoc(type = IterableDef.class, desc = "the iterator for the positions"), - examples = "foreach (pos : world.getPositions(new Pos(0, 100, 100), new Pos(0, 100, 0)));" - ) - private ArucasIterable getPositions(Arguments arguments) { - BlockPos posA = arguments.skip().nextPrimitive(PosDef.class).getBlockPos(); - BlockPos posB = arguments.nextPrimitive(PosDef.class).getBlockPos(); - Iterable posIterable = BlockPos.iterate(posA, posB); - return () -> new PosIterator(posIterable.iterator(), o -> arguments.getInterpreter().convertValue(o)); - } - - @FunctionDoc( - name = "getBlocks", - desc = "This gets an iterator for all blocks (and positions) between two positions", - params = { - @ParameterDoc(type = PosDef.class, name = "pos1", desc = "the first position"), - @ParameterDoc(type = PosDef.class, name = "pos2", desc = "the second position") - }, - returns = @ReturnDoc(type = IterableDef.class, desc = "the iterator for the blocks"), - examples = "foreach (block : world.getBlocks(new Pos(0, 100, 100), new Pos(0, 100, 0)));" - ) - private ArucasIterable getBlocks(Arguments arguments) { - World world = arguments.nextPrimitive(this); - BlockPos posA = arguments.nextPrimitive(PosDef.class).getBlockPos(); - BlockPos posB = arguments.nextPrimitive(PosDef.class).getBlockPos(); - Iterable posIterable = BlockPos.iterate(posA, posB); - return () -> new PosIterator.Block(world, posIterable.iterator(), o -> arguments.getInterpreter().convertValue(o)); - } - - @FunctionDoc( - name = "getPositionsFromCentre", - desc = { - "This gets an iterator for all positions between two positions.", - "The iterator iterates from the centre outwards" - }, - params = { - @ParameterDoc(type = PosDef.class, name = "centre", desc = "the central position"), - @ParameterDoc(type = NumberDef.class, name = "xRange", desc = "how far to iterate on the x axis"), - @ParameterDoc(type = NumberDef.class, name = "yRange", desc = "how far to iterate on the y axis"), - @ParameterDoc(type = NumberDef.class, name = "zRange", desc = "how far to iterate on the z axis") - }, - returns = @ReturnDoc(type = IterableDef.class, desc = "the iterator for the positions"), - examples = "foreach (pos : world.getPositionsFromCentre(new Pos(0, 100, 100), 10, 10, 10));" - ) - private ArucasIterable getPositionsFromCentre(Arguments arguments) { - BlockPos posA = arguments.skip().nextPrimitive(PosDef.class).getBlockPos(); - int x = arguments.nextPrimitive(NumberDef.class).intValue(); - int y = arguments.nextPrimitive(NumberDef.class).intValue(); - int z = arguments.nextPrimitive(NumberDef.class).intValue(); - Iterable posIterable = BlockPos.iterateOutwards(posA, x, y, z); - return () -> new PosIterator(posIterable.iterator(), o -> arguments.getInterpreter().convertValue(o)); - } - - @FunctionDoc( - name = "getBlocksFromCentre", - desc = { - "This gets an iterator for all blocks (and positions) between two positions.", - "The iterator iterates from the centre outwards" - }, - params = { - @ParameterDoc(type = PosDef.class, name = "centre", desc = "the central position"), - @ParameterDoc(type = NumberDef.class, name = "xRange", desc = "how far to iterate on the x axis"), - @ParameterDoc(type = NumberDef.class, name = "yRange", desc = "how far to iterate on the y axis"), - @ParameterDoc(type = NumberDef.class, name = "zRange", desc = "how far to iterate on the z axis") - }, - returns = @ReturnDoc(type = IterableDef.class, desc = "the iterator for the blocks"), - examples = "foreach (block : world.getBlocksFromCentre(new Pos(0, 100, 100), 10, 5, 60));" - ) - private ArucasIterable getBlocksFromCentre(Arguments arguments) { - World world = arguments.nextPrimitive(this); - BlockPos posA = arguments.nextPrimitive(PosDef.class).getBlockPos(); - int x = arguments.nextPrimitive(NumberDef.class).intValue(); - int y = arguments.nextPrimitive(NumberDef.class).intValue(); - int z = arguments.nextPrimitive(NumberDef.class).intValue(); - Iterable posIterable = BlockPos.iterateOutwards(posA, x, y, z); - return () -> new PosIterator.Block(world, posIterable.iterator(), o -> arguments.getInterpreter().convertValue(o)); - } - - @FunctionDoc( - name = "reloadChunks", - desc = "This reloads all the chunks, as if you were to press F3 + A.", - examples = "world.reloadChunks();" - ) - private Void reloadChunks(Arguments arguments) { - ClientScriptUtils.ensureMainThread("reloadChunks", arguments.getInterpreter(), () -> { - EssentialUtils.getClient().worldRenderer.reload(); - }); - return null; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/BoxShapeDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/BoxShapeDef.java deleted file mode 100644 index 31ee857f..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/BoxShapeDef.java +++ /dev/null @@ -1,122 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions.shapes; - -import kotlin.Unit; -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.ConstructorDoc; -import me.senseiwells.arucas.api.docs.annotations.ParameterDoc; -import me.senseiwells.arucas.builtin.NumberDef; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.ConstructorFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.clientscript.definitions.PosDef; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptBox; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptPos; -import net.minecraft.util.math.Vec3d; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.BOX_SHAPE; - -@ClassDoc( - name = BOX_SHAPE, - desc = "This class allows you to create box shapes that can be rendered in the world.", - superclass = CorneredShapeDef.class, - language = Language.Java -) -public class BoxShapeDef extends CreatableDefinition { - public BoxShapeDef(Interpreter interpreter) { - super(BOX_SHAPE, interpreter); - } - - @NotNull - @Override - public PrimitiveDefinition superclass() { - return this.getPrimitiveDef(CorneredShapeDef.class); - } - - @Override - public List defineConstructors() { - return List.of( - ConstructorFunction.of(1, this::construct1), - ConstructorFunction.of(2, this::construct2), - ConstructorFunction.of(3, this::construct3), - ConstructorFunction.of(6, this::construct6) - ); - } - - @ConstructorDoc( - desc = "Creates a new box shape, this is used to render boxes", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "The position which will be used for the first and second corner of the box")}, - examples = "new BoxShape(new Pos(0, 0, 0));" - ) - private Unit construct1(Arguments arguments) { - ClassInstance instance = arguments.next(); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - instance.setPrimitive(this, new ScriptBox(arguments.getInterpreter(), pos.getVec3d(), pos.getVec3d())); - return null; - } - - @ConstructorDoc( - desc = "Creates a new box shape, this is used to render boxes", - params = { - @ParameterDoc(type = PosDef.class, name = "pos1", desc = "The position of the first corner of the box"), - @ParameterDoc(type = PosDef.class, name = "pos2", desc = "The position of the second corner of the box") - }, - examples = "new BoxShape(new Pos(0, 0, 0), new Pos(10, 10, 10));" - ) - private Unit construct2(Arguments arguments) { - ClassInstance instance = arguments.next(); - ScriptPos pos1 = arguments.nextPrimitive(PosDef.class); - ScriptPos pos2 = arguments.nextPrimitive(PosDef.class); - instance.setPrimitive(this, new ScriptBox(arguments.getInterpreter(), pos1.getVec3d(), pos2.getVec3d())); - return null; - } - - @ConstructorDoc( - desc = "Creates a new box shape, this is used to render boxes", - params = { - @ParameterDoc(type = NumberDef.class, name = "x", desc = "The x position which will be used for the first and second corner of the box"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "The y position which will be used for the first and second corner of the box"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "The z position which will be used for the first and second corner of the box") - }, - examples = "new BoxShape(0, 0, 0);" - ) - private Unit construct3(Arguments arguments) { - ClassInstance instance = arguments.next(); - double x = arguments.nextPrimitive(NumberDef.class).intValue(); - double y = arguments.nextPrimitive(NumberDef.class).intValue(); - double z = arguments.nextPrimitive(NumberDef.class).intValue(); - Vec3d pos = new Vec3d(x, y, z); - instance.setPrimitive(this, new ScriptBox(arguments.getInterpreter(), pos, pos)); - return null; - } - - @ConstructorDoc( - desc = "Creates a new box shape, this is used to render boxes", - params = { - @ParameterDoc(type = NumberDef.class, name = "x1", desc = "The x position of the first corner of the box"), - @ParameterDoc(type = NumberDef.class, name = "y1", desc = "The y position of the first corner of the box"), - @ParameterDoc(type = NumberDef.class, name = "z1", desc = "The z position of the first corner of the box"), - @ParameterDoc(type = NumberDef.class, name = "x2", desc = "The x position of the second corner of the box"), - @ParameterDoc(type = NumberDef.class, name = "y2", desc = "The y position of the second corner of the box"), - @ParameterDoc(type = NumberDef.class, name = "z2", desc = "The z position of the second corner of the box") - }, - examples = "new BoxShape(0, 0, 0, 10, 10, 10);" - ) - private Unit construct6(Arguments arguments) { - ClassInstance instance = arguments.next(); - double x1 = arguments.nextPrimitive(NumberDef.class).intValue(); - double y1 = arguments.nextPrimitive(NumberDef.class).intValue(); - double z1 = arguments.nextPrimitive(NumberDef.class).intValue(); - double x2 = arguments.nextPrimitive(NumberDef.class).intValue(); - double y2 = arguments.nextPrimitive(NumberDef.class).intValue(); - double z2 = arguments.nextPrimitive(NumberDef.class).intValue(); - instance.setPrimitive(this, new ScriptBox(arguments.getInterpreter(), new Vec3d(x1, y1, z1), new Vec3d(x2, y2, z2))); - return null; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/CentredShapeDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/CentredShapeDef.java deleted file mode 100644 index 9cdfafdf..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/CentredShapeDef.java +++ /dev/null @@ -1,110 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions.shapes; - -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ParameterDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.NumberDef; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.clientscript.definitions.PosDef; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptPos; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptShape; -import net.minecraft.util.math.Direction; -import org.jetbrains.annotations.NotNull; - -import java.util.EnumSet; -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.CENTRED_SHAPE; - -@ClassDoc( - name = CENTRED_SHAPE, - desc = "This class represents shapes that are positioned centrally with a width", - superclass = OutlinedShapeDef.class, - language = Language.Java -) -public class CentredShapeDef extends PrimitiveDefinition { - public CentredShapeDef(Interpreter interpreter) { - super(CENTRED_SHAPE, interpreter); - } - - @NotNull - @Override - public PrimitiveDefinition superclass() { - return this.getPrimitiveDef(OutlinedShapeDef.class); - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("setPos", 1, this::setPos), - MemberFunction.of("setWidth", 1, this::setWidth), - MemberFunction.of("getPos", this::getPos), - MemberFunction.of("getWidth", this::getWidth), - MemberFunction.of("centrePositions", this::centrePositions) - ); - } - - @FunctionDoc( - name = "setPos", - desc = "This sets the central position of the shape", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "the central position of the shape")}, - examples = "shape.setPos(new Pos(1, 0, 100));" - ) - private Void setPos(Arguments arguments) { - ScriptShape.Centred shape = arguments.nextPrimitive(this); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - shape.setPosition(pos.getVec3d()); - return null; - } - - @FunctionDoc( - name = "setWidth", - desc = "This sets the width of the shape", - params = {@ParameterDoc(type = NumberDef.class, name = "width", desc = "the width of the shape")}, - examples = "shape.setWidth(10.5);" - ) - private Void setWidth(Arguments arguments) { - ScriptShape.Centred shape = arguments.nextPrimitive(this); - float width = arguments.nextPrimitive(NumberDef.class).floatValue(); - shape.setWidth(width); - return null; - } - - @FunctionDoc( - name = "getPos", - desc = "This gets the central position of the shape", - returns = @ReturnDoc(type = PosDef.class, desc = "the central position of the shape"), - examples = "shape.getPos();" - ) - private ScriptPos getPos(Arguments arguments) { - ScriptShape.Centred shape = arguments.nextPrimitive(this); - return new ScriptPos(shape.getPosition()); - } - - @FunctionDoc( - name = "getWidth", - desc = "This gets the width of the shape", - returns = @ReturnDoc(type = NumberDef.class, desc = "the width of the shape"), - examples = "shape.getWidth();" - ) - private float getWidth(Arguments arguments) { - ScriptShape.Centred shape = arguments.nextPrimitive(this); - return shape.getWidth(); - } - - @FunctionDoc( - name = "centrePositions", - desc = "This centres the positions of the shape", - examples = "shape.centrePositions();" - ) - private Void centrePositions(Arguments arguments) { - ScriptShape.Centred shape = arguments.nextPrimitive(this); - shape.setPosition(shape.getPosition().floorAlongAxes(EnumSet.of(Direction.Axis.X, Direction.Axis.Y, Direction.Axis.Z))); - return null; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/CorneredShapeDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/CorneredShapeDef.java deleted file mode 100644 index 9b342977..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/CorneredShapeDef.java +++ /dev/null @@ -1,109 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions.shapes; - -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ParameterDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.clientscript.definitions.PosDef; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptPos; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptShape; -import net.minecraft.util.math.Direction; -import org.jetbrains.annotations.NotNull; - -import java.util.EnumSet; -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.CORNERED_SHAPE; - -@ClassDoc( - name = CORNERED_SHAPE, - desc = "This class represents all shapes that use 2 corners to dictate their position", - superclass = OutlinedShapeDef.class, - language = Language.Java -) -public class CorneredShapeDef extends PrimitiveDefinition { - public CorneredShapeDef(Interpreter interpreter) { - super(CORNERED_SHAPE, interpreter); - } - - @NotNull - @Override - public PrimitiveDefinition superclass() { - return this.getPrimitiveDef(OutlinedShapeDef.class); - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("setPos1", 1, this::setPos1), - MemberFunction.of("setPos2", 1, this::setPos2), - MemberFunction.of("getPos1", this::getPos1), - MemberFunction.of("getPos2", this::getPos2), - MemberFunction.of("centrePositions", this::centrePositions) - ); - } - - @FunctionDoc( - name = "setPos1", - desc = "This sets the first position of the shape", - params = {@ParameterDoc(type = PosDef.class, name = "pos1", desc = "the first position of the shape")}, - examples = "shape.setPos1(new Pos(1, 0, 100));" - ) - private Void setPos1(Arguments arguments) { - ScriptShape.Cornered shape = arguments.nextPrimitive(this); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - shape.setCornerA(pos.getVec3d()); - return null; - } - - @FunctionDoc( - name = "setPos2", - desc = "This sets the second position of the shape", - params = {@ParameterDoc(type = PosDef.class, name = "pos2", desc = "the second position of the shape")}, - examples = "shape.setPos2(new Pos(1, 0, 100));" - ) - private Void setPos2(Arguments arguments) { - ScriptShape.Cornered shape = arguments.nextPrimitive(this); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - shape.setCornerB(pos.getVec3d()); - return null; - } - - @FunctionDoc( - name = "getPos1", - desc = "This gets the first position of the shape", - returns = @ReturnDoc(type = PosDef.class, desc = "the first position of the shape"), - examples = "shape.getPos1();" - ) - private ScriptPos getPos1(Arguments arguments) { - ScriptShape.Cornered shape = arguments.nextPrimitive(this); - return new ScriptPos(shape.getCornerA()); - } - - @FunctionDoc( - name = "getPos2", - desc = "This gets the second position of the shape", - returns = @ReturnDoc(type = PosDef.class, desc = "the second position of the shape"), - examples = "shape.getPos2();" - ) - private ScriptPos getPos2(Arguments arguments) { - ScriptShape.Cornered shape = arguments.nextPrimitive(this); - return new ScriptPos(shape.getCornerB()); - } - - @FunctionDoc( - name = "centrePositions", - desc = "This centres the positions of the shape", - examples = "shape.centrePositions();" - ) - private Void centrePositions(Arguments arguments) { - ScriptShape.Cornered shape = arguments.nextPrimitive(this); - shape.setCornerA(shape.getCornerA().floorAlongAxes(EnumSet.of(Direction.Axis.X, Direction.Axis.Y, Direction.Axis.Z))); - return null; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/FakeBlockShapeDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/FakeBlockShapeDef.java deleted file mode 100644 index e1e601ca..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/FakeBlockShapeDef.java +++ /dev/null @@ -1,189 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions.shapes; - -import kotlin.Unit; -import me.senseiwells.arucas.api.docs.annotations.*; -import me.senseiwells.arucas.builtin.BooleanDef; -import me.senseiwells.arucas.builtin.NullDef; -import me.senseiwells.arucas.builtin.StringDef; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.ConstructorFunction; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.clientscript.definitions.BlockDef; -import me.senseiwells.essentialclient.clientscript.definitions.MaterialDef; -import me.senseiwells.essentialclient.clientscript.definitions.PosDef; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.ClientScriptUtils; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptBlockState; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptFakeBlock; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptMaterial; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptPos; -import net.minecraft.util.math.Direction; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.FAKE_BLOCK; - -@ClassDoc( - name = FAKE_BLOCK, - desc = "This class can be used to create fake blocks which can be rendered in the world.", - superclass = ShapeDef.class, - language = Language.Java -) -public class FakeBlockShapeDef extends CreatableDefinition { - public FakeBlockShapeDef(Interpreter interpreter) { - super(FAKE_BLOCK, interpreter); - } - - @NotNull - @Override - public PrimitiveDefinition superclass() { - return this.getPrimitiveDef(ShapeDef.class); - } - - @Override - public List defineConstructors() { - return List.of( - ConstructorFunction.of(2, this::construct) - ); - } - - @ConstructorDoc( - desc = "Creates a fake block with the given block and position", - params = { - @ParameterDoc(type = BlockDef.class, name = "block", desc = "The block to use"), - @ParameterDoc(type = PosDef.class, name = "pos", desc = "The position of the block") - }, - examples = "new FakeBlock(Material.BEDROCK.asBlock(), new Pos(0, 0, 0));" - ) - private Unit construct(Arguments arguments) { - ClassInstance instance = arguments.next(); - ScriptMaterial material = arguments.nextPrimitive(MaterialDef.class); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - ScriptFakeBlock block = new ScriptFakeBlock(arguments.getInterpreter(), pos.getVec3d(), material.asBlockState()); - instance.setPrimitive(this, block); - return null; - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("setBlock", 1, this::setBlock), - MemberFunction.of("setPos", 1, this::setPos), - MemberFunction.of("getBlock", this::getBlock), - MemberFunction.of("getPos", this::getPos), - MemberFunction.of("setCull", 1, this::setCull), - MemberFunction.of("shouldCull", this::shouldCull), - MemberFunction.of("setDirection", 1, this::setDirection), - MemberFunction.of("getDirection", this::getDirection) - ); - } - - @FunctionDoc( - name = "setBlock", - desc = "Sets the block type to render of the fake block", - params = {@ParameterDoc(type = BlockDef.class, name = "block", desc = "The block to render")}, - examples = "fakeBlock.setBlock(Material.BEDROCK.asBlock());" - ) - private Void setBlock(Arguments arguments) { - ScriptFakeBlock block = arguments.nextPrimitive(this); - ScriptMaterial material = arguments.nextPrimitive(MaterialDef.class); - block.setState(material.asBlockState()); - return null; - } - - @FunctionDoc( - name = "setPos", - desc = "Sets the position of the fake block", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "The position of the fake block")}, - examples = "fakeBlock.setPos(new Pos(0, 0, 0));" - ) - private Void setPos(Arguments arguments) { - ScriptFakeBlock block = arguments.nextPrimitive(this); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - block.setPosition(pos.getVec3d()); - return null; - } - - @FunctionDoc( - name = "getBlock", - desc = "Gets the current block type of the fake block", - returns = @ReturnDoc(type = BlockDef.class, desc = "The block type of the fake block"), - examples = "fakeBlock.getBlock();" - ) - private ScriptMaterial getBlock(Arguments arguments) { - ScriptFakeBlock block = arguments.nextPrimitive(this); - return new ScriptBlockState(block.getState(), EssentialUtils.vec3dToBlockPos(block.getPosition())); - } - - @FunctionDoc( - name = "getPos", - desc = "Gets the position of the fake block", - returns = @ReturnDoc(type = PosDef.class, desc = "The position of the fake block"), - examples = "fakeBlock.getPos();" - ) - private ScriptPos getPos(Arguments arguments) { - ScriptFakeBlock block = arguments.nextPrimitive(this); - return new ScriptPos(block.getPosition()); - } - - @FunctionDoc( - name = "setCull", - desc = "Sets whether the fake block should be culled", - params = {@ParameterDoc(type = BooleanDef.class, name = "cull", desc = "Whether the fake block should be culled")}, - examples = "fakeBlock.setCull(true);" - ) - private Void setCull(Arguments arguments) { - ScriptFakeBlock block = arguments.nextPrimitive(this); - block.setCull(arguments.nextPrimitive(BooleanDef.class)); - return null; - } - - @FunctionDoc( - name = "shouldCull", - desc = "Gets whether the fake block should be culled", - returns = @ReturnDoc(type = BooleanDef.class, desc = "Whether the fake block should be culled"), - examples = "fakeBlock.shouldCull();" - ) - private boolean shouldCull(Arguments arguments) { - ScriptFakeBlock block = arguments.nextPrimitive(this); - return block.shouldCull(); - } - - @FunctionDoc( - name = "setDirection", - desc = { - "Sets the direction of the fake block,", - "this may be null in which case the block will face the player" - }, - params = {@ParameterDoc(type = StringDef.class, name = "direction", desc = "The direction of the fake block")}, - examples = "fakeBlock.setDirection(Direction.UP);" - ) - private Void setDirection(Arguments arguments) { - ScriptFakeBlock block = arguments.nextPrimitive(this); - if (arguments.isNext(NullDef.class)) { - block.setDirection(null); - } else { - Direction direction = ClientScriptUtils.stringToDirection(arguments.nextConstant(), null); - block.setDirection(direction); - } - return null; - } - - @FunctionDoc( - name = "getDirection", - desc = "Gets the direction of the fake block", - returns = @ReturnDoc(type = StringDef.class, desc = "The direction of the fake block, may be null"), - examples = "fakeBlock.getDirection();" - ) - private String getDirection(Arguments arguments) { - ScriptFakeBlock block = arguments.nextPrimitive(this); - Direction direction = block.getDirection(); - return direction == null ? null : direction.getName(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/LineShapeDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/LineShapeDef.java deleted file mode 100644 index 3c8aa18a..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/LineShapeDef.java +++ /dev/null @@ -1,91 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions.shapes; - -import kotlin.Unit; -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.ConstructorDoc; -import me.senseiwells.arucas.api.docs.annotations.ParameterDoc; -import me.senseiwells.arucas.builtin.NumberDef; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.ConstructorFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.clientscript.definitions.PosDef; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptLine; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptPos; -import net.minecraft.util.math.Vec3d; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.LINE_SHAPE; - -@ClassDoc( - name = LINE_SHAPE, - desc = "This class allows you to create a line shape which can be used to draw lines in the world.", - superclass = CorneredShapeDef.class, - language = Language.Java -) -public class LineShapeDef extends CreatableDefinition { - public LineShapeDef(Interpreter interpreter) { - super(LINE_SHAPE, interpreter); - } - - @NotNull - @Override - public PrimitiveDefinition superclass() { - return this.getPrimitiveDef(CorneredShapeDef.class); - } - - @Override - public List defineConstructors() { - return List.of( - ConstructorFunction.of(2, this::construct2), - ConstructorFunction.of(6, this::construct6) - ); - } - - @ConstructorDoc( - desc = "Creates a new line shape", - params = { - @ParameterDoc(type = PosDef.class, name = "pos1", desc = "The starting position of the line"), - @ParameterDoc(type = PosDef.class, name = "pos2", desc = "The ending position of the line") - }, - examples = "new LineShape(new Pos(0, 0, 0), new Pos(1, 1, 1));" - ) - private Unit construct2(Arguments arguments) { - ClassInstance instance = arguments.next(); - ScriptPos pos1 = arguments.nextPrimitive(PosDef.class); - ScriptPos pos2 = arguments.nextPrimitive(PosDef.class); - instance.setPrimitive(this, new ScriptLine(arguments.getInterpreter(), pos1.getVec3d(), pos2.getVec3d())); - return null; - } - - @ConstructorDoc( - desc = "Creates a new line shape", - params = { - @ParameterDoc(type = NumberDef.class, name = "x1", desc = "The x position of the starting position of the line"), - @ParameterDoc(type = NumberDef.class, name = "y1", desc = "The y position of the starting position of the line"), - @ParameterDoc(type = NumberDef.class, name = "z1", desc = "The z position of the starting position of the line"), - @ParameterDoc(type = NumberDef.class, name = "x2", desc = "The x position of the ending position of the line"), - @ParameterDoc(type = NumberDef.class, name = "y2", desc = "The y position of the ending position of the line"), - @ParameterDoc(type = NumberDef.class, name = "z2", desc = "The z position of the ending position of the line") - }, - examples = "new LineShape(0, 0, 0, 1, 1, 1);" - ) - private Unit construct6(Arguments arguments) { - ClassInstance instance = arguments.next(); - double x1 = arguments.nextPrimitive(NumberDef.class); - double y1 = arguments.nextPrimitive(NumberDef.class); - double z1 = arguments.nextPrimitive(NumberDef.class); - double x2 = arguments.nextPrimitive(NumberDef.class); - double y2 = arguments.nextPrimitive(NumberDef.class); - double z2 = arguments.nextPrimitive(NumberDef.class); - Vec3d first = new Vec3d(x1, y1, z1); - Vec3d second = new Vec3d(x2, y2, z2); - instance.setPrimitive(this, new ScriptLine(arguments.getInterpreter(), first, second)); - return null; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/OutlinedShapeDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/OutlinedShapeDef.java deleted file mode 100644 index 386ffb58..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/OutlinedShapeDef.java +++ /dev/null @@ -1,189 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions.shapes; - -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ParameterDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.NumberDef; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptShape; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.OUTLINED_SHAPE; - -@ClassDoc( - name = OUTLINED_SHAPE, - desc = "This class represents all shapes that can be outlined", - superclass = ShapeDef.class, - language = Language.Java -) -public class OutlinedShapeDef extends PrimitiveDefinition { - public OutlinedShapeDef(Interpreter interpreter) { - super(OUTLINED_SHAPE, interpreter); - } - - @NotNull - @Override - public PrimitiveDefinition superclass() { - return this.getPrimitiveDef(ShapeDef.class); - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("setOutlineColour", 1, this::setOutlineColour1), - MemberFunction.of("setOutlineColor", 1, this::setOutlineColour1), - MemberFunction.of("setOutlineColour", 3, this::setOutlineColour3), - MemberFunction.of("setOutlineColor", 3, this::setOutlineColour3), - MemberFunction.of("setOutlineRed", 1, this::setOutlineRed), - MemberFunction.of("setOutlineGreen", 1, this::setOutlineGreen), - MemberFunction.of("setOutlineBlue", 1, this::setOutlineBlue), - MemberFunction.of("setOutlinePixelWidth", 1, this::setOutlineWidth, "Use .setOutlineWidth(width) instead"), - MemberFunction.of("setOutlineWidth", 1, this::setOutlineWidth), - MemberFunction.of("getOutlineRed", this::getOutlineRed), - MemberFunction.of("getOutlineGreen", this::getOutlineGreen), - MemberFunction.of("getOutlineBlue", this::getOutlineBlue), - MemberFunction.of("getOutlinePixelWidth", this::getOutlineWidth) - ); - } - - @FunctionDoc( - name = "setOutlineColour", - desc = { - "This sets the width of the shape, using a single value, this function", - "also has a sibling named `setOutlineColor()` that has the same functionality.", - "The colour generally should be hexadecimal in the form 0xRRGGBB" - }, - params = {@ParameterDoc(type = NumberDef.class, name = "colour", desc = "the colour you want to set")}, - examples = "shape.setOutlineColour(0xFF00FF);" - ) - private Void setOutlineColour1(Arguments arguments) { - ScriptShape.Outlined shape = arguments.nextPrimitive(this); - int colour = arguments.nextPrimitive(NumberDef.class).intValue(); - shape.setOutlineColour(colour); - return null; - } - - @FunctionDoc( - name = "setOutlineColour", - desc = { - "This sets the outline colour of the shape, using three values, this function", - "also has a sibling named `setOutlineColor()` that has the same functionality.", - "If the colours are not between 0 and 255 an error will be thrown" - }, - params = { - @ParameterDoc(type = NumberDef.class, name = "red", desc = "the amount of red 0 - 255"), - @ParameterDoc(type = NumberDef.class, name = "green", desc = "the amount of green 0 - 255"), - @ParameterDoc(type = NumberDef.class, name = "blue", desc = "the amount of blue 0 - 255") - }, - examples = "shape.setOutlineColour(255, 0, 255);" - ) - private Void setOutlineColour3(Arguments arguments) { - ScriptShape.Outlined shape = arguments.nextPrimitive(this); - int red = arguments.nextPrimitive(NumberDef.class).intValue(); - int green = arguments.nextPrimitive(NumberDef.class).intValue(); - int blue = arguments.nextPrimitive(NumberDef.class).intValue(); - shape.setOutlineRed(red); - shape.setOutlineGreen(green); - shape.setOutlineBlue(blue); - return null; - } - - @FunctionDoc( - name = "setOutlineRed", - desc = "This sets the outline red value of the shape, using a single value", - params = {@ParameterDoc(type = NumberDef.class, name = "red", desc = "the amount of red between 0 - 255")}, - examples = "shape.setOutlineRed(34);" - ) - private Void setOutlineRed(Arguments arguments) { - ScriptShape.Outlined shape = arguments.nextPrimitive(this); - int red = arguments.nextPrimitive(NumberDef.class).intValue(); - shape.setOutlineRed(red); - return null; - } - - @FunctionDoc( - name = "setOutlineGreen", - desc = "This sets the outline green value of the shape, using a single value", - params = {@ParameterDoc(type = NumberDef.class, name = "green", desc = "the amount of green between 0 - 255")}, - examples = "shape.setOutlineGreen(34);" - ) - private Void setOutlineGreen(Arguments arguments) { - ScriptShape.Outlined shape = arguments.nextPrimitive(this); - int green = arguments.nextPrimitive(NumberDef.class).intValue(); - shape.setOutlineGreen(green); - return null; - } - - @FunctionDoc( - name = "setOutlineBlue", - desc = "This sets the outline blue value of the shape, using a single value", - params = {@ParameterDoc(type = NumberDef.class, name = "blue", desc = "the amount of blue between 0 - 255")}, - examples = "shape.setOutlineBlue(34);" - ) - private Void setOutlineBlue(Arguments arguments) { - ScriptShape.Outlined shape = arguments.nextPrimitive(this); - int blue = arguments.nextPrimitive(NumberDef.class).intValue(); - shape.setOutlineBlue(blue); - return null; - } - - @FunctionDoc( - name = "setOutlineWidth", - desc = "This sets the outline width of the shape, this should not be negative", - params = {@ParameterDoc(type = NumberDef.class, name = "width", desc = "the width of the outline")}, - examples = "shape.setOutlineWidth(2);" - ) - private Void setOutlineWidth(Arguments arguments) { - ScriptShape.Outlined shape = arguments.nextPrimitive(this); - int width = arguments.nextPrimitive(NumberDef.class).intValue(); - shape.setOutlineWidth(width); - return null; - } - - @FunctionDoc( - name = "getOutlineRed", - desc = "This gets the outline red value of the shape", - returns = @ReturnDoc(type = NumberDef.class, desc = "the red value of the outline"), - examples = "shape.getOutlineRed();" - ) - private Number getOutlineRed(Arguments arguments) { - return arguments.nextPrimitive(this).getRed(); - } - - @FunctionDoc( - name = "getOutlineGreen", - desc = "This gets the outline green value of the shape", - returns = @ReturnDoc(type = NumberDef.class, desc = "the green value of the outline"), - examples = "shape.getOutlineGreen();" - ) - private Number getOutlineGreen(Arguments arguments) { - return arguments.nextPrimitive(this).getGreen(); - } - - @FunctionDoc( - name = "getOutlineBlue", - desc = "This gets the outline blue value of the shape", - returns = @ReturnDoc(type = NumberDef.class, desc = "the blue value of the outline"), - examples = "shape.getOutlineBlue();" - ) - private Number getOutlineBlue(Arguments arguments) { - return arguments.nextPrimitive(this).getBlue(); - } - - @FunctionDoc( - name = "getOutlineWidth", - desc = "This gets the outline width of the shape", - returns = @ReturnDoc(type = NumberDef.class, desc = "the width of the outline"), - examples = "shape.getOutlineWidth();" - ) - private Number getOutlineWidth(Arguments arguments) { - return arguments.nextPrimitive(this).getOutlineWidth(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/ShapeDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/ShapeDef.java deleted file mode 100644 index 72b59985..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/ShapeDef.java +++ /dev/null @@ -1,493 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions.shapes; - -import me.senseiwells.arucas.api.docs.annotations.ClassDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.api.docs.annotations.ParameterDoc; -import me.senseiwells.arucas.api.docs.annotations.ReturnDoc; -import me.senseiwells.arucas.builtin.BooleanDef; -import me.senseiwells.arucas.builtin.ListDef; -import me.senseiwells.arucas.builtin.NumberDef; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.impl.ArucasList; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptShape; - -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.SHAPE; - -@ClassDoc( - name = SHAPE, - desc = { - "This class is the base class for all shapes that can be rendered,", - "providing the base functionality for all shapes" - }, - language = Language.Java -) -public class ShapeDef extends PrimitiveDefinition { - public ShapeDef(Interpreter interpreter) { - super(SHAPE, interpreter); - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("setColour", 1, this::setColour1), - MemberFunction.of("setColor", 1, this::setColour1), - MemberFunction.of("setColour", 3, this::setColour3), - MemberFunction.of("setColor", 3, this::setColour3), - MemberFunction.of("setRed", 1, this::setRed), - MemberFunction.of("setGreen", 1, this::setGreen), - MemberFunction.of("setBlue", 1, this::setBlue), - MemberFunction.of("setOpacity", 1, this::setOpacity), - MemberFunction.of("setRenderThroughBlocks", 1, this::setRenderThroughBlocks), - MemberFunction.of("getRed", this::getRed), - MemberFunction.of("getGreen", this::getGreen), - MemberFunction.of("getBlue", this::getBlue), - MemberFunction.of("getOpacity", this::getOpacity), - MemberFunction.of("getRGB", this::getRGB), - MemberFunction.of("getRGBList", this::getRGBList), - MemberFunction.of("getRGBAList", this::getRGBAList), - MemberFunction.of("shouldRenderThroughBlocks", this::shouldRenderThroughBlocks), - - MemberFunction.of("render", this::render), - MemberFunction.of("stopRendering", this::stopRendering), - - MemberFunction.of("setScale", 3, this::setScale), - MemberFunction.of("setXScale", 1, this::setXScale), - MemberFunction.of("setYScale", 1, this::setYScale), - MemberFunction.of("setZScale", 1, this::setZScale), - MemberFunction.of("getXScale", this::getXScale), - MemberFunction.of("getYScale", this::getYScale), - MemberFunction.of("getZScale", this::getZScale), - - MemberFunction.of("setTilt", 3, this::setTilt), - MemberFunction.of("setXTilt", 1, this::setXTilt), - MemberFunction.of("setYTilt", 1, this::setYTilt), - MemberFunction.of("setZTilt", 1, this::setZTilt), - MemberFunction.of("getXTilt", this::getXTilt), - MemberFunction.of("getYTilt", this::getYTilt), - MemberFunction.of("getZTilt", this::getZTilt) - ); - } - - @FunctionDoc( - name = "setColour", - desc = { - "This sets the colour of the shape, using a single value, this", - "function also has a sibling named `setColor()` that has the same functionality.", - "The colour generally should be hexadecimal in the form 0xRRGGBB" - }, - params = {@ParameterDoc(type = NumberDef.class, name = "colour", desc = "the colour you want to set")}, - examples = "shape.setColour(0xFF0000);" - ) - private Void setColour1(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - int colour = arguments.nextPrimitive(NumberDef.class).intValue(); - shape.setColour(colour); - return null; - } - - @FunctionDoc( - name = "setColour", - desc = { - "This sets the colour of the shape, using three values this function", - "also has a sibling named `setColor()` that has the same functionality.", - "If the colours are not between 0 and 255 an error will be thrown" - }, - params = { - @ParameterDoc(type = NumberDef.class, name = "red", desc = "the amount of red 0 - 255"), - @ParameterDoc(type = NumberDef.class, name = "green", desc = "the amount of green 0 - 255"), - @ParameterDoc(type = NumberDef.class, name = "blue", desc = "the amount of blue 0 - 255") - }, - examples = "shape.setColour(34, 55, 0);" - ) - private Void setColour3(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - int red = arguments.nextPrimitive(NumberDef.class).intValue(); - int green = arguments.nextPrimitive(NumberDef.class).intValue(); - int blue = arguments.nextPrimitive(NumberDef.class).intValue(); - shape.setRed(red); - shape.setGreen(green); - shape.setBlue(blue); - return null; - } - - @FunctionDoc( - name = "setRed", - desc = { - "This sets the red value of the shape, using a single value.", - "If the colour is not between 0 and 255 an error will be thrown" - }, - params = {@ParameterDoc(type = NumberDef.class, name = "red", desc = "the amount of red between 0 - 255")}, - examples = "shape.setRed(34);" - ) - private Void setRed(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - int red = arguments.nextPrimitive(NumberDef.class).intValue(); - shape.setRed(red); - return null; - } - - @FunctionDoc( - name = "setGreen", - desc = { - "This sets the green value of the shape, using a single value.", - "If the colour is not between 0 and 255 an error will be thrown" - }, - params = {@ParameterDoc(type = NumberDef.class, name = "green", desc = "the amount of green between 0 - 255")}, - examples = "shape.setGreen(34);" - ) - private Void setGreen(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - int green = arguments.nextPrimitive(NumberDef.class).intValue(); - shape.setGreen(green); - return null; - } - - @FunctionDoc( - name = "setBlue", - desc = { - "This sets the blue value of the shape, using a single value.", - "If the colour is not between 0 and 255 an error will be thrown" - }, - params = {@ParameterDoc(type = NumberDef.class, name = "blue", desc = "the amount of blue between 0 - 255")}, - examples = "shape.setBlue(34);" - ) - private Void setBlue(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - int blue = arguments.nextPrimitive(NumberDef.class).intValue(); - shape.setBlue(blue); - return null; - } - - @FunctionDoc( - name = "setOpacity", - desc = { - "This sets the opacity of the shape, using a single value.", - "If the colour is not between 0 and 255 an error will be thrown" - }, - params = {@ParameterDoc(type = NumberDef.class, name = "opacity", desc = "the amount of opacity between 0 - 255")}, - examples = "shape.setOpacity(34);" - ) - private Void setOpacity(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - int opacity = arguments.nextPrimitive(NumberDef.class).intValue(); - shape.setAlpha(opacity); - return null; - } - - @FunctionDoc( - name = "setRenderThroughBlocks", - desc = "This sets whether the shape should render through blocks", - params = {@ParameterDoc(type = BooleanDef.class, name = "boolean", desc = "whether the shape should render through blocks")}, - examples = "shape.setRenderThroughBlocks(true);" - ) - private Void setRenderThroughBlocks(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - boolean renderThroughBlocks = arguments.nextPrimitive(BooleanDef.class); - shape.setIgnoreDepth(renderThroughBlocks); - return null; - } - - @FunctionDoc( - name = "getRed", - desc = "This returns the red value of the shape", - returns = @ReturnDoc(type = NumberDef.class, desc = "the red value of the shape"), - examples = "shape.getRed();" - ) - private int getRed(Arguments arguments) { - return arguments.nextPrimitive(this).getRed(); - } - - @FunctionDoc( - name = "getGreen", - desc = "This returns the green value of the shape", - returns = @ReturnDoc(type = NumberDef.class, desc = "the green value of the shape"), - examples = "shape.getGreen();" - ) - private int getGreen(Arguments arguments) { - return arguments.nextPrimitive(this).getGreen(); - } - - @FunctionDoc( - name = "getBlue", - desc = "This returns the blue value of the shape", - returns = @ReturnDoc(type = NumberDef.class, desc = "the blue value of the shape"), - examples = "shape.getBlue();" - ) - private int getBlue(Arguments arguments) { - return arguments.nextPrimitive(this).getBlue(); - } - - @FunctionDoc( - name = "getOpacity", - desc = "This returns the opacity of the shape", - returns = @ReturnDoc(type = NumberDef.class, desc = "the opacity of the shape"), - examples = "shape.getOpacity();" - ) - private int getOpacity(Arguments arguments) { - return arguments.nextPrimitive(this).getAlpha(); - } - - @FunctionDoc( - name = "getRGB", - desc = "This returns the RGB value of the shape", - returns = @ReturnDoc(type = NumberDef.class, desc = "the RGB value of the shape as a single number in the form 0xRRGGBB"), - examples = "shape.getRGB();" - ) - private int getRGB(Arguments arguments) { - return arguments.nextPrimitive(this).getColour(); - } - - @FunctionDoc( - name = "getRGBList", - desc = "This returns the RGB value of the shape as a list", - returns = @ReturnDoc(type = ListDef.class, desc = "the RGB value of the shape as a list in the form [red, green, blue]"), - examples = "r, g, b = shape.getRGBList();" - ) - private ArucasList getRGBList(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - ArucasList list = new ArucasList(); - Interpreter interpreter = arguments.getInterpreter(); - list.add(interpreter.create(NumberDef.class, (double) shape.getRed())); - list.add(interpreter.create(NumberDef.class, (double) shape.getGreen())); - list.add(interpreter.create(NumberDef.class, (double) shape.getBlue())); - return list; - } - - @FunctionDoc( - name = "getRGBAList", - desc = "This returns the RGBA value of the shape as a list", - returns = @ReturnDoc(type = ListDef.class, desc = "the RGBA value of the shape as a list in the form [red, green, blue, opacity]"), - examples = "r, g, b, a = shape.getRGBAList();" - ) - private ArucasList getRGBAList(Arguments arguments) { // Checkstyle ignore - ScriptShape shape = arguments.nextPrimitive(this); - ArucasList list = new ArucasList(); - Interpreter interpreter = arguments.getInterpreter(); - list.add(interpreter.create(NumberDef.class, (double) shape.getRed())); - list.add(interpreter.create(NumberDef.class, (double) shape.getGreen())); - list.add(interpreter.create(NumberDef.class, (double) shape.getBlue())); - list.add(interpreter.create(NumberDef.class, (double) shape.getAlpha())); - return list; - } - - @FunctionDoc( - name = "shouldRenderThroughBlocks", - desc = "This returns whether the shape should render through blocks", - returns = @ReturnDoc(type = BooleanDef.class, desc = "whether the shape should render through blocks"), - examples = "shape.shouldRenderThroughBlocks();" - ) - private boolean shouldRenderThroughBlocks(Arguments arguments) { - return arguments.nextPrimitive(this).shouldIgnoreDepth(); - } - - @FunctionDoc( - name = "render", - desc = { - "This sets the shape to be rendered indefinitely, the shape will only stop rendering when", - "the script ends or when you call the stopRendering() method" - }, - examples = "shape.render();" - ) - private Void render(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - shape.render(true); - return null; - } - - @FunctionDoc( - name = "stopRendering", - desc = "This stops the shape from rendering", - examples = "shape.stopRendering();" - ) - private Void stopRendering(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - shape.render(false); - return null; - } - - @FunctionDoc( - name = "setScale", - desc = "This sets the scale of the shape", - params = { - @ParameterDoc(type = NumberDef.class, name = "xScale", desc = "the x scale of the shape"), - @ParameterDoc(type = NumberDef.class, name = "yScale", desc = "the y scale of the shape"), - @ParameterDoc(type = NumberDef.class, name = "zScale", desc = "the z scale of the shape") - }, - examples = "shape.setScale(1.5, 2.5, 3.5);" - ) - private Void setScale(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - float xScale = arguments.nextPrimitive(NumberDef.class).floatValue(); - float yScale = arguments.nextPrimitive(NumberDef.class).floatValue(); - float zScale = arguments.nextPrimitive(NumberDef.class).floatValue(); - shape.setXScale(xScale); - shape.setYScale(yScale); - shape.setZScale(zScale); - return null; - } - - @FunctionDoc( - name = "setXScale", - desc = "This sets the x scale of the shape", - params = {@ParameterDoc(type = NumberDef.class, name = "xScale", desc = "the x scale of the shape")}, - examples = "shape.setXScale(1.5);" - ) - private Void setXScale(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - float xScale = arguments.nextPrimitive(NumberDef.class).floatValue(); - shape.setXScale(xScale); - return null; - } - - @FunctionDoc( - name = "setYScale", - desc = "This sets the y scale of the shape", - params = {@ParameterDoc(type = NumberDef.class, name = "yScale", desc = "the y scale of the shape")}, - examples = "shape.setYScale(2.5);" - ) - private Void setYScale(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - float yScale = arguments.nextPrimitive(NumberDef.class).floatValue(); - shape.setYScale(yScale); - return null; - } - - @FunctionDoc( - name = "setZScale", - desc = "This sets the z scale of the shape", - params = {@ParameterDoc(type = NumberDef.class, name = "zScale", desc = "the z scale of the shape")}, - examples = "shape.setZScale(3.5);" - ) - private Void setZScale(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - float zScale = arguments.nextPrimitive(NumberDef.class).floatValue(); - shape.setZScale(zScale); - return null; - } - - @FunctionDoc( - name = "getXScale", - desc = "This gets the x scale of the shape", - examples = "shape.getXScale();" - ) - private float getXScale(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - return shape.getXScale(); - } - - @FunctionDoc( - name = "getYScale", - desc = "This gets the y scale of the shape", - examples = "shape.getYScale();" - ) - private float getYScale(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - return shape.getYScale(); - } - - @FunctionDoc( - name = "getZScale", - desc = "This gets the z scale of the shape", - examples = "shape.getZScale();" - ) - private float getZScale(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - return shape.getZScale(); - } - - @FunctionDoc( - name = "setTilt", - desc = "This sets the tilt of the shape", - params = { - @ParameterDoc(type = NumberDef.class, name = "xTilt", desc = "the x tilt"), - @ParameterDoc(type = NumberDef.class, name = "yTilt", desc = "the y tilt"), - @ParameterDoc(type = NumberDef.class, name = "zTilt", desc = "the z tilt") - }, - examples = "shape.setTilt(100, 0, 80);" - ) - private Void setTilt(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - float xTilt = arguments.nextPrimitive(NumberDef.class).floatValue(); - float yTilt = arguments.nextPrimitive(NumberDef.class).floatValue(); - float zTilt = arguments.nextPrimitive(NumberDef.class).floatValue(); - shape.setXTilt(xTilt); - shape.setYTilt(yTilt); - shape.setZTilt(zTilt); - return null; - } - - @FunctionDoc( - name = "setXTilt", - desc = "This sets the x tilt of the shape", - params = {@ParameterDoc(type = NumberDef.class, name = "xTilt", desc = "the x tilt")}, - examples = "shape.setXTilt(100);" - ) - private Void setXTilt(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - float xTilt = arguments.nextPrimitive(NumberDef.class).floatValue(); - shape.setXTilt(xTilt); - return null; - } - - @FunctionDoc( - name = "setYTilt", - desc = "This sets the y tilt of the shape", - params = {@ParameterDoc(type = NumberDef.class, name = "yTilt", desc = "the y tilt")}, - examples = "shape.setYTilt(0);" - ) - private Void setYTilt(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - float yTilt = arguments.nextPrimitive(NumberDef.class).floatValue(); - shape.setYTilt(yTilt); - return null; - } - - @FunctionDoc( - name = "setZTilt", - desc = "This sets the z tilt of the shape", - params = {@ParameterDoc(type = NumberDef.class, name = "zTilt", desc = "the z tilt")}, - examples = "shape.setZTilt(80);" - ) - private Void setZTilt(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - float zTilt = arguments.nextPrimitive(NumberDef.class).floatValue(); - shape.setZTilt(zTilt); - return null; - } - - @FunctionDoc( - name = "getXTilt", - desc = "This gets the x tilt of the shape", - examples = "shape.getXTilt();" - ) - private float getXTilt(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - return shape.getXTilt(); - } - - @FunctionDoc( - name = "getYTilt", - desc = "This gets the y tilt of the shape", - examples = "shape.getYTilt();" - ) - private float getYTilt(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - return shape.getYTilt(); - } - - @FunctionDoc( - name = "getZTilt", - desc = "This gets the z tilt of the shape", - examples = "shape.getZTilt();" - ) - private float getZTilt(Arguments arguments) { - ScriptShape shape = arguments.nextPrimitive(this); - return shape.getZTilt(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/SphereShapeDef.java b/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/SphereShapeDef.java deleted file mode 100644 index 4b4fa3b7..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/definitions/shapes/SphereShapeDef.java +++ /dev/null @@ -1,108 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.definitions.shapes; - -import kotlin.Unit; -import me.senseiwells.arucas.api.docs.annotations.*; -import me.senseiwells.arucas.builtin.NumberDef; -import me.senseiwells.arucas.classes.CreatableDefinition; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.ConstructorFunction; -import me.senseiwells.arucas.functions.builtin.MemberFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.misc.Language; -import me.senseiwells.essentialclient.clientscript.definitions.PosDef; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptPos; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptSphere; -import net.minecraft.util.math.Vec3d; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.SPHERE_SHAPE; - -@ClassDoc( - name = SPHERE_SHAPE, - desc = "This class is used to create a sphere shape which can be rendered in the world.", - superclass = CentredShapeDef.class, - language = Language.Java -) -public class SphereShapeDef extends CreatableDefinition { - public SphereShapeDef(Interpreter interpreter) { - super(SPHERE_SHAPE, interpreter); - } - - @NotNull - @Override - public PrimitiveDefinition superclass() { - return this.getPrimitiveDef(CentredShapeDef.class); - } - - @Override - public List defineConstructors() { - return List.of( - ConstructorFunction.of(1, this::construct1), - ConstructorFunction.of(3, this::construct3) - ); - } - - @ConstructorDoc( - desc = "This creates a new sphere shape", - params = {@ParameterDoc(type = PosDef.class, name = "pos", desc = "The position of the sphere")}, - examples = "new SphereShape(new Pos(0, 10, 0));" - ) - private Unit construct1(Arguments arguments) { - ClassInstance instance = arguments.next(); - ScriptPos pos = arguments.nextPrimitive(PosDef.class); - instance.setPrimitive(this, new ScriptSphere(arguments.getInterpreter(), pos.getVec3d())); - return null; - } - - @ConstructorDoc( - desc = "This creates a new sphere shape", - params = { - @ParameterDoc(type = NumberDef.class, name = "x", desc = "The x position of the sphere"), - @ParameterDoc(type = NumberDef.class, name = "y", desc = "The y position of the sphere"), - @ParameterDoc(type = NumberDef.class, name = "z", desc = "The z position of the sphere") - }, - examples = "new SphereShape(0, 10, 0);" - ) - private Unit construct3(Arguments arguments) { - ClassInstance instance = arguments.next(); - double x = arguments.nextPrimitive(NumberDef.class); - double y = arguments.nextPrimitive(NumberDef.class); - double z = arguments.nextPrimitive(NumberDef.class); - instance.setPrimitive(this, new ScriptSphere(arguments.getInterpreter(), new Vec3d(x, y, z))); - return null; - } - - @Override - public List defineMethods() { - return List.of( - MemberFunction.of("setSteps", 1, this::setSteps), - MemberFunction.of("getSteps", this::getSteps) - ); - } - - @FunctionDoc( - name = "setSteps", - desc = "This sets the number of steps the sphere will take to render", - params = {@ParameterDoc(type = NumberDef.class, name = "steps", desc = "The number of steps")}, - examples = "sphere.setSteps(30);" - ) - private Void setSteps(Arguments arguments) { - ScriptSphere sphere = arguments.nextPrimitive(this); - sphere.setSteps(arguments.nextPrimitive(NumberDef.class).floatValue()); - return null; - } - - @FunctionDoc( - name = "getSteps", - desc = "This gets the number of steps the sphere will take to render", - returns = @ReturnDoc(type = NumberDef.class, desc = "The number of steps"), - examples = "sphere.getSteps();" - ) - private float getSteps(Arguments arguments) { - return arguments.nextPrimitive(this).getSteps(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/events/CancelEvent.java b/src/main/java/me/senseiwells/essentialclient/clientscript/events/CancelEvent.java deleted file mode 100644 index 2be2d5cb..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/events/CancelEvent.java +++ /dev/null @@ -1,11 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.events; - -import me.senseiwells.arucas.exceptions.Propagator; - -public class CancelEvent extends Propagator { - public static final CancelEvent INSTANCE = new CancelEvent(); - - private CancelEvent() { - super("Cannot cancel event outside of a cancellable event"); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/events/MinecraftScriptEvent.java b/src/main/java/me/senseiwells/essentialclient/clientscript/events/MinecraftScriptEvent.java deleted file mode 100644 index 5514641d..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/events/MinecraftScriptEvent.java +++ /dev/null @@ -1,186 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.events; - -import me.senseiwells.arucas.builtin.ListDef; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.impl.ArucasList; -import me.senseiwells.essentialclient.clientscript.core.ClientScript; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptEvent; -import me.senseiwells.essentialclient.utils.clientscript.impl.WaitingEvent; - -import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Future; -import java.util.function.Function; - -public class MinecraftScriptEvent { - private final String name; - private final String description; - private final String[] parameters; - private final boolean isCancellable; - - protected final Map> REGISTERED_EVENTS = new HashMap<>(); - protected final Map> WAITING_EVENTS = new HashMap<>(); - - public MinecraftScriptEvent(String eventName, String description, String[] parameters, boolean isCancellable) { - this.name = eventName; - this.description = description; - this.parameters = parameters; - this.isCancellable = isCancellable; - MinecraftScriptEvents.addEventToMap(eventName, this); - } - - public MinecraftScriptEvent(String eventName, String description, String... parameters) { - this(eventName, description, parameters, false); - } - - public String getName() { - return this.name; - } - - public String getDescription() { - return this.description; - } - - public String[] getParameters() { - return this.parameters; - } - - public boolean canCancel() { - return this.isCancellable; - } - - public boolean isThreadDefinable() { - return true; - } - - public synchronized void registerEvent(ScriptEvent gameEvent) { - if (gameEvent.getInterpreter().isRunning()) { - Set gameEventWrappers = this.REGISTERED_EVENTS.computeIfAbsent(gameEvent.getId(), id -> { - // Possible leak? - gameEvent.getInterpreter().addStopEvent(() -> this.REGISTERED_EVENTS.remove(id)); - return new LinkedHashSet<>(); - }); - gameEventWrappers.add(gameEvent); - } - } - - public synchronized boolean unregisterEvent(ScriptEvent gameEvent) { - Set gameEventWrappers = this.REGISTERED_EVENTS.get(gameEvent.getId()); - return gameEventWrappers != null && gameEventWrappers.remove(gameEvent); - } - - public synchronized boolean isEventRegistered(ScriptEvent gameEvent) { - Set gameEventWrappers = this.REGISTERED_EVENTS.get(gameEvent.getId()); - return gameEventWrappers != null && gameEventWrappers.contains(gameEvent); - } - - public synchronized void clearRegisteredEvents(UUID uuid) { - Set gameEventWrappers = this.REGISTERED_EVENTS.get(uuid); - if (gameEventWrappers != null) { - gameEventWrappers.clear(); - } - } - - public synchronized Future registerWaitingEvent(Interpreter interpreter) { - CompletableFuture future = new CompletableFuture<>(); - Set futures = this.WAITING_EVENTS.computeIfAbsent(interpreter.getProperties().getId(), id -> { - interpreter.addStopEvent(() -> this.WAITING_EVENTS.remove(id)); - return new LinkedHashSet<>(); - }); - futures.add(new WaitingEvent(interpreter, future)); - return future; - } - - public synchronized boolean run(Object... args) { - return this.run(interpreter -> { - List eventArgs = new ArrayList<>(); - for (Object arg : args) { - eventArgs.add(interpreter.convertValue(arg)); - } - return eventArgs; - }); - } - - public synchronized boolean run(Function> argumentSupplier) { - boolean shouldCancel = false; - for (Set gameEventWrappers : this.REGISTERED_EVENTS.values()) { - List eventArguments = null; - for (ScriptEvent gameEvent : gameEventWrappers) { - if (eventArguments == null) { - eventArguments = argumentSupplier.apply(gameEvent.getInterpreter()); - } - if (gameEvent.invoke(eventArguments)) { - shouldCancel = true; - } - } - } - for (Set events : this.WAITING_EVENTS.values()) { - List eventArguments = null; - for (WaitingEvent event : events) { - if (eventArguments == null) { - eventArguments = argumentSupplier.apply(event.interpreter()); - } - event.future().complete(event.interpreter().create(ListDef.class, new ArucasList(eventArguments))); - } - } - this.WAITING_EVENTS.clear(); - if (shouldCancel && ClientRules.CLIENTSCRIPT_DEBUGGER.getValue()) { - ClientScript.LOGGER.info("Event '{}' was cancelled", this.name); - } - return shouldCancel; - } - - @Override - public String toString() { - return this.name; - } - - /** - * This type of Event only gets called on a certain - * scripting instance, for example when a script stops - * the event only gets triggered for the script that - * is currently stopping, not any others running concurrently - */ - public static class Unique extends MinecraftScriptEvent { - private final boolean isThreadDefinable; - - public Unique(String name, String description, String[] parameters, boolean isThreadDefinable) { - super(name, description, parameters); - this.isThreadDefinable = isThreadDefinable; - } - - public Unique(String name, String description, String... parameters) { - this(name, description, parameters, false); - } - - @Override - public boolean isThreadDefinable() { - return this.isThreadDefinable; - } - - public synchronized boolean run(UUID uuid, ClassInstance... arguments) { - boolean shouldCancel = false; - Set gameEventWrappers = this.REGISTERED_EVENTS.get(uuid); - if (gameEventWrappers == null) { - return false; - } - for (ScriptEvent gameEvent : gameEventWrappers) { - if (gameEvent.invoke(Arrays.asList(arguments))) { - shouldCancel = true; - } - } - if (shouldCancel && ClientRules.CLIENTSCRIPT_DEBUGGER.getValue()) { - ClientScript.LOGGER.info("Event '{}' was cancelled", this.getName()); - } - return shouldCancel; - } - - @Deprecated - @Override - public synchronized boolean run(Object... arguments) { - return false; - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/events/MinecraftScriptEvents.java b/src/main/java/me/senseiwells/essentialclient/clientscript/events/MinecraftScriptEvents.java deleted file mode 100644 index 08af6189..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/events/MinecraftScriptEvents.java +++ /dev/null @@ -1,90 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.events; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; -import java.util.function.Consumer; - -import static me.senseiwells.arucas.utils.misc.Types.*; -import static me.senseiwells.essentialclient.clientscript.core.MinecraftAPI.*; - -public class MinecraftScriptEvents { - private static final Map EVENT_MAP = new HashMap<>(); - - public static final MinecraftScriptEvent - ON_CLIENT_TICK = register("onClientTick", "The event is fired on every client tick"), - ON_HEALTH_UPDATE = register("onHealthUpdate", "This event is fired when the player's health changes", NUMBER, "health", "the new health"), - ON_BLOCK_UPDATE = register("onBlockUpdate", "This event is fired when a block update is recieved on the client", BLOCK, "block", "the block that was updated"), - ON_TOTEM = register("onTotem", "This event is fired when the player uses a totem"), - ON_CLOSE_SCREEN = register("onCloseScreen", "This event is fired when the player closes a screen", SCREEN, "screen", "the screen that was just closed"), - ON_CONNECT = register("onConnect", "The event is fired when the player connects to a server", PLAYER, "player", "the player entity", WORLD, "world", "the world the player joined"), - ON_DISCONNECT = register("onDisconnect", "This event is fired when the player disconnects from a server"), - ON_OPEN_SCREEN = register("onOpenScreen", "This event is fired when the player opens a screen", SCREEN, "screen", "the screen that was just opened"), - ON_PICK_UP_ITEM = register("onPickUpItem", "This event is fired when the player picks up an item", ITEM_STACK, "itemStack", "the item"), - ON_ANVIL = register("onAnvil", "This event is fired when the player anvils an item", ITEM_STACK, "first", "the first input", ITEM_STACK, "second", "the second input", ITEM_STACK, "result", "the result of the first and second input", STRING, "newName", "the new name of the item stack", NUMBER, "levelCost", "the amount of xp required"), - ON_FISH_BITE = register("onFishBite", "This event is fired when a fish bites the player's fishing rod", ENTITY, "entity", "the fishing bobber entity"), - ON_DEATH = register("onDeath", "This event is fired when the player dies", ENTITY, "entity", "the entity that killed the player, may be null", TEXT, "message", "the death message"), - ON_RESPAWN = register("onRespawn", "This event is fired when the player respawns", PLAYER, "player", "the respawned player entity"), - ON_EAT = register("onEat", "This event is fired when the player eats something", ITEM_STACK, "food", "the item stack that was eaten"), - ON_GAMEMODE_CHANGE = register("onGamemodeChange", "This event is fired when the player changes their gamemode", STRING, "gamemode", "the new gamemode"), - ON_BLOCK_BROKEN = register("onBlockBroken", "This event is fired when the player breaks a new block", BLOCK, "block", "the block that was broken"), - ON_BLOCK_PLACED = register("onBlockPlaced", "This event is fired when the player places a block", BLOCK, "block", "the block that was placed"), - ON_DIMENSION_CHANGE = register("onDimensionChange", "This event is fired when the player changes their dimension", WORLD, "world", "the new world"), - ON_PLAYER_JOIN = register("onPlayerJoin", "This event is fired when a player joins the server", STRING, "name", "the player's name", STRING, "uuid", "the player's uuid"), - ON_PLAYER_LEAVE = register("onPlayerLeave", "This event is fired when a player leaves the server", STRING, "name", "the player's name", STRING, "uuid", "the player's uuid"), - ON_ENTITY_SPAWN = register("onEntitySpawn", "This event is fired when an entity spawns, this doesn't include mobs", ENTITY, "entity", "the entity that was spawned"), - ON_MOB_SPAWN = register("onMobSpawn", "This event is fired when a mob spawns", LIVING_ENTITY, "mob", "the mob that was spawned"), - ON_ENTITY_REMOVED = register("onEntityRemoved", "This event is fired when an entity is removed", ENTITY, "entity", "the entity that was removed"), - ON_SCRIPT_PACKET = register("onScriptPacket", "This event is fired when a script packet is received from scarpet on the server", LIST, "packet", "a list of data that was received"), - ON_PLAYER_LOOK = registerCancellable("onPlayerLook", "This event is fired when the player changes their yaw and/or pitch", NUMBER, "yaw", "the player's yaw", NUMBER, "pitch", "the player's pitch"), - ON_PICK_BLOCK = registerCancellable("onPickBlock", "This event is fired when the player picks a block with middle mouse", ITEM_STACK, "itemStack", "the item stack that was picked"), - ON_ATTACK = registerCancellable("onAttack", "This event is fired when the player attacks"), - ON_USE = registerCancellable("onUse", "This event is fired when the player uses"), - ON_MOUSE_SCROLL = registerCancellable("onMouseScroll", "This event is fired when the player scrolls", NUMBER, "direction", "either -1 or 1 depending on the scroll direction"), - ON_KEY_PRESS = registerCancellable("onKeyPress", "This event is fired when a key is pressed", STRING, "key", "the key that was pressed"), - ON_KEY_RELEASE = registerCancellable("onKeyRelease", "This event is fired when a key is released", STRING, "key", "the key that was released"), - ON_DROP_ITEM = registerCancellable("onDropItem", "This event is fired when the player tries to drop an item", ITEM_STACK, "itemStack", "the item that is trying to be dropped"), - ON_INTERACT_ITEM = registerCancellable("onInteractItem", "This event is fired when the player interacts with an item", ITEM_STACK, "itemStack", "the item stack that was interacted with"), - ON_INTERACT_BLOCK = registerCancellable("onInteractBlock", "This event is fired when the player interacts with a block", BLOCK, "block", "the block the player is interacting with", ITEM_STACK, "itemStack", "the item stack that was interacted with"), - ON_INTERACT_ENTITY = registerCancellable("onInteractEntity", "This event is fired when the player interacts with an entity", ENTITY, "entity", "the entity that was interacted with", ITEM_STACK, "itemStack", "the item stack that was interacted with"), - ON_SEND_MESSAGE = registerCancellable("onSendMessage", "This event is fired when the player sends a message in chat", STRING, "message", "the message that was sent"), - ON_RECEIVE_MESSAGE = registerCancellable("onReceiveMessage", "This event is fired when the player receives a message in chat", STRING, "uuid", "the sender's UUID", STRING, "message", "the message that was received", STRING, "type", "the type of message that was received; 'chat', 'say_command', 'msg_command_incoming', 'msg_command_outgoing', 'team_msg_command_incoming', 'team_msg_command_outgoing', and 'emote_command'"), - ON_CLICK_SLOT = registerCancellable("onClickSlot", "This event is fired when the player clicks on a slot in their inventory", NUMBER, "slot", "the slot number that was clicked", STRING, "action", "ths action that was used"), - ON_CLICK_RECIPE = registerCancellable("onClickRecipe", "This event is fired when the player clicks on a recipe in the recipe book", RECIPE, "recipe", "the recipe that was clicked"), - ON_ATTACK_BLOCK = registerCancellable("onAttackBlock", "This event is fired when the player attacks a block", BLOCK, "block", "the block that was attacked"), - ON_ATTACK_ENTITY = registerCancellable("onAttackEntity", "This event is fired when the player attacks an entity", ENTITY, "entity", "the entity that was attacked"), - ON_CLICK_TRADE = register("onClickTrade", "This event is fired when trade is clicked", NUMBER, "index", "the trade index that was clicked"), - ON_CLICK_STONECUTTER_RECIPE = register("onClickStonecutterRecipe", "This event is fired when the player clicks on a recipe in the stonecutter", RECIPE, "recipe", "the recipe that was clicked"); - - public static final MinecraftScriptEvent.Unique - ON_SCRIPT_END = registerUnique("onScriptEnd", "This event is fired when the script is ends"); - - protected static void addEventToMap(String name, MinecraftScriptEvent minecraftScriptEvent) { - EVENT_MAP.put(name.toLowerCase(), minecraftScriptEvent); - } - - public static MinecraftScriptEvent getEvent(String name) { - return EVENT_MAP.get(name.toLowerCase()); - } - - public static void clearEventFunctions(UUID id) { - forEachEvent(e -> e.clearRegisteredEvents(id)); - } - - public static void forEachEvent(Consumer consumer) { - EVENT_MAP.values().forEach(consumer); - } - - private static MinecraftScriptEvent register(String name, String description, String... parameters) { - return new MinecraftScriptEvent(name, description, parameters); - } - - private static MinecraftScriptEvent registerCancellable(String name, String description, String... parameters) { - return new MinecraftScriptEvent(name, description, parameters, true); - } - - @SuppressWarnings("SameParameterValue") - private static MinecraftScriptEvent.Unique registerUnique(String name, String description, String... parameters) { - return new MinecraftScriptEvent.Unique(name, description, parameters); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/clientscript/extensions/ArucasMinecraftExtension.java b/src/main/java/me/senseiwells/essentialclient/clientscript/extensions/ArucasMinecraftExtension.java deleted file mode 100644 index ee1d1baf..00000000 --- a/src/main/java/me/senseiwells/essentialclient/clientscript/extensions/ArucasMinecraftExtension.java +++ /dev/null @@ -1,47 +0,0 @@ -package me.senseiwells.essentialclient.clientscript.extensions; - -import me.senseiwells.arucas.api.ArucasExtension; -import me.senseiwells.arucas.api.docs.annotations.ExtensionDoc; -import me.senseiwells.arucas.api.docs.annotations.FunctionDoc; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.functions.builtin.Arguments; -import me.senseiwells.arucas.functions.builtin.BuiltInFunction; -import me.senseiwells.arucas.utils.impl.ArucasThread; -import me.senseiwells.arucas.utils.misc.Language; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -@ExtensionDoc( - name = "MinecraftExtension", - desc = "Extension that provides simple functions related to Minecraft.", - language = Language.Java -) -public class ArucasMinecraftExtension implements ArucasExtension { - @NotNull - @Override - public String getName() { - return "MinecraftExtension"; - } - - @Override - public List getBuiltInFunctions() { - return List.of( - BuiltInFunction.of("hold", this::hold) - ); - } - - @FunctionDoc( - name = "hold", - desc = "This freezes the current thread and halts execution, same functionality as 'Thread.freeze()'", - examples = "hold();" - ) - private Void hold(Arguments arguments) { - Thread thread = Thread.currentThread(); - if (thread instanceof ArucasThread arucasThread) { - arucasThread.freeze(); - return null; - } - throw new RuntimeError("Thread is not safe to freeze"); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/commands/AlternateDimensionCommand.java b/src/main/java/me/senseiwells/essentialclient/commands/AlternateDimensionCommand.java deleted file mode 100644 index a202470b..00000000 --- a/src/main/java/me/senseiwells/essentialclient/commands/AlternateDimensionCommand.java +++ /dev/null @@ -1,90 +0,0 @@ -package me.senseiwells.essentialclient.commands; - -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.command.CommandHelper; -import me.senseiwells.essentialclient.utils.render.Texts; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.text.ClickEvent; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.world.World; - -import static net.minecraft.server.command.CommandManager.literal; - -public class AlternateDimensionCommand { - public static void register(CommandDispatcher dispatcher) { - if (!ClientRules.COMMAND_ALTERNATE_DIMENSION.getValue()) { - return; - } - - CommandHelper.CLIENT_COMMANDS.add("alternatedimension"); - - LiteralArgumentBuilder commandBuilder = literal("alternatedimension"); - commandBuilder.executes(context -> { - ClientPlayerEntity playerEntity = EssentialUtils.getPlayer(); - String dimension; - double newX; - double newZ; - if (playerEntity.getEntityWorld().getRegistryKey() == World.OVERWORLD) { - dimension = "the_nether"; - newX = playerEntity.getX() / 8; - newZ = playerEntity.getZ() / 8; - } else if (playerEntity.getEntityWorld().getRegistryKey() == World.NETHER) { - dimension = "overworld"; - newX = playerEntity.getX() * 8; - newZ = playerEntity.getZ() * 8; - } else { - throw new SimpleCommandExceptionType(Texts.INVALID_DIMENSION).create(); - } - MutableText message = Texts.COORDINATES.generate(dimension).formatted(Formatting.GREEN); - MutableText clickable = Text.literal(" [%s, %s, %s]".formatted( - CommandHelper.DECIMAL_FORMAT.format(newX), - CommandHelper.DECIMAL_FORMAT.format(playerEntity.getY()), - CommandHelper.DECIMAL_FORMAT.format(newZ) - )).styled(style -> style.withClickEvent(new ClickEvent( - ClickEvent.Action.RUN_COMMAND, - "/execute in %s run tp @s %f %f %f".formatted(dimension, newX, playerEntity.getY(), newZ) - ))).formatted(Formatting.GOLD, Formatting.BOLD); - EssentialUtils.sendMessage(message.append(clickable)); - return 1; - }); - - ClientPlayerEntity player = EssentialUtils.getPlayer(); - if (player != null && player.hasPermissionLevel(2)) { - commandBuilder.then(literal("teleport") - .executes(context -> { - ClientPlayerEntity playerEntity = EssentialUtils.getPlayer(); - String dimension; - double newX; - double newZ; - if (playerEntity.getEntityWorld().getRegistryKey() == World.OVERWORLD) { - dimension = "the_nether"; - newX = playerEntity.getX() / 8; - newZ = playerEntity.getZ() / 8; - } else if (playerEntity.getEntityWorld().getRegistryKey() == World.NETHER) { - dimension = "overworld"; - newX = playerEntity.getX() * 8; - newZ = playerEntity.getZ() * 8; - } else { - throw new SimpleCommandExceptionType(Texts.INVALID_DIMENSION).create(); - } - EssentialUtils.sendChatMessage("/execute in %s run tp @s %f %f %f".formatted( - dimension, - newX, - playerEntity.getY(), - newZ - )); - return 1; - }) - ); - } - - dispatcher.register(commandBuilder); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/commands/ClientNickCommand.java b/src/main/java/me/senseiwells/essentialclient/commands/ClientNickCommand.java deleted file mode 100644 index db70987b..00000000 --- a/src/main/java/me/senseiwells/essentialclient/commands/ClientNickCommand.java +++ /dev/null @@ -1,73 +0,0 @@ -package me.senseiwells.essentialclient.commands; - -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.arguments.StringArgumentType; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.command.CommandHelper; -import me.senseiwells.essentialclient.utils.config.ConfigClientNick; -import me.senseiwells.essentialclient.utils.render.Texts; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.util.Formatting; - -import static net.minecraft.server.command.CommandManager.argument; -import static net.minecraft.server.command.CommandManager.literal; - -public class ClientNickCommand { - public static void register(CommandDispatcher dispatcher) { - - if (!ClientRules.COMMAND_CLIENT_NICK.getValue()) { - return; - } - - CommandHelper.CLIENT_COMMANDS.add("clientnick"); - - dispatcher.register(literal("clientnick") - .then(literal("set") - .then(argument("playername1", StringArgumentType.string()) - .suggests((context, builder) -> CommandHelper.suggestOnlinePlayers(builder)) - .then(argument("playername2", StringArgumentType.greedyString()) - .executes(context -> { - String playerName1 = context.getArgument("playername1", String.class); - String playerName2 = context.getArgument("playername2", String.class); - playerName2 = playerName2.replaceAll("&", "§") + "§r"; - ConfigClientNick.INSTANCE.set(playerName1, playerName2); - EssentialUtils.sendMessage(Texts.NEW_DISPLAY.generate(playerName1, playerName2).formatted(Formatting.GREEN)); - return 0; - }) - ) - ) - ) - .then(literal("delete") - .then(argument("playername", StringArgumentType.string()) - .suggests((context, builder) -> ConfigClientNick.INSTANCE.suggestPlayerRename(builder)) - .executes(context -> { - String playerName = context.getArgument("playername", String.class); - String name = ConfigClientNick.INSTANCE.remove(playerName); - if (name == null) { - EssentialUtils.sendMessage(Texts.NOT_RENAMED.generate(playerName).formatted(Formatting.RED)); - } else { - EssentialUtils.sendMessage(Texts.NO_LONGER_RENAMED.generate(playerName).formatted(Formatting.GOLD)); - } - return 0; - }) - ) - ) - .then(literal("get") - .then(argument("playername", StringArgumentType.string()) - .suggests((context, builder) -> ConfigClientNick.INSTANCE.suggestPlayerRename(builder)) - .executes(context -> { - String playerName = context.getArgument("playername", String.class); - String name = ConfigClientNick.INSTANCE.get(playerName); - if (name == null) { - EssentialUtils.sendMessage(Texts.IS_NOT_RENAMED.generate(playerName).formatted(Formatting.RED)); - } else { - EssentialUtils.sendMessage(Texts.IS_RENAMED_TO.generate(playerName, name).formatted(Formatting.GOLD)); - } - return 0; - }) - ) - ) - ); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/commands/ClientScriptCommand.java b/src/main/java/me/senseiwells/essentialclient/commands/ClientScriptCommand.java deleted file mode 100644 index ed35989b..00000000 --- a/src/main/java/me/senseiwells/essentialclient/commands/ClientScriptCommand.java +++ /dev/null @@ -1,127 +0,0 @@ -package me.senseiwells.essentialclient.commands; - -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.arguments.BoolArgumentType; -import com.mojang.brigadier.arguments.StringArgumentType; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; -import me.senseiwells.essentialclient.clientscript.core.ClientScript; -import me.senseiwells.essentialclient.clientscript.core.ClientScriptInstance; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.ScriptRepositoryManager; -import me.senseiwells.essentialclient.utils.command.CommandHelper; -import me.senseiwells.essentialclient.utils.command.EnumArgumentType; -import me.senseiwells.essentialclient.utils.render.Texts; -import net.minecraft.command.CommandSource; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.util.Formatting; - -import static me.senseiwells.essentialclient.utils.clientscript.ScriptRepositoryManager.Category; -import static net.minecraft.server.command.CommandManager.argument; -import static net.minecraft.server.command.CommandManager.literal; - -public class ClientScriptCommand { - private static final DynamicCommandExceptionType NO_SUCH_SCRIPT = new DynamicCommandExceptionType(Texts.NO_SCRIPT::generate); - - public static void register(CommandDispatcher dispatcher) { - CommandHelper.CLIENT_COMMANDS.add("clientscript"); - - LiteralArgumentBuilder - root = literal("clientscript"), - download = literal("download"), - runFromWeb = literal("runfromweb"); - - root.then(literal("run") - .then(argument("scriptName", StringArgumentType.string()) - .suggests((c, b) -> CommandSource.suggestMatching(ClientScript.INSTANCE.getScriptInstanceNames(), b)) - .executes(context -> { - String scriptName = StringArgumentType.getString(context, "scriptName"); - ClientScriptInstance instance = ClientScript.INSTANCE.getScriptInstance(scriptName); - if (instance == null) { - throw NO_SUCH_SCRIPT.create(scriptName); - } - instance.stopScript(); - instance.toggleScript(); - return 1; - }) - .then(argument("script", StringArgumentType.greedyString()) - .executes(context -> { - String scriptName = StringArgumentType.getString(context, "scriptName"); - String scriptContent = StringArgumentType.getString(context, "script"); - ClientScriptInstance.runFromContent(scriptName, scriptContent); - return 1; - }) - ) - ) - ); - - root.then(literal("stopall") - .executes(context -> { - ClientScript.INSTANCE.stopAllInstances(); - return 1; - }) - ); - - download.then(argument("category", EnumArgumentType.enumeration(Category.class)) - .then(argument("scriptname", StringArgumentType.string()) - .suggests(((c, b) -> CommandSource.suggestMatching( - ScriptRepositoryManager.INSTANCE.getChildrenNames(EnumArgumentType.getEnumeration(c, "category", Category.class)), b)) - ) - .executes(context -> { - Category category = EnumArgumentType.getEnumeration(context, "category", Category.class); - String scriptName = StringArgumentType.getString(context, "scriptname"); - if (ScriptRepositoryManager.INSTANCE.downloadScript(category, scriptName, false)) { - throw NO_SUCH_SCRIPT.create(scriptName); - } - EssentialUtils.sendMessage(Texts.DOWNLOAD_SUCCESS.generate(scriptName).formatted(Formatting.GOLD)); - return 1; - }) - .then(argument("shouldoverwrite", BoolArgumentType.bool()) - .executes(context -> { - Category category = EnumArgumentType.getEnumeration(context, "category", Category.class); - String scriptName = StringArgumentType.getString(context, "scriptname"); - boolean shouldOverwrite = BoolArgumentType.getBool(context, "shouldoverwrite"); - if (ScriptRepositoryManager.INSTANCE.downloadScript(category, scriptName, shouldOverwrite)) { - throw NO_SUCH_SCRIPT.create(scriptName); - } - EssentialUtils.sendMessage(Texts.DOWNLOAD_SUCCESS.generate(scriptName).formatted(Formatting.GOLD)); - return 1; - }) - ) - ) - ); - - runFromWeb.then(argument("category", EnumArgumentType.enumeration(Category.class)) - .then(argument("scriptname", StringArgumentType.string()) - .suggests(((c, b) -> CommandSource.suggestMatching( - ScriptRepositoryManager.INSTANCE.getChildrenNames(EnumArgumentType.getEnumeration(c, "category", Category.class)), b)) - ) - .executes(context -> { - Category category = EnumArgumentType.getEnumeration(context, "category", Category.class); - String scriptName = StringArgumentType.getString(context, "scriptname"); - String scriptContent = ScriptRepositoryManager.INSTANCE.getScriptFromWeb(category, scriptName, true); - if (scriptContent == null) { - throw NO_SUCH_SCRIPT.create(scriptName); - } - ClientScriptInstance.runFromContent(scriptName, scriptContent); - return 1; - }) - .then(argument("fromcache", BoolArgumentType.bool()) - .executes(context -> { - Category category = EnumArgumentType.getEnumeration(context, "category", Category.class); - String scriptName = StringArgumentType.getString(context, "scriptname"); - boolean fromCache = BoolArgumentType.getBool(context, "fromcache"); - String scriptContent = ScriptRepositoryManager.INSTANCE.getScriptFromWeb(category, scriptName, fromCache); - if (scriptContent == null) { - throw NO_SUCH_SCRIPT.create(scriptName); - } - ClientScriptInstance.runFromContent(scriptName, scriptContent); - return 1; - }) - ) - ) - ); - - dispatcher.register(root.then(download).then(runFromWeb)); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/commands/CommandRegister.java b/src/main/java/me/senseiwells/essentialclient/commands/CommandRegister.java deleted file mode 100644 index 9a4e2c19..00000000 --- a/src/main/java/me/senseiwells/essentialclient/commands/CommandRegister.java +++ /dev/null @@ -1,28 +0,0 @@ -package me.senseiwells.essentialclient.commands; - -import com.mojang.brigadier.CommandDispatcher; -import me.senseiwells.essentialclient.utils.command.CommandHelper; -import net.minecraft.command.CommandRegistryAccess; -import net.minecraft.server.command.ServerCommandSource; - -public class CommandRegister { - private static CommandRegistryAccess registryAccess; - - public static void registerCommands(CommandDispatcher dispatcher, CommandRegistryAccess access) { - registryAccess = access; - - CommandHelper.clearClientCommands(); - PlayerClientCommand.register(dispatcher); - PlayerListCommand.register(dispatcher); - RegionCommand.register(dispatcher); - ClientNickCommand.register(dispatcher); - UpdateClientCommand.register(dispatcher); - AlternateDimensionCommand.register(dispatcher); - ClientScriptCommand.register(dispatcher); - CommandHelper.registerFunctionCommands(dispatcher); - } - - public static CommandRegistryAccess getRegistryAccess() { - return registryAccess; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/commands/PlayerClientCommand.java b/src/main/java/me/senseiwells/essentialclient/commands/PlayerClientCommand.java deleted file mode 100644 index 744698c2..00000000 --- a/src/main/java/me/senseiwells/essentialclient/commands/PlayerClientCommand.java +++ /dev/null @@ -1,176 +0,0 @@ -package me.senseiwells.essentialclient.commands; - -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.arguments.DoubleArgumentType; -import com.mojang.brigadier.arguments.StringArgumentType; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType; -import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; -import com.mojang.brigadier.tree.LiteralCommandNode; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.command.CommandHelper; -import me.senseiwells.essentialclient.utils.command.EnumArgumentType; -import me.senseiwells.essentialclient.utils.command.PlayerData; -import me.senseiwells.essentialclient.utils.command.WorldEnum; -import me.senseiwells.essentialclient.utils.config.ConfigPlayerClient; -import me.senseiwells.essentialclient.utils.render.Texts; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.command.CommandSource; -import net.minecraft.command.argument.RotationArgumentType; -import net.minecraft.command.argument.Vec3ArgumentType; -import net.minecraft.server.command.CommandManager; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.util.Formatting; -import net.minecraft.util.math.Vec2f; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.GameMode; - -import java.util.List; - -import static net.minecraft.server.command.CommandManager.argument; -import static net.minecraft.server.command.CommandManager.literal; - -public class PlayerClientCommand { - public static final DynamicCommandExceptionType NO_PLAYER = new DynamicCommandExceptionType(Texts.NO_CONFIG::generate); - public static final Dynamic2CommandExceptionType WRONG_GAMEMODE = new Dynamic2CommandExceptionType(Texts.WRONG_GAMEMODE::generate); - - public static void register(CommandDispatcher dispatcher) { - if (!ClientRules.COMMAND_PLAYER_CLIENT.getValue()) { - return; - } - - CommandHelper.CLIENT_COMMANDS.add("playerclient"); - CommandHelper.CLIENT_COMMANDS.add("pc"); - - LiteralCommandNode playerclientNode = CommandManager.literal("playerclient").build(); - LiteralCommandNode pcNode = CommandManager.literal("pc").build(); - - LiteralCommandNode spawnNode = CommandManager.literal("spawn").then(argument("playername", StringArgumentType.word()) - .suggests((context, builder) -> ConfigPlayerClient.INSTANCE.suggestPlayer(builder)) - .executes(context -> spawnPlayer(context, false)) - .then(literal("offset") - .then(argument("x-axis", DoubleArgumentType.doubleArg()) - .suggests((context, builder) -> CommandSource.suggestMatching(List.of("0", "160", "-160", "256", "-256"), builder)) - .then(argument("y-axis", DoubleArgumentType.doubleArg()) - .suggests((context, builder) -> CommandSource.suggestMatching(List.of("0", "128"), builder)) - .then(argument("z-axis", DoubleArgumentType.doubleArg()) - .suggests((context, builder) -> CommandSource.suggestMatching(List.of("0", "160", "-160", "256", "-256"), builder)) - .executes(context -> spawnPlayer(context, true)) - ) - ) - ) - ) - ).build(); - - LiteralCommandNode addNode = CommandManager.literal("add").then(argument("playername", StringArgumentType.word()) - .suggests((context, builder) -> ConfigPlayerClient.INSTANCE.suggestPlayer(builder)) - .then(literal("spawn") - .then(literal("at") - .then(argument("pos", Vec3ArgumentType.vec3()) - .then(literal("facing") - .then(argument("rotation", RotationArgumentType.rotation()) - .then(literal("in") - .then(argument("dimension", EnumArgumentType.enumeration(WorldEnum.class)) - .executes(context -> constructPlayer(context, false, false)) - .then(literal("in") - .then(argument("gamemode", EnumArgumentType.enumeration(GameMode.class)) - .executes(context -> constructPlayer(context, false, true)) - ) - ) - ) - ) - ) - ) - ) - ) - .then(literal("here") - .executes(context -> constructPlayer(context, true, false)) - .then(literal("in") - .then(argument("gamemode", EnumArgumentType.enumeration(GameMode.class)) - .executes(context -> constructPlayer(context, true, true)) - ) - ) - ) - ) - ).build(); - - LiteralCommandNode removeNode = literal("remove").then(argument("playername", StringArgumentType.word()) - .suggests((context, builder) -> ConfigPlayerClient.INSTANCE.suggestPlayer(builder)) - .executes(context -> { - String playerName = context.getArgument("playername", String.class); - if (ConfigPlayerClient.INSTANCE.remove(playerName) == null) { - throw NO_PLAYER.create(playerName); - } - EssentialUtils.sendMessage(Texts.REMOVED_CONFIG.generate(playerName).formatted(Formatting.GOLD)); - return 0; - }) - ).build(); - - //Stitching commands - dispatcher.getRoot().addChild(playerclientNode); - playerclientNode.addChild(spawnNode); - playerclientNode.addChild(addNode); - playerclientNode.addChild(removeNode); - dispatcher.getRoot().addChild(pcNode); - pcNode.addChild(spawnNode); - pcNode.addChild(addNode); - pcNode.addChild(removeNode); - - //Can't do this because of: https://github.com/Mojang/brigadier/issues/46 - //dispatcher.register(literal("pc").redirect(dispatcher.getRoot().getChild("playerclient").getRedirect())); - } - - @SuppressWarnings("RedundantThrows") - public static int constructPlayer(CommandContext context, boolean isHere, boolean hasGamemode) throws CommandSyntaxException { - ServerCommandSource source = context.getSource(); - if (!(source.getEntity() instanceof ClientPlayerEntity player)) { - return 0; - } - String playerName = context.getArgument("playername", String.class); - Vec3d playerPos = isHere ? source.getPosition() : Vec3ArgumentType.getVec3(context, "pos"); - Vec2f playerRotation = isHere ? source.getRotation() : RotationArgumentType.getRotation(context, "rotation").toAbsoluteRotation(source); - WorldEnum playerWorld = isHere ? WorldEnum.fromRegistryKey(player.getEntityWorld().getRegistryKey()) : EnumArgumentType.getEnumeration(context, "dimension", WorldEnum.class); - GameMode playerGamemode = !hasGamemode ? null : EnumArgumentType.getEnumeration(context, "gamemode", GameMode.class); - PlayerData playerData = new PlayerData(playerPos, playerRotation, playerWorld, playerGamemode); - ConfigPlayerClient.INSTANCE.set(playerName, playerData); - return 1; - } - - public static int spawnPlayer(CommandContext context, boolean hasOffset) throws CommandSyntaxException { - String playerName = context.getArgument("playername", String.class); - PlayerData playerData = ConfigPlayerClient.INSTANCE.get(playerName); - return !hasOffset ? sendCommand(playerName, playerData) : sendCommand( - playerName, - playerData, - context.getArgument("x-axis", Double.class), - context.getArgument("y-axis", Double.class), - context.getArgument("z-axis", Double.class) - ); - } - - public static int sendCommand(String playerName, PlayerData playerData) throws CommandSyntaxException { - return sendCommand(playerName, playerData, 0, 0, 0); - } - - private static int sendCommand(String playerName, PlayerData playerData, double x, double y, double z) throws CommandSyntaxException { - if (playerData == null) { - throw NO_PLAYER.create(playerName); - } - GameMode playerGameMode = EssentialUtils.getInteractionManager().getCurrentGameMode(); - if (playerData.gamemode() != null && playerGameMode != playerData.gamemode()) { - throw WRONG_GAMEMODE.create(playerGameMode, playerData.gamemode()); - } - EssentialUtils.sendChatMessage("/player %s spawn at %s %s %s facing %s %s in %s".formatted( - playerName, - playerData.pos().x + x, - playerData.pos().y + y, - playerData.pos().z + z, - playerData.rotation().y, - playerData.rotation().x, - playerData.world().name().toLowerCase() - )); - return 1; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/commands/PlayerListCommand.java b/src/main/java/me/senseiwells/essentialclient/commands/PlayerListCommand.java deleted file mode 100644 index 12eda021..00000000 --- a/src/main/java/me/senseiwells/essentialclient/commands/PlayerListCommand.java +++ /dev/null @@ -1,135 +0,0 @@ -package me.senseiwells.essentialclient.commands; - -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.arguments.StringArgumentType; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType; -import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; -import com.mojang.brigadier.tree.LiteralCommandNode; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.command.CommandHelper; -import me.senseiwells.essentialclient.utils.command.PlayerData; -import me.senseiwells.essentialclient.utils.config.ConfigPlayerClient; -import me.senseiwells.essentialclient.utils.config.ConfigPlayerList; -import me.senseiwells.essentialclient.utils.render.Texts; -import net.minecraft.command.CommandSource; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.util.Formatting; - -import java.util.ArrayList; -import java.util.List; - -import static net.minecraft.server.command.CommandManager.argument; -import static net.minecraft.server.command.CommandManager.literal; - -public class PlayerListCommand { - public static final DynamicCommandExceptionType EXISTS = new DynamicCommandExceptionType(Texts.LIST_EXISTS::generate); - public static final DynamicCommandExceptionType NOT_EXIST = new DynamicCommandExceptionType(Texts.LIST_NOT_EXISTS::generate); - public static final DynamicCommandExceptionType EMPTY = new DynamicCommandExceptionType(Texts.LIST_EMPTY::generate); - public static final Dynamic2CommandExceptionType HAS_PLAYER = new Dynamic2CommandExceptionType(Texts.LIST_HAS_PLAYER::generate); - - public static void register(CommandDispatcher dispatcher) { - if (!ClientRules.COMMAND_PLAYER_LIST.getValue() || !ClientRules.COMMAND_PLAYER_CLIENT.getValue()) { - return; - } - - CommandHelper.CLIENT_COMMANDS.add("pl"); - CommandHelper.CLIENT_COMMANDS.add("playerlist"); - - LiteralCommandNode playerListNode = literal("playerlist").build(); - LiteralCommandNode plNode = literal("pl").build(); - - LiteralCommandNode createListNode = literal("createlist").then(argument("listname", StringArgumentType.word()) - .suggests((context, builder) -> CommandSource.suggestMatching(List.of("mobswitches", "allplayers"), builder)) - .executes(PlayerListCommand::createList) - ).build(); - - LiteralCommandNode deleteListNode = literal("deletelist").then(argument("listname", StringArgumentType.word()) - .suggests((context, builder) -> ConfigPlayerList.INSTANCE.suggestList(builder)) - .executes(PlayerListCommand::deleteList) - ).build(); - - LiteralCommandNode spawnListNode = literal("spawnlist").then(argument("listname", StringArgumentType.word()) - .suggests((context, builder) -> ConfigPlayerList.INSTANCE.suggestList(builder)) - .executes(PlayerListCommand::spawnFromList) - ).build(); - - LiteralCommandNode playerNode = literal("addplayer").then(argument("listname", StringArgumentType.word()) - .suggests((context, builder) -> ConfigPlayerList.INSTANCE.suggestList(builder)) - .then(argument("playername", StringArgumentType.word()) - .suggests((context, builder) -> ConfigPlayerClient.INSTANCE.suggestPlayer(builder)) - .executes(PlayerListCommand::addToList) - ) - ).build(); - - // Stitching commands - dispatcher.getRoot().addChild(playerListNode); - playerListNode.addChild(createListNode); - playerListNode.addChild(deleteListNode); - playerListNode.addChild(spawnListNode); - playerListNode.addChild(playerNode); - dispatcher.getRoot().addChild(plNode); - plNode.addChild(createListNode); - plNode.addChild(deleteListNode); - plNode.addChild(spawnListNode); - plNode.addChild(playerNode); - } - - public static int createList(CommandContext context) throws CommandSyntaxException { - String listName = context.getArgument("listname", String.class); - List players = ConfigPlayerList.INSTANCE.get(listName); - if (players != null) { - throw EXISTS.create(listName); - } - ConfigPlayerList.INSTANCE.set(listName, new ArrayList<>()); - EssentialUtils.sendMessage(Texts.LIST_CREATED.generate(listName).formatted(Formatting.GREEN)); - return 1; - } - - public static int deleteList(CommandContext context) throws CommandSyntaxException { - String listName = context.getArgument("listname", String.class); - List players = ConfigPlayerList.INSTANCE.remove(listName); - if (players == null) { - throw NOT_EXIST.create(listName); - } - EssentialUtils.sendMessage(Texts.LIST_DELETED.generate(listName).formatted(Formatting.RED)); - return 1; - } - - public static int addToList(CommandContext context) throws CommandSyntaxException { - String listName = context.getArgument("listname", String.class); - List players = ConfigPlayerList.INSTANCE.get(listName); - if (players == null) { - throw NOT_EXIST.create(listName); - } - String playerName = context.getArgument("playername", String.class); - PlayerData playerData = ConfigPlayerClient.INSTANCE.get(playerName); - if (playerData == null) { - throw PlayerClientCommand.NO_PLAYER.create(playerName); - } - if (players.contains(playerName)) { - throw HAS_PLAYER.create(playerName, listName); - } - players.add(playerName); - EssentialUtils.sendMessage(Texts.LIST_PLAYER_ADDED.generate(playerName, listName).formatted(Formatting.GOLD)); - return 1; - } - - public static int spawnFromList(CommandContext context) throws CommandSyntaxException { - String listName = context.getArgument("listname", String.class); - List players = ConfigPlayerList.INSTANCE.get(listName); - if (players == null) { - throw NOT_EXIST.create(listName); - } - if (players.isEmpty()) { - throw EMPTY.create(listName); - } - for (String playerName : players) { - PlayerData playerData = ConfigPlayerClient.INSTANCE.get(playerName); - PlayerClientCommand.sendCommand(playerName, playerData); - } - return 1; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/commands/RegionCommand.java b/src/main/java/me/senseiwells/essentialclient/commands/RegionCommand.java deleted file mode 100644 index 3225cbf0..00000000 --- a/src/main/java/me/senseiwells/essentialclient/commands/RegionCommand.java +++ /dev/null @@ -1,46 +0,0 @@ -package me.senseiwells.essentialclient.commands; - -import com.mojang.brigadier.CommandDispatcher; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.command.CommandHelper; -import me.senseiwells.essentialclient.utils.render.Texts; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.command.argument.Vec2ArgumentType; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.math.Vec2f; - -import static net.minecraft.server.command.CommandManager.argument; -import static net.minecraft.server.command.CommandManager.literal; - -public class RegionCommand { - public static void register(CommandDispatcher dispatcher) { - - if (!ClientRules.COMMAND_REGION.getValue()) { - return; - } - - CommandHelper.CLIENT_COMMANDS.add("region"); - - dispatcher.register(literal("region") - .then(literal("get") - .then(argument("pos", Vec2ArgumentType.vec2()) - .executes(context -> { - Vec2f v = Vec2ArgumentType.getVec2(context, "pos"); - Text coords = Text.literal((int) Math.floor(v.x / 512) + "." + (int) Math.floor(v.y / 512)).formatted(Formatting.GREEN); - EssentialUtils.sendMessage(Texts.DISTANT_REGION.generate(coords).formatted(Formatting.GOLD)); - return 0; - }) - ) - .executes(context -> { - ClientPlayerEntity playerEntity = EssentialUtils.getPlayer(); - Text coords = Text.literal((int) Math.floor(playerEntity.getX() / 512) + "." + (int) Math.floor(playerEntity.getZ() / 512)).formatted(Formatting.GREEN); - EssentialUtils.sendMessage(Texts.CURRENT_REGION.generate(coords).formatted(Formatting.GOLD)); - return 0; - }) - ) - ); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/commands/UpdateClientCommand.java b/src/main/java/me/senseiwells/essentialclient/commands/UpdateClientCommand.java deleted file mode 100644 index 9d12a3b9..00000000 --- a/src/main/java/me/senseiwells/essentialclient/commands/UpdateClientCommand.java +++ /dev/null @@ -1,17 +0,0 @@ -package me.senseiwells.essentialclient.commands; - -import com.mojang.brigadier.CommandDispatcher; -import net.minecraft.server.command.ServerCommandSource; - -public class UpdateClientCommand { - public static void register(CommandDispatcher dispatcher) { - // CommandHelper.CLIENT_COMMANDS.add("updateclient"); - // - // dispatcher.register(literal("updateclient") - // .executes(context -> { - // ClientUpdater.INSTANCE.tryUpdate(); - // return 0; - // }) - // ); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/AFKRules.java b/src/main/java/me/senseiwells/essentialclient/feature/AFKRules.java deleted file mode 100644 index 1d67e0b7..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/AFKRules.java +++ /dev/null @@ -1,60 +0,0 @@ -package me.senseiwells.essentialclient.feature; - -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.render.Texts; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.network.DisconnectionInfo; -import net.minecraft.util.math.Vec3d; - -public class AFKRules { - private static Vec3d prevPlayerLocation; - - private static int ticks = 0; - private static double prevMouseX; - private static double prevMouseY; - private static boolean wasAfk = false; - - static { - ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> { - wasAfk = false; - }); - ClientTickEvents.END_CLIENT_TICK.register(client -> { - ClientPlayerEntity playerEntity = client.player; - int announceAfk = ClientRules.ANNOUNCE_AFK.getValue(); - int logout = ClientRules.AFK_LOGOUT.getValue(); - if (playerEntity == null || (announceAfk < 1 && logout < 200)) { - return; - } - Vec3d playerLocation = playerEntity.getPos(); - double mouseX = client.mouse.getX(); - double mouseY = client.mouse.getX(); - if (playerLocation.equals(prevPlayerLocation) && mouseX == prevMouseX && mouseY == prevMouseY) { - ticks++; - if (ticks == announceAfk) { - EssentialUtils.sendChatMessage(ClientRules.ANNOUNCE_AFK_MESSAGE.getValue()); - wasAfk = true; - } - if (logout >= 200 && ticks == logout) { - playerEntity.networkHandler.onDisconnected(new DisconnectionInfo(Texts.AFK)); - } - return; - } - prevPlayerLocation = playerLocation; - prevMouseX = mouseX; - prevMouseY = mouseY; - ticks = 0; - if (wasAfk) { - String message = ClientRules.ANNOUNCE_BACK_MESSAGE.getValue(); - if (!message.isBlank()) { - EssentialUtils.sendChatMessage(message); - } - wasAfk = false; - } - }); - } - - public static void load() { } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/BetterAccurateBlockPlacement.java b/src/main/java/me/senseiwells/essentialclient/feature/BetterAccurateBlockPlacement.java deleted file mode 100644 index 8a3ad3b9..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/BetterAccurateBlockPlacement.java +++ /dev/null @@ -1,102 +0,0 @@ -package me.senseiwells.essentialclient.feature; - -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.Direction; - -import static me.senseiwells.essentialclient.feature.keybinds.ClientKeyBinds.ACCURATE_INTO; -import static me.senseiwells.essentialclient.feature.keybinds.ClientKeyBinds.ACCURATE_REVERSE; - -public class BetterAccurateBlockPlacement { - public static Direction fakeDirection = null; - public static int requestedTicks = 0; - public static float fakeYaw = 0; - public static float fakePitch = 0; - private static float previousFakeYaw = 0; - private static float previousFakePitch = 0; - public static boolean wasReversePressed = false; - public static boolean wasIntoPressed = false; - - static { - ClientTickEvents.END_CLIENT_TICK.register(BetterAccurateBlockPlacement::accurateBlockPlacementOnPress); - } - - public static void load() { } - - private static void accurateBlockPlacementOnPress(MinecraftClient client) { - ClientPlayerEntity player = client.player; - if (player == null) { - return; - } - if (requestedTicks > 0) { - if (fakeYaw != previousFakeYaw || fakePitch != previousFakePitch) { - sendLookPacket(player); - previousFakeYaw = fakeYaw; - previousFakePitch = fakePitch; - } - requestedTicks--; - return; - } - fakeDirection = null; - - if (ClientRules.BETTER_ACCURATE_BLOCK_PLACEMENT.getValue()) { - fakeYaw = player.getYaw(); - fakePitch = player.getPitch(); - Direction facing = Direction.getEntityFacingOrder(player)[0]; - if (ACCURATE_INTO.isPressed() && client.crosshairTarget instanceof BlockHitResult blockHitResult) { - fakeYaw = 0; - fakePitch = 0; - requestedTicks = 1; - facing = blockHitResult.getSide(); - fakeDirection = facing; - switch (facing) { - case UP -> fakePitch = -90; - case DOWN -> fakePitch = 90; - case EAST -> fakeYaw = -90; - case WEST -> fakeYaw = 90; - case NORTH -> fakeYaw = 180; - case SOUTH -> fakeYaw = 0; - } - if (!wasIntoPressed) { - sendLookPacket(player); - wasIntoPressed = true; - } - } else if (wasIntoPressed) { - requestedTicks = 1; - sendLookPacket(player); - wasIntoPressed = false; - } - if (ACCURATE_REVERSE.isPressed()) { - requestedTicks = 1; - switch (facing) { - case NORTH, SOUTH, EAST, WEST -> fakeYaw = fakeYaw < 0 ? fakeYaw + 180 : fakeYaw - 180; - case UP, DOWN -> fakePitch = fakePitch < 0 ? fakePitch + 180 : fakePitch - 180; - } - if (!wasReversePressed) { - sendLookPacket(player); - wasReversePressed = true; - } - facing = facing.getOpposite(); - } else if (wasReversePressed) { - requestedTicks = 1; - sendLookPacket(player); - wasReversePressed = false; - } - previousFakeYaw = fakeYaw; - previousFakePitch = fakePitch; - // This is for the client, so it doesn't look jank - fakeDirection = facing; - } - } - - public static void sendLookPacket(ClientPlayerEntity player) { - EssentialUtils.getNetworkHandler().sendPacket( - new PlayerMoveC2SPacket.LookAndOnGround(fakeYaw, fakePitch, player.isOnGround()) - ); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/CarpetClient.java b/src/main/java/me/senseiwells/essentialclient/feature/CarpetClient.java deleted file mode 100644 index e08db709..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/CarpetClient.java +++ /dev/null @@ -1,346 +0,0 @@ -package me.senseiwells.essentialclient.feature; - -import carpet.CarpetExtension; -import carpet.api.settings.CarpetRule; -import carpet.api.settings.SettingsManager; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonPrimitive; -import me.senseiwells.arucas.utils.NetworkUtils; -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.gui.RulesScreen; -import me.senseiwells.essentialclient.rule.carpet.*; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.carpet.CarpetUtils; -import me.senseiwells.essentialclient.utils.config.Config; -import me.senseiwells.essentialclient.utils.interfaces.Rule; -import me.senseiwells.essentialclient.utils.misc.Scheduler; -import me.senseiwells.essentialclient.utils.render.Texts; -import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; -import net.minecraft.client.MinecraftClient; -import net.minecraft.nbt.NbtCompound; - -import java.util.*; -import java.util.concurrent.atomic.AtomicBoolean; - -public class CarpetClient implements CarpetExtension, Config.CList { - public static final CarpetClient INSTANCE = new CarpetClient(); - - private final Map> ALL_RULES; - private final Map> CURRENT_RULES; - private final Set MANAGERS; - private final String LOADNT; - private final String DATA_URL; - private final JsonElement COMMAND; - private final AtomicBoolean HANDLING_DATA; - - private boolean isServerCarpet; - - static { - ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> INSTANCE.onDisconnect()); - - SettingsManager.registerGlobalRuleObserver((source, rule, value) -> { - INSTANCE.loadSinglePlayerRules(); - CarpetClientRule clientRule = INSTANCE.CURRENT_RULES.get(rule.name()); - if (clientRule != null) { - clientRule.setFromServer(value); - } - }); - } - - private CarpetClient() { - this.ALL_RULES = new HashMap<>(); - this.CURRENT_RULES = new HashMap<>(); - this.MANAGERS = new HashSet<>(); - this.LOADNT = "Could not load rule data"; - this.DATA_URL = "https://raw.githubusercontent.com/Crec0/carpet-rules-database/main/data/parsed_data.json"; - this.COMMAND = new JsonPrimitive("COMMAND"); - this.HANDLING_DATA = new AtomicBoolean(false); - this.isServerCarpet = false; - } - - @Override - public void onGameStarted() { - EssentialClient.CONFIG_SET.add(CarpetClient.INSTANCE); - Scheduler.schedule(0, () -> this.readConfig()); - } - - public boolean isServerCarpet() { - return this.isServerCarpet || EssentialUtils.getClient().isInSingleplayer(); - } - - public boolean isCarpetManager(String name) { - return this.MANAGERS.contains(name); - } - - public CarpetClientRule getRule(String name) { - if (this.CURRENT_RULES.isEmpty() && EssentialUtils.getClient().isInSingleplayer()) { - this.loadSinglePlayerRules(); - } - return this.CURRENT_RULES.get(name); - } - - public void onDisconnect() { - this.isServerCarpet = false; - this.CURRENT_RULES.clear(); - this.MANAGERS.clear(); - } - - public Collection> getCurrentCarpetRules() { - MinecraftClient client = EssentialUtils.getClient(); - if (client.isInSingleplayer()) { - this.loadSinglePlayerRules(); - return this.CURRENT_RULES.values(); - } - if (client.getCurrentServerEntry() != null && this.isServerCarpet) { - return this.CURRENT_RULES.values(); - } - return this.ALL_RULES.values(); - } - - public void syncCarpetRule(NbtCompound compound) { - this.isServerCarpet = true; - // We run on the main thread to prevent concurrent modification exceptions - // This method will be called from the network thread - EssentialUtils.getClient().execute(() -> { - String name = compound.getString("Rule"); - String value = compound.getString("Value"); - String manager = compound.getString("Manager"); - CarpetClientRule wrapped = this.CURRENT_RULES.get(name); - if (wrapped == null) { - CarpetRule rule = CarpetUtils.getCarpetRule(name); - wrapped = this.ALL_RULES.get(name); - if (rule != null) { - if (wrapped == null) { - wrapped = this.parseRuleToClientRule(rule, manager); - } else { - wrapped = this.parseRuleToClientRule(rule, wrapped.getDescription(), wrapped.getOptionalInfo(), manager); - } - } else { - // We must copy otherwise we will be modifying the global CarpetRule - wrapped = wrapped != null ? wrapped.shallowCopy() : new StringCarpetRule(name, this.LOADNT, value); - } - this.CURRENT_RULES.put(name, wrapped); - } - - this.HANDLING_DATA.set(true); - wrapped.setFromServer(value); - this.HANDLING_DATA.set(false); - - if ( - EssentialUtils.getClient().currentScreen instanceof RulesScreen rulesScreen && - rulesScreen.getTitle() == Texts.SERVER_SCREEN - ) { - rulesScreen.refreshRules(rulesScreen.getSearchBoxText()); - } - }); - } - - private void loadSinglePlayerRules() { - if (this.CURRENT_RULES.isEmpty() && EssentialUtils.getClient().isInSingleplayer()) { - this.HANDLING_DATA.set(true); - - CarpetUtils.forEachCarpetRule((rule, managerId) -> { - CarpetClientRule clientRule = this.ALL_RULES.get(rule.name()); - clientRule = clientRule == null ? this.parseRuleToClientRule(rule, managerId) : - this.parseRuleToClientRule(rule, clientRule.getDescription(), clientRule.getOptionalInfo(), managerId); - clientRule.setFromServer(CarpetUtils.getRuleValueAsString(rule)); - this.CURRENT_RULES.put(clientRule.getName(), clientRule); - }); - - this.HANDLING_DATA.set(false); - } - } - - private CarpetClientRule jsonToClientRule(JsonElement jsonElement) { - if (!jsonElement.isJsonObject()) { - EssentialClient.LOGGER.error("Failed to load Carpet Rule (Not JSON Object!):\n{}", jsonElement); - return null; - } - JsonObject ruleObject = jsonElement.getAsJsonObject(); - JsonElement nameElement = ruleObject.get("name"); - if (nameElement == null || !nameElement.isJsonPrimitive()) { - EssentialClient.LOGGER.error("Failed to load Carpet Rule (No Valid Name!):\n{}", ruleObject); - return null; - } - String name = nameElement.getAsString(); - - CarpetRule rule = CarpetUtils.getCarpetRule(name); - try { - String description = ruleObject.get("description").getAsString(); - JsonElement repo = ruleObject.get("repo"); - if (repo != null) { - String repoString = repo.getAsString(); - description += "\n§3From: " + repoString; - } - String optionalInfo = null; - JsonElement extraInfo = ruleObject.get("extras"); - if (extraInfo != null) { - if (extraInfo.isJsonArray()) { - StringBuilder builder = new StringBuilder(); - extraInfo.getAsJsonArray().forEach(element -> { - if (element.isJsonPrimitive()) { - builder.append(element.getAsString()).append(" "); - } - }); - optionalInfo = builder.toString(); - } - if (extraInfo.isJsonPrimitive()) { - optionalInfo = extraInfo.getAsString(); - } - } - if (rule != null) { - return this.parseRuleToClientRule(rule, description, optionalInfo, rule.settingsManager().identifier()); - } - Rule.Type type = Rule.Type.fromString(ruleObject.get("type").getAsString()); - JsonElement defaultValue = ruleObject.get("default"); - if (defaultValue == null) { - defaultValue = ruleObject.get("value"); - } - JsonElement categories = ruleObject.get("categories"); - if (categories != null && categories.getAsJsonArray().contains(this.COMMAND) && type != Rule.Type.BOOLEAN) { - CycleCarpetRule wrapped = CycleCarpetRule.commandOf(name, description, defaultValue.getAsString()); - wrapped.setOptionalInfo(optionalInfo); - return wrapped; - } - JsonElement isStrict = ruleObject.get("strict"); - if (isStrict != null && isStrict.getAsBoolean() && type != Rule.Type.BOOLEAN) { - List validValues = new ArrayList<>(); - JsonElement options = ruleObject.get("options"); - if (options.isJsonArray()) { - JsonArray values = options.getAsJsonArray(); - values.forEach(element -> validValues.add(element.getAsString())); - CycleCarpetRule wrapped = new CycleCarpetRule(name, description, validValues, defaultValue.getAsString()); - wrapped.setOptionalInfo(optionalInfo); - return wrapped; - } - } - CarpetClientRule wrapped = switch (type) { - case CYCLE -> { - JsonArray validCycles = ruleObject.get("cycles").getAsJsonArray(); - List cycles = new ArrayList<>(); - validCycles.forEach(element -> cycles.add(element.getAsString())); - yield new CycleCarpetRule(name, description, cycles, defaultValue.getAsString()); - } - case BOOLEAN -> new BooleanCarpetRule(name, description, defaultValue.getAsBoolean()); - case INTEGER -> new IntegerCarpetRule(name, description, defaultValue.getAsInt()); - case DOUBLE -> new DoubleCarpetRule(name, description, defaultValue.getAsDouble()); - default -> new StringCarpetRule(name, description, defaultValue.getAsString()); - }; - wrapped.setOptionalInfo(optionalInfo); - return wrapped; - } catch (Exception e) { - if (rule != null) { - return this.parseRuleToClientRule(rule, CarpetUtils.getRuleSettingsManagerId(rule)); - } - // EssentialClient.LOGGER.error("Failed to load Carpet Rule '{}'", name, e); - return null; - } - } - - private CarpetClientRule parseRuleToClientRule(CarpetRule rule, String manager) { - return this.parseRuleToClientRule(rule, null, null, manager); - } - - private CarpetClientRule parseRuleToClientRule(CarpetRule rule, String description, String optionalInfo, String manager) { - String name = rule.name(); - Rule.Type type = Rule.Type.fromClass(rule.type()); - String defaultValue = CarpetUtils.getRuleDefaultValueAsString(rule); - if (description == null) { - description = CarpetUtils.getRuleDescription(rule); - } - if (optionalInfo == null) { - optionalInfo = CarpetUtils.getRuleExtraInfo(rule); - if (optionalInfo.isBlank()) { - optionalInfo = null; - } - } - if (CarpetUtils.isRuleCommand(rule)) { - CycleCarpetRule wrapped = CycleCarpetRule.commandOf(name, description, defaultValue); - wrapped.setOptionalInfo(optionalInfo); - return wrapped; - } - if (rule.strict() && type != Rule.Type.BOOLEAN) { - CycleCarpetRule wrapped = new CycleCarpetRule(name, description, new ArrayList<>(rule.suggestions()), defaultValue); - wrapped.setOptionalInfo(optionalInfo); - return wrapped; - } - CarpetClientRule wrapped = switch (type) { - case BOOLEAN -> new BooleanCarpetRule(name, description, "true".equals(defaultValue)); - case INTEGER -> { - Integer integer; - try { - integer = Integer.parseInt(defaultValue); - } catch (NumberFormatException e) { - integer = null; - } - yield integer == null ? null : new IntegerCarpetRule(name, description, integer); - } - case DOUBLE -> { - Double doubleValue; - try { - doubleValue = Double.parseDouble(defaultValue); - } catch (NumberFormatException e) { - doubleValue = null; - } - yield doubleValue == null ? null : new DoubleCarpetRule(name, description, doubleValue); - } - default -> null; - }; - - if (wrapped == null) { - wrapped = new StringCarpetRule(name, description, defaultValue); - } - - this.MANAGERS.add(manager); - wrapped.setCustomManager(manager); - wrapped.setOptionalInfo(optionalInfo); - return wrapped; - } - - private JsonArray getData(JsonArray fallback) { - String content = NetworkUtils.getStringFromUrl(this.DATA_URL); - if (content == null) { - EssentialClient.LOGGER.error("Failed to fetch rule data"); - return fallback; - } - return this.GSON.fromJson(content, JsonArray.class); - } - - @Override - public String getConfigName() { - return "CarpetClient"; - } - - @Override - public JsonElement getSaveData() { - JsonArray ruleData = new JsonArray(); - this.ALL_RULES.forEach((name, rule) -> { - JsonObject ruleObject = new JsonObject(); - ruleObject.addProperty("name", name); - ruleObject.addProperty("type", rule.getType().toString()); - ruleObject.addProperty("description", rule.getDescription()); - ruleObject.addProperty("extras", rule.getOptionalInfo()); - ruleObject.add("default", rule.getDefaultValueAsJson()); - if (rule instanceof CycleCarpetRule cycleRule) { - JsonArray validCycles = new JsonArray(); - cycleRule.getCycleValues().forEach(validCycles::add); - ruleObject.add("cycles", validCycles); - } - ruleData.add(ruleObject); - }); - return ruleData; - } - - @Override - public void readConfig(JsonArray jsonElement) { - JsonArray jsonArray = this.getData(jsonElement); - jsonArray.forEach(element -> { - CarpetClientRule rule = this.jsonToClientRule(element); - if (rule != null) { - this.ALL_RULES.put(rule.getName(), rule); - } - }); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/CraftingSharedConstants.java b/src/main/java/me/senseiwells/essentialclient/feature/CraftingSharedConstants.java deleted file mode 100644 index 2e379a7e..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/CraftingSharedConstants.java +++ /dev/null @@ -1,21 +0,0 @@ -package me.senseiwells.essentialclient.feature; - -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; - -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.atomic.AtomicBoolean; - -public final class CraftingSharedConstants { - public static final AtomicBoolean IS_VANILLA_CLICK = new AtomicBoolean(false); - public static final AtomicBoolean IS_SCRIPT_CLICK = new AtomicBoolean(false); - public static final ScheduledExecutorService EXECUTOR = new ScheduledThreadPoolExecutor(2); - - static { - ClientLifecycleEvents.CLIENT_STOPPING.register(client -> { - EXECUTOR.shutdownNow(); - }); - } - - public static void load() { } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/CustomClientCape.java b/src/main/java/me/senseiwells/essentialclient/feature/CustomClientCape.java deleted file mode 100644 index 7c01bcb3..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/CustomClientCape.java +++ /dev/null @@ -1,58 +0,0 @@ -package me.senseiwells.essentialclient.feature; - -import net.minecraft.util.Identifier; -import net.minecraft.util.Util; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -public class CustomClientCape { - private static Identifier currentCape; - - private static final Map CAPE_MAP = Util.make(new LinkedHashMap<>(), map -> { - map.put("None", null); - map.put("Old Mojang", id("mojangclassic")); - map.put("Mojang", id("mojangcape")); - map.put("Mojang Studios", id("mojangstudios")); - map.put("Minecon 2011", id("minecon2011")); - map.put("Minecon 2012", id("minecon2012")); - map.put("Minecon 2013", id("minecon2013")); - map.put("Minecon 2015", id("minecon2015")); - map.put("Minecon 2016", id("minecon2016")); - map.put("Bacon", id("bacon")); - map.put("Millionth", id("millionth")); - map.put("DannyB", id("dannyb")); - map.put("Julian", id("julian")); - map.put("Cheapsh0t", id("cheapsh0t")); - map.put("MrMessiah", id("mrmessiah")); - map.put("Prismarine", id("prismarine")); - map.put("Birthday", id("birthday")); - map.put("Translator", id("translator")); - map.put("Scrolls", id("scrolls")); - map.put("Cobalt", id("cobalt")); - map.put("Mojira", id("mojira")); - map.put("Turtle", id("turtle")); - map.put("Migrator", id("migrator")); - map.put("Christmas 2010", id("christmas2010")); - map.put("New Year 2011", id("newyear2011")); - }); - - private static final List CAPE_NAMES = CAPE_MAP.keySet().stream().toList(); - - public static List getCapeNames() { - return CAPE_NAMES; - } - - public static void setCurrentCape(String capeName) { - currentCape = CAPE_MAP.get(capeName); - } - - public static Identifier getCurrentCape() { - return currentCape; - } - - private static Identifier id(String name) { - return Identifier.of("essentialclient", "textures/capes/" + name + ".png"); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/GameRuleNetworkHandler.java b/src/main/java/me/senseiwells/essentialclient/feature/GameRuleNetworkHandler.java deleted file mode 100644 index 19bfddad..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/GameRuleNetworkHandler.java +++ /dev/null @@ -1,208 +0,0 @@ -package me.senseiwells.essentialclient.feature; - -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.gui.RulesScreen; -import me.senseiwells.essentialclient.mixins.gameRuleSync.RuleInvoker; -import me.senseiwells.essentialclient.rule.game.GameRule; -import me.senseiwells.essentialclient.rule.game.VanillaGameRules; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.interfaces.IGameRule; -import me.senseiwells.essentialclient.utils.misc.Scheduler; -import me.senseiwells.essentialclient.utils.network.NetworkHandler; -import me.senseiwells.essentialclient.utils.render.Texts; -import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; -import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; -import net.minecraft.client.MinecraftClient; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.network.PacketByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.util.Identifier; -import net.minecraft.world.GameRules; - -import java.util.function.BiFunction; -import java.util.function.Function; - -public class GameRuleNetworkHandler extends NetworkHandler { - public static final int VERSION = 1_0_1; - - private boolean canModifyRules = false; - - private final BiFunction helloFactory; - private final BiFunction setFactory; - - public GameRuleNetworkHandler() { - if (EssentialUtils.isModInstalled("essentialaddons")) { - this.helloFactory = essentialaddons.feature.GameRuleNetworkHandler.GameRuleHelloPayload::new; - this.setFactory = essentialaddons.feature.GameRuleNetworkHandler.SetGameRulePayload::new; - } else { - this.helloFactory = GameRuleHelloPayload::new; - this.setFactory = SetGameRulePayload::new; - } - } - - public boolean canModifyRules() { - return this.canModifyRules || EssentialUtils.getClient().isInSingleplayer(); - } - - @Override - public int getVersion() { - return VERSION; - } - - @Override - protected void onHelloSuccess() { - EssentialClient.LOGGER.info("Game Rule data is available"); - } - - @Override - protected void onHelloFail() { - EssentialClient.LOGGER.info("Could not sync Game Rule data"); - } - - @Override - public void onDisconnect() { - VanillaGameRules.getGameRules().forEach(GameRule::reset); - this.canModifyRules = false; - super.onDisconnect(); - } - - public void processGamerules(NbtCompound compound) { - if (compound == null) { - EssentialClient.LOGGER.warn("Received bad Game Rule packet"); - return; - } - for (String ruleKey : compound.getKeys()) { - String ruleValue = compound.getString(ruleKey); - GameRule gameRule = VanillaGameRules.ruleFromString(ruleKey); - if (gameRule == null) { - EssentialClient.LOGGER.warn("Game Rule '{}' could not be synced", ruleKey); - continue; - } - gameRule.setFromServer(ruleValue); - } - this.refreshScreen(); - } - - public void sendServerRuleChange(GameRule gameRule, String newValue) { - MinecraftClient client = EssentialUtils.getClient(); - if (client.getServer() != null) { - if (gameRule.getKey() != null) { - GameRules.Rule rule = client.getServer().getGameRules().get(gameRule.getKey()); - ((RuleInvoker) rule).deserialize(newValue); - ((IGameRule) rule).essentialclient$ruleChanged(gameRule.getName(), client.getServer()); - gameRule.setFromServer(newValue); - this.refreshScreen(); - } - return; - } - this.sendPayload(() -> this.setFactory.apply(gameRule.getName(), newValue)); - } - - @Override - public void registerCustomPayloads() { - if (!EssentialUtils.isModInstalled("essentialaddons")) { - PayloadTypeRegistry.playC2S().register(GameRuleHelloPayload.ID, GameRuleHelloPayload.CODEC); - PayloadTypeRegistry.playC2S().register(SetGameRulePayload.ID, SetGameRulePayload.CODEC); - - PayloadTypeRegistry.playS2C().register(GameRuleHelloPayload.ID, GameRuleHelloPayload.CODEC); - PayloadTypeRegistry.playS2C().register(GameRulePermissionsPayload.ID, GameRulePermissionsPayload.CODEC); - PayloadTypeRegistry.playS2C().register(GameRulesChangedPayload.ID, GameRulesChangedPayload.CODEC); - - ClientPlayNetworking.registerGlobalReceiver(GameRuleHelloPayload.ID, (payload, context) -> { - this.onHello(context.player().networkHandler, payload); - }); - ClientPlayNetworking.registerGlobalReceiver(GameRulePermissionsPayload.ID, (payload, context) -> { - this.canModifyRules = payload.canUpdateGamerules; - this.refreshScreen(); - }); - ClientPlayNetworking.registerGlobalReceiver(GameRulesChangedPayload.ID, (payload, context) -> { - this.processGamerules(payload.compound); - }); - } else { - Scheduler.schedule(0, () -> { - ClientPlayNetworking.registerGlobalReceiver(essentialaddons.feature.GameRuleNetworkHandler.GameRuleHelloPayload.ID, (payload, context) -> { - this.onHello(context.player().networkHandler, new GameRuleHelloPayload(payload.brand(), payload.version())); - }); - ClientPlayNetworking.registerGlobalReceiver(essentialaddons.feature.GameRuleNetworkHandler.GameRulePermissionsPayload.ID, (payload, context) -> { - this.canModifyRules = payload.canUpdateGamerules(); - this.refreshScreen(); - }); - ClientPlayNetworking.registerGlobalReceiver(essentialaddons.feature.GameRuleNetworkHandler.GameRulesChangedPayload.ID, (payload, context) -> { - this.processGamerules(payload.compound()); - }); - }); - } - } - - @Override - protected CustomPayload createHelloPayload(String brand, int version) { - return this.helloFactory.apply(brand, version); - } - - private void refreshScreen() { - if (EssentialUtils.getClient().currentScreen instanceof RulesScreen rulesScreen && rulesScreen.getTitle() == Texts.GAME_RULE_SCREEN) { - EssentialUtils.getClient().execute(() -> rulesScreen.refreshRules(rulesScreen.getSearchBoxText())); - } - } - - private static class GameRuleHelloPayload extends HelloPayload { - public static final Id ID = new CustomPayload.Id<>(Identifier.of("essential:game_rule_hello")); - public static final PacketCodec CODEC = PacketCodec.of( - HelloPayload::write, - GameRuleHelloPayload::new - ); - - public GameRuleHelloPayload(String brand, int version) { - super(brand, version); - } - - public GameRuleHelloPayload(PacketByteBuf buf) { - super(buf); - } - - @Override - public Id getId() { - return ID; - } - } - - private record SetGameRulePayload(String name, String value) implements CustomPayload { - public static final Id ID = new CustomPayload.Id<>(Identifier.of("essential:set_game_rule")); - public static final PacketCodec CODEC = PacketCodec.of( - (payload, buf) -> buf.writeString(payload.name).writeString(payload.value), - (buf) -> new SetGameRulePayload(buf.readString(), buf.readString()) - ); - - @Override - public Id getId() { - return ID; - } - } - - private record GameRulesChangedPayload(NbtCompound compound) implements CustomPayload { - public static final Id ID = new CustomPayload.Id<>(Identifier.of("essential:game_rules_changed")); - public static final PacketCodec CODEC = PacketCodec.of( - (payload, buf) -> buf.writeNbt(payload.compound), - (buf) -> new GameRulesChangedPayload(buf.readNbt()) - ); - - @Override - public Id getId() { - return ID; - } - } - - private record GameRulePermissionsPayload(boolean canUpdateGamerules) implements CustomPayload { - public static final Id ID = new CustomPayload.Id<>(Identifier.of("essential:game_rule_permissions")); - public static final PacketCodec CODEC = PacketCodec.of( - (payload, buf) -> buf.writeBoolean(payload.canUpdateGamerules), - (buf) -> new GameRulePermissionsPayload(buf.readBoolean()) - ); - - @Override - public Id getId() { - return ID; - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/HighlightLiquids.java b/src/main/java/me/senseiwells/essentialclient/feature/HighlightLiquids.java deleted file mode 100644 index 4ee1fc39..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/HighlightLiquids.java +++ /dev/null @@ -1,120 +0,0 @@ -package me.senseiwells.essentialclient.feature; - -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler; -import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry; -import net.fabricmc.fabric.api.resource.ResourceManagerHelper; -import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; -import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; -import net.minecraft.block.FluidBlock; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.color.world.BiomeColors; -import net.minecraft.client.render.model.ModelLoader; -import net.minecraft.client.texture.Sprite; -import net.minecraft.fluid.FluidState; -import net.minecraft.fluid.Fluids; -import net.minecraft.resource.ResourceManager; -import net.minecraft.resource.ResourceType; -import net.minecraft.screen.PlayerScreenHandler; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.BlockRenderView; -import org.jetbrains.annotations.Nullable; - -import java.util.function.Function; - -// Original code by plusls slightly modified by Sensei -public class HighlightLiquids implements SimpleSynchronousResourceReloadListener { - public static Sprite lavaSourceFlowSprite; - public static Sprite lavaSourceStillSprite; - public static Sprite defaultLavaSourceFlowSprite; - public static Sprite defaultLavaSourceStillSprite; - - public static Sprite waterSourceFlowSprite; - public static Sprite waterSourceStillSprite; - public static Sprite defaultWaterSourceFlowSprite; - public static Sprite defaultWaterSourceStillSprite; - - private static final Identifier LAVA_FLOWING_SPRITE_ID; - private static final Identifier LAVA_STILL_SPRITE_ID; - - private static final Identifier WATER_FLOWING_SPRITE_ID; - private static final Identifier WATER_STILL_SPRITE_ID; - - private static final int DEFAULT_WATER_COLOUR; - - static { - LAVA_FLOWING_SPRITE_ID = Identifier.of("essentialclient", "block/lava_flow"); - LAVA_STILL_SPRITE_ID = Identifier.of("essentialclient", "block/lava_still"); - WATER_FLOWING_SPRITE_ID = Identifier.of("essentialclient", "block/water_flow"); - WATER_STILL_SPRITE_ID = Identifier.of("essentialclient", "block/water_still"); - - DEFAULT_WATER_COLOUR = 0x3F76E4; - } - - public static void load() { - if (EssentialUtils.isModInstalled("fabric-rendering-fluids-v1")) { - ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(new HighlightLiquids()); - } else { - EssentialClient.LOGGER.info("Highlight Liquids not functional - no Fabric API"); - } - } - - @Override - public void reload(ResourceManager manager) { - MinecraftClient client = EssentialUtils.getClient(); - Function atlas = client.getSpriteAtlas(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE); - - lavaSourceFlowSprite = atlas.apply(LAVA_FLOWING_SPRITE_ID); - lavaSourceStillSprite = atlas.apply(LAVA_STILL_SPRITE_ID); - defaultLavaSourceStillSprite = client.getBakedModelManager().getBlockModels().getModel(Blocks.LAVA.getDefaultState()).getParticleSprite(); - defaultLavaSourceFlowSprite = ModelLoader.LAVA_FLOW.getSprite(); - FluidRenderHandler lavaSourceRenderHandler = (view, pos, state) -> { - if (view != null && pos != null && ClientRules.HIGHLIGHT_LAVA_SOURCES.getValue()) { - BlockState blockState = view.getBlockState(pos); - if (blockState.contains(FluidBlock.LEVEL) && blockState.get(FluidBlock.LEVEL) == 0) { - return new Sprite[]{lavaSourceStillSprite, lavaSourceFlowSprite}; - } - } - return new Sprite[]{defaultLavaSourceStillSprite, defaultLavaSourceFlowSprite}; - }; - FluidRenderHandlerRegistry.INSTANCE.register(Fluids.LAVA, lavaSourceRenderHandler); - FluidRenderHandlerRegistry.INSTANCE.register(Fluids.FLOWING_LAVA, lavaSourceRenderHandler); - - waterSourceFlowSprite = atlas.apply(WATER_FLOWING_SPRITE_ID); - waterSourceStillSprite = atlas.apply(WATER_STILL_SPRITE_ID); - defaultWaterSourceStillSprite = client.getBakedModelManager().getBlockModels().getModel(Blocks.WATER.getDefaultState()).getParticleSprite(); - defaultWaterSourceFlowSprite = ModelLoader.WATER_FLOW.getSprite(); - FluidRenderHandler waterSourceRenderHandler = new FluidRenderHandler() { - @Override - public Sprite[] getFluidSprites(@Nullable BlockRenderView view, @Nullable BlockPos pos, FluidState state) { - if (view != null && pos != null && ClientRules.HIGHLIGHT_WATER_SOURCES.getValue()) { - BlockState blockState = view.getBlockState(pos); - if (blockState.getFluidState().isStill()) { - return new Sprite[]{waterSourceStillSprite, waterSourceFlowSprite}; - } - } - return new Sprite[]{defaultWaterSourceStillSprite, defaultWaterSourceFlowSprite}; - } - - @Override - public int getFluidColor(@Nullable BlockRenderView view, @Nullable BlockPos pos, FluidState state) { - // if (ClientRules.HIGHLIGHT_WATER_SOURCES.getValue() && state.getLevel() == 8) { - // // Returns blank colour - // return -1; - // } - return (view == null || pos == null) ? DEFAULT_WATER_COLOUR : BiomeColors.getWaterColor(view, pos); - } - }; - FluidRenderHandlerRegistry.INSTANCE.register(Fluids.WATER, waterSourceRenderHandler); - FluidRenderHandlerRegistry.INSTANCE.register(Fluids.FLOWING_WATER, waterSourceRenderHandler); - } - - @Override - public Identifier getFabricId() { - return Identifier.of("lava_reload_listener"); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/MixinExtraSupport.java b/src/main/java/me/senseiwells/essentialclient/feature/MixinExtraSupport.java deleted file mode 100644 index 51816d48..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/MixinExtraSupport.java +++ /dev/null @@ -1,25 +0,0 @@ -package me.senseiwells.essentialclient.feature; - -import com.llamalad7.mixinextras.MixinExtrasBootstrap; - -/** - *

- * The reason we have this class is to be able - * to load MixinExtrasBootstrap at runtime. - *

- * - *

- * MixinExtras shadows to different package so - * fabric's pre-launch entry point will not be - * able to find it at runtime since shadow gradle - * does not remap the {@code fabric.mod.json} but - * will remap this class file to the right package. - *

- */ -public class MixinExtraSupport { - static { - MixinExtrasBootstrap.init(); - } - - public static void load() { } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/RecipeBookCache.java b/src/main/java/me/senseiwells/essentialclient/feature/RecipeBookCache.java deleted file mode 100644 index cee93498..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/RecipeBookCache.java +++ /dev/null @@ -1,27 +0,0 @@ -package me.senseiwells.essentialclient.feature; - -import net.minecraft.recipe.RecipeEntry; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -public class RecipeBookCache { - private static final Set> RECIPE_CACHE = new HashSet<>(); - - public static boolean isCached(RecipeEntry recipe) { - return RECIPE_CACHE.contains(recipe); - } - - public static void setRecipeCache(List> recipeCache) { - recipeCache.forEach(RecipeBookCache::addRecipeToCache); - } - - public static void addRecipeToCache(RecipeEntry recipe) { - RECIPE_CACHE.add(recipe); - } - - public static void removeRecipeFromCache(RecipeEntry recipe) { - RECIPE_CACHE.remove(recipe); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkClientNetworkHandler.java b/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkClientNetworkHandler.java deleted file mode 100644 index 512e844b..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkClientNetworkHandler.java +++ /dev/null @@ -1,250 +0,0 @@ -package me.senseiwells.essentialclient.feature.chunkdebug; - -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.network.NetworkHandler; -import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; -import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; -import net.minecraft.network.PacketByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.ChunkPos; -import net.minecraft.world.World; - -import java.util.*; - -public class ChunkClientNetworkHandler extends NetworkHandler { - public static final int VERSION = 1_0_6; - - private final Map, WorldChunkInfo> chunkInfoMap = new HashMap<>(); - - public ChunkClientNetworkHandler() { - - } - - @Override - public void onDisconnect() { - super.onDisconnect(); - ChunkGrid.instance = null; - this.clearAllChunks(); - } - - @Override - public int getVersion() { - return VERSION; - } - - @Override - protected void onHelloSuccess() { - EssentialClient.LOGGER.info("Chunk Debug is available"); - } - - @Override - protected void onHelloFail() { - EssentialClient.LOGGER.info("Server has out of date Chunk Debug!"); - } - - public Optional getChunk(RegistryKey world, ChunkPos pos) { - WorldChunkInfo chunks = this.chunkInfoMap.get(world); - if (chunks == null) { - return Optional.empty(); - } - return Optional.ofNullable(chunks.getInfo(pos.toLong())); - } - - public Iterable getChunks(RegistryKey world) { - WorldChunkInfo chunks = this.chunkInfoMap.get(world); - if (chunks == null) { - return List.of(); - } - return chunks.getAllInfo(); - } - - public void clearAllChunks() { - this.chunkInfoMap.forEach((s, chunkData) -> chunkData.clear()); - } - - public Optional getChunkCluster(RegistryKey world) { - WorldChunkInfo chunks = this.chunkInfoMap.get(world); - return chunks == null ? Optional.empty() : Optional.of(chunks.getClusters()); - } - - public void updateChunks(RegistryKey world, Iterable infos) { - WorldChunkInfo chunks = this.chunkInfoMap.computeIfAbsent(world, k -> new WorldChunkInfo()); - ChunkClusters clusters = chunks.getClusters(); - - for (ChunkInfo info : infos) { - long position = info.position(); - chunks.remove(position); - if (info.level() != ChunkLevel.UNLOADED) { - clusters.add(position); - chunks.add(info); - continue; - } - clusters.remove(position); - if (ClientRules.CHUNK_DEBUG_SHOW_UNLOADED_CHUNKS.getValue()) { - chunks.add(info); - } - } - } - - public void removeChunkData() { - this.sendPayload(StopChunkInfoPayload::new); - } - - public void requestChunkData(RegistryKey world) { - this.clearAllChunks(); - this.sendPayload(() -> new SetChunkDimensionPayload(world)); - } - - protected void requestServerRefresh() { - this.clearAllChunks(); - this.sendPayload(ReloadChunkDebugPayload::new); - } - - @Override - public void registerCustomPayloads() { - PayloadTypeRegistry.playC2S().register(ChunkDebugHelloPayload.ID, ChunkDebugHelloPayload.CODEC); - PayloadTypeRegistry.playC2S().register(ReloadChunkDebugPayload.ID, ReloadChunkDebugPayload.CODEC); - PayloadTypeRegistry.playC2S().register(StopChunkInfoPayload.ID, StopChunkInfoPayload.CODEC); - PayloadTypeRegistry.playC2S().register(SetChunkDimensionPayload.ID, SetChunkDimensionPayload.CODEC); - - PayloadTypeRegistry.playS2C().register(ChunkDebugHelloPayload.ID, ChunkDebugHelloPayload.CODEC); - PayloadTypeRegistry.playS2C().register(BatchedChunkInfoPayload.ID, BatchedChunkInfoPayload.CODEC); - - ClientPlayNetworking.registerGlobalReceiver(ChunkDebugHelloPayload.ID, (payload, context) -> { - this.onHello(context.player().networkHandler, payload); - }); - ClientPlayNetworking.registerGlobalReceiver(BatchedChunkInfoPayload.ID, (payload, context) -> { - this.updateChunks(payload.world, payload.infos); - }); - } - - @Override - protected HelloPayload createHelloPayload(String brand, int version) { - return new ChunkDebugHelloPayload(brand, version); - } - - private static class ChunkDebugHelloPayload extends HelloPayload { - public static final Id ID = new CustomPayload.Id<>(Identifier.of("chunk_debug:hello")); - public static final PacketCodec CODEC = PacketCodec.of( - ChunkDebugHelloPayload::write, - ChunkDebugHelloPayload::new - ); - - public ChunkDebugHelloPayload(String brand, int version) { - super(brand, version); - } - - public ChunkDebugHelloPayload(PacketByteBuf buf) { - super(buf.readString(), buf.readInt()); - } - - @Override - public Id getId() { - return ID; - } - } - - private record BatchedChunkInfoPayload( - RegistryKey world, - List infos - ) implements CustomPayload { - public static final Id ID = new CustomPayload.Id<>(Identifier.of("chunk_debug:batched_chunk_info")); - public static final PacketCodec CODEC = PacketCodec.of( - BatchedChunkInfoPayload::write, - BatchedChunkInfoPayload::read - ); - - public void write(PacketByteBuf buf) { - int size = this.infos.size(); - long[] chunkPositions = new long[size]; - byte[] levels = new byte[size]; - byte[] statuses = new byte[size]; - byte[] tickets = new byte[size]; - - int i = 0; - for (ChunkInfo info : this.infos) { - chunkPositions[i] = info.position(); - levels[i] = (byte) info.level().ordinal(); - statuses[i] = (byte) info.status().ordinal(); - tickets[i] = (byte) info.ticket().ordinal(); - i++; - } - - buf.writeVarInt(size); - buf.writeLongArray(chunkPositions); - buf.writeByteArray(levels); - buf.writeByteArray(statuses); - buf.writeByteArray(tickets); - } - - @Override - public Id getId() { - return ID; - } - - public static BatchedChunkInfoPayload read(PacketByteBuf buf) { - int size = buf.readVarInt(); - long[] chunkPositions = buf.readLongArray(new long[size]); - byte[] levelTypes = buf.readByteArray(size); - byte[] statusTypes = buf.readByteArray(size); - byte[] ticketTypes = buf.readByteArray(size); - RegistryKey world = buf.readRegistryKey(RegistryKeys.WORLD); - - List infos = new ArrayList<>(); - for (int i = 0; i < size; i++) { - long position = chunkPositions[i]; - ChunkLevel chunkType = ChunkLevel.decodeChunkType(levelTypes[i]); - ChunkTicket ticketType = ChunkTicket.decodeTicketType(ticketTypes[i]); - ChunkStatus status = ChunkStatus.decodeChunkStatus(statusTypes[i]); - infos.add(new ChunkInfo(position, chunkType, status, ticketType)); - } - return new BatchedChunkInfoPayload(world, infos); - } - } - - private record StopChunkInfoPayload() implements CustomPayload { - public static final Id ID = new CustomPayload.Id<>(Identifier.of("chunk_debug:stop")); - public static final PacketCodec CODEC = PacketCodec.unit(new StopChunkInfoPayload()); - - @Override - public Id getId() { - return ID; - } - } - - private record SetChunkDimensionPayload(RegistryKey dimension) implements CustomPayload { - public static final Id ID = new CustomPayload.Id<>(Identifier.of("chunk_debug:set_dimension")); - public static final PacketCodec CODEC = PacketCodec.of( - SetChunkDimensionPayload::write, - SetChunkDimensionPayload::new - ); - - public SetChunkDimensionPayload(PacketByteBuf buf) { - this(buf.readRegistryKey(RegistryKeys.WORLD)); - } - - public void write(PacketByteBuf buf) { - buf.writeRegistryKey(this.dimension); - } - - @Override - public Id getId() { - return ID; - } - } - - private record ReloadChunkDebugPayload() implements CustomPayload { - public static final Id ID = new CustomPayload.Id<>(Identifier.of("chunk_debug:reload")); - public static final PacketCodec CODEC = PacketCodec.unit(new ReloadChunkDebugPayload()); - - @Override - public Id getId() { - return ID; - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkClusterScreen.java b/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkClusterScreen.java deleted file mode 100644 index 1c29e604..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkClusterScreen.java +++ /dev/null @@ -1,97 +0,0 @@ -package me.senseiwells.essentialclient.feature.chunkdebug; - -import com.google.common.collect.ImmutableList; -import it.unimi.dsi.fastutil.longs.LongSet; -import me.senseiwells.essentialclient.gui.entries.AbstractListEntry; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.render.ChildScreen; -import me.senseiwells.essentialclient.utils.render.RenderHelper; -import me.senseiwells.essentialclient.utils.render.Texts; -import me.senseiwells.essentialclient.utils.render.WidgetHelper; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.ElementListWidget; -import net.minecraft.text.Text; -import net.minecraft.util.math.ChunkPos; - -import java.util.List; - -public class ChunkClusterScreen extends ChildScreen.Typed { - private final ChunkClusters cluster; - private ChunkListWidget chunkWidget; - - public ChunkClusterScreen(ChunkClusters clusters, ChunkDebugScreen parent) { - super(Texts.CHUNK_CLUSTER_SCREEN, parent); - this.cluster = clusters; - } - - @Override - protected void init() { - super.init(); - this.chunkWidget = new ChunkListWidget(); - this.addDrawableChild(this.chunkWidget); - ButtonWidget widget = WidgetHelper.newButton(this.width / 2 - 100, this.height - 27, 200, 20, Texts.DONE, buttonWidget -> this.close()); - this.addDrawableChild(widget); - } - - - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - super.render(context, mouseX, mouseY, delta); - this.chunkWidget.render(context, mouseX, mouseY, delta); - RenderHelper.drawScaledText(context, this.title, this.width / 2, 20, 1.5F, true); - } - - private class ChunkListWidget extends ElementListWidget { - public ChunkListWidget() { - super(ChunkClusterScreen.this.client, ChunkClusterScreen.this.width + 45, ChunkClusterScreen.this.height - 43 - 32, 43, 20); - - for (LongSet group : ChunkClusterScreen.this.cluster.getGroups()) { - this.addEntry(new ChunkClusterScreen.Entry(ChunkClusterScreen.this, group)); - } - } - - @Override - protected int getScrollbarX() { - return this.width / 2 + this.getRowWidth() / 2 - 20; - } - - @Override - public int getRowWidth() { - return 300; - } - } - - private static class Entry extends AbstractListEntry { - private final ButtonWidget viewButton; - private final LongSet group; - private final ChunkPos around; - - public Entry(ChunkClusterScreen parent, LongSet group) { - this.group = group; - this.around = new ChunkPos(group.longStream().findAny().orElse(0L)); - this.viewButton = WidgetHelper.newButton(0, 0, 75, 20, Texts.VIEW, button -> { - ChunkGrid.instance.setCentre(this.around.x, this.around.z); - EssentialUtils.getClient().setScreen(new ChunkDebugScreen(parent.getParent().getParent())); - }); - } - - @Override - public List selectableChildren() { - return this.children(); - } - - @Override - public List children() { - return ImmutableList.of(this.viewButton); - } - - @Override - public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { - context.drawTextWithShadow(EssentialUtils.getClient().textRenderer, Text.literal("Cluster of " + this.group.size() + " chunks around " + this.around), x - 30, (int) (y + entryHeight / 2.0F - 9 / 2.0F), 0xFFFFFF); - this.viewButton.setPosition(x + 190, y); - - this.viewButton.render(context, mouseX, mouseY, tickDelta); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkClusters.java b/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkClusters.java deleted file mode 100644 index 1765e331..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkClusters.java +++ /dev/null @@ -1,145 +0,0 @@ -package me.senseiwells.essentialclient.feature.chunkdebug; - -import it.unimi.dsi.fastutil.longs.LongOpenHashSet; -import it.unimi.dsi.fastutil.longs.LongSet; - -import java.util.ArrayList; -import java.util.List; - -public class ChunkClusters { - private final List groups; - private final LongSet chunks; - - public ChunkClusters() { - this.groups = new ArrayList<>(); - this.chunks = new LongOpenHashSet(); - } - - public void add(long position) { - if (!this.chunks.add(position)) { - return; - } - - long[] directions = getOffsets(position); - long up = directions[0]; - long down = directions[1]; - long right = directions[2]; - long left = directions[3]; - - List nearby = new ArrayList<>(4); - for (LongSet positions : this.groups) { - if (positions.contains(up) || positions.contains(down) || positions.contains(right) || positions.contains(left)) { - nearby.add(positions); - } - } - - if (nearby.isEmpty()) { - LongSet set = new LongOpenHashSet(); - this.groups.add(set); - set.add(position); - return; - } - if (nearby.size() == 1) { - nearby.get(0).add(position); - return; - } - - // Our chunk was between two borders - find the largest - LongSet largest = nearby.get(0); - for (int i = 1; i < nearby.size(); i++) { - LongSet next = nearby.get(i); - if (largest.size() < next.size()) { - largest = next; - } - } - largest.add(position); - - // Merge others into the largest - for (LongSet set : nearby) { - if (set != largest) { - largest.addAll(set); - this.groups.remove(set); - } - } - } - - public void remove(long position) { - if (!this.chunks.remove(position)) { - return; - } - - for (LongSet group : this.groups) { - if (group.remove(position)) { - // When we remove a group it may split that group up - this.groups.remove(group); - if (group.isEmpty()) { - return; - } - // We just completely recalculate the group - this.groups.addAll(search(position, group)); - return; - } - } - } - - public void clear() { - this.chunks.clear(); - this.groups.clear(); - } - - public int count() { - return this.groups.size(); - } - - public List getGroups() { - return this.groups; - } - - // We search around a position splitting into groups - private static List search(long origin, LongSet originGroup) { - long[] directions = getOffsets(origin); - List groups = new ArrayList<>(4); - - for (long direction : directions) { - if (!originGroup.contains(direction)) { - continue; - } - boolean grouped = false; - for (LongSet group : groups) { - if (group.contains(direction)) { - grouped = true; - break; - } - } - if (!grouped) { - LongSet found = new LongOpenHashSet(); - searchFrom(direction, originGroup, new LongOpenHashSet(), found); - if (!found.isEmpty()) { - groups.add(found); - } - } - } - return groups; - } - - private static void searchFrom(long position, LongSet group, LongSet checked, LongSet found) { - long[] directions = getOffsets(position); - - for (long direction : directions) { - if (checked.add(direction) && group.contains(direction)) { - found.add(direction); - searchFrom(direction, group, checked, found); - } - } - } - - private static long[] getOffsets(long position) { - int x = (int) position; - int z = (int) (position >> 32); - return new long[]{pack(x + 1, z), pack(x - 1, z), pack(x, z + 1), pack(x, z - 1)}; - } - - private static long pack(int x, int z) { - return (long) x & 4294967295L | ((long) z & 4294967295L) << 32; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkDebugScreen.java b/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkDebugScreen.java deleted file mode 100644 index 51d1b5a1..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkDebugScreen.java +++ /dev/null @@ -1,252 +0,0 @@ -package me.senseiwells.essentialclient.feature.chunkdebug; - -import com.mojang.blaze3d.systems.RenderSystem; -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.render.ChildScreen; -import me.senseiwells.essentialclient.utils.render.RenderHelper; -import me.senseiwells.essentialclient.utils.render.Texts; -import me.senseiwells.essentialclient.utils.render.WidgetHelper; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.client.render.BufferBuilder; -import net.minecraft.client.render.Tessellator; -import net.minecraft.client.render.VertexFormats; -import net.minecraft.text.Text; - -import java.util.Optional; - -public class ChunkDebugScreen extends ChildScreen { - public static final int - HEADER_HEIGHT = 30, - FOOTER_ROW_HEIGHT = 20, - FOOTER_ROW_PADDING = 5, - FOOTER_ROW_COUNT = 2, - FOOTER_HEIGHT = FOOTER_ROW_HEIGHT * FOOTER_ROW_COUNT + FOOTER_ROW_PADDING * (FOOTER_ROW_COUNT + 1); - - private final MinecraftClient client = EssentialUtils.getClient(); - private NumberFieldWidget xPositionBox; - private NumberFieldWidget zPositionBox; - private boolean canClick = false; - - public ChunkDebugScreen(Screen parent) { - super(Texts.CHUNK_SCREEN, parent); - } - - @Override - public void init() { - if (ChunkGrid.instance == null) { - ChunkGrid.instance = new ChunkGrid(this.client, this.width, this.height); - } - EssentialClient.CHUNK_NET_HANDLER.requestChunkData(ChunkGrid.instance.getDimension()); - int buttonWidth = (this.width - FOOTER_ROW_PADDING * 4) / 3; - int buttonHeight = this.height - FOOTER_ROW_HEIGHT * 3 + FOOTER_ROW_PADDING * 2; - Text dimensionText = ChunkGrid.instance.getPrettyDimension(); - ButtonWidget dimensionButton = this.addDrawableChild(WidgetHelper.newButton(FOOTER_ROW_PADDING, buttonHeight, buttonWidth, FOOTER_ROW_HEIGHT, dimensionText, button -> { - ChunkGrid.instance.cycleDimension(); - button.setMessage(ChunkGrid.instance.getPrettyDimension()); - EssentialClient.CHUNK_NET_HANDLER.requestChunkData(ChunkGrid.instance.getDimension()); - })); - this.addDrawableChild(WidgetHelper.newButton(buttonWidth + FOOTER_ROW_PADDING * 2, buttonHeight, buttonWidth, FOOTER_ROW_HEIGHT, Texts.RETURN_TO_PLAYER, button -> { - if (this.client.player != null) { - ChunkGrid.instance.setDimension(this.client.player.getEntityWorld()); - dimensionButton.setMessage(ChunkGrid.instance.getPrettyDimension()); - int chunkX = this.client.player.getChunkPos().x; - int chunkZ = this.client.player.getChunkPos().z; - ChunkGrid.instance.setCentre(chunkX, chunkZ); - this.xPositionBox.setText(String.valueOf(chunkX)); - this.zPositionBox.setText(String.valueOf(chunkZ)); - EssentialClient.CHUNK_NET_HANDLER.requestChunkData(ChunkGrid.instance.getDimension()); - } - })); - Text initialMinimapText = ChunkGrid.instance.getMinimapMode().prettyName; - this.addDrawableChild(WidgetHelper.newButton(buttonWidth * 2 + FOOTER_ROW_PADDING * 3, buttonHeight, buttonWidth, FOOTER_ROW_HEIGHT, initialMinimapText, button -> { - ChunkGrid.instance.cycleMinimap(); - button.setMessage(ChunkGrid.instance.getMinimapMode().prettyName); - })); - buttonHeight = this.height - FOOTER_ROW_HEIGHT * 2 + FOOTER_ROW_PADDING * 3; - this.xPositionBox = new NumberFieldWidget(this.textRenderer, FOOTER_ROW_PADDING + 28, buttonHeight, buttonWidth - 30, 20, Texts.X); - this.xPositionBox.setInitialValue(ChunkGrid.instance.getCentreX()); - this.zPositionBox = new NumberFieldWidget(this.textRenderer, buttonWidth + FOOTER_ROW_PADDING * 2 + 28, buttonHeight, buttonWidth - 30, 20, Texts.Z); - this.zPositionBox.setInitialValue(ChunkGrid.instance.getCentreZ()); - this.addDrawableChild(WidgetHelper.newButton(buttonWidth * 2 + FOOTER_ROW_PADDING * 3, buttonHeight, buttonWidth, FOOTER_ROW_HEIGHT, Texts.REFRESH, button -> { - if (hasControlDown()) { - EssentialClient.CHUNK_NET_HANDLER.requestServerRefresh(); - } else { - EssentialClient.CHUNK_NET_HANDLER.requestChunkData(ChunkGrid.instance.getDimension()); - } - })); - this.addDrawableChild(WidgetHelper.newButton(5, 5, 90, 20, Texts.CHUNK_CLUSTER_SCREEN, button -> { - Optional optional = EssentialClient.CHUNK_NET_HANDLER.getChunkCluster(ChunkGrid.instance.getDimension()); - optional.ifPresent(clusters -> this.client.setScreen(new ChunkClusterScreen(clusters, this))); - })); - - this.addDrawableChild(this.xPositionBox); - this.addDrawableChild(this.zPositionBox); - } - - @Override - public void resize(MinecraftClient client, int width, int height) { - if (ChunkGrid.instance != null) { - ChunkGrid.instance.onResize(width, height - HEADER_HEIGHT - FOOTER_HEIGHT); - } - super.resize(client, width, height); - } - - @Override - public void close() { - this.removed(); - super.close(); - } - - @Override - public void removed() { - if (ChunkGrid.instance.getMinimapMode() == ChunkGrid.Minimap.NONE) { - EssentialClient.CHUNK_NET_HANDLER.removeChunkData(); - EssentialClient.CHUNK_NET_HANDLER.clearAllChunks(); - } - } - - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - this.renderInGameBackground(context); - ChunkGrid.instance.render(0, HEADER_HEIGHT, this.width, this.height - HEADER_HEIGHT - FOOTER_HEIGHT, false); - - Tessellator tessellator = Tessellator.getInstance(); - this.drawHeaderAndFooterGradient(tessellator); - this.drawHeaderAndFooterTexture(tessellator); - super.render(context, mouseX, mouseY, delta); - - if (ChunkGrid.instance.isPanning()) { - this.xPositionBox.setText(String.valueOf(ChunkGrid.instance.getCentreX())); - this.zPositionBox.setText(String.valueOf(ChunkGrid.instance.getCentreZ())); - } - - RenderHelper.drawScaledText(context, Texts.CHUNK_SCREEN, this.width / 2, 12, 1.5F, true); - if (ChunkGrid.instance.getSelectionText() != null) { - RenderHelper.drawScaledText(context, ChunkGrid.instance.getSelectionText(), this.width / 2, HEADER_HEIGHT + 10, 1, true); - } - - this.xPositionBox.render(context, mouseX, mouseY, delta); - this.zPositionBox.render(context, mouseX, mouseY, delta); - - int textHeight = this.height - 20; - int xOffset = FOOTER_ROW_PADDING + 10; - int zOffset = this.xPositionBox.getWidth() + 50; - - RenderHelper.drawScaledText(context, Texts.X, xOffset, textHeight, 1.5F, false); - RenderHelper.drawScaledText(context, Texts.Z, zOffset, textHeight, 1.5F, false); - } - - @Override - public void renderBackground(DrawContext context, int mouseX, int mouseY, float delta) { - - } - - private void drawHeaderAndFooterGradient(Tessellator tessellator) { - RenderSystem.enableBlend(); - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - - BufferBuilder bufferBuilder = RenderHelper.startQuads(tessellator, VertexFormats.POSITION_COLOR); - - // Header gradient - bufferBuilder.vertex(0, HEADER_HEIGHT, 0).color(0, 0, 0, 255); - bufferBuilder.vertex(0, HEADER_HEIGHT + 4, 0).color(0, 0, 0, 0); - bufferBuilder.vertex(this.width, HEADER_HEIGHT + 4, 0).color(0, 0, 0, 0); - bufferBuilder.vertex(this.width, HEADER_HEIGHT, 0).color(0, 0, 0, 255); - - // Footer gradient - bufferBuilder.vertex(0, this.height - FOOTER_HEIGHT - 4, 0).color(0, 0, 0, 0); - bufferBuilder.vertex(0, this.height - FOOTER_HEIGHT, 0).color(0, 0, 0, 255); - bufferBuilder.vertex(this.width, this.height - FOOTER_HEIGHT, 0).color(0, 0, 0, 255); - bufferBuilder.vertex(this.width, this.height - FOOTER_HEIGHT - 4, 0).color(0, 0, 0, 0); - } - - private void drawHeaderAndFooterTexture(Tessellator tessellator) { - RenderHelper.setPositionTextureColourShader(); - // RenderHelper.bindTexture(OPTIONS_BACKGROUND_TEXTURE); - - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.disableBlend(); - - BufferBuilder bufferBuilder = RenderHelper.startQuads(tessellator, VertexFormats.POSITION_TEXTURE_COLOR); - - // Header - bufferBuilder.vertex(0, 0, 0).texture(0, 0).color(64, 64, 64, 255); - bufferBuilder.vertex(0, HEADER_HEIGHT, 0).texture(0, HEADER_HEIGHT / 32f).color(64, 64, 64, 255); - bufferBuilder.vertex(this.width, HEADER_HEIGHT, 0).texture(this.width / 32f, HEADER_HEIGHT / 32f).color(64, 64, 64, 255); - bufferBuilder.vertex(this.width, 0, 0).texture(this.width / 32f, 0).color(64, 64, 64, 255); - - // Footer - bufferBuilder.vertex(0, this.height - FOOTER_HEIGHT, 0).texture(0, (this.height - FOOTER_HEIGHT) / 32f).color(64, 64, 64, 255); - bufferBuilder.vertex(0, this.height, 0).texture(0, this.height / 32f).color(64, 64, 64, 255); - bufferBuilder.vertex(this.width, this.height, 0).texture(this.width / 32f, this.height / 32f).color(64, 64, 64, 255); - bufferBuilder.vertex(this.width, this.height - FOOTER_HEIGHT, 0).texture(this.width / 32f, (this.height - FOOTER_HEIGHT) / 32f).color(64, 64, 64, 255); - } - - @Override - public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { - return ChunkGrid.instance.onScroll(mouseX, mouseY, horizontalAmount + verticalAmount); - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - this.canClick = true; - ChunkGrid.instance.onClicked(mouseX, mouseY, button); - return super.mouseClicked(mouseX, mouseY, button); - } - - @Override - public boolean mouseReleased(double mouseX, double mouseY, int button) { - if (this.canClick) { - ChunkGrid.instance.onRelease(mouseX, mouseY, button); - } - return super.mouseReleased(mouseX, mouseY, button); - } - - @Override - public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { - ChunkGrid.instance.onDragged(mouseX, mouseY, button); - return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); - } - - private class NumberFieldWidget extends TextFieldWidget { - private int lastValidValue; - - private NumberFieldWidget(TextRenderer textRenderer, int x, int y, int width, int height, Text text) { - super(textRenderer, x, y, width, height, text); - } - - private void setInitialValue(int value) { - this.lastValidValue = value; - this.setText(String.valueOf(value)); - } - - private int getValue() { - return this.lastValidValue; - } - - @Override - public void setFocused(boolean focused) { - if (this.isFocused() && !focused) { - try { - int newValue = Integer.parseInt(this.getText()); - if (this.lastValidValue != newValue) { - this.lastValidValue = newValue; - ChunkGrid.instance.setCentre( - ChunkDebugScreen.this.xPositionBox.getValue(), - ChunkDebugScreen.this.zPositionBox.getValue() - ); - } - } catch (NumberFormatException e) { - this.setText(String.valueOf(this.lastValidValue)); - } - } - super.setFocused(focused); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkGrid.java b/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkGrid.java deleted file mode 100644 index 74c81d08..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkGrid.java +++ /dev/null @@ -1,536 +0,0 @@ -package me.senseiwells.essentialclient.feature.chunkdebug; - -import com.mojang.blaze3d.systems.RenderSystem; -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.render.RenderHelper; -import me.senseiwells.essentialclient.utils.render.Texts; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.render.BufferBuilder; -import net.minecraft.client.render.Tessellator; -import net.minecraft.client.render.VertexFormats; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.registry.RegistryKey; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.math.ChunkPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.world.World; - -import java.awt.*; -import java.util.List; -import java.util.*; - -public class ChunkGrid { - public static ChunkGrid instance; - - private int width; - private int height; - private int columns; - private int rows; - private int startX = 0; - private int startY = 0; - private int scale = 10; - - private final MinecraftClient client; - private final DraggablePoint cornerPoint; - private final Point staticCentrePoint = new Point(); - private final Point minimapCornerPoint = new Point(); - private final Point mouseDown = new Point(); - private final List> dimensions; - private final Map, DraggablePoint> dimensionPoints = new LinkedHashMap<>(); - - private boolean panning = false; - private int dimensionIndex = 0; - private Text selectionText = null; - private Minimap minimapMode = Minimap.NONE; - - public ChunkGrid(MinecraftClient client, int width, int height) { - this.client = client; - this.width = width; - this.height = height; - this.updateRowsAndColumns(); - - for (RegistryKey key : EssentialUtils.getNetworkHandler().getWorldKeys()) { - this.dimensionPoints.put(key, null); - } - - this.dimensions = this.dimensionPoints.keySet().stream().toList(); - ClientPlayerEntity player = client.player; - if (player != null) { - ChunkPos pos = player.getChunkPos(); - this.cornerPoint = new DraggablePoint(this.getCornerOfCentre(pos.x, pos.z)); - int dimensionIndex = this.dimensions.indexOf(player.getEntityWorld().getRegistryKey()); - this.dimensionIndex = dimensionIndex == -1 ? 0 : dimensionIndex; - } else { - this.cornerPoint = new DraggablePoint(this.getCornerOfCentre(0, 0)); - } - this.cornerPoint.mainPoint.y += 5; - } - - private void updateRowsAndColumns() { - this.rows = (int) Math.floor((float) this.height / this.scale); - this.columns = (int) Math.ceil((float) this.width / this.scale); - } - - public void render(int thisX, int thisY, int width, int height, boolean isMinimap) { - this.width = width; - this.height = height; - this.startX = thisX; - this.startY = thisY; - this.updateRowsAndColumns(); - - Tessellator tessellator = Tessellator.getInstance(); - - RenderSystem.enableDepthTest(); - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - RenderHelper.setPositionColourShader(); - - BufferBuilder bufferBuilder = RenderHelper.startQuads(tessellator, VertexFormats.POSITION_COLOR); - - if (isMinimap && ClientRules.CHUNK_DEBUG_MINIMAP_BACKGROUND.getValue()) { - int thatX = thisX + this.scale * (this.columns + 1); - int thatY = thisY + this.scale * (this.rows + 1); - - bufferBuilder.vertex(thisX - 5, thisY - 5, 0).color(53, 59, 72, 200); - bufferBuilder.vertex(thisX - 5, thatY + 5, 0).color(53, 59, 72, 200); - bufferBuilder.vertex(thatX + 5, thatY + 5, 0).color(53, 59, 72, 200); - bufferBuilder.vertex(thatX + 5, thisY - 5, 0).color(53, 59, 72, 200); - - bufferBuilder.vertex(thisX, thisY, 0).color(45, 52, 54, 200); - bufferBuilder.vertex(thisX, thatY, 0).color(45, 52, 54, 200); - bufferBuilder.vertex(thatX, thatY, 0).color(45, 52, 54, 200); - bufferBuilder.vertex(thatX, thisY, 0).color(45, 52, 54, 200); - } - - for (ChunkInfo info : EssentialClient.CHUNK_NET_HANDLER.getChunks(this.getDimension())) { - if (info.level() == ChunkLevel.UNLOADED && !ClientRules.CHUNK_DEBUG_SHOW_UNLOADED_CHUNKS.getValue()) { - continue; - } - int x = info.getX() - (isMinimap ? this.minimapCornerPoint.x : this.cornerPoint.getX()); - int z = info.getZ() - (isMinimap ? this.minimapCornerPoint.y : this.cornerPoint.getY()); - if (x < 0 || x > this.columns || z < 0 || z > this.rows) { - continue; - } - int cellX = thisX + x * this.scale; - int cellY = thisY + z * this.scale; - this.drawBox(bufferBuilder, cellX, cellY, x, z, info.getColour()); - } - - ClientPlayerEntity player = this.client.player; - if (player != null && this.isPlayerInDimension(player)) { - ChunkPos playerChunkPos = player.getChunkPos(); - int x = playerChunkPos.x - (isMinimap ? this.minimapCornerPoint.x : this.cornerPoint.getX()); - int z = playerChunkPos.z - (isMinimap ? this.minimapCornerPoint.y : this.cornerPoint.getY()); - if (x >= 0 && x <= this.columns && z >= 0 && z <= this.rows) { - int cellX = thisX + x * this.scale; - int cellY = thisY + z * this.scale; - - this.drawCross(tessellator, cellX, cellY, thisX, thisY); - } - } - - DraggablePoint selectionPoint = this.getSelectionPoint(); - if (selectionPoint != null) { - Point drawingPoint = selectionPoint.mainPoint; - if (isMinimap) { - int minimapSelectionX = this.cornerPoint.getX() + selectionPoint.getX() - this.minimapCornerPoint.x; - int minimapSelectionZ = this.cornerPoint.getY() + selectionPoint.getY() - this.minimapCornerPoint.y; - drawingPoint = new Point(minimapSelectionX, minimapSelectionZ); - } - this.drawSelectionBox(tessellator, drawingPoint, thisX, thisY); - this.updateSelectionInfo(); - } else { - this.selectionText = null; - } - - if (!isMinimap) { - this.updateStaticCentre(); - } - - RenderSystem.disableBlend(); - } - - public void renderMinimap(int width, int height) { - if (this.minimapMode == Minimap.NONE) { - return; - } - this.width = (int) (width * 0.25F); - this.height = (int) (height * 0.45F); - this.updateRowsAndColumns(); - int minimapX = width - this.scale * (this.columns + 1) - 10; - int minimapY = 10; - switch (this.minimapMode) { - case STATIC -> { - Point minimapCorner = this.getCornerOfCentre(this.staticCentrePoint.x, this.staticCentrePoint.y); - this.minimapCornerPoint.setLocation(minimapCorner); - } - case FOLLOW -> { - ClientPlayerEntity player = this.client.player; - if (player != null) { - if (!this.isPlayerInDimension(player) && !(this.client.currentScreen instanceof ChunkDebugScreen)) { - this.setDimension(player.getEntityWorld()); - EssentialClient.CHUNK_NET_HANDLER.requestChunkData(this.getDimension()); - } - ChunkPos pos = player.getChunkPos(); - Point minimapCorner = this.getCornerOfCentre(pos.x, pos.z); - this.minimapCornerPoint.setLocation(minimapCorner); - } - } - } - this.render(minimapX, minimapY, this.width, this.height, true); - } - - private void drawBox(BufferBuilder bufferBuilder, int cellX, int cellY, int x, int y, int colour) { - if ((x + y) % 2 == 0) { - colour = brighten(colour, 0.14F); - } - - int red = (colour & 0xff0000) >> 16; - int green = (colour & 0xff00) >> 8; - int blue = (colour & 0xff); - - bufferBuilder.vertex(cellX, cellY, 0).color(red, green, blue, 255); - bufferBuilder.vertex(cellX, cellY + this.scale, 0).color(red, green, blue, 255); - bufferBuilder.vertex(cellX + this.scale, cellY + this.scale, 0).color(red, green, blue, 255); - bufferBuilder.vertex(cellX + this.scale, cellY, 0).color(red, green, blue, 255); - } - - private void drawSelectionBox(Tessellator tessellator, Point selectionPoint, int thisX, int thisY) { - int red = 0xF7; - int green = 0xF0; - int blue = 0x06; - - int x = selectionPoint.x; - int z = selectionPoint.y; - int scaledX = x * this.scale; - int scaledZ = z * this.scale; - int cellX = thisX + scaledX; - int cellY = thisY + scaledZ; - - if (cellX < thisX || cellY < thisY || cellX + this.scale > thisX + this.width || cellY + this.scale > thisY + this.height) { - return; - } - - BufferBuilder bufferBuilder = RenderHelper.startDebugLines(tessellator, VertexFormats.POSITION_COLOR); - bufferBuilder.vertex(cellX, cellY, 0).color(red, green, blue, 255); - bufferBuilder.vertex(cellX, cellY + this.scale, 0).color(red, green, blue, 255); - bufferBuilder.vertex(cellX, cellY + this.scale, 0).color(red, green, blue, 255); - bufferBuilder.vertex(cellX + this.scale, cellY + this.scale, 0).color(red, green, blue, 255); - bufferBuilder.vertex(cellX + this.scale, cellY + this.scale, 0).color(red, green, blue, 255); - bufferBuilder.vertex(cellX + this.scale, cellY, 0).color(red, green, blue, 255); - bufferBuilder.vertex(cellX + this.scale, cellY, 0).color(red, green, blue, 255); - bufferBuilder.vertex(cellX, cellY, 0).color(red, green, blue, 255); - } - - private void drawCross(Tessellator tessellator, int cellX, int cellY, int x, int y) { - int red = 0xF7; - int green = 0xF0; - int blue = 0x06; - - if (cellX < x || cellY < y || cellX + this.scale > x + this.width || cellY + this.scale > y + this.height) { - return; - } - - BufferBuilder bufferBuilder = RenderHelper.startDebugLines(tessellator, VertexFormats.POSITION_COLOR); - bufferBuilder.vertex(cellX, cellY, 0).color(red, green, blue, 255); - bufferBuilder.vertex(cellX + this.scale, cellY + this.scale, 0).color(red, green, blue, 255); - bufferBuilder.vertex(cellX + this.scale, cellY, 0).color(red, green, blue, 255); - bufferBuilder.vertex(cellX, cellY + this.scale, 0).color(red, green, blue, 255); - } - - public boolean onScroll(double mouseX, double mouseY, double amount) { - if (this.isInBounds(mouseX, mouseY) && !this.panning) { - if ((amount > 0 && this.scale < 20) || (amount < 0 && this.scale > 1)) { - this.syncSelectionPointsWithCorner(() -> this.updateCornerScroll(MathHelper.clamp(amount, -1, 1))); - return true; - } - } - return false; - } - - private void updateCornerScroll(double scrollAmount) { - this.scale += (int) scrollAmount; - Point centre = this.getCentre(); - this.updateRowsAndColumns(); - this.cornerPoint.setLocation(this.getCornerOfCentre(centre.x, centre.y)); - } - - public void onClicked(double mouseX, double mouseY, int button) { - if (button == 0 && this.isInBounds(mouseX, mouseY)) { - this.mouseDown.setLocation((int) mouseX, (int) mouseY); - this.cornerPoint.getDragPoint().setLocation(this.cornerPoint.mainPoint); - this.dimensionPoints.values().forEach(draggablePoint -> { - if (draggablePoint != null) { - draggablePoint.dragPoint.setLocation(draggablePoint.mainPoint); - } - }); - } - } - - public void onRelease(double mouseX, double mouseY, int button) { - if (button == 0 && !this.panning) { - Point newSelectionPoint = this.getPointFromPosition(mouseX, mouseY); - DraggablePoint oldSelectionPoint = this.getSelectionPoint(); - if (oldSelectionPoint != null && oldSelectionPoint.mainPoint.equals(newSelectionPoint)) { - this.setSelectionPoint(null); - this.selectionText = null; - } else if (newSelectionPoint != null) { - this.setSelectionPoint(new DraggablePoint(newSelectionPoint)); - this.updateSelectionInfo(); - } - } - this.panning = false; - } - - public void onDragged(double mouseX, double mouseY, int button) { - if (button == 0 && this.isInBounds(mouseX, mouseY)) { - int changeX = (int) (mouseX - this.mouseDown.getX()) / this.scale; - int changeY = (int) (mouseY - this.mouseDown.getY()) / this.scale; - if (!this.panning && changeX * changeX + changeY * changeY > 2) { - this.panning = true; - } else if (this.panning) { - int dragX = this.cornerPoint.dragPoint.x - changeX; - int dragY = this.cornerPoint.dragPoint.y - changeY; - this.cornerPoint.setLocation(dragX, dragY); - this.updateSelectionPointDrag(changeX, changeY); - } - } - } - - public void onResize(int newWidth, int newHeight) { - Point centre = this.getCentre(); - this.width = newWidth; - this.height = newHeight; - this.updateRowsAndColumns(); - this.setCentre(centre.x, centre.y); - } - - public void setCentre(int x, int y) { - this.syncSelectionPointsWithCorner(() -> this.cornerPoint.setLocation(this.getCornerOfCentre(x, y))); - } - - private void syncSelectionPointsWithCorner(Runnable cornerFunction) { - Collection draggablePoints = this.dimensionPoints.values(); - draggablePoints.forEach(draggablePoint -> { - if (draggablePoint != null) { - draggablePoint.setLocation( - this.cornerPoint.getX() + draggablePoint.getX(), - this.cornerPoint.getY() + draggablePoint.getY() - ); - } - }); - cornerFunction.run(); - draggablePoints.forEach(draggablePoint -> { - if (draggablePoint != null) { - draggablePoint.setLocation( - draggablePoint.getX() - this.cornerPoint.getX(), - draggablePoint.getY() - this.cornerPoint.getY() - ); - } - }); - } - - private void updateSelectionPointDrag(int changeX, int changeY) { - this.dimensionPoints.values().forEach(draggablePoint -> { - if (draggablePoint != null) { - int dragX = draggablePoint.dragPoint.x + changeX; - int dragY = draggablePoint.dragPoint.y + changeY; - draggablePoint.setLocation(dragX, dragY); - } - }); - } - - public void updateSelectionInfo() { - DraggablePoint selectionPoint = this.getSelectionPoint(); - if (selectionPoint != null) { - ChunkPos chunkPos = new ChunkPos(this.cornerPoint.getX() + selectionPoint.getX(), this.cornerPoint.getY() + selectionPoint.getY()); - Optional chunkData = EssentialClient.CHUNK_NET_HANDLER.getChunk(this.getDimension(), chunkPos); - boolean isEmpty = chunkData.isEmpty(); - MutableText selection = Texts.SELECTED_CHUNK.generate("X: " + chunkPos.x + ", Z: " + chunkPos.z); - selection.append(" || "); - selection.append(Texts.CHUNK_STATUS.generate((isEmpty ? ChunkLevel.UNLOADED : chunkData.get().level()).getName())); - if (!isEmpty) { - ChunkInfo data = chunkData.get(); - if (data.hasTicket()) { - selection.append(" || "); - selection.append(Texts.CHUNK_TICKET.generate(data.ticket().getName())); - } - selection.append(" || "); - selection.append(Texts.CHUNK_STAGE.generate(data.status().getName())); - } - this.selectionText = selection; - } - } - - private void updateStaticCentre() { - this.staticCentrePoint.setLocation(this.getCentre()); - } - - public int getCentreX() { - return this.getCentre().x; - } - - public int getCentreZ() { - return this.getCentre().y; - } - - public RegistryKey getDimension() { - return this.dimensions.get(this.dimensionIndex); - } - - public boolean isPlayerInDimension(PlayerEntity player) { - return this.getDimension().equals(player.getEntityWorld().getRegistryKey()); - } - - private DraggablePoint getSelectionPoint() { - return this.dimensionPoints.get(this.getDimension()); - } - - private void setSelectionPoint(DraggablePoint newPoint) { - this.dimensionPoints.put(this.getDimension(), newPoint); - } - - public Text getSelectionText() { - return this.selectionText; - } - - public Text getPrettyDimension() { - RegistryKey dimension = this.getDimension(); - if (dimension == World.OVERWORLD) { - return Texts.OVERWORLD; - } - if (dimension == World.NETHER) { - return Texts.NETHER; - } - if (dimension == World.END) { - return Texts.END; - } - return Text.literal(dimension.getValue().getPath()); - } - - public void setDimension(World world) { - int dimensionIndex = this.dimensions.indexOf(world.getRegistryKey()); - this.dimensionIndex = dimensionIndex == -1 ? 0 : dimensionIndex; - } - - public void cycleDimension() { - if (this.dimensionIndex >= this.dimensions.size() - 1) { - this.dimensionIndex = 0; - return; - } - this.dimensionIndex++; - } - - public Minimap getMinimapMode() { - return this.minimapMode; - } - - public void cycleMinimap() { - this.minimapMode = this.minimapMode.getNextMinimap(); - } - - public boolean isPanning() { - return this.panning; - } - - private boolean isInBounds(double mouseX, double mouseY) { - boolean withinX = mouseX > this.startX && mouseX < this.startX + this.width; - boolean withinY = mouseY > this.startY && mouseY < this.startY + this.height; - return withinX && withinY; - } - - private Point getCentre() { - int centreX = this.cornerPoint.getX() + this.columns / 2; - int centreY = this.cornerPoint.getY() + this.rows / 2; - return new Point(centreX, centreY); - } - - private Point getCornerOfCentre(int centreX, int centreY) { - int cornerX = centreX - this.columns / 2; - int cornerY = centreY - this.rows / 2; - return new Point(cornerX, cornerY); - } - - private Point getPointFromPosition(double x, double y) { - if (!this.isInBounds(x, y)) { - return null; - } - y = y - ChunkDebugScreen.HEADER_HEIGHT; - int pointX = (int) (x / this.scale); - int pointY = (int) (y / this.scale); - return new Point(pointX, pointY); - } - - @SuppressWarnings("SameParameterValue") - private static int brighten(int colour, float factor) { - int alpha = (colour & 0xff000000) >>> 24; - int red = (colour & 0xff0000) >> 16; - int green = (colour & 0xff00) >> 8; - int blue = colour & 0xff; - int mix = (int) ((red + green + blue) * factor / 3); - red += mix; - green += mix; - blue += mix; - int redOverflow = Integer.max(red - 255, 0); - int greenOverflow = Integer.max(green - 255, 0); - int blueOverflow = Integer.max(blue - 255, 0); - red = Integer.min(red - redOverflow * 3, 255); - green = Integer.min(green - greenOverflow * 3, 255); - blue = Integer.min(blue - blueOverflow * 3, 255); - return (alpha << 24) | (red << 16) | (green << 8) | (blue); - } - - public enum Minimap { - NONE(Texts.MINIMAP_NONE), - STATIC(Texts.MINIMAP_STATIC), - FOLLOW(Texts.MINIMAP_FOLLOW); - - public final Text prettyName; - - Minimap(Text prettyName) { - this.prettyName = prettyName; - } - - private Minimap getNextMinimap() { - int ordinal = this.ordinal(); - if (this.ordinal() >= 2) { - return NONE; - } - return Minimap.values()[ordinal + 1]; - } - } - - private static class DraggablePoint { - private final Point mainPoint; - private final Point dragPoint = new Point(); - - private DraggablePoint(Point main) { - this.mainPoint = main; - } - - private int getX() { - return this.mainPoint.x; - } - - private int getY() { - return this.mainPoint.y; - } - - private Point getDragPoint() { - return this.dragPoint; - } - - private void setLocation(Point newLocation) { - this.mainPoint.setLocation(newLocation); - } - - private void setLocation(int x, int y) { - this.mainPoint.setLocation(x, y); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkInfo.java b/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkInfo.java deleted file mode 100644 index b0dc85b4..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkInfo.java +++ /dev/null @@ -1,49 +0,0 @@ -package me.senseiwells.essentialclient.feature.chunkdebug; - -import net.minecraft.util.math.ChunkPos; - -public class ChunkInfo { - private final long position; - private final ChunkLevel level; - private final ChunkStatus status; - private final ChunkTicket ticket; - - public ChunkInfo(long position, ChunkLevel level, ChunkStatus status, ChunkTicket ticket) { - this.position = position; - this.level = level; - this.status = status; - this.ticket = ticket; - } - - public long position() { - return this.position; - } - - public int getX() { - return ChunkPos.getPackedX(this.position); - } - - public int getZ() { - return ChunkPos.getPackedZ(this.position); - } - - public ChunkLevel level() { - return this.level; - } - - public ChunkStatus status() { - return this.status; - } - - public boolean hasTicket() { - return this.ticket != null; - } - - public ChunkTicket ticket() { - return this.ticket; - } - - public int getColour() { - return Colourable.getHighestPriority(this.level, this.status, this.ticket).getColour(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkLevel.java b/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkLevel.java deleted file mode 100644 index 9063f5ce..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkLevel.java +++ /dev/null @@ -1,41 +0,0 @@ -package me.senseiwells.essentialclient.feature.chunkdebug; - -import me.senseiwells.essentialclient.utils.render.Texts; -import net.minecraft.text.Text; - -public enum ChunkLevel implements Colourable { - UNLOADED(Texts.UNLOADED, 0x404040), // Dark grey - BORDER(Texts.BORDER, 0x4FC3F7), // Light blue - LAZY(Texts.LAZY, 0xFFA219), // Orange-yellow - ENTITY_TICKING(Texts.ENTITY_TICKING, 0x198C19); // Green - - private final Text prettyName; - private final int colour; - - ChunkLevel(Text prettyName, int colour) { - this.prettyName = prettyName; - this.colour = colour; - } - - public static ChunkLevel decodeChunkType(int code) { - if (code < 1 || code > 3) { - return UNLOADED; - } - return ChunkLevel.values()[code]; - } - - @Override - public int getColour() { - return this.colour; - } - - @Override - public int getPriority() { - return 1; - } - - @Override - public Text getName() { - return this.prettyName; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkStatus.java b/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkStatus.java deleted file mode 100644 index a5ef15b0..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkStatus.java +++ /dev/null @@ -1,51 +0,0 @@ -package me.senseiwells.essentialclient.feature.chunkdebug; - -import me.senseiwells.essentialclient.utils.render.Texts; -import net.minecraft.text.Text; - -public enum ChunkStatus implements Colourable { - EMPTY(Texts.EMPTY_STATUS, -1), - STRUCTURE_STARTS(Texts.STRUCTURE_STARTS, 0x98F859), // Pale green - STRUCTURE_REFERENCES(Texts.STRUCTURE_REFERENCES, 0xFFBC2C), // Light orange - BIOMES(Texts.BIOMES, 0x8FB815), // Dark lime green - NOISE(Texts.NOISE, 0x61857F), // Grey-blue - SURFACE(Texts.SURFACE, 0x013220), // Pine green - CARVERS(Texts.CARVERS, 0x88631F), // Brown - FEATURES(Texts.FEATURES, 0x3659DE), // Blue - INITIALIZE_LIGHT(Texts.TICKET_LIGHT, -1), - LIGHT(Texts.TICKET_LIGHT, -1), - SPAWN(Texts.SPAWN, 0xBFFF00), // Lime green - FULL(Texts.FULL, 0x0A18D8); // Dark blue - - private static final int COUNT = ChunkStatus.values().length; - - private final Text prettyName; - private final int colour; - - ChunkStatus(Text prettyName, int colour) { - this.prettyName = prettyName; - this.colour = colour; - } - - @Override - public int getColour() { - return this.colour; - } - - @Override - public int getPriority() { - return this.ordinal() > 0 && this.ordinal() < (COUNT - 1) ? 3 : 0; - } - - @Override - public Text getName() { - return this.prettyName; - } - - public static ChunkStatus decodeChunkStatus(int code) { - if (code < 1 || code >= COUNT) { - return EMPTY; - } - return ChunkStatus.values()[code]; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkTicket.java b/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkTicket.java deleted file mode 100644 index a9b86dbf..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/ChunkTicket.java +++ /dev/null @@ -1,46 +0,0 @@ -package me.senseiwells.essentialclient.feature.chunkdebug; - -import me.senseiwells.essentialclient.utils.render.Texts; -import net.minecraft.text.Text; - -public enum ChunkTicket implements Colourable { - START(Texts.TICKET_SPAWN, 0xBFFF00), // Lime green - DRAGON(Texts.DRAGON, 0xCC00CC), // Magenta - PLAYER(Texts.PLAYER, -1), // Green - FORCED(Texts.FORCED, 0x336FFF), // Blue - LIGHT(Texts.LIGHT, -1), - PORTAL(Texts.PORTAL, 0x472483), // Purple - POST_TELEPORT(Texts.TELEPORT, 0xFF6600), // Orange - CHONK(Texts.CHONK, 0x72FF13), // Light Green - UNKNOWN(Texts.TICKET_UNKNOWN, -1); - - private final Text prettyName; - private final int colour; - - ChunkTicket(Text prettyName, int colour) { - this.prettyName = prettyName; - this.colour = colour; - } - - @Override - public int getColour() { - return this.colour; - } - - @Override - public int getPriority() { - return this.hasColour() ? 2 : 0; - } - - @Override - public Text getName() { - return this.prettyName; - } - - public static ChunkTicket decodeTicketType(int code) { - if (code < 1 || code > 9) { - return null; - } - return ChunkTicket.values()[code - 1]; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/Colourable.java b/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/Colourable.java deleted file mode 100644 index 322a8157..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/Colourable.java +++ /dev/null @@ -1,24 +0,0 @@ -package me.senseiwells.essentialclient.feature.chunkdebug; - -import net.minecraft.text.Text; - -public interface Colourable { - int getColour(); - - int getPriority(); - - Text getName(); - - default boolean hasColour() { - return this.getColour() >= 0; - } - - static Colourable getHighestPriority(Colourable highest, Colourable... colourables) { - for (Colourable other : colourables) { - if (other != null && other.getPriority() > highest.getPriority()) { - highest = other; - } - } - return highest; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/WorldChunkInfo.java b/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/WorldChunkInfo.java deleted file mode 100644 index ef6ede39..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/chunkdebug/WorldChunkInfo.java +++ /dev/null @@ -1,44 +0,0 @@ -package me.senseiwells.essentialclient.feature.chunkdebug; - -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import net.minecraft.util.math.ChunkPos; - -public class WorldChunkInfo { - private final Long2ObjectMap chunks; - private final ChunkClusters clusters; - - public WorldChunkInfo() { - this.chunks = new Long2ObjectOpenHashMap<>(); - this.clusters = new ChunkClusters(); - } - - public ChunkInfo getInfo(ChunkPos pos) { - return this.chunks.get(pos.toLong()); - } - - public ChunkInfo getInfo(long position) { - return this.chunks.get(position); - } - - public Iterable getAllInfo() { - return this.chunks.values(); - } - - public ChunkClusters getClusters() { - return this.clusters; - } - - public void clear() { - this.chunks.clear(); - this.clusters.clear(); - } - - void remove(long position) { - this.chunks.remove(position); - } - - void add(ChunkInfo info) { - this.chunks.put(info.position(), info); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/keybinds/ClientKeyBind.java b/src/main/java/me/senseiwells/essentialclient/feature/keybinds/ClientKeyBind.java deleted file mode 100644 index d387fd07..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/keybinds/ClientKeyBind.java +++ /dev/null @@ -1,100 +0,0 @@ -package me.senseiwells.essentialclient.feature.keybinds; - -import me.senseiwells.essentialclient.utils.EssentialUtils; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.util.InputUtil; -import org.jetbrains.annotations.NotNull; - -import java.util.Collection; -import java.util.Iterator; - -public abstract class ClientKeyBind implements Comparable { - private final String name; - private final String category; - - private boolean canUseInGui; - private boolean isPressed; - - private Callback callback; - - ClientKeyBind(String name, String category) { - this.name = name; - this.category = category; - } - - public abstract void press(InputUtil.Key key); - - public abstract void release(InputUtil.Key key); - - public abstract void addKey(InputUtil.Key key); - - public abstract void clearKey(); - - public abstract void resetKey(); - - public abstract boolean isSingleKey(); - - public abstract boolean isDefault(); - - public abstract Collection getKeys(); - - public void setCallback(Callback callback) { - this.callback = callback; - } - - public Callback getCallback() { - return this.callback; - } - - void setPressed(boolean pressed) { - this.isPressed = pressed; - } - - void setCanUseInGui(boolean canUseInGui) { - this.canUseInGui = canUseInGui; - } - - void callCallback() { - if (this.callback != null) { - this.callback.pressed(EssentialUtils.getClient()); - } - } - - public boolean isPressed() { - return this.isPressed; - } - - public boolean canUseInGui() { - return this.canUseInGui; - } - - public String getName() { - return this.name; - } - - public String getCategory() { - return this.category; - } - - public String getDisplay() { - StringBuilder builder = new StringBuilder(); - Iterator keyIterator = this.getKeys().iterator(); - while (keyIterator.hasNext()) { - builder.append(keyIterator.next().getLocalizedText().getString()); - if (keyIterator.hasNext()) { - builder.append(" + "); - } - } - return builder.toString(); - } - - @Override - public int compareTo(@NotNull ClientKeyBind o) { - return this.name.compareTo(o.name); - } - - @FunctionalInterface - public interface Callback { - void pressed(MinecraftClient client); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/keybinds/ClientKeyBinds.java b/src/main/java/me/senseiwells/essentialclient/feature/keybinds/ClientKeyBinds.java deleted file mode 100644 index 18cb3e94..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/keybinds/ClientKeyBinds.java +++ /dev/null @@ -1,225 +0,0 @@ -package me.senseiwells.essentialclient.feature.keybinds; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.clientscript.core.ClientScript; -import me.senseiwells.essentialclient.feature.chunkdebug.ChunkDebugScreen; -import me.senseiwells.essentialclient.gui.clientscript.ClientScriptScreen; -import me.senseiwells.essentialclient.gui.config.ConfigScreen; -import me.senseiwells.essentialclient.utils.config.MappedStringConfig; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.util.InputUtil; -import org.lwjgl.glfw.GLFW; - -import java.util.*; -import java.util.function.Supplier; - -public class ClientKeyBinds extends MappedStringConfig { - private static final String DEFAULT_CATEGORY = "Essential Client"; - - public static final ClientKeyBinds INSTANCE = new ClientKeyBinds(); - - public static final MultiKeyBind - ACCURATE_REVERSE, - ACCURATE_INTO, - CLIENT_SCRIPT_TOGGLE_ALL, - CLIENT_SCRIPT_STOP_ALL, - OPEN_ESSENTIAL_CLIENT_MENU, - OPEN_CHUNK_DEBUG, - OPEN_CLIENT_SCRIPT; - - public static final SingleKeyBind - TOGGLE_DEBUG_MENU; - - static { - ACCURATE_REVERSE = registerMulti("Accurate Reverse"); - ACCURATE_INTO = registerMulti("Accurate Into"); - CLIENT_SCRIPT_TOGGLE_ALL = registerMulti("Toggle Selected Scripts", client -> ClientScript.INSTANCE.startAllInstances()); - CLIENT_SCRIPT_STOP_ALL = registerMulti("Stop Selected Scripts", client -> ClientScript.INSTANCE.stopAllInstances()); - OPEN_ESSENTIAL_CLIENT_MENU = registerMulti("Open Essential Client Menu", client -> setScreenIfNull(client, () -> new ConfigScreen(null))); - OPEN_CLIENT_SCRIPT = registerMulti("Open Client Script", client -> setScreenIfNull(client, () -> new ClientScriptScreen(null))); - OPEN_CHUNK_DEBUG = registerMulti("Open Chunk Debug", client -> { - if (EssentialClient.CHUNK_NET_HANDLER.isAvailable()) { - if (client.currentScreen instanceof ChunkDebugScreen) { - client.currentScreen.close(); - return; - } - setScreenIfNull(client, () -> new ChunkDebugScreen(null)); - } - }, GLFW.GLFW_KEY_F6); - - TOGGLE_DEBUG_MENU = registerSingle("Toggle Debug Menu", GLFW.GLFW_KEY_F3); - } - - private final Map> unregisteredKeyBinds; - - private ClientKeyBinds() { - this.unregisteredKeyBinds = new HashMap<>(); - } - - public static void load() { } - - @Override - protected JsonElement valueToJson(ClientKeyBind value) { - JsonArray keys = new JsonArray(); - for (InputUtil.Key key : value.getKeys()) { - keys.add(key.getTranslationKey()); - } - JsonObject keyData = new JsonObject(); - keyData.add("keys", keys); - keyData.addProperty("canUseInGui", value.canUseInGui()); - return keyData; - } - - @Override - protected ClientKeyBind jsonToValue(String key, JsonElement valueElement) { - ClientKeyBind existingKeyBind = this.map.get(key); - - List keys = new ArrayList<>(); - if (valueElement.isJsonPrimitive()) { - keys.add(InputUtil.fromTranslationKey(valueElement.getAsString())); - } else if (valueElement.isJsonArray()) { - for (JsonElement element : valueElement.getAsJsonArray()) { - keys.add(InputUtil.fromTranslationKey(element.getAsString())); - } - } else { - JsonObject keyData = valueElement.getAsJsonObject(); - for (JsonElement element : keyData.get("keys").getAsJsonArray()) { - keys.add(InputUtil.fromTranslationKey(element.getAsString())); - } - if (existingKeyBind != null && keyData.has("canUseInGui")) { - existingKeyBind.setCanUseInGui(keyData.get("canUseInGui").getAsBoolean()); - } - } - - if (existingKeyBind != null) { - existingKeyBind.clearKey(); - for (InputUtil.Key inputKey : keys) { - existingKeyBind.addKey(inputKey); - } - } else { - this.unregisteredKeyBinds.put(key, keys); - EssentialClient.LOGGER.warn("Could not load keybind: {}", key); - } - return null; - } - - @Override - public JsonObject getSaveData() { - JsonObject object = new JsonObject(); - this.map.forEach((k, v) -> object.add(k, this.valueToJson(v))); - this.unregisteredKeyBinds.forEach((s, keys) -> { - JsonArray array = new JsonArray(); - for (InputUtil.Key key : keys) { - array.add(key.getTranslationKey()); - } - object.add(s, array); - }); - return super.getSaveData(); - } - - @Override - public String getConfigName() { - return "ClientKeyBinds"; - } - - public static void onKeyPress(InputUtil.Key key, boolean isInGui) { - for (ClientKeyBind keyBind : getAllKeyBinds()) { - if (keyBind.canUseInGui() || !isInGui) { - keyBind.press(key); - } - } - } - - public static void onKeyRelease(InputUtil.Key key, boolean isInGui) { - for (ClientKeyBind keyBind : getAllKeyBinds()) { - if (keyBind.canUseInGui() || !isInGui) { - keyBind.release(key); - } - } - } - - public static Collection getAllKeyBinds() { - return INSTANCE.map.values(); - } - - public static MultiKeyBind registerMulti(String name, int... keys) { - return registerMulti(name, null, keys); - } - - public static MultiKeyBind registerMulti(String name, ClientKeyBind.Callback onPressed, int... keys) { - return registerMulti(name, DEFAULT_CATEGORY, onPressed, keys); - } - - public static MultiKeyBind registerMulti(String name, String category, ClientKeyBind.Callback onPressed, Collection keys) { - return registerMulti(name, category, onPressed, keys.stream().mapToInt(InputUtil.Key::getCode).toArray()); - } - - public static MultiKeyBind registerMulti(String name, String category, ClientKeyBind.Callback onPressed, int... keys) { - ClientKeyBind clientKeyBind = ClientKeyBinds.INSTANCE.map.get(name); - if (clientKeyBind instanceof MultiKeyBind multiKeyBind) { - multiKeyBind.setCallback(onPressed); - return multiKeyBind; - } - - if (clientKeyBind != null) { - EssentialClient.LOGGER.warn("Overwriting key bind {}", name); - } - - MultiKeyBind keyBind = new MultiKeyBind(name, category); - List inputKeys = INSTANCE.unregisteredKeyBinds.remove(name); - if (inputKeys != null) { - keyBind.clearKey(); - inputKeys.forEach(keyBind::addKey); - } else { - keyBind.addKeys(keys); - } - keyBind.setCallback(onPressed); - - INSTANCE.map.put(name, keyBind); - return keyBind; - } - - public static SingleKeyBind registerSingle(String name, int key) { - return registerSingle(name, null, key); - } - - public static SingleKeyBind registerSingle(String name, ClientKeyBind.Callback onPressed, int key) { - return registerSingle(name, DEFAULT_CATEGORY, onPressed, key); - } - - public static SingleKeyBind registerSingle(String name, String category, ClientKeyBind.Callback onPressed, int key) { - ClientKeyBind clientKeyBind = INSTANCE.map.get(name); - if (clientKeyBind instanceof SingleKeyBind singleKeyBind) { - singleKeyBind.setCallback(onPressed); - return singleKeyBind; - } - - if (clientKeyBind != null) { - EssentialClient.LOGGER.warn("Overwriting key bind {}", name); - } - - SingleKeyBind keyBind = new SingleKeyBind(name, category, InputUtil.fromKeyCode(key, 0)); - List inputKeys = INSTANCE.unregisteredKeyBinds.remove(name); - if (inputKeys != null && inputKeys.size() == 1) { - keyBind.addKey(inputKeys.get(0)); - } - keyBind.setCallback(onPressed); - - INSTANCE.map.put(name, keyBind); - return keyBind; - } - - public static ClientKeyBind unregisterKeyBind(String name) { - return INSTANCE.map.remove(name); - } - - private static void setScreenIfNull(MinecraftClient client, Supplier screenFactory) { - if (client.currentScreen == null) { - client.setScreen(screenFactory.get()); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/keybinds/MultiKeyBind.java b/src/main/java/me/senseiwells/essentialclient/feature/keybinds/MultiKeyBind.java deleted file mode 100644 index 64f3ff90..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/keybinds/MultiKeyBind.java +++ /dev/null @@ -1,98 +0,0 @@ -package me.senseiwells.essentialclient.feature.keybinds; - -import me.senseiwells.essentialclient.utils.EssentialUtils; -import net.minecraft.client.util.InputUtil; - -import java.util.LinkedHashSet; -import java.util.Set; - -public class MultiKeyBind extends ClientKeyBind { - private final Set keys; - private final InputUtil.Key[] defaultKeys; - private InputUtil.Key firstKey; - - MultiKeyBind(String name, String category, InputUtil.Key... defaultKeys) { - super(name, category); - this.keys = new LinkedHashSet<>(); - this.defaultKeys = defaultKeys; - - this.resetKey(); - } - - public void addKeys(int... keys) { - for (int key : keys) { - InputUtil.Key inputKey = InputUtil.fromKeyCode(key, 0); - this.addKey(inputKey); - } - } - - public InputUtil.Key getFirstKey() { - return this.firstKey == null ? InputUtil.UNKNOWN_KEY : this.firstKey; - } - - @Override - public void press(InputUtil.Key key) { - if (!this.isPressed() && this.keys.contains(key)) { - long handle = EssentialUtils.getClient().getWindow().getHandle(); - for (InputUtil.Key inputKey : this.keys) { - if (!InputUtil.isKeyPressed(handle, inputKey.getCode())) { - return; - } - } - - this.setPressed(true); - this.callCallback(); - } - } - - @Override - public void release(InputUtil.Key key) { - this.setPressed(false); - } - - @Override - public void addKey(InputUtil.Key key) { - if (this.firstKey == null) { - this.firstKey = key; - } - this.keys.add(key); - } - - @Override - public void clearKey() { - this.firstKey = null; - this.setPressed(false); - this.keys.clear(); - } - - @Override - public void resetKey() { - for (InputUtil.Key key : this.defaultKeys) { - this.addKey(key); - } - } - - @Override - public boolean isSingleKey() { - return false; - } - - @Override - public boolean isDefault() { - if (this.keys.size() != this.defaultKeys.length) { - return false; - } - - for (InputUtil.Key key : this.defaultKeys) { - if (!this.keys.contains(key)) { - return false; - } - } - return true; - } - - @Override - public Set getKeys() { - return this.keys; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/feature/keybinds/SingleKeyBind.java b/src/main/java/me/senseiwells/essentialclient/feature/keybinds/SingleKeyBind.java deleted file mode 100644 index 24d51f3b..00000000 --- a/src/main/java/me/senseiwells/essentialclient/feature/keybinds/SingleKeyBind.java +++ /dev/null @@ -1,62 +0,0 @@ -package me.senseiwells.essentialclient.feature.keybinds; - -import net.minecraft.client.util.InputUtil; - -import java.util.List; - -public class SingleKeyBind extends ClientKeyBind { - private final InputUtil.Key defaultKey; - private InputUtil.Key boundKey; - - SingleKeyBind(String name, String category, InputUtil.Key defaultKey) { - super(name, category); - this.defaultKey = this.boundKey = defaultKey; - } - - public InputUtil.Key getBoundKey() { - return this.boundKey; - } - - @Override - public void press(InputUtil.Key key) { - if (key.equals(this.boundKey)) { - this.setPressed(true); - this.callCallback(); - } - } - - @Override - public void release(InputUtil.Key key) { - this.setPressed(false); - } - - @Override - public void addKey(InputUtil.Key key) { - this.boundKey = key; - } - - @Override - public void clearKey() { - this.boundKey = InputUtil.UNKNOWN_KEY; - } - - @Override - public void resetKey() { - this.boundKey = this.defaultKey; - } - - @Override - public boolean isSingleKey() { - return true; - } - - @Override - public boolean isDefault() { - return this.defaultKey.equals(this.boundKey); - } - - @Override - public List getKeys() { - return List.of(this.boundKey); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/RulesScreen.java b/src/main/java/me/senseiwells/essentialclient/gui/RulesScreen.java deleted file mode 100644 index cdce11b6..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/RulesScreen.java +++ /dev/null @@ -1,162 +0,0 @@ -package me.senseiwells.essentialclient.gui; - -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.feature.CarpetClient; -import me.senseiwells.essentialclient.gui.config.ConfigListWidget; -import me.senseiwells.essentialclient.gui.entries.BaseListEntry; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.rule.game.VanillaGameRules; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.interfaces.Rule; -import me.senseiwells.essentialclient.utils.render.ChildScreen; -import me.senseiwells.essentialclient.utils.render.Texts; -import me.senseiwells.essentialclient.utils.render.WidgetHelper; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.text.OrderedText; -import net.minecraft.text.Text; - -import java.util.Collection; -import java.util.Comparator; -import java.util.List; - -public abstract class RulesScreen extends ChildScreen { - private List tooltip; - private ConfigListWidget widget; - private TextFieldWidget searchBox; - private boolean invalid; - private boolean isEmpty; - - public RulesScreen(Text screenName, Screen parent) { - super(screenName, parent); - } - - public String getSearchBoxText() { - return this.searchBox.getText(); - } - - public void setCurrentTooltip(List tooltip) { - this.tooltip = tooltip; - } - - public void setInvalid(boolean invalid) { - this.invalid = invalid; - } - - public void setEmpty(boolean isEmpty) { - this.isEmpty = isEmpty; - } - - public void refreshRules(String filter) { - this.widget.reloadEntries(this, filter); - } - - public void refreshScroll() { - this.widget.setScrollAmount(0); - } - - public abstract Collection> getRules(String filter); - - public Comparator> entryComparator() { - return Comparator.comparing(a -> a.getRule().getName()); - } - - public boolean canModify() { - return true; - } - - public boolean shouldCategorise() { - return ClientRules.DISPLAY_RULE_TYPE.getValue().equals("Categories"); - } - - @Override - protected void init() { - if (this.client == null) { - return; - } - this.searchBox = new TextFieldWidget(this.textRenderer, this.width / 2 - 100, 22, 200, 15, Texts.EMPTY); - this.searchBox.setChangedListener(s -> { - this.refreshScroll(); - this.refreshRules(s); - }); - this.widget = new ConfigListWidget(this, this.client, this.searchBox.getText()); - this.addDrawableChild(this.widget); - this.addDrawableChild(this.searchBox); - this.addDrawableChild(WidgetHelper.newButton(this.width / 2 - 100, this.height - 27, 200, 20, Texts.DONE, buttonWidget -> this.close())); - // this.setInitialFocus(this.searchBox); - } - - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - super.render(context, mouseX, mouseY, delta); - this.widget.render(context, mouseX, mouseY, delta); - context.drawCenteredTextWithShadow(this.textRenderer, this.title, this.width / 2, 8, 0xFFFFFF); - if (this.invalid) { - String text = this.isEmpty ? "You can't leave a field empty!" : "Invalid value!"; - context.fill(8, 9, 20 + this.textRenderer.getWidth(text), 14 + this.textRenderer.fontHeight, 0x68000000); - context.drawTextWithShadow(this.textRenderer, Text.literal(text), 18, 12, 16733525); - } - if (this.tooltip != null) { - context.drawOrderedTooltip(this.textRenderer, this.tooltip, mouseX, mouseY); - this.tooltip = null; - } - } - - @Override - public void close() { - if (this.client != null) { - this.widget.updateAllEntriesOnClose(); - } - super.close(); - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - this.searchBox.setFocused(false); - this.widget.unFocusAll(); - return super.mouseClicked(mouseX, mouseY, button); - } - - public static RulesScreen getClientRulesScreen(Screen parent) { - return new RulesScreen(Texts.CLIENT_SCREEN, parent) { - @Override - public Collection> getRules(String filter) { - return ClientRules.getClientRules(); - } - }; - } - - public static RulesScreen getCarpetRulesScreen(Screen parent) { - return new RulesScreen(Texts.SERVER_SCREEN, parent) { - @Override - public Collection> getRules(String filter) { - return CarpetClient.INSTANCE.getCurrentCarpetRules(); - } - - @Override - public boolean canModify() { - return EssentialUtils.getClient().isInSingleplayer() || (CarpetClient.INSTANCE.isServerCarpet() && EssentialUtils.playerHasOp()); - } - }; - } - - public static RulesScreen getGameRulesScreen(Screen parent) { - return new RulesScreen(Texts.GAME_RULE_SCREEN, parent) { - @Override - public Collection> getRules(String filter) { - return VanillaGameRules.getGameRules(); - } - - @Override - public boolean canModify() { - return EssentialClient.GAME_RULE_NET_HANDLER.canModifyRules(); - } - - @Override - public boolean shouldCategorise() { - return true; - } - }; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/clientscript/ClientScriptScreen.java b/src/main/java/me/senseiwells/essentialclient/gui/clientscript/ClientScriptScreen.java deleted file mode 100644 index af3ba28a..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/clientscript/ClientScriptScreen.java +++ /dev/null @@ -1,227 +0,0 @@ -package me.senseiwells.essentialclient.gui.clientscript; - -import me.senseiwells.arucas.Arucas; -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.clientscript.core.ClientScript; -import me.senseiwells.essentialclient.clientscript.core.ClientScriptInstance; -import me.senseiwells.essentialclient.feature.keybinds.ClientKeyBind; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.render.ChildScreen; -import me.senseiwells.essentialclient.utils.render.WidgetHelper; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.CheckboxWidget; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.client.util.InputUtil; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.Util; -import org.lwjgl.glfw.GLFW; - -import java.io.IOException; -import java.nio.file.FileAlreadyExistsException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; - -import static me.senseiwells.essentialclient.utils.render.Texts.*; - -public class ClientScriptScreen extends ChildScreen { - private ClientScriptWidget scriptWidget; - - public ClientScriptScreen(Screen parent) { - super(SCRIPT_SCREEN, parent); - } - - @Override - protected void init() { - if (this.client == null) { - return; - } - int height = this.height - 27; - this.scriptWidget = new ClientScriptWidget(this.client, this); - this.addDrawableChild(this.scriptWidget); - this.addDrawableChild(WidgetHelper.newButton(10, height, 100, 20, REFRESH, button -> this.refresh())); - this.addDrawableChild(WidgetHelper.newButton(this.width / 2 - 100, height, 200, 20, DONE, button -> this.close())); - this.addDrawableChild(WidgetHelper.newButton(this.width - 110, height, 100, 20, DOCUMENTATION, button -> Util.getOperatingSystem().open(EssentialUtils.SCRIPT_WIKI_URL))); - this.addDrawableChild(WidgetHelper.newButton(10, 10, 80, 20, NEW, button -> this.client.setScreen(new CreateClientScriptScreen(this)))); - this.addDrawableChild(WidgetHelper.newButton(this.width - 90, 10, 80, 20, DOWNLOAD, button -> this.client.setScreen(new DownloadClientScriptScreen(this)))); - } - - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - super.render(context, mouseX, mouseY, delta); - this.scriptWidget.render(context, mouseX, mouseY, delta); - context.drawCenteredTextWithShadow(this.textRenderer, this.title, this.width / 2, 8, 0xFFFFFF); - context.drawCenteredTextWithShadow(this.textRenderer, ARUCAS_VERSION.generate(Arucas.VERSION), this.width / 2, 24, 0x949494); - } - - public void refresh() { - ClientScript.INSTANCE.refresh(); - this.scriptWidget.load(this.client); - } - - public void openScriptConfigScreen(ClientScriptInstance scriptInstance) { - ScriptConfigScreen configScreen = new ScriptConfigScreen(this, scriptInstance); - EssentialUtils.getClient().setScreen(configScreen); - } - - static class ScriptConfigScreen extends ChildScreen.Typed { - private final ClientScriptInstance scriptInstance; - private final TextFieldWidget nameBox; - private final ButtonWidget openBox; - private final ButtonWidget deleteBox; - private final ButtonWidget keyBindBox; - private final CheckboxWidget selectedCheck; - private boolean firstKey; - private boolean editingKeyBind; - private String newName; - - ScriptConfigScreen(ClientScriptScreen parent, ClientScriptInstance scriptInstance) { - super(SCRIPT_CONFIG.generate(scriptInstance.getName()), parent); - this.scriptInstance = scriptInstance; - String scriptName = scriptInstance.getName(); - this.nameBox = new TextFieldWidget(EssentialUtils.getClient().textRenderer, 0, 0, 200, 20, SCRIPT_NAME); - this.nameBox.setText(scriptName); - this.nameBox.setChangedListener(s -> this.newName = s); - this.openBox = WidgetHelper.newButton(0, 0, 200, 20, OPEN_SCRIPT, button -> Util.getOperatingSystem().open(this.scriptInstance.getFileLocation().toFile())); - this.deleteBox = WidgetHelper.newButton(0, 0, 200, 20, DELETE_SCRIPT, button -> { - try { - this.scriptInstance.delete(); - this.getParent().scriptWidget.clear(); - this.getParent().scriptWidget.load(this.client); - super.close(); - } catch (IOException e) { - EssentialClient.LOGGER.error("Failed to delete script", e); - } - }); - this.keyBindBox = WidgetHelper.newButton(0, 0, 75, 20, Text.translatable(scriptInstance.getKeyBind().getDisplay()), button -> this.firstKey = this.editingKeyBind = true); - this.selectedCheck = CheckboxWidget.builder(SELECTED, EssentialUtils.getClient().textRenderer) - .pos(0, 0) - .checked(ClientScript.INSTANCE.isSelected(scriptName)) - .callback((w, b) -> { - if (b) { - ClientScript.INSTANCE.removeSelectedInstance(scriptName); - } else { - ClientScript.INSTANCE.addSelectedInstance(scriptName); - } - }) - .build(); - this.newName = ""; - } - - @Override - protected void init() { - int halfHeight = this.height / 2; - int halfWidth = this.width / 2; - this.nameBox.setPosition(halfWidth - 100, halfHeight - 55); - this.openBox.setPosition(halfWidth - 100, halfHeight - 25); - this.deleteBox.setPosition(halfWidth - 100, halfHeight); - this.keyBindBox.setPosition(halfWidth - 50, halfHeight + 25); - this.selectedCheck.setPosition(this.keyBindBox.getX() + 80, halfHeight + 25); - this.addDrawableChild(this.nameBox); - this.addDrawableChild(this.openBox); - this.addDrawableChild(this.deleteBox); - this.addDrawableChild(this.keyBindBox); - this.addDrawableChild(this.selectedCheck); - this.addDrawableChild(WidgetHelper.newButton(halfWidth - 100, this.height - 27, 200, 20, DONE, button -> this.close())); - this.setFocused(this.nameBox); - super.init(); - } - - @Override - public void close() { - if (!this.newName.isEmpty() && !this.newName.equals(this.scriptInstance.getName())) { - try { - Path original = this.scriptInstance.getFileLocation(); - Path newLocation = original.resolveSibling(this.newName + ".arucas"); - if (Files.exists(newLocation)) { - throw new FileAlreadyExistsException("Tried to rename to an existing file"); - } - this.scriptInstance.renameScript(this.newName, newLocation); - Files.move(original, newLocation); - this.getParent().refresh(); - } catch (Exception exception) { - EssentialClient.LOGGER.error(exception); - } - } - super.close(); - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (this.editingKeyBind) { - this.editingKeyBind = false; - return true; - } - return super.mouseClicked(mouseX, mouseY, button); - } - - @Override - public boolean charTyped(char chr, int keyCode) { - return this.nameBox.charTyped(chr, keyCode); - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (this.editingKeyBind) { - ClientKeyBind keyBind = this.scriptInstance.getKeyBind(); - if (keyBind.isSingleKey()) { - InputUtil.Key key = keyCode == GLFW.GLFW_KEY_ESCAPE ? InputUtil.UNKNOWN_KEY : InputUtil.fromKeyCode(keyCode, scanCode); - keyBind.addKey(key); - this.editingKeyBind = false; - return true; - } - if (this.firstKey) { - this.firstKey = false; - keyBind.clearKey(); - } - if (keyCode == GLFW.GLFW_KEY_ESCAPE) { - this.editingKeyBind = false; - return true; - } - keyBind.addKey(InputUtil.fromKeyCode(keyCode, scanCode)); - return true; - } - if (keyCode == GLFW.GLFW_KEY_ENTER && this.nameBox.isFocused()) { - this.newName = this.nameBox.getText(); - this.nameBox.setFocused(false); - } - return super.keyPressed(keyCode, scanCode, modifiers) || this.nameBox.keyPressed(keyCode, scanCode, modifiers); - } - - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - super.render(context, mouseX, mouseY, delta); - context.drawTextWithShadow(this.textRenderer, SCRIPT_NAME, (int) (this.width / 2.0F - 100), (int) (this.height / 2.0F - 68), 0x949494); - context.drawTextWithShadow(this.textRenderer, KEYBIND, (int) (this.width / 2.0F - 100), (int) (this.height / 2.0F + 30), 0xE0E0E0); - context.drawCenteredTextWithShadow(this.textRenderer, this.title, this.width / 2, 8, 0xFFFFFF); - - ClientKeyBind keyBinding = this.scriptInstance.getKeyBind(); - - MutableText editMessage = Text.literal(keyBinding.getDisplay()); - if (this.client != null && this.client.textRenderer.getWidth(editMessage) > 70) { - editMessage = Text.literal("..."); - } - - if (this.editingKeyBind) { - this.keyBindBox.setMessage( - Text.literal("> ").append(editMessage.formatted(Formatting.YELLOW)).append(" <").formatted(Formatting.YELLOW) - ); - } else { - this.keyBindBox.setMessage(editMessage); - } - - if (this.keyBindBox.isMouseOver(mouseX, mouseY)) { - String display = keyBinding.getDisplay(); - List textList = List.of( - Text.literal(keyBinding.getName()).formatted(Formatting.GOLD), - display.isEmpty() ? NO_KEYBINDING : Text.literal(display) - ); - context.drawTooltip(this.textRenderer, textList, mouseX, mouseY); - } - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/clientscript/ClientScriptWidget.java b/src/main/java/me/senseiwells/essentialclient/gui/clientscript/ClientScriptWidget.java deleted file mode 100644 index 26d3fd6d..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/clientscript/ClientScriptWidget.java +++ /dev/null @@ -1,107 +0,0 @@ -package me.senseiwells.essentialclient.gui.clientscript; - -import com.google.common.collect.ImmutableList; -import me.senseiwells.essentialclient.clientscript.core.ClientScript; -import me.senseiwells.essentialclient.clientscript.core.ClientScriptInstance; -import me.senseiwells.essentialclient.gui.entries.AbstractListEntry; -import me.senseiwells.essentialclient.utils.render.WidgetHelper; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.CheckboxWidget; -import net.minecraft.client.gui.widget.ClickableWidget; -import net.minecraft.client.gui.widget.ElementListWidget; -import net.minecraft.text.Text; - -import java.util.List; - -import static me.senseiwells.essentialclient.utils.render.Texts.*; - -public class ClientScriptWidget extends ElementListWidget { - private final ClientScriptScreen parent; - - public ClientScriptWidget(MinecraftClient minecraftClient, ClientScriptScreen scriptScreen) { - super(minecraftClient, scriptScreen.width + 45, scriptScreen.height - 43 - 32, 43, 20); - this.parent = scriptScreen; - this.load(minecraftClient); - } - - public void load(MinecraftClient client) { - this.clear(); - for (ClientScriptInstance instance : ClientScript.INSTANCE.getScriptInstancesInOrder()) { - this.addEntry(new ScriptListEntry(client, instance)); - } - } - - public void clear() { - this.clearEntries(); - } - - class ScriptListEntry extends AbstractListEntry { - private final MinecraftClient client; - private final String name; - private final ClientScriptInstance scriptInstance; - private final ButtonWidget configButton; - private final ButtonWidget startButton; - private final CheckboxWidget checkButton; - - ScriptListEntry(MinecraftClient client, ClientScriptInstance instance) { - this.client = client; - this.name = instance.getName(); - this.scriptInstance = instance; - boolean isTemporary = instance.isTemporary(); - this.configButton = WidgetHelper.newButton(0, 0, 45, 20, isTemporary ? REMOVE : CONFIG, buttonWidget -> { - if (!isTemporary) { - ClientScriptWidget.this.parent.openScriptConfigScreen(this.scriptInstance); - return; - } - ClientScript.INSTANCE.removeInstance(this.scriptInstance); - ClientScriptWidget.this.clear(); - ClientScriptWidget.this.load(this.client); - }); - this.startButton = WidgetHelper.newButton(0, 0, 45, 20, instance.isScriptRunning() ? STOP : START, buttonWidget -> { - if (this.scriptInstance.isScriptRunning()) { - this.scriptInstance.stopScript(); - return; - } - this.scriptInstance.toggleScript(); - }); - this.checkButton = CheckboxWidget.builder(EMPTY, client.textRenderer) - .pos(0, 0) - .checked(ClientScript.INSTANCE.isSelected(this.name)) - .callback((w, b) -> { - if (b) { - ClientScript.INSTANCE.removeSelectedInstance(this.name); - } else { - ClientScript.INSTANCE.addSelectedInstance(this.name); - } - }) - .build(); - this.checkButton.active = !isTemporary; - } - - @Override - public List children() { - return ImmutableList.of(this.configButton, this.startButton, this.checkButton); - } - - @Override - public List selectableChildren() { - return this.children(); - } - - @Override - public void render(DrawContext context, int index, int y, int x, int width, int height, int mouseX, int mouseY, boolean hovered, float tickDelta) { - context.drawTextWithShadow(this.client.textRenderer, Text.literal(this.name), x - 50, y + height / 2 - 9 / 2, 16777215); - WidgetHelper.setPosition(this.checkButton, x + width - 20, y); - WidgetHelper.setPosition(this.startButton, x + width - 70, y); - WidgetHelper.setPosition(this.configButton, x + width - 120, y); - - this.startButton.active = this.client.player != null; - this.startButton.setMessage(this.scriptInstance.isScriptRunning() ? STOP : START); - this.configButton.render(context, mouseX, mouseY, tickDelta); - this.startButton.render(context, mouseX, mouseY, tickDelta); - this.checkButton.render(context, mouseX, mouseY, tickDelta); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/clientscript/CreateClientScriptScreen.java b/src/main/java/me/senseiwells/essentialclient/gui/clientscript/CreateClientScriptScreen.java deleted file mode 100644 index 849191f3..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/clientscript/CreateClientScriptScreen.java +++ /dev/null @@ -1,93 +0,0 @@ -package me.senseiwells.essentialclient.gui.clientscript; - -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.clientscript.core.ClientScript; -import me.senseiwells.essentialclient.clientscript.core.ClientScriptInstance; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.render.ChildScreen; -import me.senseiwells.essentialclient.utils.render.Texts; -import me.senseiwells.essentialclient.utils.render.WidgetHelper; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.TextFieldWidget; -import org.lwjgl.glfw.GLFW; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import static me.senseiwells.essentialclient.utils.render.Texts.*; - -public class CreateClientScriptScreen extends ChildScreen { - private final TextFieldWidget nameBox; - private final ButtonWidget createButton; - private final ButtonWidget cancelButton; - - public CreateClientScriptScreen(ClientScriptScreen parent) { - super(CREATE_NEW_SCRIPT, parent); - this.nameBox = new TextFieldWidget(EssentialUtils.getClient().textRenderer, 0, 0, 200, 20, SCRIPT_NAME); - this.createButton = WidgetHelper.newButton(0, 0, 80, 20, Texts.CREATE, button -> { - String name = this.nameBox.getText(); - Path scriptPath = ClientScript.INSTANCE.getScriptDirectory(); - Path newScriptPath = scriptPath.resolve(name + ".arucas"); - if (Files.exists(newScriptPath)) { - for (int i = 1; ; i++) { - String iName = name + " " + i; - newScriptPath = scriptPath.resolve(iName + ".arucas"); - if (!Files.exists(newScriptPath)) { - name = iName; - break; - } - } - } - try { - Files.createFile(newScriptPath); - } catch (IOException e) { - EssentialClient.LOGGER.error(e); - return; - } - ClientScriptInstance instance = new ClientScriptInstance(name, newScriptPath); - parent.refresh(); - parent.openScriptConfigScreen(instance); - }); - this.cancelButton = WidgetHelper.newButton(0, 0, 80, 20, CANCEL, button -> this.close()); - } - - @Override - protected void init() { - if (this.client == null) { - return; - } - int halfHeight = this.height / 2; - int halfWidth = this.width / 2; - this.nameBox.setPosition(halfWidth - 100, halfHeight - 20); - this.createButton.setPosition(halfWidth + 5, halfHeight + 10); - this.cancelButton.setPosition(halfWidth - 85, halfHeight + 10); - this.addDrawableChild(this.nameBox); - this.addDrawableChild(this.createButton); - this.addDrawableChild(this.cancelButton); - this.setFocused(this.nameBox); - super.init(); - } - - @Override - public void tick() { - super.tick(); - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (keyCode == GLFW.GLFW_KEY_ENTER && this.nameBox.isFocused()) { - this.nameBox.setFocused(false); - } - return super.keyPressed(keyCode, scanCode, modifiers) || this.nameBox.keyPressed(keyCode, scanCode, modifiers); - } - - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - super.render(context, mouseX, mouseY, delta); - - context.drawTextWithShadow(this.textRenderer, SCRIPT_NAME, (int) (this.width / 2.0F - 100), (int) (this.height / 2.0F - 33), 0x949494); - context.drawCenteredTextWithShadow(this.textRenderer, this.title, this.width / 2, 8, 0xFFFFFF); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/clientscript/DownloadClientScriptScreen.java b/src/main/java/me/senseiwells/essentialclient/gui/clientscript/DownloadClientScriptScreen.java deleted file mode 100644 index 204d1179..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/clientscript/DownloadClientScriptScreen.java +++ /dev/null @@ -1,33 +0,0 @@ -package me.senseiwells.essentialclient.gui.clientscript; - -import me.senseiwells.essentialclient.utils.render.ChildScreen; -import me.senseiwells.essentialclient.utils.render.Texts; -import me.senseiwells.essentialclient.utils.render.WidgetHelper; -import net.minecraft.client.gui.DrawContext; - -import static me.senseiwells.essentialclient.utils.render.Texts.DONE; - -public class DownloadClientScriptScreen extends ChildScreen.Typed { - private DownloadClientScriptWidget widget; - - public DownloadClientScriptScreen(ClientScriptScreen parent) { - super(Texts.DOWNLOAD_SCRIPT, parent); - } - - @Override - protected void init() { - if (this.client == null) { - return; - } - this.widget = new DownloadClientScriptWidget(this.client, this); - this.addDrawableChild(this.widget); - this.addDrawableChild(WidgetHelper.newButton(this.width / 2 - 100, this.height - 27, 200, 20, DONE, button -> this.close())); - } - - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - super.render(context, mouseX, mouseY, delta); - this.widget.render(context, mouseX, mouseY, delta); - context.drawCenteredTextWithShadow(this.textRenderer, this.title, this.width / 2, 8, 0xFFFFFF); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/clientscript/DownloadClientScriptWidget.java b/src/main/java/me/senseiwells/essentialclient/gui/clientscript/DownloadClientScriptWidget.java deleted file mode 100644 index 4477a030..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/clientscript/DownloadClientScriptWidget.java +++ /dev/null @@ -1,117 +0,0 @@ -package me.senseiwells.essentialclient.gui.clientscript; - -import com.google.common.collect.ImmutableList; -import me.senseiwells.essentialclient.gui.entries.AbstractListEntry; -import me.senseiwells.essentialclient.utils.clientscript.ScriptRepositoryManager; -import me.senseiwells.essentialclient.utils.clientscript.ScriptRepositoryManager.Category; -import me.senseiwells.essentialclient.utils.render.Texts; -import me.senseiwells.essentialclient.utils.render.WidgetHelper; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.ElementListWidget; -import net.minecraft.client.toast.SystemToast; -import net.minecraft.client.toast.ToastManager; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.Util; - -import java.util.List; - -public class DownloadClientScriptWidget extends ElementListWidget { - private final DownloadClientScriptScreen downloadScreen; - private int maxScriptNameLength; - - public DownloadClientScriptWidget(MinecraftClient minecraftClient, DownloadClientScriptScreen downloadScreen) { - super(minecraftClient, downloadScreen.width + 45, downloadScreen.height - 43 - 32, 43, 20); - this.downloadScreen = downloadScreen; - - for (Category category : Category.values()) { - this.addEntry(new CategoryEntry(category.getPrettyName())); - for (String script : ScriptRepositoryManager.INSTANCE.getChildrenNames(category)) { - int length = script.length(); - if (length > this.maxScriptNameLength) { - this.maxScriptNameLength = length; - } - this.addEntry(new ScriptListEntry(category, script)); - } - } - } - - abstract static class Entry extends AbstractListEntry { } - - class CategoryEntry extends Entry { - private final int textWidth; - final Text text; - - CategoryEntry(Text text) { - this.textWidth = DownloadClientScriptWidget.this.client.textRenderer.getWidth(text); - this.text = text; - } - - @Override - public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { - TextRenderer renderer = DownloadClientScriptWidget.this.client.textRenderer; - context.drawTextWithShadow(renderer, this.text, (int) (DownloadClientScriptWidget.this.downloadScreen.width / 2.0F - this.textWidth / 2.0F), y + entryHeight - 9 - 1, 0xFFFFFF); - } - - @Override - public List selectableChildren() { - return this.children(); - } - - @Override - public List children() { - return ImmutableList.of(); - } - } - - class ScriptListEntry extends Entry { - private final String scriptName; - private final ButtonWidget viewButton; - private final ButtonWidget downloadButton; - - ScriptListEntry(Category category, String scriptName) { - this.scriptName = scriptName; - this.viewButton = WidgetHelper.newButton(0, 0, 50, 20, Texts.VIEW, button -> { - Util.getOperatingSystem().open(ScriptRepositoryManager.INSTANCE.getViewableLink(category, scriptName)); - }); - this.downloadButton = WidgetHelper.newButton(0, 0, 60, 20, Texts.DOWNLOAD.copy().formatted(Formatting.DARK_GREEN), button -> { - ToastManager toastManager = DownloadClientScriptWidget.this.client.getToastManager(); - if (ScriptRepositoryManager.INSTANCE.downloadScript(category, scriptName, true)) { - SystemToast.show( - toastManager, SystemToast.Type.PACK_COPY_FAILURE, - Texts.DOWNLOAD_FAILED, null - ); - return; - } - SystemToast.show( - toastManager, SystemToast.Type.WORLD_BACKUP, - Texts.DOWNLOAD_SUCCESSFUL, null - ); - DownloadClientScriptWidget.this.downloadScreen.getParent().refresh(); - }); - } - - @Override - public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { - float width = x - 20 - DownloadClientScriptWidget.this.maxScriptNameLength; - context.drawTextWithShadow(DownloadClientScriptWidget.this.client.textRenderer, Text.literal(this.scriptName), (int) width, (int) (y + entryHeight / 2.0F - 9 / 2.0F), 0xFFFFFF); - WidgetHelper.setPosition(this.downloadButton, x + 155, y); - WidgetHelper.setPosition(this.viewButton, x + 100, y); - this.viewButton.render(context, mouseX, mouseY, tickDelta); - this.downloadButton.render(context, mouseX, mouseY, tickDelta); - } - - @Override - public List selectableChildren() { - return this.children(); - } - - @Override - public List children() { - return ImmutableList.of(this.viewButton, this.downloadButton); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/config/ConfigListWidget.java b/src/main/java/me/senseiwells/essentialclient/gui/config/ConfigListWidget.java deleted file mode 100644 index c943bb3c..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/config/ConfigListWidget.java +++ /dev/null @@ -1,81 +0,0 @@ -package me.senseiwells.essentialclient.gui.config; - -import me.senseiwells.essentialclient.gui.RulesScreen; -import me.senseiwells.essentialclient.gui.entries.*; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.interfaces.Rule; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.widget.ElementListWidget; - -import java.util.*; - -public class ConfigListWidget extends ElementListWidget { - public static final int LENGTH = 136; - - public ConfigListWidget(RulesScreen rulesScreen, MinecraftClient client, String filter) { - super(client, rulesScreen.width + 45, rulesScreen.height - 43 - 32, 43, 20); - this.reloadEntries(rulesScreen, filter); - } - - public void reloadEntries(RulesScreen rulesScreen, String filter) { - this.clearEntries(); - Collection> rules = rulesScreen.getRules(filter); - - SortedMap>> sortedEntries = new TreeMap<>(); - rules.forEach(rule -> { - if (!rule.display()) { - return; - } - String ruleName = rule.getName(); - if (filter != null && !ruleName.toLowerCase(Locale.ROOT).contains(filter.toLowerCase(Locale.ROOT))) { - return; - } - BaseListEntry entry = switch (rule.getType()) { - case BOOLEAN -> new BooleanListEntry((Rule.Bool) rule, this.client, rulesScreen); - case CYCLE -> new CycleListEntry((Rule.Cycle) rule, this.client, rulesScreen); - case INTEGER, DOUBLE -> new NumberListEntry(rule, this.client, rulesScreen); - case STRING -> new StringListEntry(rule, this.client, rulesScreen); - case SLIDER -> new SliderListEntry((Rule.Slider) rule, this.client, rulesScreen); - case LIST -> new ListListEntry((Rule.ListRule) rule, this.client, rulesScreen); - default -> throw new IllegalStateException("Unexpected value: " + rule.getType()); - }; - - String category = rule.getCategory() == null ? ClientRules.MISCELLANEOUS : rule.getCategory(); - Set> set = sortedEntries.computeIfAbsent(category, k -> new HashSet<>()); - set.add(entry); - }); - - if (sortedEntries.size() == 1 || !rulesScreen.shouldCategorise()) { - sortedEntries.values().stream().flatMap(Collection::stream).sorted(rulesScreen.entryComparator()).forEach(this::addEntry); - return; - } - sortedEntries.forEach((category, entries) -> { - this.addEntry(new CategoryEntry(category)); - entries.stream().sorted(rulesScreen.entryComparator()).forEach(this::addEntry); - }); - } - - public void updateAllEntriesOnClose() { - this.children().forEach(Entry::updateEntryOnClose); - } - - public void unFocusAll() { - this.children().forEach(Entry::unFocus); - } - - @Override - protected int getScrollbarX() { - return this.width / 2 + this.getRowWidth() / 2; - } - - @Override - public int getRowWidth() { - return 360; - } - - public abstract static class Entry extends AbstractListEntry { - public void unFocus() { } - - public void updateEntryOnClose() { } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/config/ConfigScreen.java b/src/main/java/me/senseiwells/essentialclient/gui/config/ConfigScreen.java deleted file mode 100644 index d20a62dd..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/config/ConfigScreen.java +++ /dev/null @@ -1,76 +0,0 @@ -package me.senseiwells.essentialclient.gui.config; - -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.feature.chunkdebug.ChunkDebugScreen; -import me.senseiwells.essentialclient.gui.RulesScreen; -import me.senseiwells.essentialclient.gui.clientscript.ClientScriptScreen; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.render.ChildScreen; -import me.senseiwells.essentialclient.utils.render.Texts; -import me.senseiwells.essentialclient.utils.render.WidgetHelper; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.Text; -import net.minecraft.util.Util; - -import static me.senseiwells.essentialclient.utils.render.Texts.*; - -public class ConfigScreen extends ChildScreen { - public ConfigScreen(Screen parent) { - super(CLIENT_SCREEN, parent); - } - - @Override - protected void init() { - if (this.client == null) { - return; - } - int width = this.width / 2 - 100; - int height = this.height / 6; - this.addDrawableChild(WidgetHelper.newButton(width, height, 200, 20, CLIENT_SCREEN, button -> this.client.setScreen(RulesScreen.getClientRulesScreen(this)))); - this.addDrawableChild(WidgetHelper.newButton(width, height + 24, 200, 20, SERVER_SCREEN, button -> this.client.setScreen(RulesScreen.getCarpetRulesScreen(this)))); - this.addDrawableChild(WidgetHelper.newButton(width, height + 48, 200, 20, GAME_RULE_SCREEN, button -> this.client.setScreen(RulesScreen.getGameRulesScreen(this)))); - this.addDrawableChild(WidgetHelper.newButton(width, height + 72, 200, 20, SCRIPT_SCREEN, button -> this.client.setScreen(new ClientScriptScreen(this)))); - this.addDrawableChild(WidgetHelper.newButton(width, height + 96, 200, 20, CONTROLS_SCREEN, button -> this.client.setScreen(new ControlsScreen(this)))); - this.addDrawableChild(WidgetHelper.newButton(width, height + 120, 200, 20, CHUNK_SCREEN, button -> this.client.setScreen(new ChunkDebugScreen(this)))).active = EssentialClient.CHUNK_NET_HANDLER.isAvailable(); - this.addDrawableChild(WidgetHelper.newButton(width, this.height - 27, 200, 20, DONE, button -> this.close())); - this.addDrawableChild(WidgetHelper.newButton(this.width - 89, this.height - 27, 80, 20, WIKI_PAGE, button -> Util.getOperatingSystem().open(EssentialUtils.WIKI_URL))); - this.addDrawableChild(WidgetHelper.newButton(9, this.height - 27, 80, 20, CONFIG_FOLDER, button -> Util.getOperatingSystem().open(EssentialUtils.getEssentialConfigFile().toFile()))); - } - - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - super.render(context, mouseX, mouseY, delta); - int width = this.width / 2; - TextRenderer renderer = this.textRenderer; - context.drawCenteredTextWithShadow(renderer, ESSENTIAL_CLIENT, width, 8, 0xFFFFFF); - context.drawCenteredTextWithShadow(renderer, VERSION.generate(EssentialClient.VERSION), width, 8 + renderer.fontHeight + 8, 0x949494); - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (this.client != null && mouseX > this.width - 30 && mouseY < 30) { - this.client.setScreen(new Secret(Texts.EMPTY, this)); - return true; - } - return super.mouseClicked(mouseX, mouseY, button); - } - - private static class Secret extends ChildScreen { - protected Secret(Text title, Screen parent) { - super(title, parent); - } - - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - super.render(context, mouseX, mouseY, delta); - MatrixStack matrices = context.getMatrices(); - matrices.push(); - matrices.scale(2.0F, 2.0F, 2.0F); - context.drawCenteredTextWithShadow(this.textRenderer, TOP_SECRET, this.width / 2, 8, 0xFFFFFF); - matrices.pop(); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/config/ControlsListWidget.java b/src/main/java/me/senseiwells/essentialclient/gui/config/ControlsListWidget.java deleted file mode 100644 index f646a276..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/config/ControlsListWidget.java +++ /dev/null @@ -1,155 +0,0 @@ -package me.senseiwells.essentialclient.gui.config; - -import com.google.common.collect.ImmutableList; -import me.senseiwells.essentialclient.feature.keybinds.ClientKeyBind; -import me.senseiwells.essentialclient.feature.keybinds.ClientKeyBinds; -import me.senseiwells.essentialclient.gui.entries.AbstractListEntry; -import me.senseiwells.essentialclient.utils.render.Texts; -import me.senseiwells.essentialclient.utils.render.WidgetHelper; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.ElementListWidget; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; - -import java.util.*; - -public class ControlsListWidget extends ElementListWidget { - private final ControlsScreen controlsScreen; - private int maxKeyNameLength; - - public ControlsListWidget(MinecraftClient client, ControlsScreen controlsScreen) { - super(client, controlsScreen.width + 45, controlsScreen.height - 43 - 32, 43, 20); - this.controlsScreen = controlsScreen; - - SortedMap> sortedKeys = new TreeMap<>(); - for (ClientKeyBind keyBind : ClientKeyBinds.getAllKeyBinds()) { - Set keyBinds = sortedKeys.computeIfAbsent(keyBind.getCategory(), n -> new TreeSet<>()); - keyBinds.add(keyBind); - } - - sortedKeys.forEach((category, keys) -> { - this.addEntry(new CategoryEntry(Text.translatable(category))); - for (ClientKeyBind keyBind : keys) { - Text text = Text.translatable(keyBind.getName()); - int i = client.textRenderer.getWidth(text); - if (i > this.maxKeyNameLength) { - this.maxKeyNameLength = i; - } - this.addEntry(new KeyBindEntry(keyBind, text)); - } - }); - - } - - @Override - protected int getScrollbarX() { - return super.getScrollbarX() + 15; - } - - @Override - public int getRowWidth() { - return super.getRowWidth() + 32; - } - - abstract static class Entry extends AbstractListEntry { } - - class CategoryEntry extends Entry { - private final int textWidth; - final Text text; - - CategoryEntry(Text text) { - this.textWidth = ControlsListWidget.this.client.textRenderer.getWidth(text); - this.text = text; - } - - @Override - public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { - context.drawTextWithShadow(ControlsListWidget.this.client.textRenderer, this.text, (int) (ControlsListWidget.this.controlsScreen.width / 2.0F - this.textWidth / 2.0F), y + entryHeight - 9 - 1, 0xFFFFFF); - } - - @Override - public List selectableChildren() { - return this.children(); - } - - @Override - public List children() { - return ImmutableList.of(); - } - } - - class KeyBindEntry extends Entry { - private final ClientKeyBind keyBind; - private final Text bindingText; - private final ButtonWidget editButton; - private final ButtonWidget resetButton; - - KeyBindEntry(ClientKeyBind keyBind, Text text) { - this.keyBind = keyBind; - this.bindingText = text; - this.editButton = WidgetHelper.newButton(0, 0, 75, 20, text, button -> { - ControlsListWidget.this.controlsScreen.setFocusedKeyBinding(this.keyBind); - }); - this.resetButton = WidgetHelper.newButton(0, 0, 50, 20, Texts.RESET, button -> { - this.keyBind.clearKey(); - this.keyBind.resetKey(); - }); - this.resetButton.active = !this.keyBind.isDefault(); - } - - @Override - public List selectableChildren() { - return this.children(); - } - - @Override - public List children() { - return ImmutableList.of(this.editButton, this.resetButton); - } - - - @Override - public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { - boolean focused = ControlsListWidget.this.controlsScreen.isBindingFocused(this.keyBind); - float width = x + 90 - ControlsListWidget.this.maxKeyNameLength; - context.drawTextWithShadow(ControlsListWidget.this.client.textRenderer, this.bindingText, (int) width, (int) (y + entryHeight / 2.0F - 9 / 2.0F), 0xFFFFFF); - WidgetHelper.setPosition(this.resetButton, x + 190, y); - this.resetButton.active = !this.keyBind.isDefault(); - this.resetButton.render(context, mouseX, mouseY, tickDelta); - WidgetHelper.setPosition(this.editButton, x + 105, y); - - MutableText editMessage = Text.literal(this.keyBind.getDisplay()); - int textWidth = ControlsListWidget.this.client.textRenderer.getWidth(editMessage); - if (textWidth > 70) { - editMessage = Text.literal("..."); - } - - if (focused) { - this.editButton.setMessage( - Text.literal("> ").append(editMessage.formatted(Formatting.YELLOW)).append(" <").formatted(Formatting.YELLOW) - ); - } else { - this.editButton.setMessage(editMessage); - } - - this.editButton.render(context, mouseX, mouseY, tickDelta); - - if (this.editButton.isMouseOver(mouseX, mouseY)) { - ControlsListWidget.this.controlsScreen.setHoveredKeyBinding(this.keyBind); - } - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - return this.editButton.mouseClicked(mouseX, mouseY, button) || this.resetButton.mouseClicked(mouseX, mouseY, button); - } - - @Override - public boolean mouseReleased(double mouseX, double mouseY, int button) { - return this.editButton.mouseReleased(mouseX, mouseY, button) || this.resetButton.mouseReleased(mouseX, mouseY, button); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/config/ControlsScreen.java b/src/main/java/me/senseiwells/essentialclient/gui/config/ControlsScreen.java deleted file mode 100644 index 8799fdd5..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/config/ControlsScreen.java +++ /dev/null @@ -1,94 +0,0 @@ -package me.senseiwells.essentialclient.gui.config; - -import me.senseiwells.essentialclient.feature.keybinds.ClientKeyBind; -import me.senseiwells.essentialclient.utils.render.ChildScreen; -import me.senseiwells.essentialclient.utils.render.Texts; -import me.senseiwells.essentialclient.utils.render.WidgetHelper; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.util.InputUtil; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import org.lwjgl.glfw.GLFW; - -import java.util.List; - -public class ControlsScreen extends ChildScreen { - private ClientKeyBind hoveredKeyBinding; - private ClientKeyBind focusedKeyBinding; - private ControlsListWidget controlWidget; - private boolean firstKey; - - public ControlsScreen(Screen parent) { - super(Texts.CONTROLS_SCREEN, parent); - } - - public void setHoveredKeyBinding(ClientKeyBind keyBind) { - this.hoveredKeyBinding = keyBind; - } - - public void setFocusedKeyBinding(ClientKeyBind keyBind) { - this.firstKey = true; - this.focusedKeyBinding = keyBind; - } - - public boolean isBindingFocused(ClientKeyBind keyBind) { - return keyBind == this.focusedKeyBinding; - } - - @Override - protected void init() { - this.controlWidget = new ControlsListWidget(this.client, this); - this.addDrawableChild(this.controlWidget); - this.addDrawableChild(WidgetHelper.newButton(this.width / 2 - 100, this.height - 27, 200, 20, Texts.DONE, buttonWidget -> this.close())); - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (this.focusedKeyBinding != null) { - this.focusedKeyBinding = null; - return true; - } - return super.mouseClicked(mouseX, mouseY, button); - } - - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - super.render(context, mouseX, mouseY, delta); - this.controlWidget.render(context, mouseX, mouseY, delta); - context.drawCenteredTextWithShadow(this.textRenderer, this.title, this.width / 2, 8, 0xFFFFFF); - - if (this.hoveredKeyBinding != null) { - String display = this.hoveredKeyBinding.getDisplay(); - List textList = List.of( - Text.literal(this.hoveredKeyBinding.getName()).formatted(Formatting.GOLD), - display.isEmpty() ? Texts.NO_KEYBINDING : Text.literal(display) - ); - context.drawTooltip(this.textRenderer, textList, mouseX, mouseY); - this.hoveredKeyBinding = null; - } - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (this.focusedKeyBinding != null) { - if (this.focusedKeyBinding.isSingleKey()) { - InputUtil.Key key = keyCode == GLFW.GLFW_KEY_ESCAPE ? InputUtil.UNKNOWN_KEY : InputUtil.fromKeyCode(keyCode, scanCode); - this.focusedKeyBinding.addKey(key); - this.focusedKeyBinding = null; - return true; - } - if (this.firstKey) { - this.firstKey = false; - this.focusedKeyBinding.clearKey(); - } - if (keyCode == GLFW.GLFW_KEY_ESCAPE) { - this.focusedKeyBinding = null; - return true; - } - this.focusedKeyBinding.addKey(InputUtil.fromKeyCode(keyCode, scanCode)); - return true; - } - return super.keyPressed(keyCode, scanCode, modifiers); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/config/ListListWidget.java b/src/main/java/me/senseiwells/essentialclient/gui/config/ListListWidget.java deleted file mode 100644 index e4bfa414..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/config/ListListWidget.java +++ /dev/null @@ -1,138 +0,0 @@ -package me.senseiwells.essentialclient.gui.config; - -import com.google.common.collect.ImmutableList; -import me.senseiwells.essentialclient.gui.entries.AbstractListEntry; -import me.senseiwells.essentialclient.utils.render.WidgetHelper; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.ClickableWidget; -import net.minecraft.client.gui.widget.ElementListWidget; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.text.Text; -import org.lwjgl.glfw.GLFW; - -import java.util.ArrayList; -import java.util.List; - -public class ListListWidget extends ElementListWidget { - private final ListScreen listScreen; - - public ListListWidget(ListScreen listScreen, MinecraftClient client) { - super(client, listScreen.width + 45, listScreen.height - 43 - 32, 43, 20); - this.listScreen = listScreen; - this.reloadEntries(); - } - - public void reloadEntries() { - this.clearEntries(); - - List values = this.listScreen.getValues(); - - if (values.isEmpty()) { - this.addEntry(new Entry(this.client, 1, "", this.listScreen.getRule().getMaxLength())); - } - - for (int index = 0; index < values.size(); index++) { - this.addEntry(new Entry(this.client, index + 1, values.get(index), this.listScreen.getRule().getMaxLength())); - } - } - - public void unFocusAll() { - this.children().stream().map(e -> e.textField).forEach(t -> t.setFocused(false)); - } - - public void tick() { - - } - - public List getTextValues() { - List textValues = new ArrayList<>(); - for (Entry entry : this.children()) { - textValues.add(entry.textField.getText()); - } - return textValues; - } - - @Override - protected int getScrollbarX() { - return this.width / 2 + this.getRowWidth() / 2 + 4; - } - - @Override - public int getRowWidth() { - return 360; - } - - public class Entry extends AbstractListEntry { - private final MinecraftClient client; - private final TextFieldWidget textField; - private final ButtonWidget addButton; - private final ButtonWidget removeButton; - private final int index; - - public Entry(MinecraftClient client, int index, String value, int maxLength) { - this.client = client; - - this.textField = new TextFieldWidget(client.textRenderer, 0, 0, 150, 14, Text.literal(value)); - this.textField.setMaxLength(maxLength); - this.textField.setText(value); - - this.addButton = WidgetHelper.newButton(0, 0, 20, 20, Text.of("+"), button -> { - ListListWidget.this.listScreen.saveEntries(); - ListListWidget.this.listScreen.modify(l -> l.add(index, "")); - ListListWidget.this.reloadEntries(); - }); - this.removeButton = WidgetHelper.newButton(0, 0, 20, 20, Text.of("-"), button -> { - ListListWidget.this.listScreen.saveEntries(); - ListListWidget.this.listScreen.modify(l -> l.remove(index - 1)); - ListListWidget.this.reloadEntries(); - }); - - this.index = index; - } - - @Override - public boolean charTyped(char chr, int keyCode) { - return this.textField.charTyped(chr, keyCode); - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (keyCode == GLFW.GLFW_KEY_ENTER) { - this.textField.setFocused(false); - return true; - } - return super.keyPressed(keyCode, scanCode, modifiers) || this.textField.keyPressed(keyCode, scanCode, modifiers); - } - - - @Override - public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float delta) { - TextRenderer font = this.client.textRenderer; - int fontX = x + 90 - 100; - int fontY = y + height / 2 - 9 / 2; - - context.drawTextWithShadow(font, Text.literal(String.valueOf(this.index)), fontX, fontY, 0xFFFFFF); - - WidgetHelper.setPosition(this.textField, x + 65, y); - WidgetHelper.setPosition(this.addButton, x + 235, y); - WidgetHelper.setPosition(this.removeButton, x + 255, y); - - this.textField.render(context, mouseX, mouseY, delta); - this.addButton.render(context, mouseX, mouseY, delta); - this.removeButton.render(context, mouseX, mouseY, delta); - } - - @Override - public List children() { - return ImmutableList.of(this.textField, this.addButton, this.removeButton); - } - - @Override - public List selectableChildren() { - return this.children(); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/config/ListScreen.java b/src/main/java/me/senseiwells/essentialclient/gui/config/ListScreen.java deleted file mode 100644 index 2a2902a7..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/config/ListScreen.java +++ /dev/null @@ -1,76 +0,0 @@ -package me.senseiwells.essentialclient.gui.config; - -import me.senseiwells.essentialclient.gui.RulesScreen; -import me.senseiwells.essentialclient.utils.interfaces.Rule; -import me.senseiwells.essentialclient.utils.render.ChildScreen; -import me.senseiwells.essentialclient.utils.render.Texts; -import me.senseiwells.essentialclient.utils.render.WidgetHelper; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.text.Text; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - -public class ListScreen extends ChildScreen.Typed { - private final Rule.ListRule rule; - private ListListWidget widget; - - public ListScreen(Text title, RulesScreen parent, Rule.ListRule rule) { - super(title, parent); - this.rule = rule; - } - - public List getValues() { - return this.rule.getValue(); - } - - public void modify(Consumer> consumer) { - List strings = new ArrayList<>(this.rule.getValue()); - consumer.accept(strings); - this.rule.setValue(strings); - } - - public void saveEntries() { - List values = this.widget.getTextValues(); - this.rule.setValue(values); - } - - @Override - protected void init() { - if (this.client == null) { - return; - } - this.widget = new ListListWidget(this, this.client); - this.addDrawableChild(this.widget); - this.addDrawableChild(WidgetHelper.newButton(this.width / 2 - 100, this.height - 27, 200, 20, Texts.DONE, buttonWidget -> this.close())); - } - - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - super.render(context, mouseX, mouseY, delta); - this.widget.render(context, mouseX, mouseY, delta); - context.drawCenteredTextWithShadow(this.textRenderer, this.title, this.width / 2, 8, 0xFFFFFF); - } - - @Override - public void tick() { - this.widget.tick(); - } - - @Override - public void close() { - this.saveEntries(); - super.close(); - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - this.widget.unFocusAll(); - return super.mouseClicked(mouseX, mouseY, button); - } - - public Rule.ListRule getRule() { - return this.rule; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/entries/AbstractListEntry.java b/src/main/java/me/senseiwells/essentialclient/gui/entries/AbstractListEntry.java deleted file mode 100644 index 0072cb99..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/entries/AbstractListEntry.java +++ /dev/null @@ -1,8 +0,0 @@ -package me.senseiwells.essentialclient.gui.entries; - -import net.minecraft.client.gui.ParentElement; -import net.minecraft.client.gui.widget.ElementListWidget; - -public abstract class AbstractListEntry> extends ElementListWidget.Entry implements ParentElement { - -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/entries/BaseListEntry.java b/src/main/java/me/senseiwells/essentialclient/gui/entries/BaseListEntry.java deleted file mode 100644 index 734ecd5c..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/entries/BaseListEntry.java +++ /dev/null @@ -1,127 +0,0 @@ -package me.senseiwells.essentialclient.gui.entries; - -import com.google.common.collect.ImmutableList; -import me.senseiwells.essentialclient.gui.RulesScreen; -import me.senseiwells.essentialclient.gui.config.ConfigListWidget; -import me.senseiwells.essentialclient.utils.interfaces.Rule; -import me.senseiwells.essentialclient.utils.render.RuleWidget; -import me.senseiwells.essentialclient.utils.render.Texts; -import me.senseiwells.essentialclient.utils.render.WidgetHelper; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.ClickableWidget; -import net.minecraft.text.OrderedText; -import net.minecraft.text.StringVisitable; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Supplier; - -public abstract class BaseListEntry extends ConfigListWidget.Entry { - protected final Rule rule; - protected final RulesScreen rulesScreen; - protected final MinecraftClient client; - protected final String ruleName; - protected final RuleWidget ruleWidget; - protected final T editButton; - protected final ButtonWidget resetButton; - private Consumer resetConsumer; - - public BaseListEntry(Rule rule, MinecraftClient client, RulesScreen rulesScreen, Supplier editButton) { - this.rule = rule; - this.client = client; - this.rulesScreen = rulesScreen; - this.ruleName = rule.getName(); - this.ruleWidget = new RuleWidget(this.ruleName, 190, 15); - this.editButton = editButton.get(); - this.resetButton = WidgetHelper.newButton(0, 0, 50, 20, Texts.RESET, button -> { - this.resetConsumer.accept(button); - }); - this.resetConsumer = buttonWidget -> { - this.rule.resetToDefault(); - this.editButton.setMessage(Text.literal(this.rule.getDefaultValue().toString())); - }; - this.checkDisabled(); - } - - protected void setResetButton(Consumer consumer) { - this.resetConsumer = consumer; - } - - protected void renderEditButton(DrawContext context, int x, int y, int mouseX, int mouseY, float delta) { - this.editButton.setPosition(x + 180, y); - this.editButton.render(context, mouseX, mouseY, delta); - } - - protected void checkDisabled() { - if (this.cannotEdit() || !this.rule.isAvailable() || !this.rule.changeable()) { - this.children().forEach(child -> { - child.active = false; - }); - } - } - - protected boolean cannotEdit() { - return !this.rulesScreen.canModify(); - } - - protected boolean isRuleWidgetHovered(double mouseX, double mouseY) { - return this.ruleWidget.isHovered((int) mouseX, (int) mouseY) && mouseY > 32 && mouseY < this.rulesScreen.height - 32; - } - - public Rule getRule() { - return this.rule; - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (button == 0 && this.isRuleWidgetHovered(mouseX, mouseY)) { - this.ruleWidget.toggle(); - } - return super.mouseClicked(mouseX, mouseY, button); - } - - @Override - public void render(DrawContext context, int index, int y, int x, int width, int height, int mouseX, int mouseY, boolean hovered, float delta) { - TextRenderer font = this.client.textRenderer; - float fontX = (float) (x + 100 - ConfigListWidget.LENGTH); - float fontY = (float) (y + height / 2 - 9 / 2); - this.ruleWidget.setPos(x - 50, y + 2); - this.ruleWidget.drawRule(context, font, fontX, fontY, 16777215); - if (this.isRuleWidgetHovered(mouseX, mouseY)) { - List lines = new ArrayList<>(); - Text nameText = Text.literal(this.ruleName).formatted(Formatting.GOLD); - lines.add(nameText.asOrderedText()); - String info; - if (this.ruleWidget.isToggled() && this.rule.getOptionalInfo() != null) { - info = "§3Extra Info:§r\n" + this.rule.getOptionalInfo(); - } else { - info = this.rule.getDescription(); - } - if (info != null) { - lines.addAll(this.client.textRenderer.wrapLines(StringVisitable.plain(info.replace("\r", "")), 220)); - this.rulesScreen.setCurrentTooltip(lines); - } - } - this.resetButton.setPosition(x + 290, y); - this.resetButton.active = this.rule.isAvailable() && this.rule.changeable() && this.rule.isNotDefault(); - this.resetButton.render(context, mouseX, mouseY, delta); - - this.renderEditButton(context, x, y, mouseX, mouseY, delta); - } - - @Override - public List children() { - return ImmutableList.of(this.editButton, this.resetButton); - } - - @Override - public List selectableChildren() { - return this.children(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/entries/BooleanListEntry.java b/src/main/java/me/senseiwells/essentialclient/gui/entries/BooleanListEntry.java deleted file mode 100644 index ad440599..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/entries/BooleanListEntry.java +++ /dev/null @@ -1,25 +0,0 @@ -package me.senseiwells.essentialclient.gui.entries; - -import me.senseiwells.essentialclient.gui.RulesScreen; -import me.senseiwells.essentialclient.utils.interfaces.Rule; -import me.senseiwells.essentialclient.utils.render.WidgetHelper; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.widget.ButtonWidget; - -import static me.senseiwells.essentialclient.utils.render.Texts.FALSE; -import static me.senseiwells.essentialclient.utils.render.Texts.TRUE; - -public class BooleanListEntry extends BaseListEntry { - public BooleanListEntry(Rule.Bool rule, MinecraftClient client, RulesScreen rulesScreen) { - super(rule, client, rulesScreen, () -> { - return WidgetHelper.newButton(0, 0, 100, 20, rule.getValue() ? TRUE : FALSE, buttonWidget -> { - rule.invert(); - buttonWidget.setMessage(rule.getValue() ? TRUE : FALSE); - }); - }); - this.setResetButton(buttonWidget -> { - this.rule.resetToDefault(); - this.editButton.setMessage(rule.getDefaultValue() ? TRUE : FALSE); - }); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/entries/CategoryEntry.java b/src/main/java/me/senseiwells/essentialclient/gui/entries/CategoryEntry.java deleted file mode 100644 index 1518da4b..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/entries/CategoryEntry.java +++ /dev/null @@ -1,35 +0,0 @@ -package me.senseiwells.essentialclient.gui.entries; - -import com.google.common.collect.ImmutableList; -import me.senseiwells.essentialclient.gui.config.ConfigListWidget; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.text.Text; - -import java.util.List; - -public class CategoryEntry extends ConfigListWidget.Entry { - private final String name; - - public CategoryEntry(String name) { - this.name = name; - } - - @Override - public List selectableChildren() { - return ImmutableList.of(); - } - - @Override - public List children() { - return ImmutableList.of(); - } - - @Override - public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { - int fontX = (x + entryWidth) / 2; - int fontY = (y + entryHeight / 2 - 9 / 2); - context.drawCenteredTextWithShadow(EssentialUtils.getClient().textRenderer, Text.literal(this.name), fontX, fontY, 16777215); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/entries/CycleListEntry.java b/src/main/java/me/senseiwells/essentialclient/gui/entries/CycleListEntry.java deleted file mode 100644 index 7d2fa458..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/entries/CycleListEntry.java +++ /dev/null @@ -1,19 +0,0 @@ -package me.senseiwells.essentialclient.gui.entries; - -import me.senseiwells.essentialclient.gui.RulesScreen; -import me.senseiwells.essentialclient.utils.interfaces.Rule; -import me.senseiwells.essentialclient.utils.render.WidgetHelper; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.text.Text; - -public class CycleListEntry extends BaseListEntry { - public CycleListEntry(Rule.Cycle rule, MinecraftClient client, RulesScreen rulesScreen) { - super(rule, client, rulesScreen, () -> { - return WidgetHelper.newButton(0, 0, 100, 20, Text.literal(rule.getValue()), buttonWidget -> { - rule.cycleValues(); - buttonWidget.setMessage(Text.literal(rule.getValue())); - }); - }); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/entries/ListListEntry.java b/src/main/java/me/senseiwells/essentialclient/gui/entries/ListListEntry.java deleted file mode 100644 index e395103f..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/entries/ListListEntry.java +++ /dev/null @@ -1,19 +0,0 @@ -package me.senseiwells.essentialclient.gui.entries; - -import me.senseiwells.essentialclient.gui.RulesScreen; -import me.senseiwells.essentialclient.gui.config.ListScreen; -import me.senseiwells.essentialclient.utils.interfaces.Rule; -import me.senseiwells.essentialclient.utils.render.Texts; -import me.senseiwells.essentialclient.utils.render.WidgetHelper; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.widget.ButtonWidget; - -public class ListListEntry extends BaseListEntry { - public ListListEntry(Rule.ListRule rule, MinecraftClient client, RulesScreen rulesScreen) { - super(rule, client, rulesScreen, () -> { - return WidgetHelper.newButton(0, 0, 100, 20, Texts.EDIT_LIST, buttonWidget -> { - client.setScreen(new ListScreen(Texts.EDITING_LIST.generate(rule.getName()), rulesScreen, rule)); - }); - }); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/entries/NumberListEntry.java b/src/main/java/me/senseiwells/essentialclient/gui/entries/NumberListEntry.java deleted file mode 100644 index 663437ed..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/entries/NumberListEntry.java +++ /dev/null @@ -1,25 +0,0 @@ -package me.senseiwells.essentialclient.gui.entries; - -import me.senseiwells.essentialclient.gui.RulesScreen; -import me.senseiwells.essentialclient.utils.interfaces.Rule; -import net.minecraft.client.MinecraftClient; - -public class NumberListEntry extends StringListEntry { - public NumberListEntry(Rule clientRule, MinecraftClient client, RulesScreen rulesScreen) { - super(clientRule, client, rulesScreen); - } - - @Override - protected void checkForInvalid(String newValue) { - super.checkForInvalid(newValue); - try { - switch (this.rule.getType()) { - case DOUBLE -> Double.parseDouble(newValue); - case INTEGER -> Integer.parseInt(newValue); - default -> throw new IllegalStateException("Unexpected value: " + this.rule.getType()); - } - } catch (NumberFormatException e) { - this.setInvalid(true); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/entries/SliderListEntry.java b/src/main/java/me/senseiwells/essentialclient/gui/entries/SliderListEntry.java deleted file mode 100644 index f230db5c..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/entries/SliderListEntry.java +++ /dev/null @@ -1,43 +0,0 @@ -package me.senseiwells.essentialclient.gui.entries; - -import me.senseiwells.essentialclient.gui.RulesScreen; -import me.senseiwells.essentialclient.utils.interfaces.Rule; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.widget.SliderWidget; -import net.minecraft.text.Text; - -public class SliderListEntry extends BaseListEntry { - public SliderListEntry(Rule.Slider rule, MinecraftClient client, RulesScreen rulesScreen) { - super(rule, client, rulesScreen, () -> { - return new RuleSliderWidget(rule, 0, 0, 100, 20, Text.literal(rule.getValue().toString()), rule.getPercentage()); - }); - this.setResetButton(buttonWidget -> { - this.rule.resetToDefault(); - this.editButton.setValueQuietly(rule.getPercentage()); - }); - } - - public static class RuleSliderWidget extends SliderWidget { - private final Rule.Slider slider; - - public RuleSliderWidget(Rule.Slider slider, int x, int y, int width, int height, Text text, double value) { - super(x, y, width, height, text, value); - this.slider = slider; - } - - protected void setValueQuietly(double percentage) { - this.value = percentage; - this.updateMessage(); - } - - @Override - protected void updateMessage() { - this.setMessage(Text.literal(this.slider.getFormatted())); - } - - @Override - protected void applyValue() { - this.slider.setFromPercentage(this.value); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/entries/StringListEntry.java b/src/main/java/me/senseiwells/essentialclient/gui/entries/StringListEntry.java deleted file mode 100644 index f0d36728..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/entries/StringListEntry.java +++ /dev/null @@ -1,108 +0,0 @@ -package me.senseiwells.essentialclient.gui.entries; - -import me.senseiwells.essentialclient.gui.RulesScreen; -import me.senseiwells.essentialclient.utils.interfaces.Rule; -import me.senseiwells.essentialclient.utils.render.Texts; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.client.render.DiffuseLighting; -import net.minecraft.item.Items; -import org.lwjgl.glfw.GLFW; - -public class StringListEntry extends BaseListEntry { - private boolean invalid; - private boolean changed; - - public StringListEntry(Rule rule, MinecraftClient client, RulesScreen rulesScreen) { - super(rule, client, rulesScreen, () -> { - return new TextFieldWidget(client.textRenderer, 0, 0, 96, 14, Texts.EMPTY); - }); - this.setResetButton(buttonWidget -> { - this.rule.resetToDefault(); - this.editButton.setText(this.rule.getDefaultValue().toString()); - }); - this.invalid = false; - this.changed = false; - if (rule instanceof Rule.Str strRule) { - this.editButton.setMaxLength(strRule.getMaxLength()); - } - this.editButton.setText(rule.getValue().toString()); - this.editButton.setChangedListener(this::checkForInvalid); - // rulesScreen.addTextField(this.editButton); - } - - protected void checkForInvalid(String newString) { - this.changed = true; - boolean isEmpty = newString.isEmpty(); - this.rulesScreen.setEmpty(isEmpty); - this.setInvalid(isEmpty); - } - - protected void setInvalid(boolean invalid) { - this.invalid = invalid; - this.rulesScreen.setInvalid(invalid); - } - - @Override - public boolean charTyped(char chr, int keyCode) { - return this.editButton.charTyped(chr, keyCode); - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (keyCode == GLFW.GLFW_KEY_ENTER) { - this.editButton.setFocused(false); - if (!this.invalid) { - this.changed = false; - this.rule.setValueFromString(this.editButton.getText()); - } - } - return super.keyPressed(keyCode, scanCode, modifiers) || this.editButton.keyPressed(keyCode, scanCode, modifiers); - } - - @Override - protected void renderEditButton(DrawContext context, int x, int y, int mouseX, int mouseY, float delta) { - int xi = x + 182; - int yi = y + 3; - this.editButton.setPosition(xi, yi); - this.editButton.setEditableColor(this.invalid ? 16733525 : 16777215); - if (this.invalid) { - DiffuseLighting.enableGuiDepthLighting(); - context.drawItem( - Items.BARRIER.getDefaultStack(), - xi + this.editButton.getWidth() - 18, - yi - 1 - ); - DiffuseLighting.disableGuiDepthLighting(); - } - this.editButton.render(context, mouseX, mouseY, delta); - } - - @Override - protected void checkDisabled() { - if (this.cannotEdit() || !this.rule.isAvailable() || !this.rule.changeable()) { - this.children().forEach(child -> { - child.active = false; - }); - this.editButton.setEditable(false); - this.editButton.setFocusUnlocked(false); - } - } - - @Override - public void unFocus() { - this.editButton.setFocused(false); - } - - @Override - public void updateEntryOnClose() { - if (this.invalid) { - this.rule.resetToDefault(); - return; - } - if (this.changed) { - this.rule.setValueFromString(this.editButton.getText()); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/gui/modmenu/ModMenuImpl.java b/src/main/java/me/senseiwells/essentialclient/gui/modmenu/ModMenuImpl.java deleted file mode 100644 index bbede474..00000000 --- a/src/main/java/me/senseiwells/essentialclient/gui/modmenu/ModMenuImpl.java +++ /dev/null @@ -1,12 +0,0 @@ -package me.senseiwells.essentialclient.gui.modmenu; - -import com.terraformersmc.modmenu.api.ConfigScreenFactory; -import com.terraformersmc.modmenu.api.ModMenuApi; -import me.senseiwells.essentialclient.gui.config.ConfigScreen; - -public class ModMenuImpl implements ModMenuApi { - @Override - public ConfigScreenFactory getModConfigScreenFactory() { - return ConfigScreen::new; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/autoWalk/KeyboardInputMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/autoWalk/KeyboardInputMixin.java deleted file mode 100644 index c323f78f..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/autoWalk/KeyboardInputMixin.java +++ /dev/null @@ -1,48 +0,0 @@ -package me.senseiwells.essentialclient.mixins.autoWalk; - -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import net.minecraft.client.input.Input; -import net.minecraft.client.input.KeyboardInput; -import net.minecraft.client.option.GameOptions; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(KeyboardInput.class) -public class KeyboardInputMixin extends Input { - @Shadow - @Final - private GameOptions settings; - - @Unique - private int ticks = 0; - @Unique - private boolean shouldAutoHold = false; - - @Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/option/KeyBinding;isPressed()Z", ordinal = 3, shift = At.Shift.AFTER)) - private void onTick(boolean slowDown, float f, CallbackInfo ci) { - if (this.settings.forwardKey.isPressed()) { - int autoWalk = ClientRules.AUTO_WALK.getValue(); - this.shouldAutoHold = autoWalk > 0 && this.ticks++ > autoWalk; - if (this.shouldAutoHold) { - EssentialUtils.sendMessageToActionBar(Text.literal("You are now autowalking").formatted(Formatting.GREEN)); - } - this.pressingForward = true; - } else { - this.ticks = 0; - this.pressingForward = this.shouldAutoHold; - } - - if (this.settings.backKey.isPressed()) { - this.ticks = 0; - this.shouldAutoHold = false; - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/betterAccurateBlockPlacement/ClientPlayerEntityMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/betterAccurateBlockPlacement/ClientPlayerEntityMixin.java deleted file mode 100644 index 17a85cc2..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/betterAccurateBlockPlacement/ClientPlayerEntityMixin.java +++ /dev/null @@ -1,98 +0,0 @@ -package me.senseiwells.essentialclient.mixins.betterAccurateBlockPlacement; - -import com.mojang.authlib.GameProfile; -import me.senseiwells.essentialclient.feature.BetterAccurateBlockPlacement; -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.network.packet.Packet; -import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.World; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.Slice; - -@Mixin(ClientPlayerEntity.class) -public abstract class ClientPlayerEntityMixin extends PlayerEntity { - public ClientPlayerEntityMixin(World world, BlockPos pos, float yaw, GameProfile profile) { - super(world, pos, yaw, profile); - } - - @Redirect( - method = "sendMovementPackets", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;sendPacket(Lnet/minecraft/network/packet/Packet;)V", - ordinal = 0 - ), - slice = @Slice( - from = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isCamera()Z") - ), - require = 0 - ) - private void onSendPacketVehicle(ClientPlayNetworkHandler clientPlayNetworkHandler, Packet packet) { - if (!ClientRules.BETTER_ACCURATE_BLOCK_PLACEMENT.getValue()) { - clientPlayNetworkHandler.sendPacket(packet); - return; - } - Vec3d vec3d = this.getVelocity(); - clientPlayNetworkHandler.sendPacket(new PlayerMoveC2SPacket.Full( - vec3d.x, -999, vec3d.y, - BetterAccurateBlockPlacement.fakeYaw, - BetterAccurateBlockPlacement.fakePitch, - this.isOnGround() - )); - } - - @Redirect( - method = "sendMovementPackets", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;sendPacket(Lnet/minecraft/network/packet/Packet;)V", - ordinal = 1 - ), - slice = @Slice( - from = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isCamera()Z") - ), - require = 0 - ) - private void onSendPacketAll(ClientPlayNetworkHandler clientPlayNetworkHandler, Packet packet) { - if (!ClientRules.BETTER_ACCURATE_BLOCK_PLACEMENT.getValue()) { - clientPlayNetworkHandler.sendPacket(packet); - return; - } - - PlayerMoveC2SPacket.Full existing = ((PlayerMoveC2SPacket.Full) packet); - clientPlayNetworkHandler.sendPacket(new PlayerMoveC2SPacket.Full( - existing.getX(0), existing.getY(0), existing.getZ(0), - BetterAccurateBlockPlacement.fakeYaw, - BetterAccurateBlockPlacement.fakePitch, - this.isOnGround() - )); - } - - @SuppressWarnings("ConstantConditions") - @Redirect( - method = "sendMovementPackets", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;sendPacket(Lnet/minecraft/network/packet/Packet;)V", - ordinal = 3 - ), - slice = @Slice( - from = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isCamera()Z") - ), - require = 0 - ) - private void onSendPacketLook(ClientPlayNetworkHandler clientPlayNetworkHandler, Packet packet) { - if (!ClientRules.BETTER_ACCURATE_BLOCK_PLACEMENT.getValue()) { - clientPlayNetworkHandler.sendPacket(packet); - return; - } - BetterAccurateBlockPlacement.sendLookPacket((ClientPlayerEntity) (Object) this); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/betterAccurateBlockPlacement/ItemPlacementContextMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/betterAccurateBlockPlacement/ItemPlacementContextMixin.java deleted file mode 100644 index 44f7d52c..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/betterAccurateBlockPlacement/ItemPlacementContextMixin.java +++ /dev/null @@ -1,26 +0,0 @@ -package me.senseiwells.essentialclient.mixins.betterAccurateBlockPlacement; - -import me.senseiwells.essentialclient.feature.BetterAccurateBlockPlacement; -import net.minecraft.item.ItemPlacementContext; -import net.minecraft.util.math.Direction; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(ItemPlacementContext.class) -public class ItemPlacementContextMixin { - @Inject(method = "getPlayerLookDirection", at = @At("HEAD"), cancellable = true) - private void onGetDirection(CallbackInfoReturnable cir) { - if (BetterAccurateBlockPlacement.fakeDirection != null) { - cir.setReturnValue(BetterAccurateBlockPlacement.fakeDirection); - } - } - - @Inject(method = "getVerticalPlayerLookDirection", at = @At("HEAD"), cancellable = true, require = 0) - private void onGetVerticalDirection(CallbackInfoReturnable cir) { - if (BetterAccurateBlockPlacement.fakeDirection != null && BetterAccurateBlockPlacement.fakeDirection.getAxis() == Direction.Axis.Y) { - cir.setReturnValue(BetterAccurateBlockPlacement.fakeDirection); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/betterAccurateBlockPlacement/ItemUsageContextMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/betterAccurateBlockPlacement/ItemUsageContextMixin.java deleted file mode 100644 index a256d272..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/betterAccurateBlockPlacement/ItemUsageContextMixin.java +++ /dev/null @@ -1,24 +0,0 @@ -package me.senseiwells.essentialclient.mixins.betterAccurateBlockPlacement; - -import me.senseiwells.essentialclient.feature.BetterAccurateBlockPlacement; -import net.minecraft.item.ItemUsageContext; -import net.minecraft.util.math.Direction; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(ItemUsageContext.class) -public class ItemUsageContextMixin { - @Inject( - method = "getHorizontalPlayerFacing", - at = @At("HEAD"), - cancellable = true - ) - private void onGetFacing(CallbackInfoReturnable cir) { - Direction direction = BetterAccurateBlockPlacement.fakeDirection; - if (direction != null && direction.getAxis() != Direction.Axis.Y) { - cir.setReturnValue(direction); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/carpet/ClientNetworkHandlerMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/carpet/ClientNetworkHandlerMixin.java deleted file mode 100644 index 559fc47a..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/carpet/ClientNetworkHandlerMixin.java +++ /dev/null @@ -1,17 +0,0 @@ -package me.senseiwells.essentialclient.mixins.carpet; - -import carpet.network.ClientNetworkHandler; -import me.senseiwells.essentialclient.feature.CarpetClient; -import net.minecraft.nbt.NbtCompound; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -@Mixin(value = ClientNetworkHandler.class, remap = false) -public class ClientNetworkHandlerMixin { - @ModifyVariable(method = "lambda$static$1", at = @At("STORE"), ordinal = 1) - private static NbtCompound onGetRuleNBT(NbtCompound original) { - CarpetClient.INSTANCE.syncCarpetRule(original); - return original; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/chunkDebug/InGameHudMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/chunkDebug/InGameHudMixin.java deleted file mode 100644 index 6227667e..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/chunkDebug/InGameHudMixin.java +++ /dev/null @@ -1,26 +0,0 @@ -package me.senseiwells.essentialclient.mixins.chunkDebug; - -import me.senseiwells.essentialclient.feature.chunkdebug.ChunkGrid; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.client.render.RenderTickCounter; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(InGameHud.class) -public class InGameHudMixin { - @Inject( - method = "renderCrosshair", - at = @At(value = "TAIL") - ) - private void afterCrossHairRender( - DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci - ) { - if (ChunkGrid.instance != null) { - ChunkGrid.instance.renderMinimap(context.getScaledWindowWidth(), context.getScaledWindowWidth()); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/cleanConfirmScreen/ConfirmScreenMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/cleanConfirmScreen/ConfirmScreenMixin.java deleted file mode 100644 index 09ef3e0a..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/cleanConfirmScreen/ConfirmScreenMixin.java +++ /dev/null @@ -1,28 +0,0 @@ -package me.senseiwells.essentialclient.mixins.cleanConfirmScreen; - -import net.minecraft.client.font.MultilineText; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.screen.ConfirmScreen; -import net.minecraft.text.StringVisitable; -import net.minecraft.text.Text; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(ConfirmScreen.class) -public class ConfirmScreenMixin { - @Redirect( - method = "init", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/font/MultilineText;create(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/text/Text;I)Lnet/minecraft/client/font/MultilineText;" - ) - ) - private MultilineText onDisplayMessage(TextRenderer renderer, Text text, int maxWidth) { - String message = text.getString(); - if (message.length() > 120) { - text = Text.literal(message.substring(0, 120) + "..."); - } - return MultilineText.create(renderer, text, maxWidth); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientNick/MessageHandlerMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientNick/MessageHandlerMixin.java deleted file mode 100644 index 58a3f236..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientNick/MessageHandlerMixin.java +++ /dev/null @@ -1,33 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientNick; - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import com.mojang.authlib.GameProfile; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.config.ConfigClientNick; -import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.client.network.message.MessageHandler; -import net.minecraft.network.message.MessageType; -import net.minecraft.network.message.SignedMessage; -import net.minecraft.text.Text; -import net.minecraft.text.TextVisitFactory; -import org.apache.commons.lang3.StringUtils; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(MessageHandler.class) -public class MessageHandlerMixin { - @ModifyExpressionValue(method = "onChatMessage", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/message/MessageType$Parameters;applyChatDecoration(Lnet/minecraft/text/Text;)Lnet/minecraft/text/Text;")) - private Text modifyChatMessage(Text text, SignedMessage signedMessage, GameProfile profile, MessageType.Parameters params) { - if (ClientRules.COMMAND_CLIENT_NICK.getValue()) { - PlayerListEntry playerListEntry = EssentialUtils.getNetworkHandler().getPlayerListEntry(signedMessage.getSender()); - if (playerListEntry != null) { - String newName = ConfigClientNick.INSTANCE.get(playerListEntry.getProfile().getName()); - String message = TextVisitFactory.removeFormattingCodes(text); - String oldName = StringUtils.substringBetween(message, "<", ">"); - text = newName != null && oldName != null ? Text.literal(message.replaceAll(oldName, newName)) : text; - } - } - return text; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientNick/PlayerEntityRendererMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientNick/PlayerEntityRendererMixin.java deleted file mode 100644 index f354ef9b..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientNick/PlayerEntityRendererMixin.java +++ /dev/null @@ -1,52 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientNick; - -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.config.ConfigClientNick; -import net.minecraft.client.network.AbstractClientPlayerEntity; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.EntityRendererFactory; -import net.minecraft.client.render.entity.LivingEntityRenderer; -import net.minecraft.client.render.entity.PlayerEntityRenderer; -import net.minecraft.client.render.entity.model.PlayerEntityModel; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.Entity; -import net.minecraft.text.Text; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(PlayerEntityRenderer.class) -public abstract class PlayerEntityRendererMixin extends LivingEntityRenderer> { - public PlayerEntityRendererMixin( - EntityRendererFactory.Context context, - PlayerEntityModel model, - float shadowRadius - ) { - super(context, model, shadowRadius); - } - - @Redirect( - method = "renderLabelIfPresent(Lnet/minecraft/client/network/AbstractClientPlayerEntity;Lnet/minecraft/text/Text;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IF)V", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/render/entity/LivingEntityRenderer;renderLabelIfPresent(Lnet/minecraft/entity/Entity;Lnet/minecraft/text/Text;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IF)V", - ordinal = 1 - ) - ) - private void onRenderLabel( - LivingEntityRenderer> instance, - Entity entity, - Text text, - MatrixStack matrices, - VertexConsumerProvider vertexConsumers, - int light, - float tickDelta - ) { - if (ClientRules.COMMAND_CLIENT_NICK.getValue()) { - String playerName = entity.getNameForScoreboard(); - String newPlayerName = ConfigClientNick.INSTANCE.get(playerName); - text = newPlayerName != null ? Text.literal(newPlayerName) : text; - } - super.renderLabelIfPresent((AbstractClientPlayerEntity) entity, text, matrices, vertexConsumers, light, tickDelta); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientNick/PlayerListHudMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientNick/PlayerListHudMixin.java deleted file mode 100644 index 7610755f..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientNick/PlayerListHudMixin.java +++ /dev/null @@ -1,31 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientNick; - -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.config.ConfigClientNick; -import net.minecraft.client.gui.hud.PlayerListHud; -import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.scoreboard.Team; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(PlayerListHud.class) -public abstract class PlayerListHudMixin { - @Shadow - protected abstract Text applyGameModeFormatting(PlayerListEntry entry, MutableText name); - - @Inject(method = "getPlayerName", at = @At("HEAD"), cancellable = true) - private void onGetPlayerName(PlayerListEntry entry, CallbackInfoReturnable cir) { - if (ClientRules.COMMAND_CLIENT_NICK.getValue()) { - String playerName = entry.getProfile().getName(); - String newName = ConfigClientNick.INSTANCE.get(playerName); - if (newName != null) { - cir.setReturnValue(this.applyGameModeFormatting(entry, Team.decorateName(entry.getScoreboardTeam(), Text.of(newName)))); - } - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/AnvilScreenHandlerMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/AnvilScreenHandlerMixin.java deleted file mode 100644 index 6a7d1ddd..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/AnvilScreenHandlerMixin.java +++ /dev/null @@ -1,45 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import me.senseiwells.essentialclient.clientscript.events.MinecraftScriptEvents; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.player.PlayerInventory; -import net.minecraft.item.ItemStack; -import net.minecraft.screen.*; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(AnvilScreenHandler.class) -public abstract class AnvilScreenHandlerMixin extends ForgingScreenHandler { - @Shadow - private String newItemName; - - @Shadow - @Final - private Property levelCost; - - public AnvilScreenHandlerMixin(@Nullable ScreenHandlerType type, int syncId, PlayerInventory playerInventory, ScreenHandlerContext context) { - super(type, syncId, playerInventory, context); - } - - @Inject(method = "onTakeOutput", at = @At("HEAD")) - private void onAnvil( - PlayerEntity player, - ItemStack stack, - CallbackInfo ci - ) { - if (player instanceof ClientPlayerEntity) { - MinecraftScriptEvents.ON_ANVIL.run( - this.input.getStack(0), - this.input.getStack(1), - stack, this.newItemName, - this.levelCost.get() - ); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/BlockItemMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/BlockItemMixin.java deleted file mode 100644 index d2c3bf48..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/BlockItemMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import me.senseiwells.essentialclient.clientscript.events.MinecraftScriptEvents; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptBlockState; -import net.minecraft.block.BlockState; -import net.minecraft.item.BlockItem; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(BlockItem.class) -public class BlockItemMixin { - @Redirect(method = "place(Lnet/minecraft/item/ItemPlacementContext;)Lnet/minecraft/util/ActionResult;", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;getBlockState(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/BlockState;")) - private BlockState onBlockPlaced(World instance, BlockPos pos) { - BlockState state = instance.getBlockState(pos); - MinecraftScriptEvents.ON_BLOCK_PLACED.run(new ScriptBlockState(state, pos)); - return state; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ChatHudMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ChatHudMixin.java deleted file mode 100644 index d12e1814..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ChatHudMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import me.senseiwells.essentialclient.utils.interfaces.ChatHudAccessor; -import net.minecraft.client.gui.hud.ChatHud; -import net.minecraft.client.gui.hud.ChatHudLine; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import java.util.List; - -@Mixin(ChatHud.class) -public class ChatHudMixin implements ChatHudAccessor { - @Final - @Shadow - private List messages; - - @Override - public List essentialclient$getMessages() { - return this.messages; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ClientPlayNetworkHandlerMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ClientPlayNetworkHandlerMixin.java deleted file mode 100644 index e595bffe..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ClientPlayNetworkHandlerMixin.java +++ /dev/null @@ -1,254 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import com.llamalad7.mixinextras.injector.WrapWithCondition; -import com.mojang.authlib.GameProfile; -import me.senseiwells.essentialclient.clientscript.core.ClientScriptIO; -import me.senseiwells.essentialclient.clientscript.events.MinecraftScriptEvents; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptBlockState; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptItemStack; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientCommonNetworkHandler; -import net.minecraft.client.network.ClientConnectionState; -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.client.network.message.MessageHandler; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.entity.Entity; -import net.minecraft.entity.ItemEntity; -import net.minecraft.entity.LivingEntity; -import net.minecraft.network.ClientConnection; -import net.minecraft.network.message.MessageType; -import net.minecraft.network.message.SignedMessage; -import net.minecraft.network.packet.s2c.play.*; -import net.minecraft.registry.DynamicRegistryManager; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.util.Identifier; -import net.minecraft.util.Util; -import net.minecraft.world.GameMode; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.Map; -import java.util.UUID; - -@Mixin(ClientPlayNetworkHandler.class) -public abstract class ClientPlayNetworkHandlerMixin extends ClientCommonNetworkHandler { - @Shadow - private ClientWorld world; - - @Final - @Shadow - private DynamicRegistryManager.Immutable combinedDynamicRegistries; - - @Shadow - @Final - private Map playerListEntries; - - protected ClientPlayNetworkHandlerMixin(MinecraftClient client, ClientConnection connection, ClientConnectionState connectionState) { - super(client, connection, connectionState); - } - - @Inject( - method = "onHealthUpdate", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/network/NetworkThreadUtils;forceMainThread(Lnet/minecraft/network/packet/Packet;Lnet/minecraft/network/listener/PacketListener;Lnet/minecraft/util/thread/ThreadExecutor;)V", - shift = At.Shift.AFTER - ) - ) - private void onHealthUpdate(HealthUpdateS2CPacket packet, CallbackInfo ci) { - MinecraftScriptEvents.ON_HEALTH_UPDATE.run(packet.getHealth()); - } - - @Inject( - method = "onBlockUpdate", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/network/NetworkThreadUtils;forceMainThread(Lnet/minecraft/network/packet/Packet;Lnet/minecraft/network/listener/PacketListener;Lnet/minecraft/util/thread/ThreadExecutor;)V", - shift = At.Shift.AFTER - ) - ) - private void onBlockUpdate(BlockUpdateS2CPacket packet, CallbackInfo ci) { - MinecraftScriptEvents.ON_BLOCK_UPDATE.run(new ScriptBlockState(packet.getState(), packet.getPos())); - } - - @Inject( - method = "onEntityStatus", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/render/GameRenderer;showFloatingItem(Lnet/minecraft/item/ItemStack;)V" - ) - ) - private void onTotem(CallbackInfo ci) { - MinecraftScriptEvents.ON_TOTEM.run(); - } - - @Inject( - method = "onGameStateChange", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;setGameMode(Lnet/minecraft/world/GameMode;)V" - ) - ) - private void onGamemodeChange(GameStateChangeS2CPacket packet, CallbackInfo ci) { - MinecraftScriptEvents.ON_GAMEMODE_CHANGE.run(GameMode.byId((int) packet.getValue()).getName()); - } - - @Inject( - method = "onItemPickupAnimation", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/network/NetworkThreadUtils;forceMainThread(Lnet/minecraft/network/packet/Packet;Lnet/minecraft/network/listener/PacketListener;Lnet/minecraft/util/thread/ThreadExecutor;)V", - shift = At.Shift.AFTER - ) - ) - private void onPickUp(ItemPickupAnimationS2CPacket packet, CallbackInfo ci) { - Entity entity = this.world.getEntityById(packet.getEntityId()); - LivingEntity livingEntity = (LivingEntity) this.world.getEntityById(packet.getCollectorEntityId()); - if (entity instanceof ItemEntity itemEntity && this.client.player != null && this.client.player.equals(livingEntity)) { - MinecraftScriptEvents.ON_PICK_UP_ITEM.run(new ScriptItemStack(itemEntity.getStack().copy())); - } - } - - @Inject(method = "onPlayerRespawn", at = @At("TAIL")) - private void onPlayerRespawn(PlayerRespawnS2CPacket packet, CallbackInfo ci) { - MinecraftScriptEvents.ON_RESPAWN.run(this.client.player); - } - - @WrapWithCondition( - method = "onChatMessage", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/network/message/MessageHandler;onChatMessage(Lnet/minecraft/network/message/SignedMessage;Lcom/mojang/authlib/GameProfile;Lnet/minecraft/network/message/MessageType$Parameters;)V" - ) - ) - private boolean onChatMessage(MessageHandler instance, SignedMessage message, GameProfile sender, MessageType.Parameters params) { - MessageType messageType = params.type().value(); - Identifier typeId = this.combinedDynamicRegistries.get(RegistryKeys.MESSAGE_TYPE).getId(messageType); - String content = message.getContent().getString(); - String type = typeId == null ? "unknown" : typeId.getPath(); - return !MinecraftScriptEvents.ON_RECEIVE_MESSAGE.run(sender.getId().toString(), content, type); - } - - @Inject( - method = "onGameMessage", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/network/NetworkThreadUtils;forceMainThread(Lnet/minecraft/network/packet/Packet;Lnet/minecraft/network/listener/PacketListener;Lnet/minecraft/util/thread/ThreadExecutor;)V", - shift = At.Shift.AFTER - ), - cancellable = true - ) - private void onGameMessage(GameMessageS2CPacket packet, CallbackInfo ci) { - String content = packet.content().getString(); - String type = packet.overlay() ? "overlay" : "system"; - if (MinecraftScriptEvents.ON_RECEIVE_MESSAGE.run(Util.NIL_UUID.toString(), content, type)) { - ci.cancel(); - } - } - - @Inject( - method = "onPlayerList", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/network/NetworkThreadUtils;forceMainThread(Lnet/minecraft/network/packet/Packet;Lnet/minecraft/network/listener/PacketListener;Lnet/minecraft/util/thread/ThreadExecutor;)V", - shift = At.Shift.AFTER - ) - ) - private void onPlayerList(PlayerListS2CPacket packet, CallbackInfo info) { - for (PlayerListS2CPacket.Action action : packet.getActions()) { - if (action == PlayerListS2CPacket.Action.ADD_PLAYER) { - packet.getEntries().forEach(entry -> MinecraftScriptEvents.ON_PLAYER_JOIN.run(entry.profile().getName(), entry.profile().getId().toString())); - } - } - } - - @Inject( - method = "onPlayerRemove", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/network/NetworkThreadUtils;forceMainThread(Lnet/minecraft/network/packet/Packet;Lnet/minecraft/network/listener/PacketListener;Lnet/minecraft/util/thread/ThreadExecutor;)V", - shift = At.Shift.AFTER - ) - ) - private void onPlayerRemove(PlayerRemoveS2CPacket packet, CallbackInfo ci) { - for (UUID uuid : packet.profileIds()) { - PlayerListEntry entry = this.playerListEntries.get(uuid); - if (entry != null) { - MinecraftScriptEvents.ON_PLAYER_LEAVE.run(entry.getProfile().getName(), uuid.toString()); - } - } - } - - @Inject( - method = "onDeathMessage", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;getEntityById(I)Lnet/minecraft/entity/Entity;", shift = At.Shift.BEFORE) - ) - private void onDeath( - DeathMessageS2CPacket packet, - CallbackInfo ci - ) { - Entity entity = this.world.getEntityById(packet.playerId()); - if (entity == this.client.player) { - Entity killer = null; - MinecraftScriptEvents.ON_DEATH.run(killer, packet.message()); - } - } - - @Inject( - method = "onEntitySpawn", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/world/ClientWorld;addEntity(Lnet/minecraft/entity/Entity;)V", - shift = At.Shift.AFTER - ) - ) - private void onEntitySpawn(EntitySpawnS2CPacket packet, CallbackInfo ci) { - Entity entity = this.world.getEntityById(packet.getId()); - if (entity instanceof LivingEntity) { - MinecraftScriptEvents.ON_MOB_SPAWN.run(entity); - return; - } - if (entity != null) { - MinecraftScriptEvents.ON_ENTITY_SPAWN.run(entity); - } - } - - @Inject( - method = "method_37472", - at = @At( - value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;removeEntity(ILnet/minecraft/entity/Entity$RemovalReason;)V", - shift = At.Shift.BEFORE - ) - ) - private void onEntityRemoved(int entityId, CallbackInfo ci) { - Entity entity = this.world.getEntityById(entityId); - MinecraftScriptEvents.ON_ENTITY_REMOVED.run(entity); - } - - @Inject(method = "sendChatMessage", at = @At("HEAD"), cancellable = true) // Checkstyle Ignore - private void onChatMessage(String message, CallbackInfo ci) { - if (ClientScriptIO.INSTANCE.submitInput(message) || MinecraftScriptEvents.ON_SEND_MESSAGE.run(message)) { - ci.cancel(); - } - } - - @Inject(method = "sendChatCommand", at = @At("HEAD"), cancellable = true) - private void onCommand(String command, CallbackInfo ci) { - if (ClientScriptIO.INSTANCE.submitInput("/" + command) || MinecraftScriptEvents.ON_SEND_MESSAGE.run("/" + command)) { - ci.cancel(); - } - } - - @Inject(method = "sendCommand", at = @At("HEAD"), cancellable = true) - private void onCommand(String command, CallbackInfoReturnable cir) { - if (MinecraftScriptEvents.ON_SEND_MESSAGE.run("/" + command)) { - cir.setReturnValue(true); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ClientPlayerEntityMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ClientPlayerEntityMixin.java deleted file mode 100644 index 7b9e097d..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ClientPlayerEntityMixin.java +++ /dev/null @@ -1,69 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import com.mojang.authlib.GameProfile; -import me.senseiwells.essentialclient.clientscript.events.MinecraftScriptEvents; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.component.type.FoodComponent; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(ClientPlayerEntity.class) -public abstract class ClientPlayerEntityMixin extends PlayerEntity { - @Shadow public abstract float getPitch(float tickDelta); - - @Shadow public abstract float getYaw(float tickDelta); - - public ClientPlayerEntityMixin(World world, BlockPos pos, float yaw, GameProfile profile) { - super(world, pos, yaw, profile); - } - - @Inject(method = "dropSelectedItem", at = @At("HEAD"), cancellable = true) - private void onDropItem(boolean dropEntireStack, CallbackInfoReturnable cir) { - ItemStack heldItem = this.getMainHandStack(); - if (MinecraftScriptEvents.ON_DROP_ITEM.run(heldItem)) { - cir.setReturnValue(false); - } - } - - @Inject(method = "closeScreen", at = @At("HEAD")) - private void onCloseScreen(CallbackInfo ci) { - MinecraftScriptEvents.ON_CLOSE_SCREEN.run(EssentialUtils.getClient().currentScreen); - } - - @Override - public ItemStack eatFood(World world, ItemStack stack, FoodComponent foodComponent) { - MinecraftScriptEvents.ON_EAT.run(stack); - return super.eatFood(world, stack, foodComponent); - } - - @Override - public void changeLookDirection(double cursorDeltaX, double cursorDeltaY) { - float deltaPitch = (float) cursorDeltaY * 0.15F; - float deltaYaw = (float) cursorDeltaX * 0.15F; - float newPitch = this.getPitch() + deltaPitch; - float newYaw = this.getYaw() + deltaYaw; - - if (this.prevPitch == newPitch && this.prevYaw == newYaw) { - return; - } - - float parameterYaw = newYaw % 360; - if (parameterYaw < -180) { - parameterYaw += 360; - } - if (MinecraftScriptEvents.ON_PLAYER_LOOK.run(parameterYaw, newPitch)) { - return; - } - - super.changeLookDirection(cursorDeltaX, cursorDeltaY); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ClientPlayerInteractionManagerMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ClientPlayerInteractionManagerMixin.java deleted file mode 100644 index 32a94872..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ClientPlayerInteractionManagerMixin.java +++ /dev/null @@ -1,106 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import me.senseiwells.essentialclient.clientscript.events.MinecraftScriptEvents; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptBlockState; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptItemStack; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.network.ClientPlayerInteractionManager; -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.recipe.RecipeEntry; -import net.minecraft.screen.slot.SlotActionType; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(ClientPlayerInteractionManager.class) -public class ClientPlayerInteractionManagerMixin { - @Final - @Shadow - private MinecraftClient client; - - @Inject(method = "attackBlock", at = @At("HEAD"), cancellable = true) - private void onAttackBlock(BlockPos pos, Direction direction, CallbackInfoReturnable cir) { - if (this.client.world != null) { - if (MinecraftScriptEvents.ON_ATTACK_BLOCK.run(new ScriptBlockState(this.client.world.getBlockState(pos), pos))) { - cir.setReturnValue(false); - } - } - } - - @Inject(method = "attackEntity", at = @At("HEAD"), cancellable = true) - private void onAttackEntity(PlayerEntity player, Entity target, CallbackInfo ci) { - if (MinecraftScriptEvents.ON_ATTACK_ENTITY.run(target)) { - ci.cancel(); - } - } - - @Inject( - method = "breakBlock", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/block/Block;onBreak(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/entity/player/PlayerEntity;)Lnet/minecraft/block/BlockState;", - shift = At.Shift.BEFORE - ) - ) - private void onBreakBlock(BlockPos pos, CallbackInfoReturnable cir) { - if (this.client.world != null) { - MinecraftScriptEvents.ON_BLOCK_BROKEN.run(new ScriptBlockState(this.client.world.getBlockState(pos), pos)); - } - } - - @Inject(method = "clickSlot", at = @At("HEAD"), cancellable = true) - private void onClickSlot( - int syncId, - int slotId, - int button, - SlotActionType actionType, - PlayerEntity player, - CallbackInfo ci - ) { - if (MinecraftScriptEvents.ON_CLICK_SLOT.run(slotId, actionType.name(), new ScriptItemStack(slotId < 0 ? ItemStack.EMPTY : player.currentScreenHandler.slots.get(slotId).getStack().copy()))) { - ci.cancel(); - } - } - - @Inject(method = "clickRecipe", at = @At("HEAD"), cancellable = true) - private void onClickRecipe(int syncId, RecipeEntry recipe, boolean craftAll, CallbackInfo ci) { - if (MinecraftScriptEvents.ON_CLICK_RECIPE.run(recipe)) { - ci.cancel(); - } - } - - @Inject(method = "interactItem", at = @At("HEAD"), cancellable = true) - private void onInteractItem(PlayerEntity player, Hand hand, CallbackInfoReturnable cir) { - ItemStack itemStack = player.getStackInHand(hand); - if (MinecraftScriptEvents.ON_INTERACT_ITEM.run(new ScriptItemStack(itemStack))) { - cir.setReturnValue(ActionResult.PASS); - } - } - - @Inject(method = "interactBlock", at = @At("HEAD"), cancellable = true) - private void onInteractBlock(ClientPlayerEntity player, Hand hand, BlockHitResult hitResult, CallbackInfoReturnable cir) { - BlockPos pos = hitResult.getBlockPos(); - if (this.client.world != null && MinecraftScriptEvents.ON_INTERACT_BLOCK.run(new ScriptBlockState(this.client.world.getBlockState(pos), pos), new ScriptItemStack(player.getStackInHand(hand)))) { - cir.setReturnValue(ActionResult.PASS); - } - } - - @Inject(method = "interactEntity", at = @At("HEAD"), cancellable = true) - private void onInteractEntity(PlayerEntity player, Entity entity, Hand hand, CallbackInfoReturnable cir) { - if (MinecraftScriptEvents.ON_INTERACT_ENTITY.run(entity, new ScriptItemStack(player.getStackInHand(hand)))) { - cir.setReturnValue(ActionResult.PASS); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ClientWorldAccessor.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ClientWorldAccessor.java deleted file mode 100644 index df9f4f3f..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ClientWorldAccessor.java +++ /dev/null @@ -1,13 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import net.minecraft.client.world.ClientWorld; -import net.minecraft.world.EntityList; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(ClientWorld.class) -public interface ClientWorldAccessor { - @Accessor("entityList") - EntityList getEntityList(); -} - diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/DebugHudMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/DebugHudMixin.java deleted file mode 100644 index a20440da..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/DebugHudMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import me.senseiwells.essentialclient.clientscript.core.ClientScript; -import me.senseiwells.essentialclient.clientscript.core.ClientScriptInstance; -import net.minecraft.client.gui.hud.DebugHud; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.List; - -@Mixin(DebugHud.class) -public class DebugHudMixin { - @Inject(method = "getLeftText", at = @At("RETURN")) - private void onGetDebug(CallbackInfoReturnable> cir) { - List debugInfo = cir.getReturnValue(); - debugInfo.add("[EssentialClient] Scripts Running: %d".formatted( - ClientScript.INSTANCE.getScriptInstances().stream().filter(ClientScriptInstance::isScriptRunning).count()) - ); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/EntityListMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/EntityListMixin.java deleted file mode 100644 index 6c43cc95..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/EntityListMixin.java +++ /dev/null @@ -1,40 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import me.senseiwells.essentialclient.utils.interfaces.IEntityList; -import net.minecraft.entity.Entity; -import net.minecraft.world.EntityList; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -@Mixin(EntityList.class) -public class EntityListMixin implements IEntityList { - @Unique - final Set ALL_ENTITIES = ConcurrentHashMap.newKeySet(); - - @Inject( - method = "add", - at = @At("TAIL") - ) - private void onAdd(Entity entity, CallbackInfo ci) { - this.ALL_ENTITIES.add(entity); - } - - @Inject( - method = "remove", - at = @At("TAIL") - ) - private void onRemove(Entity entity, CallbackInfo ci) { - this.ALL_ENTITIES.remove(entity); - } - - @Override - public Entity[] essentialclient$getAllEntities() { - return this.ALL_ENTITIES.toArray(Entity[]::new); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/EntityMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/EntityMixin.java deleted file mode 100644 index 1c1c1a7b..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/EntityMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import net.minecraft.entity.Entity; -import net.minecraft.world.World; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(Entity.class) -public abstract class EntityMixin { - @Shadow - private World world; - - @Shadow - public abstract boolean isGlowingLocal(); - - @Inject(method = "isGlowing", at = @At("HEAD"), cancellable = true) - private void checkLocalGlowing(CallbackInfoReturnable cir) { - if (this.world.isClient() && this.isGlowingLocal()) { - cir.setReturnValue(true); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/FishingBobberEntityMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/FishingBobberEntityMixin.java deleted file mode 100644 index 8567de9b..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/FishingBobberEntityMixin.java +++ /dev/null @@ -1,41 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import me.senseiwells.essentialclient.clientscript.events.MinecraftScriptEvents; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.data.TrackedData; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.projectile.FishingBobberEntity; -import net.minecraft.world.World; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(FishingBobberEntity.class) -public abstract class FishingBobberEntityMixin extends Entity { - public FishingBobberEntityMixin(EntityType type, World world) { - super(type, world); - } - - @Shadow - public abstract PlayerEntity getPlayerOwner(); - - // @Inject( - // method = "onTrackedDataSet", - // at = @At( - // value = "INVOKE", - // target = "Lnet/minecraft/entity/projectile/FishingBobberEntity;setVelocity(DDD)V", - // shift = At.Shift.BEFORE - // ), - // remap = true - // ) - // private void onFishBite(TrackedData data, CallbackInfo ci) { - // PlayerEntity playerEntity = this.getPlayerOwner(); - // if (playerEntity != null && playerEntity == EssentialUtils.getPlayer()) { - // MinecraftScriptEvents.ON_FISH_BITE.run(this); - // } - // } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/HandledScreenMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/HandledScreenMixin.java deleted file mode 100644 index 5125c2db..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/HandledScreenMixin.java +++ /dev/null @@ -1,20 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import me.senseiwells.essentialclient.utils.render.FakeInventoryScreen; -import net.minecraft.client.gui.screen.ingame.HandledScreen; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(HandledScreen.class) -public abstract class HandledScreenMixin { - @SuppressWarnings("ConstantConditions") - @Inject(method = "tick", at = @At("HEAD"), cancellable = true) - private void onTick(CallbackInfo ci) { - if ((Object) this instanceof FakeInventoryScreen fakeInventoryScreen) { - fakeInventoryScreen.fakeTick(); - ci.cancel(); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ItemEntityAccessor.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ItemEntityAccessor.java deleted file mode 100644 index eeee5fba..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ItemEntityAccessor.java +++ /dev/null @@ -1,13 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import net.minecraft.entity.ItemEntity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import java.util.UUID; - -@Mixin(ItemEntity.class) -public interface ItemEntityAccessor { - @Accessor("throwerUuid") - UUID getThrower(); -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/KeyBindingAccessor.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/KeyBindingAccessor.java deleted file mode 100644 index 2e9ae5c4..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/KeyBindingAccessor.java +++ /dev/null @@ -1,12 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import net.minecraft.client.option.KeyBinding; -import net.minecraft.client.util.InputUtil; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(KeyBinding.class) -public interface KeyBindingAccessor { - @Accessor("boundKey") - InputUtil.Key getBoundKey(); -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/KeyboardMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/KeyboardMixin.java deleted file mode 100644 index 81a9c13b..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/KeyboardMixin.java +++ /dev/null @@ -1,39 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import me.senseiwells.essentialclient.clientscript.events.MinecraftScriptEvents; -import me.senseiwells.essentialclient.utils.keyboard.KeyboardHelper; -import net.minecraft.client.Keyboard; -import net.minecraft.client.MinecraftClient; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(Keyboard.class) -public class KeyboardMixin { - @Shadow - @Final - private MinecraftClient client; - - @Inject(method = "onKey", at = @At("HEAD"), cancellable = true) - private void onKey(long window, int key, int scancode, int i, int modifiers, CallbackInfo ci) { - if (window != this.client.getWindow().getHandle()) { - return; - } - String keyName = KeyboardHelper.translateKeyToString(key); - if (keyName == null) { - keyName = "unknown"; - } - - boolean shouldCancel = switch (i) { - case 0 -> MinecraftScriptEvents.ON_KEY_RELEASE.run(keyName); - case 1 -> MinecraftScriptEvents.ON_KEY_PRESS.run(keyName); - default -> false; - }; - if (shouldCancel) { - ci.cancel(); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/LivingEntityMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/LivingEntityMixin.java deleted file mode 100644 index 3af80936..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/LivingEntityMixin.java +++ /dev/null @@ -1,19 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptFakeEntity; -import net.minecraft.entity.LivingEntity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(LivingEntity.class) -public abstract class LivingEntityMixin { - @Shadow - protected abstract float turnHead(float bodyRotation, float headRotation); - - @Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;turnHead(FF)F")) - private float onTurnHead(LivingEntity instance, float bodyRotation, float headRotation) { - return ScriptFakeEntity.isFakeEntity(instance.getId()) ? 0 : this.turnHead(bodyRotation, headRotation); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/MerchantScreenMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/MerchantScreenMixin.java deleted file mode 100644 index e297296a..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/MerchantScreenMixin.java +++ /dev/null @@ -1,20 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import me.senseiwells.essentialclient.clientscript.events.MinecraftScriptEvents; -import net.minecraft.client.gui.screen.ingame.MerchantScreen; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(MerchantScreen.class) -public class MerchantScreenMixin { - @Shadow - private int selectedIndex; - - @Inject(method = "method_19896", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/MerchantScreen;syncRecipeIndex()V")) - private void onButtonPress(CallbackInfo ci) { - MinecraftScriptEvents.ON_CLICK_TRADE.run(this.selectedIndex); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/MinecraftClientAccessor.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/MinecraftClientAccessor.java deleted file mode 100644 index 1562dc30..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/MinecraftClientAccessor.java +++ /dev/null @@ -1,13 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import net.minecraft.client.MinecraftClient; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(MinecraftClient.class) -public interface MinecraftClientAccessor { - @Accessor("currentFps") - static int getFps() { - throw new AssertionError(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/MinecraftClientMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/MinecraftClientMixin.java deleted file mode 100644 index cb8af0b6..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/MinecraftClientMixin.java +++ /dev/null @@ -1,89 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import me.senseiwells.essentialclient.clientscript.events.MinecraftScriptEvents; -import me.senseiwells.essentialclient.utils.misc.Scheduler; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.DownloadingTerrainScreen; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.option.GameOptions; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.item.ItemStack; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -@Mixin(MinecraftClient.class) -public class MinecraftClientMixin { - @Shadow - public ClientPlayerEntity player; - - @Shadow - public Screen currentScreen; - - @Shadow - @Final - public GameOptions options; - - @Inject(method = "tick", at = @At("TAIL")) - private void onTick(CallbackInfo ci) { - MinecraftScriptEvents.ON_CLIENT_TICK.run(); - } - - @Inject(method = "doAttack", at = @At("HEAD"), cancellable = true) - private void onAttack(CallbackInfoReturnable cir) { - if (MinecraftScriptEvents.ON_ATTACK.run()) { - cir.setReturnValue(false); - } - } - - @Inject(method = "doItemUse", at = @At("HEAD"), cancellable = true) - private void onUse(CallbackInfo ci) { - if (MinecraftScriptEvents.ON_USE.run()) { - ci.cancel(); - } - } - - @Inject( - method = "doItemPick", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/entity/player/PlayerInventory;getSlotWithStack(Lnet/minecraft/item/ItemStack;)I" - ), - locals = LocalCapture.CAPTURE_FAILHARD, - cancellable = true - ) - private void onPickBlock(CallbackInfo ci, boolean bl, BlockEntity blockEntity, ItemStack itemStack12) { - if (MinecraftScriptEvents.ON_PICK_BLOCK.run(itemStack12)) { - ci.cancel(); - } - } - - @Inject(method = "joinWorld", at = @At("TAIL")) - private void onJoinWorld(ClientWorld world, DownloadingTerrainScreen.WorldEntryReason worldEntryReason, CallbackInfo ci) { - if (world != null) { - MinecraftScriptEvents.ON_DIMENSION_CHANGE.run(world); - } - } - - @Inject(method = "setScreen", at = @At("HEAD")) - private void onOpenScreen(Screen screen, CallbackInfo ci) { - if (screen != null) { - MinecraftScriptEvents.ON_OPEN_SCREEN.run(screen); - } else { - MinecraftScriptEvents.ON_CLOSE_SCREEN.run(this.currentScreen); - - Scheduler.schedule(0, () -> { - // Needed for attack("hold") - // Also needs to happen after this may have been set to true - this.options.attackKey.setPressed(false); - }); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/MouseMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/MouseMixin.java deleted file mode 100644 index 181d0272..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/MouseMixin.java +++ /dev/null @@ -1,40 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import com.llamalad7.mixinextras.sugar.Local; -import me.senseiwells.essentialclient.clientscript.events.MinecraftScriptEvents; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.Mouse; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -@Mixin(Mouse.class) -public class MouseMixin { - @Shadow - @Final - private MinecraftClient client; - - @Inject( - method = "onMouseScroll", - at = @At( - value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;getOverlay()Lnet/minecraft/client/gui/screen/Overlay;" - ), - cancellable = true - ) - private void mouseScroll( - long window, - double horizontal, - double vertical, - CallbackInfo ci, - @Local(ordinal = 4) double d, - @Local(ordinal = 3) double e - ) { - if (window == this.client.getWindow().getHandle() && MinecraftScriptEvents.ON_MOUSE_SCROLL.run(d, e)) { - ci.cancel(); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/NbtListMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/NbtListMixin.java deleted file mode 100644 index ef2dc671..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/NbtListMixin.java +++ /dev/null @@ -1,16 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import net.minecraft.nbt.NbtElement; -import net.minecraft.nbt.NbtList; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -import java.util.List; - -@Mixin(NbtList.class) -public interface NbtListMixin { - @Invoker("") - static NbtList createNbtList(List list, byte type) { - throw new AssertionError(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ScreenMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ScreenMixin.java deleted file mode 100644 index 48f7af0d..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/ScreenMixin.java +++ /dev/null @@ -1,20 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import me.senseiwells.essentialclient.utils.clientscript.FunctionClickEvent; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.text.Style; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(Screen.class) -public class ScreenMixin { - @Inject(method = "handleTextClick", at = @At("HEAD"), cancellable = true) - private void onTextClick(Style style, CallbackInfoReturnable cir) { - if (style != null && style.getClickEvent() instanceof FunctionClickEvent functionEvent) { - functionEvent.executeFunction(); - cir.setReturnValue(true); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/StonecutterScreenHandlerMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/StonecutterScreenHandlerMixin.java deleted file mode 100644 index de8bc008..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/StonecutterScreenHandlerMixin.java +++ /dev/null @@ -1,32 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import me.senseiwells.essentialclient.clientscript.events.MinecraftScriptEvents; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.recipe.StonecuttingRecipe; -import net.minecraft.screen.Property; -import net.minecraft.screen.StonecutterScreenHandler; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.List; - -@Mixin(StonecutterScreenHandler.class) -public abstract class StonecutterScreenHandlerMixin { - @Shadow - @Final - private Property selectedRecipe; - @Shadow - private List availableRecipes; - - @Inject(method = "onButtonClick", at = @At(value = "INVOKE", target = "Lnet/minecraft/screen/StonecutterScreenHandler;populateResult()V")) - private void onButtonClick(PlayerEntity player, int id, CallbackInfoReturnable cir) { - int i = this.selectedRecipe.get(); - if (i >= 0 && i < this.availableRecipes.size()) { - MinecraftScriptEvents.ON_CLICK_STONECUTTER_RECIPE.run(this.availableRecipes.get(i)); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/WorldRendererMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/WorldRendererMixin.java deleted file mode 100644 index 3913b7e0..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/clientScript/WorldRendererMixin.java +++ /dev/null @@ -1,24 +0,0 @@ -package me.senseiwells.essentialclient.mixins.clientScript; - -import com.llamalad7.mixinextras.sugar.Local; -import me.senseiwells.essentialclient.utils.render.RenderHelper; -import net.minecraft.client.render.*; -import net.minecraft.client.util.math.MatrixStack; -import org.joml.Matrix4f; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(WorldRenderer.class) -public class WorldRendererMixin { - @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/BackgroundRenderer;clearFog()V", shift = At.Shift.BEFORE)) - private void postRender( - RenderTickCounter tickCounter, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, Matrix4f matrix4f2, CallbackInfo ci, @Local MatrixStack matrices - ) { - RenderHelper.renderAllShapes(matrices); - // Rendering blocks needs to come after rendering - // shapes because it clears the depth buffer - RenderHelper.renderBlocks(matrices); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/commandSuggestorIgnoresSpaces/ChatInputSuggestorMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/commandSuggestorIgnoresSpaces/ChatInputSuggestorMixin.java deleted file mode 100644 index a36e5354..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/commandSuggestorIgnoresSpaces/ChatInputSuggestorMixin.java +++ /dev/null @@ -1,28 +0,0 @@ -package me.senseiwells.essentialclient.mixins.commandSuggestorIgnoresSpaces; - -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.gui.screen.ChatInputSuggestor; -import net.minecraft.client.gui.widget.TextFieldWidget; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(ChatInputSuggestor.class) -public abstract class ChatInputSuggestorMixin { - @Redirect(method = "refresh", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/TextFieldWidget;getCursor()I")) - private int onGetCursor(TextFieldWidget textFieldWidget) { - int current = textFieldWidget.getCursor(); - boolean hasSpace = false; - String message = textFieldWidget.getText(); - if (current == 0 || !message.startsWith("/") || !ClientRules.COMMAND_SUGGESTER_IGNORES_SPACES.getValue()) { - return current; - } - current--; - while (message.charAt(current) == ' ') { - hasSpace = true; - current--; - } - current += hasSpace ? 2 : 1; - return current; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/core/ClientPlayNetworkHandlerMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/core/ClientPlayNetworkHandlerMixin.java deleted file mode 100644 index 0735d259..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/core/ClientPlayNetworkHandlerMixin.java +++ /dev/null @@ -1,109 +0,0 @@ -package me.senseiwells.essentialclient.mixins.core; - -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.StringReader; -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.clientscript.core.ClientScript; -import me.senseiwells.essentialclient.clientscript.events.MinecraftScriptEvents; -import me.senseiwells.essentialclient.commands.CommandRegister; -import me.senseiwells.essentialclient.feature.CarpetClient; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.command.CommandHelper; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientCommonNetworkHandler; -import net.minecraft.client.network.ClientConnectionState; -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.command.CommandRegistryAccess; -import net.minecraft.command.CommandSource; -import net.minecraft.network.ClientConnection; -import net.minecraft.network.packet.s2c.play.CommandTreeS2CPacket; -import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket; -import net.minecraft.registry.DynamicRegistryManager; -import net.minecraft.resource.featuretoggle.FeatureSet; -import net.minecraft.server.command.ServerCommandSource; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(value = ClientPlayNetworkHandler.class, priority = 900) -public abstract class ClientPlayNetworkHandlerMixin extends ClientCommonNetworkHandler { - @Shadow - private CommandDispatcher commandDispatcher; - - @Final - @Shadow - private DynamicRegistryManager.Immutable combinedDynamicRegistries; - - @Final - @Shadow - private FeatureSet enabledFeatures; - - protected ClientPlayNetworkHandlerMixin(MinecraftClient client, ClientConnection connection, ClientConnectionState connectionState) { - super(client, connection, connectionState); - } - - @Shadow - public abstract boolean sendCommand(String command); - - @SuppressWarnings("unchecked") - @Inject(method = "onCommandTree", at = @At("TAIL")) - public void onOnCommandTree(CommandTreeS2CPacket packet, CallbackInfo ci) { - CommandRegistryAccess access = CommandRegistryAccess.of(this.combinedDynamicRegistries, this.enabledFeatures); - CommandHelper.setCommandPacket(packet, access); - CommandRegister.registerCommands((CommandDispatcher) (Object) this.commandDispatcher, access); - } - - @Inject(method = "onGameJoin", at = @At("TAIL")) - private void onGameJoin(GameJoinS2CPacket packet, CallbackInfo ci) { - if (ClientRules.START_SELECTED_SCRIPTS_ON_JOIN.getValue()) { - ClientScript.INSTANCE.startAllInstances(); - } - MinecraftScriptEvents.ON_CONNECT.run(EssentialUtils.getPlayer(), EssentialUtils.getWorld()); - if (this.client.getServer() != null && !EssentialUtils.isModInstalled("essentialaddons")) { - EssentialClient.GAME_RULE_NET_HANDLER.onHelloSinglePlayer(); - EssentialClient.GAME_RULE_NET_HANDLER.processGamerules(this.client.getServer().getGameRules().toNbt()); - } - } - - @Inject(method = "sendChatCommand", at = @At("HEAD"), cancellable = true) - private void onCommand(String command, CallbackInfo ci) { - if (this.onCommand(command)) { - ci.cancel(); - } - } - - @Inject(method = "sendCommand", at = @At("HEAD"), cancellable = true) - private void onCommand(String command, CallbackInfoReturnable cir) { - if (this.onCommand(command)) { - cir.setReturnValue(true); - } - } - - @Unique - private boolean onCommand(String command) { - StringReader reader = new StringReader(command); - int cursor = reader.getCursor(); - String commandName = reader.canRead() ? reader.readUnquotedString() : ""; - if (CarpetClient.INSTANCE.isCarpetManager(commandName) && ClientRules.CARPET_ALWAYS_SET_DEFAULT.getValue()) { - reader.skip(); - if (reader.canRead()) { - String subCommand = reader.readUnquotedString(); - if (reader.canRead() && !"setDefault".equals(subCommand)) { - this.sendCommand("%s setDefault %s%s".formatted(commandName, subCommand, reader.getRemaining())); - } - } - } - reader.setCursor(cursor); - if (CommandHelper.isClientCommand(commandName)) { - CommandHelper.executeCommand(reader, command); - return true; - } - return false; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/core/GameMenuScreenMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/core/GameMenuScreenMixin.java deleted file mode 100644 index 37bbe906..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/core/GameMenuScreenMixin.java +++ /dev/null @@ -1,29 +0,0 @@ -package me.senseiwells.essentialclient.mixins.core; - -import me.senseiwells.essentialclient.gui.config.ConfigScreen; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.render.Texts; -import net.minecraft.client.gui.screen.GameMenuScreen; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.GridWidget; -import net.minecraft.client.gui.widget.Widget; -import net.minecraft.text.Text; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(GameMenuScreen.class) -public abstract class GameMenuScreenMixin extends Screen { - protected GameMenuScreenMixin(Text title) { - super(title); - } - - @Redirect(method = "initWidgets", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/GridWidget$Adder;add(Lnet/minecraft/client/gui/widget/Widget;I)Lnet/minecraft/client/gui/widget/Widget;")) - private Widget onInit(GridWidget.Adder instance, Widget widget, int occupiedColumns) { - if (this.client != null && ClientRules.ESSENTIAL_CLIENT_BUTTON.getValue()) { - instance.add(ButtonWidget.builder(Texts.CLIENT_MENU, (b) -> this.client.setScreen(new ConfigScreen(this))).width(204).build(), 2); - } - return instance.add(widget, occupiedColumns); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/core/KeyboardMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/core/KeyboardMixin.java deleted file mode 100644 index d22c0872..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/core/KeyboardMixin.java +++ /dev/null @@ -1,33 +0,0 @@ -package me.senseiwells.essentialclient.mixins.core; - -import me.senseiwells.essentialclient.feature.keybinds.ClientKeyBinds; -import net.minecraft.client.Keyboard; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.util.InputUtil; -import org.lwjgl.glfw.GLFW; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(Keyboard.class) -public class KeyboardMixin { - @Shadow - @Final - private MinecraftClient client; - - @Inject(method = "onKey", at = @At(value = "HEAD")) - private void onKey(long window, int key, int scancode, int action, int modifiers, CallbackInfo ci) { - if (this.client.getWindow().getHandle() == window) { - InputUtil.Key inputKey = InputUtil.fromKeyCode(key, scancode); - boolean isInGui = this.client.currentScreen != null; - if (action == GLFW.GLFW_RELEASE) { - ClientKeyBinds.onKeyRelease(inputKey, isInGui); - } else { - ClientKeyBinds.onKeyPress(inputKey, isInGui); - } - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/core/MinecraftClientMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/core/MinecraftClientMixin.java deleted file mode 100644 index c985f10e..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/core/MinecraftClientMixin.java +++ /dev/null @@ -1,50 +0,0 @@ -package me.senseiwells.essentialclient.mixins.core; - -import me.senseiwells.essentialclient.clientscript.core.ClientScript; -import me.senseiwells.essentialclient.clientscript.events.MinecraftScriptEvents; -import me.senseiwells.essentialclient.utils.interfaces.MinecraftClientInvoker; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.util.thread.ReentrantThreadExecutor; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(MinecraftClient.class) -public abstract class MinecraftClientMixin extends ReentrantThreadExecutor implements MinecraftClientInvoker { - @Shadow - public ClientPlayerEntity player; - - public MinecraftClientMixin(String string) { - super(string); - } - - @Shadow - private void doItemUse() { } - - @Shadow - protected abstract boolean doAttack(); - - @Inject(method = "disconnect(Lnet/minecraft/client/gui/screen/Screen;)V", at = @At("HEAD")) - private void onLeaveWorld(Screen screen, CallbackInfo ci) { - MinecraftScriptEvents.ON_DISCONNECT.run(); - } - - @Inject(method = "disconnect(Lnet/minecraft/client/gui/screen/Screen;)V", at = @At("RETURN")) - private void onDisconnect(Screen screen, CallbackInfo ci) { - ClientScript.INSTANCE.stopAllInstances(); - } - - @Override - public void essentialclient$rightClick() { - this.execute(this::doItemUse); - } - - @Override - public void essentialclient$leftClick() { - this.execute(this::doAttack); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/core/TitleScreenMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/core/TitleScreenMixin.java deleted file mode 100644 index d66c6724..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/core/TitleScreenMixin.java +++ /dev/null @@ -1,57 +0,0 @@ -package me.senseiwells.essentialclient.mixins.core; - -import me.senseiwells.essentialclient.gui.config.ConfigScreen; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.render.Texts; -import me.senseiwells.essentialclient.utils.render.WidgetHelper; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.TitleScreen; -import net.minecraft.text.Text; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.*; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(TitleScreen.class) -public abstract class TitleScreenMixin extends Screen { - protected TitleScreenMixin(Text title) { - super(title); - } - - @ModifyConstant(method = "init", constant = @Constant(intValue = 72)) - private int pushLimit(int original) { - if (ClientRules.ESSENTIAL_CLIENT_BUTTON.getValue()) { - return 86; - } - return original; - } - - @Inject(method = "initWidgetsNormal", at = @At("TAIL")) - private void onInit(CallbackInfo ci) { - if (this.client != null && ClientRules.ESSENTIAL_CLIENT_BUTTON.getValue()) { - this.addDrawableChild(WidgetHelper.newButton( - this.width / 2 - 100, - this.height / 4 + 120, - 200, 20, - Texts.CLIENT_MENU, - b -> this.client.setScreen(new ConfigScreen(this)) - )); - } - } - - @ModifyArg(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/PressableTextWidget;(IIIILnet/minecraft/text/Text;Lnet/minecraft/client/gui/widget/ButtonWidget$PressAction;Lnet/minecraft/client/font/TextRenderer;)V"), index = 1) - private int onPressableText(int y) { - return ClientRules.TITLE_TEXT_TO_TOP.getValue() ? 5 : y; - } - - @ModifyArg( - method = "render", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/gui/DrawContext;drawTextWithShadow(Lnet/minecraft/client/font/TextRenderer;Ljava/lang/String;III)I" - ), - index = 4 - ) - private int onDrawText(int y) { - return ClientRules.TITLE_TEXT_TO_TOP.getValue() ? 5 : y; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/craftingHax/ClientPlayerInteractionManagerMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/craftingHax/ClientPlayerInteractionManagerMixin.java deleted file mode 100644 index 04aceb9d..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/craftingHax/ClientPlayerInteractionManagerMixin.java +++ /dev/null @@ -1,33 +0,0 @@ -package me.senseiwells.essentialclient.mixins.craftingHax; - -import me.senseiwells.essentialclient.feature.CraftingSharedConstants; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.inventory.InventoryUtils; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.ingame.HandledScreen; -import net.minecraft.client.network.ClientPlayerInteractionManager; -import net.minecraft.recipe.RecipeEntry; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ClientPlayerInteractionManager.class) -public class ClientPlayerInteractionManagerMixin { - @Shadow - @Final - private MinecraftClient client; - - @Inject(method = "clickRecipe", at = @At("RETURN")) - public void onRecipeClick(int syncId, RecipeEntry recipe, boolean craftAll, CallbackInfo ci) { - if (ClientRules.CRAFTING_HAX.getValue() && CraftingSharedConstants.IS_VANILLA_CLICK.get()) { - if (Screen.hasControlDown() && this.client.currentScreen instanceof HandledScreen handledScreen) { - InventoryUtils.dropStackScheduled(handledScreen.getScreenHandler(), craftAll); - CraftingSharedConstants.IS_VANILLA_CLICK.set(false); - } - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/customClientCape/AbstractClientPlayerEntityMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/customClientCape/AbstractClientPlayerEntityMixin.java deleted file mode 100644 index f722bf85..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/customClientCape/AbstractClientPlayerEntityMixin.java +++ /dev/null @@ -1,32 +0,0 @@ -package me.senseiwells.essentialclient.mixins.customClientCape; - -import me.senseiwells.essentialclient.feature.CustomClientCape; -import net.minecraft.client.network.AbstractClientPlayerEntity; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.util.SkinTextures; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(AbstractClientPlayerEntity.class) -public class AbstractClientPlayerEntityMixin { - @SuppressWarnings("ConstantConditions") - @Inject(method = "getSkinTextures", at = @At("RETURN"), cancellable = true) - private void onGetCapeTexture(CallbackInfoReturnable cir) { - if ((Object) this instanceof ClientPlayerEntity) { - if (CustomClientCape.getCurrentCape() != null) { - SkinTextures old = cir.getReturnValue(); - cir.setReturnValue(new SkinTextures( - old.texture(), - old.textureUrl(), - CustomClientCape.getCurrentCape(), - CustomClientCape.getCurrentCape(), - old.model(), - old.secure() - )); - } - } - } - -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/daylightCycleSlowdownMultiplier/ClientPlayNetworkHandlerMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/daylightCycleSlowdownMultiplier/ClientPlayNetworkHandlerMixin.java deleted file mode 100644 index cc31f9ce..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/daylightCycleSlowdownMultiplier/ClientPlayNetworkHandlerMixin.java +++ /dev/null @@ -1,19 +0,0 @@ -package me.senseiwells.essentialclient.mixins.daylightCycleSlowdownMultiplier; - -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ClientPlayNetworkHandler.class) -public class ClientPlayNetworkHandlerMixin { - @Inject(method = "onWorldTimeUpdate", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;setTimeOfDay(J)V"), cancellable = true) - private void onTimeOfDayUpdate(WorldTimeUpdateS2CPacket packet, CallbackInfo ci) { - if (ClientRules.PERMANENT_TIME.getValue() >= 0) { - ci.cancel(); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/daylightCycleSlowdownMultiplier/ClientWorldMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/daylightCycleSlowdownMultiplier/ClientWorldMixin.java deleted file mode 100644 index 9babdefe..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/daylightCycleSlowdownMultiplier/ClientWorldMixin.java +++ /dev/null @@ -1,23 +0,0 @@ -package me.senseiwells.essentialclient.mixins.daylightCycleSlowdownMultiplier; - -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.world.ClientWorld; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ClientWorld.class) -public abstract class ClientWorldMixin { - @Shadow - public abstract void setTimeOfDay(long timeOfDay); - - @Inject(method = "tickTime", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;setTimeOfDay(J)V"), cancellable = true) - private void onSetTimeOfDay(CallbackInfo ci) { - if (ClientRules.PERMANENT_TIME.getValue() >= 0) { - this.setTimeOfDay(ClientRules.PERMANENT_TIME.getValue()); - ci.cancel(); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/disableArmourRendering/ArmorFeatureRendererMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/disableArmourRendering/ArmorFeatureRendererMixin.java deleted file mode 100644 index 0e5f3cc3..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/disableArmourRendering/ArmorFeatureRendererMixin.java +++ /dev/null @@ -1,35 +0,0 @@ -package me.senseiwells.essentialclient.mixins.disableArmourRendering; - -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.feature.ArmorFeatureRenderer; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.player.PlayerEntity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ArmorFeatureRenderer.class) -public class ArmorFeatureRendererMixin { - @Inject(method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/entity/LivingEntity;FFFFFF)V", at = @At("HEAD"), cancellable = true) - private void onRender(MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, T livingEntity, float f, float g, float h, float j, float k, float l, CallbackInfo ci) { - switch (ClientRules.DISABLE_ARMOUR_RENDERING.getValue()) { - case "You" -> { - if (livingEntity instanceof ClientPlayerEntity) { - ci.cancel(); - } - } - case "Players" -> { - if (livingEntity instanceof PlayerEntity) { - ci.cancel(); - } - } - case "Entities" -> { - ci.cancel(); - } - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/disableBobViewWhenHurt/GameRendererMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/disableBobViewWhenHurt/GameRendererMixin.java deleted file mode 100644 index 3180cba9..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/disableBobViewWhenHurt/GameRendererMixin.java +++ /dev/null @@ -1,23 +0,0 @@ -package me.senseiwells.essentialclient.mixins.disableBobViewWhenHurt; - -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.render.GameRenderer; -import net.minecraft.client.util.math.MatrixStack; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(GameRenderer.class) -public class GameRendererMixin { - @Inject( - method = "bobView", - at = @At("HEAD"), - cancellable = true - ) - private void bobViewWhenHurt(MatrixStack matrices, float f, CallbackInfo ci) { - if (ClientRules.DISABLE_BOB_VIEW_WHEN_HURT.getValue()) { - ci.cancel(); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/disableBossBar/BossBarHudMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/disableBossBar/BossBarHudMixin.java deleted file mode 100644 index ae3b4f74..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/disableBossBar/BossBarHudMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package me.senseiwells.essentialclient.mixins.disableBossBar; - -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.hud.BossBarHud; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(BossBarHud.class) -public class BossBarHudMixin { - @Inject(method = "render", at = @At("HEAD"), cancellable = true) - private void onRender( - DrawContext context, - CallbackInfo ci - ) { - if (ClientRules.DISABLE_BOSS_BAR.getValue()) { - ci.cancel(); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/disableHotbarScrolling/MouseMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/disableHotbarScrolling/MouseMixin.java deleted file mode 100644 index 42f6d138..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/disableHotbarScrolling/MouseMixin.java +++ /dev/null @@ -1,16 +0,0 @@ -package me.senseiwells.essentialclient.mixins.disableHotbarScrolling; - -import com.llamalad7.mixinextras.injector.WrapWithCondition; -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.Mouse; -import net.minecraft.entity.player.PlayerInventory; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(Mouse.class) -public class MouseMixin { - @WrapWithCondition(method = "onMouseScroll", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerInventory;scrollInHotbar(D)V")) - private boolean onScrollHotbar(PlayerInventory playerInventory, double scrollAmount) { - return !ClientRules.DISABLE_HOTBAR_SCROLLING.getValue(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/disableMapRendering/ItemFrameEntityRendererMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/disableMapRendering/ItemFrameEntityRendererMixin.java deleted file mode 100644 index 859a3a89..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/disableMapRendering/ItemFrameEntityRendererMixin.java +++ /dev/null @@ -1,28 +0,0 @@ -package me.senseiwells.essentialclient.mixins.disableMapRendering; - -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.ItemFrameEntityRenderer; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.decoration.ItemFrameEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ItemFrameEntityRenderer.class) -public class ItemFrameEntityRendererMixin { - @Inject( - method = "render(Lnet/minecraft/entity/decoration/ItemFrameEntity;FFLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", - at = @At("HEAD"), - cancellable = true - ) - private void onRender(ItemFrameEntity itemFrameEntity, float f, float g, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, CallbackInfo ci) { - ItemStack itemStack = itemFrameEntity.getHeldItemStack(); - if (itemStack.getItem() == Items.FILLED_MAP && ClientRules.DISABLE_MAP_RENDERING.getValue()) { - ci.cancel(); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/disableMessages/MessageHandlerMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/disableMessages/MessageHandlerMixin.java deleted file mode 100644 index 09d2bdb1..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/disableMessages/MessageHandlerMixin.java +++ /dev/null @@ -1,29 +0,0 @@ -package me.senseiwells.essentialclient.mixins.disableMessages; - -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.render.Texts; -import net.minecraft.client.network.message.MessageHandler; -import net.minecraft.text.Text; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(MessageHandler.class) -public class MessageHandlerMixin { - @Inject(method = "onGameMessage", at = @At("HEAD"), cancellable = true) - private void onChatMessage(Text message, boolean overlay, CallbackInfo ci) { - if (!overlay && ClientRules.DISABLE_OP_MESSAGES.getValue()) { - ci.cancel(); - return; - } - String key = Texts.getTranslatableKey(message); - if (key != null && ClientRules.DISABLE_JOIN_LEAVE_MESSAGES.getValue()) { - switch (key) { - case "multiplayer.player.joined", "multiplayer.player.left", "multiplayer.player.joined.renamed" -> { - ci.cancel(); - } - } - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/disableNameTags/EntityRendererMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/disableNameTags/EntityRendererMixin.java deleted file mode 100644 index b3ba12bd..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/disableNameTags/EntityRendererMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -package me.senseiwells.essentialclient.mixins.disableNameTags; - -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.Entity; -import net.minecraft.text.Text; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(EntityRenderer.class) -public class EntityRendererMixin { - @Inject(method = "renderLabelIfPresent", at = @At("HEAD"), cancellable = true) - private void onRender( - Entity entity, - Text text, - MatrixStack matrices, - VertexConsumerProvider vertexConsumers, - int light, - float tickDelta, - CallbackInfo ci - ) { - if (ClientRules.DISABLE_NAME_TAGS.getValue()) { - ci.cancel(); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/disableNarrator/KeyboardMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/disableNarrator/KeyboardMixin.java deleted file mode 100644 index 5cd3d1fa..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/disableNarrator/KeyboardMixin.java +++ /dev/null @@ -1,15 +0,0 @@ -package me.senseiwells.essentialclient.mixins.disableNarrator; - -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.Keyboard; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.Constant; -import org.spongepowered.asm.mixin.injection.ModifyConstant; - -@Mixin(value = Keyboard.class, priority = 1100) -public class KeyboardMixin { - @ModifyConstant(method = "onKey", constant = @Constant(intValue = 66), require = 0) - private int disableNarrator(int old) { - return ClientRules.DISABLE_NARRATOR.getValue() ? -2 : old; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/disableNightVisionFlash/GameRendererMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/disableNightVisionFlash/GameRendererMixin.java deleted file mode 100644 index 773f607e..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/disableNightVisionFlash/GameRendererMixin.java +++ /dev/null @@ -1,23 +0,0 @@ -package me.senseiwells.essentialclient.mixins.disableNightVisionFlash; - -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.render.GameRenderer; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.effect.StatusEffects; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.Objects; - -@Mixin(GameRenderer.class) -public class GameRendererMixin { - @Inject(method = "getNightVisionStrength", at = @At("RETURN"), cancellable = true) - private static void removeFlash(LivingEntity livingEntity, float f, CallbackInfoReturnable cir) { - float i = Objects.requireNonNull(livingEntity.getStatusEffect(StatusEffects.NIGHT_VISION)).getDuration(); - if (ClientRules.DISABLE_NIGHT_VISION_FLASH.getValue()) { - cir.setReturnValue(i > 0 ? 1 : i); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/disableRecipeNotifications/RecipeToastMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/disableRecipeNotifications/RecipeToastMixin.java deleted file mode 100644 index 019272a5..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/disableRecipeNotifications/RecipeToastMixin.java +++ /dev/null @@ -1,19 +0,0 @@ -package me.senseiwells.essentialclient.mixins.disableRecipeNotifications; - -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.toast.RecipeToast; -import net.minecraft.client.toast.Toast; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(RecipeToast.class) -public abstract class RecipeToastMixin { - @Inject(at = @At("HEAD"), method = "draw", cancellable = true) - private void hideToast(CallbackInfoReturnable cir) { - if (ClientRules.DISABLE_RECIPE_NOTIFICATIONS.getValue()) { - cir.setReturnValue(Toast.Visibility.HIDE); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/disableScreenshotMessage/ScreenshotRecorderMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/disableScreenshotMessage/ScreenshotRecorderMixin.java deleted file mode 100644 index 6e7bb2e6..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/disableScreenshotMessage/ScreenshotRecorderMixin.java +++ /dev/null @@ -1,17 +0,0 @@ -package me.senseiwells.essentialclient.mixins.disableScreenshotMessage; - -import com.llamalad7.mixinextras.injector.WrapWithCondition; -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.util.ScreenshotRecorder; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -import java.util.function.Consumer; - -@Mixin(ScreenshotRecorder.class) -public class ScreenshotRecorderMixin { - @WrapWithCondition(method = "method_1661", at = @At(value = "INVOKE", target = "Ljava/util/function/Consumer;accept(Ljava/lang/Object;)V", remap = false)) - private static boolean onConsumeText(Consumer textConsumer, Object text) { - return !ClientRules.DISABLE_SCREENSHOT_MESSAGE.getValue(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/disableTutorialNotifications/TutorialToastMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/disableTutorialNotifications/TutorialToastMixin.java deleted file mode 100644 index 7fac337a..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/disableTutorialNotifications/TutorialToastMixin.java +++ /dev/null @@ -1,19 +0,0 @@ -package me.senseiwells.essentialclient.mixins.disableTutorialNotifications; - -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.toast.Toast; -import net.minecraft.client.toast.TutorialToast; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(TutorialToast.class) -public abstract class TutorialToastMixin { - @Inject(at = @At("HEAD"), method = "draw", cancellable = true) - private void hideToast(CallbackInfoReturnable cir) { - if (ClientRules.DISABLE_TUTORIAL_NOTIFICATIONS.getValue()) { - cir.setReturnValue(Toast.Visibility.HIDE); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/displayTimePlayed/GameMenuScreenMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/displayTimePlayed/GameMenuScreenMixin.java deleted file mode 100644 index f869df0d..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/displayTimePlayed/GameMenuScreenMixin.java +++ /dev/null @@ -1,40 +0,0 @@ -package me.senseiwells.essentialclient.mixins.displayTimePlayed; - -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.GameMenuScreen; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.text.Text; -import org.apache.commons.lang3.time.DurationFormatUtils; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.time.Duration; -import java.time.LocalDateTime; - -@Mixin(GameMenuScreen.class) -public class GameMenuScreenMixin extends Screen { - protected GameMenuScreenMixin(Text title) { - super(title); - } - - @Inject(method = "render", at = @At("TAIL")) - public void render( - DrawContext context, - int mouseX, - int mouseY, - float delta, - CallbackInfo callbackInfo - ) { - LocalDateTime currentTime = LocalDateTime.now(); - Duration duration = Duration.between(EssentialClient.START_TIME, currentTime); - - String draw = DurationFormatUtils.formatDuration(duration.toMillis(), "H:mm:ss", true); - if (ClientRules.DISPLAY_TIME_PLAYED.getValue()) { - context.drawTextWithShadow(this.textRenderer, draw, 8, 8, 16777215); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/gameRuleSync/GameRuleAccessor.java b/src/main/java/me/senseiwells/essentialclient/mixins/gameRuleSync/GameRuleAccessor.java deleted file mode 100644 index 68ac0708..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/gameRuleSync/GameRuleAccessor.java +++ /dev/null @@ -1,15 +0,0 @@ -package me.senseiwells.essentialclient.mixins.gameRuleSync; - -import net.minecraft.world.GameRules; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import java.util.Map; - -@Mixin(GameRules.class) -public interface GameRuleAccessor { - @Accessor("RULE_TYPES") - static Map, GameRules.Type> getRules() { - throw new AssertionError(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/gameRuleSync/RuleInvoker.java b/src/main/java/me/senseiwells/essentialclient/mixins/gameRuleSync/RuleInvoker.java deleted file mode 100644 index 9767a912..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/gameRuleSync/RuleInvoker.java +++ /dev/null @@ -1,11 +0,0 @@ -package me.senseiwells.essentialclient.mixins.gameRuleSync; - -import net.minecraft.world.GameRules; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -@Mixin(GameRules.Rule.class) -public interface RuleInvoker { - @Invoker("deserialize") - void deserialize(String value); -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/gameRuleSync/RuleMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/gameRuleSync/RuleMixin.java deleted file mode 100644 index faf691c0..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/gameRuleSync/RuleMixin.java +++ /dev/null @@ -1,35 +0,0 @@ -package me.senseiwells.essentialclient.mixins.gameRuleSync; - -import me.senseiwells.essentialclient.utils.interfaces.IGameRule; -import me.senseiwells.essentialclient.utils.render.Texts; -import net.minecraft.server.MinecraftServer; -import net.minecraft.text.Text; -import net.minecraft.world.GameRules; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -@Mixin(GameRules.Rule.class) -public abstract class RuleMixin> implements IGameRule { - @Shadow - @Final - protected GameRules.Type type; - - @Shadow - public abstract String serialize(); - - @Shadow - protected abstract void changed(@Nullable MinecraftServer server); - - /** - * We can't @Invoke this method because it - * leads to some weird recursion, idk. - */ - @Override - public void essentialclient$ruleChanged(String ruleName, MinecraftServer server) { - Text text = Texts.SET_GAME_RULE.generate(ruleName, this.serialize()); - server.getPlayerManager().broadcast(text, false); - this.changed(server); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/keyboard/KeyboardMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/keyboard/KeyboardMixin.java deleted file mode 100644 index 8f91f211..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/keyboard/KeyboardMixin.java +++ /dev/null @@ -1,15 +0,0 @@ -package me.senseiwells.essentialclient.mixins.keyboard; - -import me.senseiwells.essentialclient.feature.keybinds.ClientKeyBinds; -import net.minecraft.client.Keyboard; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.Constant; -import org.spongepowered.asm.mixin.injection.ModifyConstant; - -@Mixin(value = Keyboard.class, priority = 1100) -public class KeyboardMixin { - @ModifyConstant(method = "onKey", constant = @Constant(intValue = 292), require = 0) - private int onKey292(int original) { - return ClientKeyBinds.TOGGLE_DEBUG_MENU.getBoundKey().getCode(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/longChatMessages/ChatScreenMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/longChatMessages/ChatScreenMixin.java deleted file mode 100644 index c394f258..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/longChatMessages/ChatScreenMixin.java +++ /dev/null @@ -1,15 +0,0 @@ -package me.senseiwells.essentialclient.mixins.longChatMessages; - -import me.senseiwells.essentialclient.utils.EssentialUtils; -import net.minecraft.client.gui.screen.ChatScreen; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.Constant; -import org.spongepowered.asm.mixin.injection.ModifyConstant; - -@Mixin(ChatScreen.class) -public class ChatScreenMixin { - @ModifyConstant(method = "init", constant = @Constant(intValue = 256)) - private int getMaxLength(int constant) { - return EssentialUtils.getMaxChatLength(constant); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/longChatMessages/GenericChatMessageC2SPacketMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/longChatMessages/GenericChatMessageC2SPacketMixin.java deleted file mode 100644 index 68f720ee..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/longChatMessages/GenericChatMessageC2SPacketMixin.java +++ /dev/null @@ -1,16 +0,0 @@ -package me.senseiwells.essentialclient.mixins.longChatMessages; - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket; -import net.minecraft.network.packet.c2s.play.CommandExecutionC2SPacket; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(ChatMessageC2SPacket.class) -public class GenericChatMessageC2SPacketMixin { - @ModifyExpressionValue(method = "write", at = @At(value = "CONSTANT", args = "intValue=256")) - private int getMaxLength(int constant) { - return EssentialUtils.getMaxChatLength(constant); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/longChatMessages/StringHelperMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/longChatMessages/StringHelperMixin.java deleted file mode 100644 index c97072ca..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/longChatMessages/StringHelperMixin.java +++ /dev/null @@ -1,15 +0,0 @@ -package me.senseiwells.essentialclient.mixins.longChatMessages; - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import net.minecraft.util.StringHelper; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(StringHelper.class) -public class StringHelperMixin { - @ModifyExpressionValue(method = "truncateChat", at = @At(value = "CONSTANT", args = "intValue=256")) - private static int getMaxLength(int original) { - return EssentialUtils.getMaxChatLength(original); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/mouseScrollRules/MouseMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/mouseScrollRules/MouseMixin.java deleted file mode 100644 index 0fddc214..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/mouseScrollRules/MouseMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package me.senseiwells.essentialclient.mixins.mouseScrollRules; - -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.Mouse; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.Constant; -import org.spongepowered.asm.mixin.injection.ModifyConstant; - -@Mixin(Mouse.class) -public class MouseMixin { - @ModifyConstant(method = "onMouseScroll", constant = @Constant(floatValue = 0.2F)) - private float newScrollLimit(float originalFloat) { - return ClientRules.INCREASE_SPECTATOR_SCROLL_SPEED.getValue() ? 10.0F : originalFloat; - } - - @ModifyConstant(method = "onMouseScroll", constant = @Constant(floatValue = 0.005F)) - private float newSensitivityLimit(float originalFloat) { - int newSensitivity = ClientRules.INCREASE_SPECTATOR_SCROLL_SENSITIVITY.getValue(); - return newSensitivity > 0 ? originalFloat * newSensitivity : originalFloat; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/openScreenshotDirectory/ScreenshotRecorderMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/openScreenshotDirectory/ScreenshotRecorderMixin.java deleted file mode 100644 index c2e13619..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/openScreenshotDirectory/ScreenshotRecorderMixin.java +++ /dev/null @@ -1,17 +0,0 @@ -package me.senseiwells.essentialclient.mixins.openScreenshotDirectory; - -import com.llamalad7.mixinextras.injector.ModifyReceiver; -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.util.ScreenshotRecorder; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -import java.io.File; - -@Mixin(ScreenshotRecorder.class) -public class ScreenshotRecorderMixin { - @ModifyReceiver(method = "method_1664", at = @At(value = "INVOKE", target = "Ljava/io/File;getAbsolutePath()Ljava/lang/String;", remap = false)) - private static File onFileGetPath(File instance) { - return ClientRules.OPEN_SCREENSHOT_DIRECTORY.getValue() ? instance.getParentFile() : instance; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/overrideCreativeWalkSpeed/LivingEntityMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/overrideCreativeWalkSpeed/LivingEntityMixin.java deleted file mode 100644 index 621091c5..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/overrideCreativeWalkSpeed/LivingEntityMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package me.senseiwells.essentialclient.mixins.overrideCreativeWalkSpeed; - -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.player.PlayerEntity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(LivingEntity.class) -public class LivingEntityMixin { - @Shadow - private float movementSpeed; - - @SuppressWarnings("ConstantConditions") - @Inject(method = "getMovementSpeed(F)F", at = @At("HEAD"), cancellable = true) - private void overrideMovementSpeed(float slipperiness, CallbackInfoReturnable cir) { - float speed = ClientRules.OVERRIDE_CREATIVE_WALK_SPEED.getValue().floatValue(); - if (speed > 0 && (Object) this instanceof PlayerEntity playerEntity && playerEntity.isCreative()) { - cir.setReturnValue(this.movementSpeed * speed); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/permanentChatHud/ChatHudMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/permanentChatHud/ChatHudMixin.java deleted file mode 100644 index b9bb2738..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/permanentChatHud/ChatHudMixin.java +++ /dev/null @@ -1,18 +0,0 @@ -package me.senseiwells.essentialclient.mixins.permanentChatHud; - -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.gui.hud.ChatHud; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ChatHud.class) -public class ChatHudMixin { - @Inject(method = "clear", at = @At("HEAD"), cancellable = true) - private void onClear(boolean clearHistory, CallbackInfo ci) { - if (ClientRules.PERMANENT_CHAT_HUD.getValue()) { - ci.cancel(); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/quickLockRecipe/AnimatedResultButtonMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/quickLockRecipe/AnimatedResultButtonMixin.java deleted file mode 100644 index eae93a76..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/quickLockRecipe/AnimatedResultButtonMixin.java +++ /dev/null @@ -1,18 +0,0 @@ -package me.senseiwells.essentialclient.mixins.quickLockRecipe; - -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.gui.screen.recipebook.AnimatedResultButton; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(AnimatedResultButton.class) -public class AnimatedResultButtonMixin { - @Inject(method = "isValidClickButton", at = @At("RETURN"), cancellable = true) - private void isValid(int button, CallbackInfoReturnable cir) { - if (ClientRules.QUICK_LOCK_RECIPE.getValue()) { - cir.setReturnValue(cir.getReturnValue() || button == 2); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/quickLockRecipe/RecipeBookResultsMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/quickLockRecipe/RecipeBookResultsMixin.java deleted file mode 100644 index 7a993739..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/quickLockRecipe/RecipeBookResultsMixin.java +++ /dev/null @@ -1,37 +0,0 @@ -package me.senseiwells.essentialclient.mixins.quickLockRecipe; - -import net.minecraft.client.gui.screen.recipebook.AnimatedResultButton; -import net.minecraft.client.gui.screen.recipebook.RecipeBookResults; -import net.minecraft.client.gui.screen.recipebook.RecipeResultCollection; -import net.minecraft.recipe.RecipeEntry; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.List; - -@Mixin(RecipeBookResults.class) -public class RecipeBookResultsMixin { - @Shadow - @Final - private List resultButtons; - @Shadow - private RecipeEntry lastClickedRecipe; - @Shadow - private RecipeResultCollection resultCollection; - - @Inject(method = "mouseClicked", at = @At(value = "INVOKE", target = "Ljava/util/List;iterator()Ljava/util/Iterator;", shift = At.Shift.BEFORE), cancellable = true) - private void checkMiddleMouse(double mouseX, double mouseY, int button, int areaLeft, int areaTop, int areaWidth, int areaHeight, CallbackInfoReturnable cir) { - for (AnimatedResultButton resultButton : this.resultButtons) { - if (resultButton.mouseClicked(mouseX, mouseY, button) && button == 2) { - this.lastClickedRecipe = resultButton.currentRecipe(); - this.resultCollection = resultButton.getResultCollection(); - cir.setReturnValue(true); - break; - } - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/quickLockRecipe/RecipeBookWidgetMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/quickLockRecipe/RecipeBookWidgetMixin.java deleted file mode 100644 index ad76d52c..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/quickLockRecipe/RecipeBookWidgetMixin.java +++ /dev/null @@ -1,55 +0,0 @@ -package me.senseiwells.essentialclient.mixins.quickLockRecipe; - -import me.senseiwells.essentialclient.utils.EssentialUtils; -import net.minecraft.client.gui.screen.recipebook.RecipeBookResults; -import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.client.resource.language.I18n; -import net.minecraft.recipe.RecipeEntry; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(RecipeBookWidget.class) -public abstract class RecipeBookWidgetMixin { - @Shadow - @Final - private RecipeBookResults recipesArea; - @Shadow - private TextFieldWidget searchField; - - @Shadow - protected abstract void refreshResults(boolean resetCurrentPage); - - @Inject( - method = "mouseClicked", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/gui/screen/recipebook/RecipeBookResults;getLastClickedRecipe()Lnet/minecraft/recipe/RecipeEntry;" - ), - cancellable = true - ) - private void isMiddleClick(double mouseX, double mouseY, int button, CallbackInfoReturnable cir) { - RecipeEntry recipe = this.recipesArea.getLastClickedRecipe(); - if (button == 2 && recipe != null) { - String itemName = recipe.value().getResult(EssentialUtils.getRegistryManager()).getItem().getTranslationKey(); - if (I18n.hasTranslation(itemName)) { - this.searchField.setText(I18n.translate(itemName)); - this.refreshResults(true); - } - cir.setReturnValue(true); - } - } - - @Inject(method = "mouseClicked", at = @At(value = "INVOKE", target = "Ljava/util/List;iterator()Ljava/util/Iterator;"), cancellable = true) - private void isMiddleClickNothing(double mouseX, double mouseY, int button, CallbackInfoReturnable cir) { - if (button == 2) { - this.searchField.setText(""); - this.refreshResults(true); - cir.setReturnValue(true); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/removeWarnReceivedPassengers/ClientPlayNetworkHandlerMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/removeWarnReceivedPassengers/ClientPlayNetworkHandlerMixin.java deleted file mode 100644 index 6fb5ec06..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/removeWarnReceivedPassengers/ClientPlayNetworkHandlerMixin.java +++ /dev/null @@ -1,18 +0,0 @@ -package me.senseiwells.essentialclient.mixins.removeWarnReceivedPassengers; - -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.network.ClientPlayNetworkHandler; -import org.slf4j.Logger; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(ClientPlayNetworkHandler.class) -public class ClientPlayNetworkHandlerMixin { - @Redirect(method = "onEntityPassengersSet", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;)V", remap = false)) - private void onWarn(Logger instance, String s) { - if (!ClientRules.REMOVE_WARN_RECEIVED_PASSENGERS.getValue()) { - instance.warn(s); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/soulBlocksEffectOnFov/AbstractClientPlayerEntityMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/soulBlocksEffectOnFov/AbstractClientPlayerEntityMixin.java deleted file mode 100644 index cf843d02..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/soulBlocksEffectOnFov/AbstractClientPlayerEntityMixin.java +++ /dev/null @@ -1,74 +0,0 @@ -package me.senseiwells.essentialclient.mixins.soulBlocksEffectOnFov; - -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.network.AbstractClientPlayerEntity; -import net.minecraft.enchantment.EnchantmentHelper; -import net.minecraft.enchantment.Enchantments; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.attribute.EntityAttributeInstance; -import net.minecraft.entity.attribute.EntityAttributeModifier; -import net.minecraft.entity.attribute.EntityAttributes; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.util.Identifier; -import net.minecraft.world.World; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.UUID; - -@Mixin(AbstractClientPlayerEntity.class) -public abstract class AbstractClientPlayerEntityMixin extends LivingEntity { - @Unique - private static final Identifier SOUL_SPEED_BOOST_ID = Identifier.ofVanilla("enchantment.soul_speed"); - - protected AbstractClientPlayerEntityMixin(EntityType entityType, World world) { - super(entityType, world); - } - - @Inject( - method = "getFovMultiplier", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/network/AbstractClientPlayerEntity;getAttributeValue(Lnet/minecraft/registry/entry/RegistryEntry;)D" - ) - ) - public void injectedBefore(CallbackInfoReturnable cir) { - EntityAttributeInstance genericSpeedAttribute = this.getAttributeInstance(EntityAttributes.GENERIC_MOVEMENT_SPEED); - if (genericSpeedAttribute != null && genericSpeedAttribute.getModifier(SOUL_SPEED_BOOST_ID) != null) { - var enchants = this.getRegistryManager().getWrapperOrThrow(RegistryKeys.ENCHANTMENT); - var soulSpeed = enchants.getOrThrow(Enchantments.SOUL_SPEED); - genericSpeedAttribute.removeModifier(SOUL_SPEED_BOOST_ID); - genericSpeedAttribute.addTemporaryModifier(new EntityAttributeModifier( - SOUL_SPEED_BOOST_ID, - 0.01 * ClientRules.SOUL_SPEED_FOV_MULTIPLIER.getValue() * (0.03F * (1.0F + EnchantmentHelper.getEquipmentLevel(soulSpeed, this) * 0.35F)), - EntityAttributeModifier.Operation.ADD_VALUE - )); - } - } - - @Inject( - method = "getFovMultiplier", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/network/AbstractClientPlayerEntity;getAttributeValue(Lnet/minecraft/registry/entry/RegistryEntry;)D", - shift = At.Shift.AFTER - ) - ) - private void injectedAfter(CallbackInfoReturnable cir) { - EntityAttributeInstance genericSpeedAttribute = this.getAttributeInstance(EntityAttributes.GENERIC_MOVEMENT_SPEED); - if (genericSpeedAttribute != null && genericSpeedAttribute.getModifier(SOUL_SPEED_BOOST_ID) != null) { - var enchants = this.getRegistryManager().getWrapperOrThrow(RegistryKeys.ENCHANTMENT); - var soulSpeed = enchants.getOrThrow(Enchantments.SOUL_SPEED); - genericSpeedAttribute.removeModifier(SOUL_SPEED_BOOST_ID); - genericSpeedAttribute.addTemporaryModifier(new EntityAttributeModifier( - SOUL_SPEED_BOOST_ID, - (0.03F * (1.0F + (float) EnchantmentHelper.getEquipmentLevel(soulSpeed, this) * 0.35F)), - EntityAttributeModifier.Operation.ADD_VALUE - )); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/stackableShulkers/HopperBlockEntityMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/stackableShulkers/HopperBlockEntityMixin.java deleted file mode 100644 index 42f9592a..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/stackableShulkers/HopperBlockEntityMixin.java +++ /dev/null @@ -1,19 +0,0 @@ -package me.senseiwells.essentialclient.mixins.stackableShulkers; - -import me.senseiwells.essentialclient.utils.EssentialUtils; -import net.minecraft.block.entity.HopperBlockEntity; -import net.minecraft.item.ItemStack; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(HopperBlockEntity.class) -public class HopperBlockEntityMixin { - @Inject(method = "canMergeItems", at = @At("HEAD"), cancellable = true) - private static void canMergeItems(ItemStack first, ItemStack second, CallbackInfoReturnable cir) { - if (EssentialUtils.isStackableShulkers(first.getItem())) { - cir.setReturnValue(false); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/stackableShulkers/ItemStackMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/stackableShulkers/ItemStackMixin.java deleted file mode 100644 index 6644da5c..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/stackableShulkers/ItemStackMixin.java +++ /dev/null @@ -1,33 +0,0 @@ -package me.senseiwells.essentialclient.mixins.stackableShulkers; - -import me.senseiwells.essentialclient.utils.EssentialUtils; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.ContainerComponent; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -// Priority is to be able to be applied before tweakeroo (for compatibility) -@Mixin(value = ItemStack.class, priority = 900) -public abstract class ItemStackMixin { - @Shadow - public abstract Item getItem(); - - @Inject(method = "getMaxCount", at = @At(value = "HEAD"), cancellable = true) - public void getMaxCount(CallbackInfoReturnable cir) { - if (EssentialUtils.isStackableShulkers(this.getItem())) { - @SuppressWarnings("ConstantConditions") - ItemStack stack = (ItemStack) (Object) this; - ContainerComponent container = stack.get(DataComponentTypes.CONTAINER); - if (container == null || container.streamNonEmpty().findAny().isEmpty()) { - cir.setReturnValue(64); - } else if (EssentialUtils.isStackableShulkerWithItems()) { - cir.setReturnValue(64); - } - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/survivalInventoryInCreative/CreativeInventoryScreenMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/survivalInventoryInCreative/CreativeInventoryScreenMixin.java deleted file mode 100644 index de2e9cfd..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/survivalInventoryInCreative/CreativeInventoryScreenMixin.java +++ /dev/null @@ -1,57 +0,0 @@ -package me.senseiwells.essentialclient.mixins.survivalInventoryInCreative; - -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.interfaces.IScreenInventory; -import me.senseiwells.essentialclient.utils.render.Texts; -import me.senseiwells.essentialclient.utils.render.WidgetHelper; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen; -import net.minecraft.client.gui.screen.ingame.InventoryScreen; -import net.minecraft.client.network.ClientPlayerInteractionManager; -import net.minecraft.text.Text; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(CreativeInventoryScreen.class) -public class CreativeInventoryScreenMixin extends Screen implements IScreenInventory { - @Unique - private boolean forced; - - protected CreativeInventoryScreenMixin(Text title) { - super(title); - } - - @Redirect( - method = "handledScreenTick", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;hasCreativeInventory()Z"), - require = 0 - ) - private boolean hasCreativeInventory(ClientPlayerInteractionManager instance) { - return !this.forced && instance.hasCreativeInventory(); - } - - @Redirect(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;hasCreativeInventory()Z"), require = 0) - private boolean hasCreativeInventoryInit(ClientPlayerInteractionManager instance) { - return !this.forced && instance.hasCreativeInventory(); - } - - @Inject(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/CreativeInventoryScreen;setSelectedTab(Lnet/minecraft/item/ItemGroup;)V")) - private void onInit(CallbackInfo ci) { - if (ClientRules.SURVIVAL_INVENTORY_IN_CREATIVE.getValue() && this.client != null && this.client.player != null) { - this.addDrawableChild(WidgetHelper.newButton(5, 5, 100, 20, Texts.SWAP_INVENTORY, button -> { - InventoryScreen screen = new InventoryScreen(this.client.player); - ((IScreenInventory) screen).essentialclient$setForced(); - this.client.setScreen(screen); - })); - } - } - - @Override - public void essentialclient$setForced() { - this.forced = true; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/survivalInventoryInCreative/InventoryScreenMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/survivalInventoryInCreative/InventoryScreenMixin.java deleted file mode 100644 index f39426df..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/survivalInventoryInCreative/InventoryScreenMixin.java +++ /dev/null @@ -1,65 +0,0 @@ -package me.senseiwells.essentialclient.mixins.survivalInventoryInCreative; - -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.interfaces.IScreenInventory; -import me.senseiwells.essentialclient.utils.render.Texts; -import me.senseiwells.essentialclient.utils.render.WidgetHelper; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen; -import net.minecraft.client.gui.screen.ingame.InventoryScreen; -import net.minecraft.client.network.ClientPlayerInteractionManager; -import net.minecraft.text.Text; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(InventoryScreen.class) -public class InventoryScreenMixin extends Screen implements IScreenInventory { - @Unique - private boolean forced; - - protected InventoryScreenMixin(Text title) { - super(title); - } - - @Redirect( - method = "handledScreenTick", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;hasCreativeInventory()Z"), - require = 0 - ) - private boolean hasCreativeInventory(ClientPlayerInteractionManager instance) { - return !this.forced && instance.hasCreativeInventory(); - } - - @Redirect(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;hasCreativeInventory()Z"), require = 0) - private boolean hasCreativeInventoryInit(ClientPlayerInteractionManager instance) { - return !this.forced && instance.hasCreativeInventory(); - } - - @Inject( - method = "init", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/gui/screen/ingame/InventoryScreen;addSelectableChild(Lnet/minecraft/client/gui/Element;)Lnet/minecraft/client/gui/Element;" - ) - ) - private void onInit(CallbackInfo ci) { - if (ClientRules.SURVIVAL_INVENTORY_IN_CREATIVE.getValue() && this.client != null && this.client.interactionManager != null && this.client.player != null && this.client.interactionManager.hasCreativeInventory()) { - this.addDrawableChild(WidgetHelper.newButton(5, 5, 100, 20, Texts.SWAP_INVENTORY, button -> { - CreativeInventoryScreen screen = new CreativeInventoryScreen( - this.client.player, this.client.player.networkHandler.getEnabledFeatures(), this.client.options.getOperatorItemsTab().getValue() - ); - ((IScreenInventory) screen).essentialclient$setForced(); - this.client.setScreen(screen); - })); - } - } - - @Override - public void essentialclient$setForced() { - this.forced = true; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/switchToTotem/ClientPlayerEntityMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/switchToTotem/ClientPlayerEntityMixin.java deleted file mode 100644 index bb26865a..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/switchToTotem/ClientPlayerEntityMixin.java +++ /dev/null @@ -1,28 +0,0 @@ -package me.senseiwells.essentialclient.mixins.switchToTotem; - -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.inventory.InventoryUtils; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.EquipmentSlot; -import net.minecraft.item.Items; -import net.minecraft.screen.slot.Slot; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ClientPlayerEntity.class) -public class ClientPlayerEntityMixin { - @SuppressWarnings("ConstantConditions") - @Inject(method = "updateHealth", at = @At("HEAD")) - private void checkHealth(float health, CallbackInfo ci) { - int switchToTotemHealth = ClientRules.SWITCH_TO_TOTEM.getValue(); - if (switchToTotemHealth > 0 && switchToTotemHealth > health) { - ClientPlayerEntity playerEntity = (ClientPlayerEntity) (Object) this; - Slot totemSlot = InventoryUtils.getItemSlot(playerEntity, Items.TOTEM_OF_UNDYING); - if (totemSlot != null && totemSlot.id != 45) { - InventoryUtils.swapItemToEquipmentSlot(playerEntity, EquipmentSlot.OFFHAND, totemSlot.id); - } - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/toggleTab/InGameHudMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/toggleTab/InGameHudMixin.java deleted file mode 100644 index cb01615e..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/toggleTab/InGameHudMixin.java +++ /dev/null @@ -1,96 +0,0 @@ -package me.senseiwells.essentialclient.mixins.toggleTab; - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.client.gui.hud.PlayerListHud; -import net.minecraft.client.option.KeyBinding; -import net.minecraft.client.render.RenderTickCounter; -import net.minecraft.scoreboard.Scoreboard; -import net.minecraft.scoreboard.ScoreboardDisplaySlot; -import net.minecraft.scoreboard.ScoreboardObjective; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(InGameHud.class) -public class InGameHudMixin { - @Shadow - @Final - private MinecraftClient client; - @Shadow - @Final - private PlayerListHud playerListHud; - @Unique - private boolean tabVisible = false; - - @ModifyExpressionValue( - method = "renderPlayerList", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/option/KeyBinding;isPressed()Z" - ) - ) - private boolean isPressed(boolean original) { - return false; - } - - @WrapWithCondition( - method = "renderPlayerList", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/gui/hud/PlayerListHud;setVisible(Z)V", - ordinal = 0 - ) - ) - private boolean shouldSetVisible(PlayerListHud instance, boolean shouldBeVisible) { - return false; - } - - @Inject( - method = "renderPlayerList", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/scoreboard/Scoreboard;getObjectiveForSlot(Lnet/minecraft/scoreboard/ScoreboardDisplaySlot;)Lnet/minecraft/scoreboard/ScoreboardObjective;", - shift = At.Shift.BEFORE - ) - ) - private void onRenderTab( - DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci - ) { - if (this.client.world == null || this.client.player == null) { - return; - } - - Scoreboard scoreboard = this.client.world.getScoreboard(); - ScoreboardObjective objective = scoreboard.getObjectiveForSlot(ScoreboardDisplaySlot.LIST); - boolean shouldRender = ClientRules.TOGGLE_TAB.getValue() || this.client.options.playerListKey.isPressed(); - - this.setPlayerListHudVisible(shouldRender); - if (this.tabVisible) { - this.playerListHud.render(context, context.getScaledWindowWidth(), scoreboard, objective); - } - } - - @Unique - private void setPlayerListHudVisible(boolean visible) { - if (ClientRules.TOGGLE_TAB.getValue()) { - KeyBinding tabKey = this.client.options.playerListKey; - if (tabKey.isPressed() && !tabKey.wasPressed()) { - tabKey.setPressed(false); - this.tabVisible = !this.tabVisible; - } - visible = this.tabVisible; - } else { - this.tabVisible = visible; - } - this.playerListHud.setVisible(visible); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/unlockAllRecipes/ClientPlayNetworkHandlerMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/unlockAllRecipes/ClientPlayNetworkHandlerMixin.java deleted file mode 100644 index dfdd5bf5..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/unlockAllRecipes/ClientPlayNetworkHandlerMixin.java +++ /dev/null @@ -1,58 +0,0 @@ -package me.senseiwells.essentialclient.mixins.unlockAllRecipes; - -import me.senseiwells.essentialclient.feature.RecipeBookCache; -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientCommonNetworkHandler; -import net.minecraft.client.network.ClientConnectionState; -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.client.recipebook.ClientRecipeBook; -import net.minecraft.network.ClientConnection; -import net.minecraft.network.packet.s2c.play.ChangeUnlockedRecipesS2CPacket; -import net.minecraft.network.packet.s2c.play.SynchronizeRecipesS2CPacket; -import net.minecraft.recipe.RecipeManager; -import net.minecraft.util.Identifier; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ClientPlayNetworkHandler.class) -public abstract class ClientPlayNetworkHandlerMixin extends ClientCommonNetworkHandler { - @Shadow - @Final - private RecipeManager recipeManager; - - protected ClientPlayNetworkHandlerMixin(MinecraftClient client, ClientConnection connection, ClientConnectionState connectionState) { - super(client, connection, connectionState); - } - - @Inject(method = "onSynchronizeRecipes", at = @At("HEAD")) - private void onSyncRecipes(SynchronizeRecipesS2CPacket packet, CallbackInfo ci) { - if (this.client.player != null) { - RecipeBookCache.setRecipeCache(packet.getRecipes()); - if (ClientRules.UNLOCK_ALL_RECIPES_ON_JOIN.getValue()) { - ClientRecipeBook recipeBook = this.client.player.getRecipeBook(); - packet.getRecipes().forEach(recipeBook::add); - } - } - } - - @Inject(method = "onUnlockRecipes", at = @At("HEAD")) - private void onUnlock(ChangeUnlockedRecipesS2CPacket packet, CallbackInfo ci) { - switch (packet.getAction()) { - case ADD, INIT -> { - for (Identifier identifier : packet.getRecipeIdsToChange()) { - this.recipeManager.get(identifier).ifPresent(RecipeBookCache::removeRecipeFromCache); - } - } - case REMOVE -> { - for (Identifier identifier : packet.getRecipeIdsToChange()) { - this.recipeManager.get(identifier).ifPresent(RecipeBookCache::addRecipeToCache); - } - } - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/unlockAllRecipes/ClientPlayerInteractionManagerMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/unlockAllRecipes/ClientPlayerInteractionManagerMixin.java deleted file mode 100644 index 71c0383d..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/unlockAllRecipes/ClientPlayerInteractionManagerMixin.java +++ /dev/null @@ -1,38 +0,0 @@ -package me.senseiwells.essentialclient.mixins.unlockAllRecipes; - -import me.senseiwells.essentialclient.feature.CraftingSharedConstants; -import me.senseiwells.essentialclient.feature.RecipeBookCache; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.inventory.InventoryUtils; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.ingame.HandledScreen; -import net.minecraft.client.network.ClientPlayerInteractionManager; -import net.minecraft.recipe.RecipeEntry; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ClientPlayerInteractionManager.class) -public class ClientPlayerInteractionManagerMixin { - @Unique - private RecipeEntry essentialclient$lastRecipeCache = null; - - @Inject(method = "clickRecipe", at = @At("HEAD"), cancellable = true) - public void onClickRecipe(int syncId, RecipeEntry recipe, boolean craftAll, CallbackInfo ci) { - MinecraftClient client = EssentialUtils.getClient(); - if (client.currentScreen instanceof HandledScreen handledScreen && RecipeBookCache.isCached(recipe)) { - if (CraftingSharedConstants.IS_SCRIPT_CLICK.get()) { - InventoryUtils.doCraftingSlotsFillAction(recipe, this.essentialclient$lastRecipeCache, handledScreen, craftAll); - CraftingSharedConstants.IS_SCRIPT_CLICK.set(false); - ci.cancel(); - } - if (ClientRules.UNLOCK_ALL_RECIPES_ON_JOIN.getValue() && CraftingSharedConstants.IS_VANILLA_CLICK.get()) { - InventoryUtils.doCraftingSlotsFillAction(recipe, this.essentialclient$lastRecipeCache, handledScreen, craftAll); - } - this.essentialclient$lastRecipeCache = recipe; - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/unlockAllRecipes/GhostSlotClearInvoker.java b/src/main/java/me/senseiwells/essentialclient/mixins/unlockAllRecipes/GhostSlotClearInvoker.java deleted file mode 100644 index f2263482..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/unlockAllRecipes/GhostSlotClearInvoker.java +++ /dev/null @@ -1,21 +0,0 @@ -package me.senseiwells.essentialclient.mixins.unlockAllRecipes; - -import me.senseiwells.essentialclient.utils.interfaces.IGhostRecipeBookWidget; -import net.minecraft.client.gui.screen.recipebook.RecipeBookGhostSlots; -import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -@Mixin(RecipeBookWidget.class) -public abstract class GhostSlotClearInvoker implements IGhostRecipeBookWidget { - - @Shadow - @Final - protected RecipeBookGhostSlots ghostSlots; - - @Override - public void essentialclient$clearGhostSlots() { - this.ghostSlots.reset(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/unlockAllRecipes/RecipeBookWidgetMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/unlockAllRecipes/RecipeBookWidgetMixin.java deleted file mode 100644 index 63866f28..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/unlockAllRecipes/RecipeBookWidgetMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package me.senseiwells.essentialclient.mixins.unlockAllRecipes; - -import me.senseiwells.essentialclient.feature.CraftingSharedConstants; -import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(RecipeBookWidget.class) -public class RecipeBookWidgetMixin { - @Inject( - method = "mouseClicked", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;clickRecipe(ILnet/minecraft/recipe/RecipeEntry;Z)V" - ) - ) - public void onClick(double mouseX, double mouseY, int button, CallbackInfoReturnable cir) { - CraftingSharedConstants.IS_VANILLA_CLICK.set(true); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/mixins/waterFovMultiplier/GameRendererMixin.java b/src/main/java/me/senseiwells/essentialclient/mixins/waterFovMultiplier/GameRendererMixin.java deleted file mode 100644 index bbe19496..00000000 --- a/src/main/java/me/senseiwells/essentialclient/mixins/waterFovMultiplier/GameRendererMixin.java +++ /dev/null @@ -1,18 +0,0 @@ -package me.senseiwells.essentialclient.mixins.waterFovMultiplier; - -import me.senseiwells.essentialclient.rule.ClientRules; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.GameRenderer; -import net.minecraft.util.math.MathHelper; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - - -@Mixin(GameRenderer.class) -public class GameRendererMixin { - @Redirect(method = "getFov", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/MathHelper;lerp(DDD)D")) - private double onLerp(double delta, double start, double end) { - return MathHelper.lerp(0.01 * ClientRules.WATER_FOV_MULTIPLIER.getValue() * MinecraftClient.getInstance().options.getFovEffectScale().getValue(), 1.0F, 0.85714287F); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/ClientRules.java b/src/main/java/me/senseiwells/essentialclient/rule/ClientRules.java deleted file mode 100644 index cdc3bb02..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/ClientRules.java +++ /dev/null @@ -1,191 +0,0 @@ -package me.senseiwells.essentialclient.rule; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonPrimitive; -import me.senseiwells.essentialclient.feature.AFKRules; -import me.senseiwells.essentialclient.feature.BetterAccurateBlockPlacement; -import me.senseiwells.essentialclient.feature.CustomClientCape; -import me.senseiwells.essentialclient.feature.HighlightLiquids; -import me.senseiwells.essentialclient.gui.RulesScreen; -import me.senseiwells.essentialclient.rule.client.*; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.command.CommandHelper; -import me.senseiwells.essentialclient.utils.config.MappedStringConfig; -import me.senseiwells.essentialclient.utils.interfaces.Rule; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerEntity; - -import java.util.Collection; -import java.util.List; - -public class ClientRules extends MappedStringConfig> { - public static final ClientRules INSTANCE = new ClientRules(); - - public static final String - RENDERING = "Rendering", - UTILITY = "Utility", - COMMANDS = "Commands", - MISCELLANEOUS = "Miscellaneous"; - - public static final BooleanClientRule - BETTER_ACCURATE_BLOCK_PLACEMENT = register(new BooleanClientRule("betterAccurateBlockPlacement", "This is the same as accurate block placement for tweakeroo but handled all client side, see controls...", UTILITY)), - CARPET_ALWAYS_SET_DEFAULT = register(new BooleanClientRule("carpetAlwaysSetDefault", "This makes it so whenever you set a carpet rule it automatically sets it to default", UTILITY)), - CHUNK_DEBUG_MINIMAP_BACKGROUND = register(new BooleanClientRule("chunkDebugMinimapBackground", "This renders a box showing the bounds of the chunk debug minimap", true, RENDERING)), - CHUNK_DEBUG_SHOW_UNLOADED_CHUNKS = register(new BooleanClientRule("chunkDebugShowUnloadedChunks", "This shows you unloaded chunks in ChunkDebug", RENDERING)), - CLIENT_SCRIPT_ANNOUNCEMENTS = register(new BooleanClientRule("clientScriptAnnouncements", "This messages in chat when a script starts and finishes", true, MISCELLANEOUS)), - COMMAND_ALTERNATE_DIMENSION = register(new BooleanClientRule("commandAlternateDimension", "This command calculates the coordinates of the alternate dimension", COMMANDS, ClientRules::refreshCommand)), - COMMAND_CLIENT_NICK = register(new BooleanClientRule("commandClientNick", "This allows you to rename player names on the client", COMMANDS, ClientRules::refreshCommand)), - COMMAND_PLAYER_CLIENT = register(new BooleanClientRule("commandPlayerClient", "This command allows you to save /player... commands and execute them", COMMANDS, ClientRules::refreshCommand)), - COMMAND_PLAYER_LIST = register(new BooleanClientRule("commandPlayerList", "This command allows you to execute /player... commands in one command (requires commandPlayerClient)", COMMANDS, ClientRules::refreshCommand)), - COMMAND_REGION = register(new BooleanClientRule("commandRegion", "This command allows you to determine the region you are in or the region at set coords", COMMANDS, ClientRules::refreshCommand)), - COMMAND_SUGGESTER_IGNORES_SPACES = register(new BooleanClientRule("commandSuggesterIgnoresSpaces", "This makes the command suggester ignore spaces", UTILITY)), - CRAFTING_HAX = register(new BooleanClientRule("craftingHax", "This allows you to craft items with the mouse", UTILITY)), - DISABLE_BOB_VIEW_WHEN_HURT = register(new BooleanClientRule("disableBobViewWhenHurt", "Disables the camera bobbing when you get hurt", UTILITY)), - DISABLE_BOSS_BAR = register(new BooleanClientRule("disableBossBar", "This will disable the boss bar from rendering", RENDERING)), - DISABLE_HOTBAR_SCROLLING = register(new BooleanClientRule("disableHotbarScrolling", "This will prevent you from scrolling in your hotbar, learn to use hotkeys :)", UTILITY)), - DISABLE_JOIN_LEAVE_MESSAGES = register(new BooleanClientRule("disableJoinLeaveMessages", "This will prevent join/leave messages from displaying", RENDERING)), - DISABLE_MAP_RENDERING = register(new BooleanClientRule("disableMapRendering", "This disables maps rendering in item frames", RENDERING)), - DISABLE_NAME_TAGS = register(new BooleanClientRule("disableNameTags", "This disables all name tags from rendering", RENDERING)), - DISABLE_NARRATOR = register(new BooleanClientRule("disableNarrator", "Disables cycling narrator when pressing CTRL + B", MISCELLANEOUS)), - DISABLE_NIGHT_VISION_FLASH = register(new BooleanClientRule("disableNightVisionFlash", "Disables the flash that occurs when night vision is about to run out", RENDERING)), - DISABLE_OP_MESSAGES = register(new BooleanClientRule("disableOpMessages", "This will prevent system messages from displaying", RENDERING)), - DISABLE_RECIPE_NOTIFICATIONS = register(new BooleanClientRule("disableRecipeNotifications", "Disables the recipe toast from showing", RENDERING)), - DISABLE_SCREENSHOT_MESSAGE = register(new BooleanClientRule("disableScreenshotMessage", "Disables the message that pops up when you take a screenshot", RENDERING)), - DISABLE_TUTORIAL_NOTIFICATIONS = register(new BooleanClientRule("disableTutorialNotifications", "Disables the tutorial toast from showing", RENDERING)), - DISPLAY_TIME_PLAYED = register(new BooleanClientRule("displayTimePlayed", "This will display how long you have had your current client open for in the corner of the pause menu", MISCELLANEOUS)), - ESSENTIAL_CLIENT_BUTTON = register(new BooleanClientRule("essentialClientButton", "This renders the Essential Client Menu on the main menu screen, and pause screen", true, UTILITY)), - TITLE_TEXT_TO_TOP = register(new BooleanClientRule("titleTextToTop", "Forces the Minecraft version and Mojang text to the top of the screen", RENDERING)), - HIGHLIGHT_LAVA_SOURCES = register(new BooleanClientRule("highlightLavaSources", "Highlights lava sources, credit to plusls for the original code for this", RENDERING, ClientRules::refreshWorld)), - HIGHLIGHT_WATER_SOURCES = register(new BooleanClientRule("highlightWaterSources", "highlights water sources", RENDERING, ClientRules::refreshWorld)), - INCREASE_SPECTATOR_SCROLL_SPEED = register(new BooleanClientRule("increaseSpectatorScrollSpeed", "Increases the limit at which you can scroll to go faster in spectator", UTILITY)), - OPEN_SCREENSHOT_DIRECTORY = register(new BooleanClientRule("openScreenshotDirectory", "This opens the screenshot directory instead of directly opening the screenshot", UTILITY)), - PERMANENT_CHAT_HUD = register(new BooleanClientRule("permanentChatHud", "This prevents the chat from being cleared, also applies when changing worlds/servers", RENDERING)), - QUICK_LOCK_RECIPE = register(new BooleanClientRule("quickLockRecipe", "If you middle click a recipe it will put the name of the item in the search bar stopping you from craftin the wrong recipe", UTILITY)), - REMOVE_WARN_RECEIVED_PASSENGERS = register(new BooleanClientRule("removeWarnReceivedPassengers", "This removes the 'Received passengers for unknown entity' warning on the client", MISCELLANEOUS)), - STACKABLE_SHULKERS_IN_PLAYER_INVENTORIES = register(new BooleanClientRule("stackableShulkersInPlayerInventories", "This allows for shulkers to stack only in your inventory", UTILITY)), - STACKABLE_SHULKERS_WITH_ITEMS = register(new BooleanClientRule("stackableShulkersWithItems", "This allows for shulkers with items to stack only in your inventory", UTILITY)), - START_SELECTED_SCRIPTS_ON_JOIN = register(new BooleanClientRule("startSelectedScriptsOnJoin", "This will enable your selected scripts when you join a world automatically", MISCELLANEOUS)), - SURVIVAL_INVENTORY_IN_CREATIVE = register(new BooleanClientRule("survivalInventoryInCreative", "This lets you open the survival inventory in creative mode", UTILITY)), - TOGGLE_TAB = register(new BooleanClientRule("toggleTab", "This allows you to toggle tab instead of holding to see tab", UTILITY)), - UNLOCK_ALL_RECIPES_ON_JOIN = register(new BooleanClientRule("unlockAllRecipesOnJoin", "Unlocks every recipe when joining a world", UTILITY)), - CLIENTSCRIPT_DEBUGGER = register(new BooleanClientRule("clientscriptDebugger", "You probably shouldn't touch this", UTILITY)); - - public static final IntegerClientRule - ANNOUNCE_AFK = register(new IntegerClientRule("announceAFK", "This announces when you become afk after a set amount of time (ticks)", UTILITY)), - AFK_LOGOUT = register(new IntegerClientRule("afkLogout", "Number of ticks until client will disconnect you from world (must be >= 200 to be active)", UTILITY)), - AUTO_WALK = register(new IntegerClientRule("autoWalk", "This will auto walk after you have held your key for set amount of ticks", UTILITY)), - INCREASE_SPECTATOR_SCROLL_SENSITIVITY = register(new IntegerClientRule("increaseSpectatorScrollSensitivity", "Increases the sensitivity at which you can scroll to go faster in spectator", UTILITY)), - SWITCH_TO_TOTEM = register(new IntegerClientRule("switchToTotem", "This will switch to a totem (if you have one), under a set amount of health", UTILITY)); - - public static final IntegerSliderClientRule - PERMANENT_TIME = register(new IntegerSliderClientRule("permanentTime", "This forces your client to set a time of day", -1, RENDERING, -1, 23999)); - - public static final DoubleClientRule - OVERRIDE_CREATIVE_WALK_SPEED = register(new DoubleClientRule("overrideCreativeWalkSpeed", "This allows you to override the vanilla walk speed in creative mode", 0.0D, UTILITY)); - - public static final DoubleSliderClientRule - SOUL_SPEED_FOV_MULTIPLIER = register(new DoubleSliderClientRule("soulSpeedFovMultiplier", "Determines the percentage of Fov scaling when walking on soil soul or soul sand", 0, RENDERING, 0, 1)), - WATER_FOV_MULTIPLIER = register(new DoubleSliderClientRule("waterFovMultiplier", "Determines the percentage of Fov scaling when fully submerged in water", 0, RENDERING, 0, 1)); - - public static final StringClientRule - ANNOUNCE_AFK_MESSAGE = register(new StringClientRule("announceAFKMessage", "This is the message you announce after you are afk", "I am now AFK", UTILITY)), - ANNOUNCE_BACK_MESSAGE = register(new StringClientRule("announceBackMessage", "This is the message you announce after you are back from being afk", "", UTILITY)); - - @SuppressWarnings("unused") - public static final CycleClientRule - CLIENT_SCRIPT_FONT = register(new CycleClientRule("clientScriptFont", "This allows you to change the font for client script errors", List.of("Minecraft", "Jetbrains"), RENDERING)), - CUSTOM_CLIENT_CAPE = register(new CycleClientRule("customClientCape", "This allows you to select a Minecraft cape to wear, this only appears client side", CustomClientCape.getCapeNames(), RENDERING, ClientRules::refreshCape)), - DISABLE_ARMOUR_RENDERING = register(new CycleClientRule("disableArmourRendering", "This allows you to disable armour rendering for entities", List.of("None", "You", "Players", "Entities"), RENDERING)), - DISPLAY_RULE_TYPE = register(new CycleClientRule("displayRuleType", "This allows you to choose the order you want rules to be displayed", List.of("Alphabetical", "Rule Type", "Categories"), MISCELLANEOUS, ClientRules::refreshScreen)); - - public static final ListClientRule - CLIENT_SCRIPT_REPOS = register(new ListClientRule("clientScriptRepos", "This allows you to define where you can download your scripts from", List.of("https://api.github.com/repos/senseiwells/clientscript/contents/scripts"), MISCELLANEOUS)); - - static { - CLIENT_SCRIPT_REPOS.setMaxLength(Integer.MAX_VALUE); - - AFKRules.load(); - BetterAccurateBlockPlacement.load(); - - if (EssentialUtils.isModInstalled("fabric-resource-loader-v0")) { - HighlightLiquids.load(); - } - } - - private ClientRules() { } - - public static void load() { } - - public static void addRule(String name, ClientRule rule) { - INSTANCE.set(name, rule); - } - - public static ClientRule ruleFromString(String name) { - return INSTANCE.get(name); - } - - public static Collection> getClientRules() { - return INSTANCE.map.values(); - } - - private static void refreshCommand(Rule value) { - ClientPlayerEntity playerEntity = EssentialUtils.getPlayer(); - if (playerEntity != null) { - playerEntity.networkHandler.onCommandTree(CommandHelper.getCommandPacket()); - } - } - - private static void refreshCape(Rule value) { - CustomClientCape.setCurrentCape(value.getValue()); - } - - private static void refreshScreen(Rule value) { - MinecraftClient client = EssentialUtils.getClient(); - if (client.currentScreen instanceof RulesScreen rulesScreen) { - rulesScreen.refreshRules(rulesScreen.getSearchBoxText()); - } - } - - private static void refreshWorld(Rule value) { - MinecraftClient client = EssentialUtils.getClient(); - if (client.worldRenderer != null) { - client.worldRenderer.reload(); - } - } - - @Override - public String getConfigName() { - return "ClientRules"; - } - - @Override - protected JsonElement valueToJson(ClientRule value) { - JsonObject clientRuleObject = new JsonObject(); - clientRuleObject.add("value", value.getValueAsJson()); - clientRuleObject.addProperty("extras", value.getOptionalInfo()); - return clientRuleObject; - } - - @Override - protected ClientRule jsonToValue(String key, JsonElement valueElement) { - JsonObject clientRuleObject = valueElement.getAsJsonObject(); - JsonElement value = clientRuleObject.get("value"); - JsonElement info = clientRuleObject.get("extras"); - ClientRule clientRule = this.get(key); - if (clientRule != null) { - clientRule.setValueFromJson(value); - if (info instanceof JsonPrimitive) { - clientRule.setOptionalInfo(info.getAsString()); - } - } - return clientRule; - } - - private static > T register(T clientRule) { - addRule(clientRule.getName(), clientRule); - clientRule.onValueChange(); - clientRule.addListener(rule -> INSTANCE.saveConfig()); - return clientRule; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/carpet/BooleanCarpetRule.java b/src/main/java/me/senseiwells/essentialclient/rule/carpet/BooleanCarpetRule.java deleted file mode 100644 index 43f6b525..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/carpet/BooleanCarpetRule.java +++ /dev/null @@ -1,19 +0,0 @@ -package me.senseiwells.essentialclient.rule.carpet; - -import me.senseiwells.essentialclient.utils.interfaces.Rule; - -public class BooleanCarpetRule extends CarpetClientRule implements Rule.Bool { - public BooleanCarpetRule(String name, String description, Boolean defaultValue) { - super(name, description, defaultValue); - } - - @Override - public CarpetClientRule shallowCopy() { - return new BooleanCarpetRule(this.getName(), this.getDescription(), this.getDefaultValue()); - } - - @Override - public Boolean getValueFromString(String value) { - return "true".equals(value); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/carpet/CarpetClientRule.java b/src/main/java/me/senseiwells/essentialclient/rule/carpet/CarpetClientRule.java deleted file mode 100644 index c2387fea..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/carpet/CarpetClientRule.java +++ /dev/null @@ -1,67 +0,0 @@ -package me.senseiwells.essentialclient.rule.carpet; - -import me.senseiwells.essentialclient.feature.CarpetClient; -import me.senseiwells.essentialclient.rule.impl.SimpleRule; -import me.senseiwells.essentialclient.utils.EssentialUtils; - -import java.util.List; -import java.util.Objects; - -public abstract class CarpetClientRule extends SimpleRule { - private String manager; - - public CarpetClientRule(String name, String description, T defaultValue) { - super(name, description, defaultValue); - this.manager = "carpet"; - } - - public final void setFromServer(String stringValue) { - T value = this.getValueFromString(stringValue); - if (value != null) { - this.setValueQuietly(value); - } - } - - public final void setCustomManager(String manager) { - this.manager = manager; - } - - @Override - public void setValue(T value) { - if (!Objects.equals(value, this.getValue()) && EssentialUtils.playerHasOp()) { - EssentialUtils.sendChatMessage("/%s %s %s".formatted(this.manager, this.getName(), value)); - if (EssentialUtils.getClient().isInSingleplayer()) { - this.setFromServer(value.toString()); - } - } - } - - @Override - public final List> getListeners() { - return null; - } - - @Override - public abstract CarpetClientRule shallowCopy(); - - public abstract T getValueFromString(String value); - - @Override - public final void setValueFromString(String stringValue) { - T value = this.getValueFromString(stringValue); - if (value != null) { - this.setValue(value); - } - } - - @Override - public boolean isAvailable() { - return (CarpetClient.INSTANCE.isServerCarpet() && EssentialUtils.playerHasOp()) || EssentialUtils.getClient().isInSingleplayer(); - } - - @Override - public final void addListener(RuleListener ruleListener) { } - - @Override - public final void onValueChange() { } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/carpet/CycleCarpetRule.java b/src/main/java/me/senseiwells/essentialclient/rule/carpet/CycleCarpetRule.java deleted file mode 100644 index 277331a2..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/carpet/CycleCarpetRule.java +++ /dev/null @@ -1,53 +0,0 @@ -package me.senseiwells.essentialclient.rule.carpet; - -import me.senseiwells.essentialclient.utils.interfaces.Rule; - -import java.util.List; - -public class CycleCarpetRule extends CarpetClientRule implements Rule.Cycle { - private final List cycleValues; - private int index; - - public CycleCarpetRule(String name, String description, List cycleValues, String defaultValue) { - super(name, description, defaultValue); - this.cycleValues = cycleValues; - this.index = cycleValues.indexOf(defaultValue); - if (this.index == -1) { - this.index = 0; - } - } - - public static CycleCarpetRule commandOf(String name, String description, String defaultValue) { - switch (defaultValue) { - case "true", "false", "ops" -> { - } - default -> defaultValue = "false"; - } - return new CycleCarpetRule(name, description, List.of("true", "false", "ops"), defaultValue); - } - - @Override - public CarpetClientRule shallowCopy() { - return new CycleCarpetRule(this.getName(), this.getDescription(), this.cycleValues, this.getDefaultValue()); - } - - @Override - public String getValueFromString(String value) { - return value; - } - - @Override - public List getCycleValues() { - return this.cycleValues; - } - - @Override - public int getCurrentIndex() { - return this.index; - } - - @Override - public void setCurrentIndex(int index) { - this.index = index; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/carpet/DoubleCarpetRule.java b/src/main/java/me/senseiwells/essentialclient/rule/carpet/DoubleCarpetRule.java deleted file mode 100644 index e62505d6..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/carpet/DoubleCarpetRule.java +++ /dev/null @@ -1,34 +0,0 @@ -package me.senseiwells.essentialclient.rule.carpet; - -import com.google.gson.JsonElement; - -public class DoubleCarpetRule extends NumberCarpetRule { - public DoubleCarpetRule(String name, String description, Double defaultValue) { - super(name, description, defaultValue); - } - - @Override - public Type getType() { - return Type.DOUBLE; - } - - @Override - public Double fromJson(JsonElement element) { - return element.getAsDouble(); - } - - @Override - public CarpetClientRule shallowCopy() { - return new DoubleCarpetRule(this.getName(), this.getDescription(), this.getDefaultValue()); - } - - @Override - public Double getValueFromString(String value) { - try { - return Double.parseDouble(value); - } catch (NumberFormatException e) { - this.logCannotSet(value); - return null; - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/carpet/IntegerCarpetRule.java b/src/main/java/me/senseiwells/essentialclient/rule/carpet/IntegerCarpetRule.java deleted file mode 100644 index 85dc05c1..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/carpet/IntegerCarpetRule.java +++ /dev/null @@ -1,34 +0,0 @@ -package me.senseiwells.essentialclient.rule.carpet; - -import com.google.gson.JsonElement; - -public class IntegerCarpetRule extends NumberCarpetRule { - public IntegerCarpetRule(String name, String description, Integer defaultValue) { - super(name, description, defaultValue); - } - - @Override - public Type getType() { - return Type.INTEGER; - } - - @Override - public Integer fromJson(JsonElement element) { - return element.getAsInt(); - } - - @Override - public CarpetClientRule shallowCopy() { - return new IntegerCarpetRule(this.getName(), this.getDescription(), this.getDefaultValue()); - } - - @Override - public Integer getValueFromString(String value) { - try { - return Integer.parseInt(value); - } catch (NumberFormatException e) { - this.logCannotSet(value); - return null; - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/carpet/NumberCarpetRule.java b/src/main/java/me/senseiwells/essentialclient/rule/carpet/NumberCarpetRule.java deleted file mode 100644 index 583770ae..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/carpet/NumberCarpetRule.java +++ /dev/null @@ -1,9 +0,0 @@ -package me.senseiwells.essentialclient.rule.carpet; - -import me.senseiwells.essentialclient.utils.interfaces.Rule; - -public abstract class NumberCarpetRule extends CarpetClientRule implements Rule.Num { - public NumberCarpetRule(String name, String description, T defaultValue) { - super(name, description, defaultValue); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/carpet/StringCarpetRule.java b/src/main/java/me/senseiwells/essentialclient/rule/carpet/StringCarpetRule.java deleted file mode 100644 index fe5bfbd9..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/carpet/StringCarpetRule.java +++ /dev/null @@ -1,27 +0,0 @@ -package me.senseiwells.essentialclient.rule.carpet; - -import me.senseiwells.essentialclient.utils.interfaces.Rule; - -public class StringCarpetRule extends CarpetClientRule implements Rule.Str { - public StringCarpetRule(String name, String description, String defaultValue) { - super(name, description, defaultValue); - } - - @Override - public CarpetClientRule shallowCopy() { - return new StringCarpetRule(this.getName(), this.getDescription(), this.getDefaultValue()); - } - - @Override - public String getValueFromString(String value) { - return value; - } - - @Override - public int getMaxLength() { - return 32; - } - - @Override - public void setMaxLength(int maxLength) { } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/client/BooleanClientRule.java b/src/main/java/me/senseiwells/essentialclient/rule/client/BooleanClientRule.java deleted file mode 100644 index e09fa418..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/client/BooleanClientRule.java +++ /dev/null @@ -1,55 +0,0 @@ -package me.senseiwells.essentialclient.rule.client; - -import com.google.gson.JsonElement; -import com.google.gson.JsonPrimitive; -import me.senseiwells.essentialclient.utils.interfaces.Rule; - -public class BooleanClientRule extends ClientRule implements Rule.Bool { - public BooleanClientRule(String name, String description, boolean defaultValue, String category, RuleListener ruleListener) { - super(name, description, defaultValue, category); - this.addListener(ruleListener); - } - - public BooleanClientRule(String name, String description, boolean defaultValue, String category) { - this(name, description, defaultValue, category, null); - } - - public BooleanClientRule(String name, String description, String category, RuleListener ruleListener) { - this(name, description, false, category, ruleListener); - } - - public BooleanClientRule(String name, String description, String category) { - this(name, description, category, null); - } - - @Override - public JsonElement toJson(Boolean value) { - return new JsonPrimitive(value); - } - - @Override - public Boolean fromJson(JsonElement value) { - return value.getAsBoolean(); - } - - @Override - public void setValueFromString(String value) { - this.setValue("true".equals(value)); - } - - @Override - public String getTypeAsString() { - return "boolean"; - } - - @Override - public BooleanClientRule shallowCopy() { - BooleanClientRule rule = new BooleanClientRule(this.getName(), this.getDescription(), this.getDefaultValue(), this.getCategory()); - if (this.getListeners() != null) { - for (RuleListener listener : this.getListeners()) { - rule.addListener(listener); - } - } - return rule; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/client/ClientRule.java b/src/main/java/me/senseiwells/essentialclient/rule/client/ClientRule.java deleted file mode 100644 index 8823ecc1..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/client/ClientRule.java +++ /dev/null @@ -1,59 +0,0 @@ -package me.senseiwells.essentialclient.rule.client; - -import com.google.gson.JsonObject; -import me.senseiwells.essentialclient.rule.impl.SimpleRule; - -import java.util.ArrayList; -import java.util.List; - -public abstract class ClientRule extends SimpleRule { - private final String category; - - private List> listeners; - - public ClientRule(String name, String description, T defaultValue) { - this(name, description, defaultValue, null); - } - - public ClientRule(String name, String description, T defaultValue, String category) { - super(name, description, defaultValue); - this.category = category; - } - - public abstract String getTypeAsString(); - - public JsonObject serialise() { - JsonObject object = new JsonObject(); - object.addProperty("type", this.getTypeAsString()); - object.addProperty("name", this.getName()); - object.addProperty("description", this.getDescription()); - object.addProperty("optional_info", this.getOptionalInfo()); - object.addProperty("display", this.display()); - object.add("default_value", this.getDefaultValueAsJson()); - object.add("value", this.getValueAsJson()); - return object; - } - - @Override - public List> getListeners() { - return this.listeners; - } - - @Override - public abstract ClientRule shallowCopy(); - - @Override - public String getCategory() { - return this.category; - } - - @Override - public void addListener(RuleListener ruleListener) { - if (ruleListener != null) { - if (this.listeners == null) { - this.listeners = new ArrayList<>(); - } - this.listeners.add(ruleListener); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/client/CycleClientRule.java b/src/main/java/me/senseiwells/essentialclient/rule/client/CycleClientRule.java deleted file mode 100644 index cb48c7ad..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/client/CycleClientRule.java +++ /dev/null @@ -1,74 +0,0 @@ -package me.senseiwells.essentialclient.rule.client; - -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import me.senseiwells.essentialclient.utils.interfaces.Rule; - -import java.util.List; - -public class CycleClientRule extends ClientRule implements Rule.Cycle { - private final List cycleValues; - private int index; - - public CycleClientRule(String name, String description, List cycleValues, String defaultValue, String category, RuleListener ruleListener) { - super(name, description, defaultValue, category); - this.addListener(ruleListener); - this.cycleValues = cycleValues; - this.index = cycleValues.indexOf(defaultValue); - if (this.index == -1) { - this.index = 0; - } - } - - public CycleClientRule(String name, String description, List cycleValues, String category, RuleListener stringRuleListener) { - this(name, description, cycleValues, cycleValues.get(0), category, stringRuleListener); - } - - public CycleClientRule(String name, String description, List cycleValues, String category) { - this(name, description, cycleValues, category, null); - } - - @Override - public List getCycleValues() { - return this.cycleValues; - } - - @Override - public int getCurrentIndex() { - return this.index; - } - - @Override - public void setCurrentIndex(int index) { - this.index = index; - } - - @Override - public String getTypeAsString() { - return "cycle"; - } - - @Override - public JsonObject serialise() { - JsonObject object = super.serialise(); - - JsonArray array = new JsonArray(); - for (String string : this.cycleValues) { - array.add(string); - } - object.add("cycle_values", array); - - return object; - } - - @Override - public CycleClientRule shallowCopy() { - CycleClientRule rule = new CycleClientRule(this.getName(), this.getDescription(), this.getCycleValues(), this.getCategory()); - if (this.getListeners() != null) { - for (RuleListener listener : this.getListeners()) { - rule.addListener(listener); - } - } - return rule; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/client/DoubleClientRule.java b/src/main/java/me/senseiwells/essentialclient/rule/client/DoubleClientRule.java deleted file mode 100644 index dbb25e9e..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/client/DoubleClientRule.java +++ /dev/null @@ -1,48 +0,0 @@ -package me.senseiwells.essentialclient.rule.client; - -import com.google.gson.JsonElement; - -public class DoubleClientRule extends NumberClientRule { - public DoubleClientRule(String name, String description, Double defaultValue, String category, RuleListener ruleListener) { - super(name, description, defaultValue, category, ruleListener); - } - - public DoubleClientRule(String name, String description, Double defaultValue, String category) { - this(name, description, defaultValue, category, null); - } - - @Override - public String getTypeAsString() { - return "double"; - } - - @Override - public Type getType() { - return Type.DOUBLE; - } - - @Override - public Double fromJson(JsonElement value) { - return value.getAsDouble(); - } - - @Override - public DoubleClientRule shallowCopy() { - DoubleClientRule rule = new DoubleClientRule(this.getName(), this.getDescription(), this.getDefaultValue(), this.getCategory()); - if (this.getListeners() != null) { - for (RuleListener listener : this.getListeners()) { - rule.addListener(listener); - } - } - return rule; - } - - @Override - public void setValueFromString(String value) { - try { - this.setValue(Double.parseDouble(value)); - } catch (NumberFormatException e) { - this.logCannotSet(value); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/client/DoubleSliderClientRule.java b/src/main/java/me/senseiwells/essentialclient/rule/client/DoubleSliderClientRule.java deleted file mode 100644 index ba0e547e..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/client/DoubleSliderClientRule.java +++ /dev/null @@ -1,82 +0,0 @@ -package me.senseiwells.essentialclient.rule.client; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import me.senseiwells.essentialclient.utils.command.CommandHelper; -import me.senseiwells.essentialclient.utils.interfaces.Rule; -import net.minecraft.util.math.MathHelper; - -public class DoubleSliderClientRule extends ClientRule implements Rule.Slider { - private final double minValue; - private final double maxValue; - - public DoubleSliderClientRule(String name, String description, double defaultValue, String category, double min, double max) { - super(name, description, defaultValue, category); - this.minValue = min; - this.maxValue = max; - } - - @Override - public Double fromJson(JsonElement element) { - return element.getAsDouble(); - } - - @Override - public String getTypeAsString() { - return "double_slider"; - } - - @Override - public JsonObject serialise() { - JsonObject object = super.serialise(); - object.addProperty("min", this.minValue); - object.addProperty("max", this.maxValue); - return object; - } - - @Override - public ClientRule shallowCopy() { - return new DoubleSliderClientRule(this.getName(), this.getDescription(), this.getDefaultValue(), this.getCategory(), this.getMin(), this.getMax()); - } - - @Override - public void setValueFromString(String value) { - try { - double doubleValue = Double.parseDouble(value); - if (doubleValue > this.getMax() || doubleValue < this.getMin()) { - this.logCannotSet(value); - return; - } - this.setValue(doubleValue); - } catch (NumberFormatException e) { - this.logCannotSet(value); - } - } - - @Override - public String getFormatted() { - return CommandHelper.DECIMAL_FORMAT.format(this.getValue()); - } - - @Override - public Double getMin() { - return this.minValue; - } - - @Override - public Double getMax() { - return this.maxValue; - } - - @Override - public Double getNewValue(double percent) { - percent = MathHelper.clamp(percent, 0, 1); - double difference = this.getMax() - this.getMin(); - return this.getMin() + difference * percent; - } - - @Override - public double getPercentage() { - return (this.getValue() - this.getMin()) / (this.getMax() - this.getMin()); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/client/IntegerClientRule.java b/src/main/java/me/senseiwells/essentialclient/rule/client/IntegerClientRule.java deleted file mode 100644 index 6cefc511..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/client/IntegerClientRule.java +++ /dev/null @@ -1,52 +0,0 @@ -package me.senseiwells.essentialclient.rule.client; - -import com.google.gson.JsonElement; - -public class IntegerClientRule extends NumberClientRule { - public IntegerClientRule(String name, String description, int defaultValue, String category, RuleListener ruleListener) { - super(name, description, defaultValue, category, ruleListener); - } - - public IntegerClientRule(String name, String description, int defaultValue, String category) { - this(name, description, defaultValue, category, null); - } - - public IntegerClientRule(String name, String description, String category) { - this(name, description, 0, category); - } - - @Override - public Type getType() { - return Type.INTEGER; - } - - @Override - public Integer fromJson(JsonElement value) { - return value.getAsInt(); - } - - @Override - public String getTypeAsString() { - return "integer"; - } - - @Override - public IntegerClientRule shallowCopy() { - IntegerClientRule rule = new IntegerClientRule(this.getName(), this.getDescription(), this.getDefaultValue(), this.getCategory()); - if (this.getListeners() != null) { - for (RuleListener listener : this.getListeners()) { - rule.addListener(listener); - } - } - return rule; - } - - @Override - public void setValueFromString(String value) { - try { - this.setValue(Integer.parseInt(value)); - } catch (NumberFormatException e) { - this.logCannotSet(value); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/client/IntegerSliderClientRule.java b/src/main/java/me/senseiwells/essentialclient/rule/client/IntegerSliderClientRule.java deleted file mode 100644 index 4d30d115..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/client/IntegerSliderClientRule.java +++ /dev/null @@ -1,82 +0,0 @@ -package me.senseiwells.essentialclient.rule.client; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import me.senseiwells.essentialclient.utils.interfaces.Rule; -import net.minecraft.util.math.MathHelper; - -public class IntegerSliderClientRule extends ClientRule implements Rule.Slider { - private final int minValue; - private final int maxValue; - - public IntegerSliderClientRule(String name, String description, int defaultValue, String category, int minValue, int maxValue) { - super(name, description, defaultValue, category); - this.minValue = minValue; - this.maxValue = maxValue; - } - - @Override - public Integer fromJson(JsonElement element) { - return element.getAsInt(); - } - - @Override - public String getTypeAsString() { - return "integer_slider"; - } - - @Override - public JsonObject serialise() { - JsonObject object = super.serialise(); - object.addProperty("min", this.minValue); - object.addProperty("max", this.maxValue); - return object; - } - - @Override - public ClientRule shallowCopy() { - return new IntegerSliderClientRule(this.getName(), this.getDescription(), this.getDefaultValue(), this.getCategory(), this.getMin(), this.getMax()); - } - - @Override - public void setValueFromString(String value) { - Integer integer; - try { - integer = Integer.parseInt(value); - } catch (NumberFormatException e) { - integer = null; - } - if (integer == null || integer > this.getMax() || integer < this.getMin()) { - this.logCannotSet(value); - return; - } - this.setValue(integer); - } - - @Override - public String getFormatted() { - return this.getValue().toString(); - } - - @Override - public Integer getMin() { - return this.minValue; - } - - @Override - public Integer getMax() { - return this.maxValue; - } - - @Override - public Integer getNewValue(double percent) { - percent = MathHelper.clamp(percent, 0, 1); - int difference = this.getMax() - this.getMin(); - return (int) Math.round(this.getMin() + difference * percent); - } - - @Override - public double getPercentage() { - return (this.getValue() - this.getMin()) / (double) (this.getMax() - this.getMin()); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/client/ListClientRule.java b/src/main/java/me/senseiwells/essentialclient/rule/client/ListClientRule.java deleted file mode 100644 index 93bc92f1..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/client/ListClientRule.java +++ /dev/null @@ -1,69 +0,0 @@ -package me.senseiwells.essentialclient.rule.client; - -import com.google.gson.Gson; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import com.google.gson.JsonSyntaxException; -import me.senseiwells.essentialclient.utils.interfaces.Rule; - -import java.util.ArrayList; -import java.util.List; - -public class ListClientRule extends ClientRule> implements Rule.ListRule { - private static final Gson GSON = new Gson(); - private int maxLength; - - public ListClientRule(String name, String description, List defaultValue, String category, RuleListener> ruleListener) { - super(name, description, new ArrayList<>(defaultValue), category); - this.addListener(ruleListener); - this.maxLength = 32; - } - - public ListClientRule(String name, String description, List listValues, String category) { - this(name, description, listValues, category, null); - } - - @Override - public String getTypeAsString() { - return "list"; - } - - @Override - public void setValueFromString(String value) { - try { - JsonArray array = GSON.fromJson(value, JsonArray.class); - List configs = this.fromJson(array); - this.setValue(configs); - } catch (JsonSyntaxException e) { - this.logCannotSet(value); - } - } - - @Override - public ListClientRule shallowCopy() { - ListClientRule rule = new ListClientRule(this.getName(), this.getDescription(), this.getValue(), this.getCategory()); - if (this.getListeners() != null) { - for (RuleListener> listener : this.getListeners()) { - rule.addListener(listener); - } - } - return rule; - } - - @Override - public JsonObject serialise() { - JsonObject object = super.serialise(); - object.addProperty("max_length", this.getMaxLength()); - return object; - } - - @Override - public int getMaxLength() { - return this.maxLength; - } - - @Override - public void setMaxLength(int maxLength) { - this.maxLength = maxLength <= 0 ? 32 : maxLength; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/client/NumberClientRule.java b/src/main/java/me/senseiwells/essentialclient/rule/client/NumberClientRule.java deleted file mode 100644 index e2f08a8d..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/client/NumberClientRule.java +++ /dev/null @@ -1,10 +0,0 @@ -package me.senseiwells.essentialclient.rule.client; - -import me.senseiwells.essentialclient.utils.interfaces.Rule; - -public abstract class NumberClientRule extends ClientRule implements Rule.Num { - public NumberClientRule(String name, String description, T defaultValue, String category, RuleListener ruleListener) { - super(name, description, defaultValue, category); - this.addListener(ruleListener); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/client/StringClientRule.java b/src/main/java/me/senseiwells/essentialclient/rule/client/StringClientRule.java deleted file mode 100644 index 508ab997..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/client/StringClientRule.java +++ /dev/null @@ -1,51 +0,0 @@ -package me.senseiwells.essentialclient.rule.client; - -import com.google.gson.JsonObject; -import me.senseiwells.essentialclient.utils.interfaces.Rule; - -public class StringClientRule extends ClientRule implements Rule.Str { - private int maxLength; - - public StringClientRule(String name, String description, String defaultValue, String category, RuleListener listener) { - super(name, description, defaultValue, category); - this.addListener(listener); - this.maxLength = 32; - } - - public StringClientRule(String name, String description, String defaultValue, String category) { - this(name, description, defaultValue, category, null); - } - - @Override - public String getTypeAsString() { - return "string"; - } - - @Override - public StringClientRule shallowCopy() { - StringClientRule rule = new StringClientRule(this.getName(), this.getDescription(), this.getDefaultValue(), this.getCategory()); - if (this.getListeners() != null) { - for (RuleListener listener : this.getListeners()) { - rule.addListener(listener); - } - } - return rule; - } - - @Override - public JsonObject serialise() { - JsonObject object = super.serialise(); - object.addProperty("max_length", this.getMaxLength()); - return object; - } - - @Override - public int getMaxLength() { - return this.maxLength; - } - - @Override - public void setMaxLength(int maxLength) { - this.maxLength = maxLength <= 0 ? 32 : maxLength; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/game/BooleanGameRule.java b/src/main/java/me/senseiwells/essentialclient/rule/game/BooleanGameRule.java deleted file mode 100644 index 91289060..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/game/BooleanGameRule.java +++ /dev/null @@ -1,20 +0,0 @@ -package me.senseiwells.essentialclient.rule.game; - -import me.senseiwells.essentialclient.utils.interfaces.Rule; -import net.minecraft.world.GameRules; - -public class BooleanGameRule extends GameRule implements Rule.Bool { - public BooleanGameRule(String name, String description, Boolean defaultValue, GameRules.Key key) { - super(name, description, defaultValue, key); - } - - @Override - public GameRule shallowCopy() { - return new BooleanGameRule(this.getName(), this.getDescription(), this.getDefaultValue(), this.getKey()); - } - - @Override - public Boolean getValueFromString(String value) { - return "true".equals(value); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/game/GameRule.java b/src/main/java/me/senseiwells/essentialclient/rule/game/GameRule.java deleted file mode 100644 index 0b91d9e6..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/game/GameRule.java +++ /dev/null @@ -1,109 +0,0 @@ -package me.senseiwells.essentialclient.rule.game; - -import com.google.gson.JsonElement; -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.rule.impl.SimpleRule; -import net.minecraft.client.resource.language.I18n; -import net.minecraft.world.GameRules; - -import java.util.List; -import java.util.Objects; - -public abstract class GameRule extends SimpleRule { - private final GameRules.Key gameRuleKey; - private boolean isAvailable; - - public GameRule(String name, String description, T defaultValue, GameRules.Key gameRuleKey) { - super(name, description, defaultValue); - this.gameRuleKey = gameRuleKey; - this.isAvailable = false; - } - - public final void setFromServer(String stringValue) { - this.isAvailable = true; - T value = this.getValueFromString(stringValue); - if (value != null) { - this.setValueQuietly(value); - } - } - - public final void reset() { - this.isAvailable = false; - this.setValueQuietly(this.getDefaultValue()); - } - - public final GameRules.Key getKey() { - return this.gameRuleKey; - } - - @Override - public abstract GameRule shallowCopy(); - - @Override - public String getCategory() { - return this.gameRuleKey == null ? "X" : I18n.translate(this.gameRuleKey.getCategory().getCategory()); - } - - public abstract T getValueFromString(String value); - - @Override - public final boolean isAvailable() { - return this.isAvailable; - } - - @Override - public final void setValueFromString(String stringValue) { - T value = this.getValueFromString(stringValue); - if (value != null) { - this.setValue(value); - } - } - - @Override - public boolean changeable() { - return EssentialClient.GAME_RULE_NET_HANDLER.canModifyRules(); - } - - @Override - public void setValue(T value) { - if (this.isAvailable && !Objects.equals(this.getValue(), value)) { - // We don't actually set the value, - // we wait for the server to accept - // it then set the value quietly - EssentialClient.GAME_RULE_NET_HANDLER.sendServerRuleChange(this, value.toString()); - } - } - - // These should not be used - - @Override - public final T fromJson(JsonElement element) { - return null; - } - - @Override - public final JsonElement toJson(T value) { - return null; - } - - @Override - public final List> getListeners() { - return null; - } - - @Override - public void onValueChange() { } - - @Override - public final JsonElement getValueAsJson() { - return null; - } - - @Override - public final JsonElement getDefaultValueAsJson() { - return null; - } - - @Override - public final void setValueFromJson(JsonElement element) { } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/game/IntegerGameRule.java b/src/main/java/me/senseiwells/essentialclient/rule/game/IntegerGameRule.java deleted file mode 100644 index d5f566b1..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/game/IntegerGameRule.java +++ /dev/null @@ -1,29 +0,0 @@ -package me.senseiwells.essentialclient.rule.game; - -import net.minecraft.world.GameRules; - -public class IntegerGameRule extends GameRule { - public IntegerGameRule(String name, String description, Integer defaultValue, GameRules.Key key) { - super(name, description, defaultValue, key); - } - - @Override - public Type getType() { - return Type.INTEGER; - } - - @Override - public GameRule shallowCopy() { - return new IntegerGameRule(this.getName(), this.getDescription(), this.getDefaultValue(), this.getKey()); - } - - @Override - public Integer getValueFromString(String value) { - try { - return Integer.parseInt(value); - } catch (NumberFormatException e) { - this.logCannotSet(value); - return null; - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/game/VanillaGameRules.java b/src/main/java/me/senseiwells/essentialclient/rule/game/VanillaGameRules.java deleted file mode 100644 index a2debe29..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/game/VanillaGameRules.java +++ /dev/null @@ -1,121 +0,0 @@ -package me.senseiwells.essentialclient.rule.game; - -import me.senseiwells.essentialclient.mixins.gameRuleSync.GameRuleAccessor; -import net.minecraft.world.GameRules; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -public class VanillaGameRules { - private static final Map> GAME_RULES = new HashMap<>(); - - @SuppressWarnings("unused") - public static final BooleanGameRule - DO_FIRE_TICK = registerBoolean("doFireTick", "Whether fire should spread and naturally extinguish", true, GameRules.DO_FIRE_TICK), - MOB_GRIEFING = registerBoolean("mobGriefing", "Whether creepers, zombies, endermen, ghasts, withers, ender dragons, rabbits, sheep, villagers, silverfish, snow golems, and end crystals should be able to change blocks, and whether mobs can pick up items. When mobGriefing is disabled, piglins will not pick up gold ingots, but a player can still barter with them by using the item on the mob. Similarly, villagers will not pick up food items but can still breed until they run out of any food already in their inventory. This also affects the capability of zombie-like creatures like zombified piglins and drowned to pathfind to turtle eggs", true, GameRules.DO_MOB_GRIEFING), - KEEP_INVENTORY = registerBoolean("keepInventory", "Whether the player should keep items and experience in their inventory after death", false, GameRules.KEEP_INVENTORY), - DO_MOB_SPAWNING = registerBoolean("doMobSpawning", "Whether mobs should naturally spawn. Does not affect monster spawners", true, GameRules.DO_MOB_SPAWNING), - DO_MOB_LOOT = registerBoolean("doMobLoot", "Whether mobs should drop items and experience orbs", true, GameRules.DO_MOB_LOOT), - DO_TILE_DROPS = registerBoolean("doTileDrops", "Whether blocks should have drops", true, GameRules.DO_TILE_DROPS), - DO_ENTITY_DROPS = registerBoolean("doEntityDrops", "Whether entities that are not mobs should have drops", true, GameRules.DO_ENTITY_DROPS), - COMMAND_BLOCK_OUTPUT = registerBoolean("commandBlockOutput", "Whether command blocks should notify admins when they perform commands", true, GameRules.COMMAND_BLOCK_OUTPUT), - NATURAL_REGENERATION = registerBoolean("naturalRegeneration", "Whether the player can regenerate health naturally if their hunger is full enough (doesn't affect external healing, such as golden apples, the Regeneration effect, etc.)", true, GameRules.NATURAL_REGENERATION), - DO_DAYLIGHT_CYCLE = registerBoolean("doDaylightCycle", "Whether the daylight cycle and moon phases progress", true, GameRules.DO_DAYLIGHT_CYCLE), - LOG_ADMIN_COMMANDS = registerBoolean("logAdminCommands", "Whether to log admin commands to server log", true, GameRules.LOG_ADMIN_COMMANDS), - SHOW_DEATH_MESSAGES = registerBoolean("showDeathMessages", "Whether death messages are put into chat when a player dies. Also affects whether a message is sent to the pet's owner when the pet dies.", true, GameRules.SHOW_DEATH_MESSAGES), - SEND_COMMAND_FEEDBACK = registerBoolean("sendCommandFeedback", "Whether the feedback from commands executed by a player should show up in chat. Also affects the default behavior of whether command blocks store their output text", true, GameRules.SEND_COMMAND_FEEDBACK), - REDUCED_DEBUG_INFO = registerBoolean("reducedDebugInfo", "Whether the debug screen shows all or reduced information; and whether the effects of F3 + B (entity hitboxes) and F3 + G (chunk boundaries) are shown", false, GameRules.REDUCED_DEBUG_INFO), - SPECTATORS_GENERATE_CHUNKS = registerBoolean("spectatorsGenerateChunks", "Whether players in spectator mode can generate chunks", true, GameRules.SPECTATORS_GENERATE_CHUNKS), - DISABLE_ELYTRA_MOVEMENT_CHECK = registerBoolean("disableElytraMovementCheck", "Whether the server should skip checking player speed when the player is wearing elytra. Often helps with jittering due to lag in multiplayer", false, GameRules.DISABLE_ELYTRA_MOVEMENT_CHECK), - DO_WEATHER_CYCLE = registerBoolean("doWeatherCycle", "Whether the weather can change naturally. The /weather command can still change weather", true, GameRules.DO_WEATHER_CYCLE), - DO_LIMITED_CRAFTING = registerBoolean("doLimitedCrafting", "Whether players should be able to craft only those recipes that they've unlocked first", false, GameRules.DO_LIMITED_CRAFTING), - ANNOUNCE_ADVANCEMENTS = registerBoolean("announceAdvancements", "Whether advancements should be announced in chat", true, GameRules.ANNOUNCE_ADVANCEMENTS), - DISABLE_RAIDS = registerBoolean("disableRaids", "Whether raids are disabled", false, GameRules.DISABLE_RAIDS), - DO_INSOMNIA = registerBoolean("doInsomnia", "Whether phantoms can spawn in the nighttime", true, GameRules.DO_INSOMNIA), - DO_IMMEDIATE_RESPAWN = registerBoolean("doImmediateRespawn", "Players respawn immediately without showing the death screen", false, GameRules.DO_IMMEDIATE_RESPAWN), - DROWNING_DAMAGE = registerBoolean("drowningDamage", "Whether the player should take damage when drowning", true, GameRules.DROWNING_DAMAGE), - FALL_DAMAGE = registerBoolean("fallDamage", "Whether the player should take fall damage", true, GameRules.FALL_DAMAGE), - FIRE_DAMAGE = registerBoolean("fireDamage", "Whether the player should take damage in fire, lava, campfires, or on magma blocks", true, GameRules.FIRE_DAMAGE), - FREEZE_DAMAGE = registerBoolean("freezeDamage", "Whether the player should take damage when inside powder snow", true, null), - DO_PATROL_SPAWNING = registerBoolean("doPatrolSpawning", "Whether patrols can spawn", true, GameRules.DO_PATROL_SPAWNING), - DO_TRADER_SPAWNING = registerBoolean("doTraderSpawning", "Whether wandering traders can spawn", true, GameRules.DO_TRADER_SPAWNING), - FORGIVE_DEAD_PLAYERS = registerBoolean("forgiveDeadPlayers", "Makes angered neutral mobs stop being angry when the targeted player dies nearby", true, GameRules.FORGIVE_DEAD_PLAYERS), - UNIVERSAL_ANGER = registerBoolean("universalAnger", "Makes angered neutral mobs attack any nearby player, not just the player that angered them. Works best if forgiveDeadPlayers is disabled", false, GameRules.UNIVERSAL_ANGER), - DO_WARDEN_SPAWNING = registerBoolean("doWardenSpawning", "Whether wardens can spawn", true, null), - BLOCK_EXPLOSION_DROP_DECAY = registerBoolean("blockExplosionDropDecay", "Whether block loot is dropped by all blocks (false) or randomly (true) depending on how far the block is from the center of a block explosion (e.g. clicking a bed in dimensions other than the Overworld)", true, null), - MOB_EXPLOSION_DROP_DECAY = registerBoolean("mobExplosionDropDecay", "Whether block loot is dropped by all blocks (false) or randomly (true) depending on how far the block is from the center of a mob explosion (e.g. Creeper explosion)", true, null), - TNT_EXPLOSION_DROP_DECAY = registerBoolean("tntExplosionDropDecay", "Whether block loot is dropped by all blocks (false) or randomly (true) depending on how far the block is from the center of a TNT explosion", false, null), - GLOBAL_SOUND_EVENTS = registerBoolean("globalSoundEvents", "Whether certain sound events are heard by all players regardless of location", true, null), - LAVA_SOURCE_CONVERSION = registerBoolean("lavaSourceConversion", "Whether new sources of lava are allowed to form", false, null), - WATER_SOURCE_CONVERSION = registerBoolean("waterSourceConversion", "Whether new sources of water are allowed to form", true, null); - - @SuppressWarnings("unused") - public static final IntegerGameRule - RANDOM_TICK_SPEED = registerInteger("randomTickSpeed", "How often a random block tick occurs (such as plant growth, leaf decay, etc.) per chunk section per game tick. 0 and negative values disables random ticks, higher numbers increase random ticks. Setting to a high integer results in high speeds of decay and growth. Numbers over 4096 make plant growth or leaf decay instantaneous", 3, GameRules.RANDOM_TICK_SPEED), - SPAWN_RADIUS = registerInteger("spawnRadius", "The number of blocks outward from the world spawn coordinates that a player spawns in when first joining a server or when dying without a personal spawnpoint. Has no effect on servers where the default game mode is adventure", 10, GameRules.SPAWN_RADIUS), - MAX_ENTITY_CRAMMING = registerInteger("maxEntityCramming", "The maximum number of pushable entities a mob or player can push, before taking 3♥ suffocation damage per half-second. Setting to 0 or lower disables the rule. Damage affects survival-mode or adventure-mode players, and all mobs but bats. Pushable entities include non-spectator-mode players, any mob except bats, as well as boats and minecarts", 24, GameRules.MAX_ENTITY_CRAMMING), - MAX_COMMAND_CHAIN_LENGTH = registerInteger("maxCommandChainLength", "The maximum length of a chain of commands that can be executed during one tick. Applies to command blocks and functions", 65536, GameRules.MAX_COMMAND_CHAIN_LENGTH), - PLAYERS_SLEEPING_PERCENTAGE = registerInteger("playersSleepingPercentage", "What percentage of players must sleep to skip the night", 100, null), - SNOW_ACCUMULATION_HEIGHT = registerInteger("snowAccumulationHeight", "The maximum number of snow layers that can be accumulated on each block", 1, null); - - static { - loadRest(); - } - - private static BooleanGameRule registerBoolean(String name, String description, boolean defaultValue, GameRules.Key ruleKey) { - ruleKey = getRuleKey(name, ruleKey); - description = description + (ruleKey == null ? "\n\nThis Game Rule is not available in your version" : ""); - return register(new BooleanGameRule(name, description, defaultValue, ruleKey)); - } - - private static IntegerGameRule registerInteger(String name, String description, int defaultValue, GameRules.Key ruleKey) { - ruleKey = getRuleKey(name, ruleKey); - description = description + (ruleKey == null ? "\n\nThis Game Rule is not available in your version" : ""); - return register(new IntegerGameRule(name, description, defaultValue, ruleKey)); - } - - private static > T register(T rule) { - GAME_RULES.put(rule.getName(), rule); - return rule; - } - - public static GameRule ruleFromString(String name) { - return GAME_RULES.get(name); - } - - public static Collection> getGameRules() { - return GAME_RULES.values(); - } - - private static GameRules.Key getRuleKey(String name, GameRules.Key existing) { - if (existing != null) { - return existing; - } - for (GameRules.Key key : getAllKeys()) { - if (key.getName().equals(name)) { - return key; - } - } - return null; - } - - private static void loadRest() { - // In case I forget to add a GameRule with its description it will still work - for (GameRules.Key key : getAllKeys()) { - if (!GAME_RULES.containsKey(key.getName())) { - GameRules.Rule rule = GameRuleAccessor.getRules().get(key).createRule(); - String noDescription = "Game Rule doesn't have a description... (Please Report this as a bug!)"; - if (rule instanceof GameRules.BooleanRule booleanRule) { - registerBoolean(key.getName(), noDescription, booleanRule.get(), key); - } else if (rule instanceof GameRules.IntRule intRule) { - registerInteger(key.getName(), noDescription, intRule.get(), key); - } - } - } - } - - private static Collection> getAllKeys() { - return GameRuleAccessor.getRules().keySet(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/rule/impl/SimpleRule.java b/src/main/java/me/senseiwells/essentialclient/rule/impl/SimpleRule.java deleted file mode 100644 index bf2a80c4..00000000 --- a/src/main/java/me/senseiwells/essentialclient/rule/impl/SimpleRule.java +++ /dev/null @@ -1,65 +0,0 @@ -package me.senseiwells.essentialclient.rule.impl; - -import me.senseiwells.essentialclient.utils.interfaces.Rule; - -public abstract class SimpleRule implements Rule { - private final String name; - private final String description; - private final T defaultValue; - - private String optionalInfo; - private boolean display; - private T value; - - public SimpleRule(String name, String description, T defaultValue) { - this.name = name; - this.description = description; - this.defaultValue = defaultValue; - this.display = true; - this.value = defaultValue; - } - - @Override - public final String getName() { - return this.name; - } - - @Override - public final String getDescription() { - return this.description; - } - - @Override - public final String getOptionalInfo() { - return this.optionalInfo; - } - - @Override - public final T getDefaultValue() { - return this.defaultValue; - } - - @Override - public final T getValue() { - return this.value; - } - - @Override - public final void setValueQuietly(T value) { - this.value = value; - } - - @Override - public final void setOptionalInfo(String optionalInfo) { - this.optionalInfo = optionalInfo; - } - - @Override - public boolean display() { - return this.display; - } - - public final void display(boolean shouldDisplay) { - this.display = shouldDisplay; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/EssentialUtils.java b/src/main/java/me/senseiwells/essentialclient/utils/EssentialUtils.java deleted file mode 100644 index 27017ac7..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/EssentialUtils.java +++ /dev/null @@ -1,315 +0,0 @@ -package me.senseiwells.essentialclient.utils; - -import me.senseiwells.essentialclient.feature.CarpetClient; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.rule.carpet.CarpetClientRule; -import me.senseiwells.essentialclient.rule.carpet.IntegerCarpetRule; -import me.senseiwells.essentialclient.rule.carpet.StringCarpetRule; -import me.senseiwells.essentialclient.rule.client.BooleanClientRule; -import me.senseiwells.essentialclient.utils.misc.Scheduler; -import net.fabricmc.loader.api.FabricLoader; -import net.fabricmc.loader.api.ModContainer; -import net.minecraft.MinecraftVersion; -import net.minecraft.block.BlockState; -import net.minecraft.block.FluidBlock; -import net.minecraft.block.ShulkerBoxBlock; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.network.ClientPlayerInteractionManager; -import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.entity.attribute.EntityAttributes; -import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.entity.effect.StatusEffectUtil; -import net.minecraft.entity.effect.StatusEffects; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.BlockItem; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.registry.DynamicRegistryManager; -import net.minecraft.registry.tag.FluidTags; -import net.minecraft.text.Text; -import net.minecraft.util.Hand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.Vec3d; - -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.function.Supplier; - -public class EssentialUtils { - private static final Path ESSENTIAL_CLIENT_PATH; - private static final ModContainer ESSENTIAL_CONTAINER; - private static final boolean DEV; - - public static final URI WIKI_URL; - public static final URI SCRIPT_WIKI_URL; - - static { - ESSENTIAL_CLIENT_PATH = FabricLoader.getInstance().getConfigDir().resolve("EssentialClient"); - DEV = FabricLoader.getInstance().isDevelopmentEnvironment(); - - Optional optional = FabricLoader.getInstance().getModContainer("essential-client"); - if (optional.isEmpty()) { - throw new IllegalStateException("EssentialClient mod container was not found?!"); - } - ESSENTIAL_CONTAINER = optional.get(); - - try { - WIKI_URL = new URI("https://github.com/senseiwells/EssentialClient/wiki"); - SCRIPT_WIKI_URL = new URI("https://github.com/senseiwells/EssentialClient/wiki/ClientScript"); - Files.createDirectories(ESSENTIAL_CLIENT_PATH); - } catch (IOException | URISyntaxException e) { - throw new RuntimeException(e); - } - } - - public static void sendMessageToActionBar(String message) { - MinecraftClient client = getClient(); - if (client.player != null) { - client.execute(() -> client.player.sendMessage(Text.literal(message), true)); - } - } - - public static void sendMessageToActionBar(Text text) { - MinecraftClient client = getClient(); - if (client.player != null) { - client.execute(() -> client.player.sendMessage(text, true)); - } - } - - public static void sendMessage(String message) { - MinecraftClient client = getClient(); - if (client.player != null) { - client.execute(() -> client.player.sendMessage(Text.literal(message), false)); - } - } - - public static void sendMessage(Text text) { - MinecraftClient client = getClient(); - if (client.player != null) { - client.execute(() -> client.player.sendMessage(text, false)); - } - } - - public static void sendChatMessage(String message) { - MinecraftClient client = getClient(); - if (client.player != null) { - client.execute(() -> { - if (message.startsWith("/")) { - client.player.networkHandler.sendChatCommand(message.substring(1)); - return; - } - client.player.networkHandler.sendChatMessage(message); - }); - } - } - - public static Path getEssentialConfigFile() { - return ESSENTIAL_CLIENT_PATH; - } - - public static MinecraftClient getClient() { - return MinecraftClient.getInstance(); - } - - public static ClientPlayerEntity getPlayer() { - return getClient().player; - } - - public static ClientWorld getWorld() { - return getClient().world; - } - - public static ClientPlayerInteractionManager getInteractionManager() { - return getClient().interactionManager; - } - - public static ClientPlayNetworkHandler getNetworkHandler() { - return getClient().getNetworkHandler(); - } - - public static DynamicRegistryManager getRegistryManager() { - return getWorld().getRegistryManager(); - } - - public static PlayerListEntry getPlayerListEntry() { - return EssentialUtils.getNetworkHandler().getPlayerListEntry(EssentialUtils.getPlayer().getUuid()); - } - - public static boolean playerHasOp() { - ClientPlayerEntity player = getPlayer(); - return player != null && player.hasPermissionLevel(2); - } - - public static String getMinecraftVersion() { - return MinecraftVersion.CURRENT.getName(); - } - - public static boolean isDev() { - return DEV; - } - - public static boolean isModInstalled(String modId) { - return FabricLoader.getInstance().isModLoaded(modId); - } - - public static String getEssentialVersion() { - return ESSENTIAL_CONTAINER.getMetadata().getVersion().getFriendlyString(); - } - - public static boolean isStackableShulkers(Item item) { - if (getClient() != null && isRuleWithCarpet(ClientRules.STACKABLE_SHULKERS_IN_PLAYER_INVENTORIES)) { - return item instanceof BlockItem b && b.getBlock() instanceof ShulkerBoxBlock; - } - return false; - } - - public static boolean isStackableShulkerWithItems() { - return isRuleWithCarpet(ClientRules.STACKABLE_SHULKERS_WITH_ITEMS); - } - - public static boolean isRuleWithCarpet(BooleanClientRule rule) { - return getClient().isInSingleplayer() && rule.getValue() || isCarpetRuleTrue(rule.getName()); - } - - private static boolean isCarpetRuleTrue(String string) { - CarpetClientRule rule = CarpetClient.INSTANCE.getRule(string); - return rule != null && rule.getValue() instanceof Boolean b && b; - } - - public static boolean canMineBlock(BlockPos pos) { - ClientPlayerEntity player = getPlayer(); - double x = player.getX() - pos.getX() - 0.5; - double y = player.getY() - pos.getY() + 1.0; - double z = player.getZ() - pos.getZ() - 0.5; - if (x * x + y * y + z * z > 36 || player.getEntityWorld().isOutOfHeightLimit(pos) || !player.getEntityWorld().getWorldBorder().contains(pos)) { - return false; - } - if (player.isBlockBreakingRestricted(player.getEntityWorld(), pos, getInteractionManager().getCurrentGameMode())) { - return false; - } - BlockState state = player.getEntityWorld().getBlockState(pos); - return !state.isAir() && !state.contains(FluidBlock.LEVEL) && state.getHardness(getWorld(), pos) >= 0; - } - - public static void mineBlock(BlockPos pos, Supplier condition, CompletableFuture future) { - if (future.isCancelled()) { - return; - } - if (canMineBlock(pos) && condition.get()) { - getInteractionManager().updateBlockBreakingProgress(pos, Direction.DOWN); - getPlayer().swingHand(Hand.MAIN_HAND); - Scheduler.schedule(0, () -> mineBlock(pos, condition, future)); - return; - } - future.complete(null); - } - - public static float getBlockBreakingSpeed(ItemStack itemStack, BlockState blockState, PlayerEntity player) { - float multiplier = itemStack.getMiningSpeedMultiplier(blockState); - if (multiplier > 1.0F) { - multiplier += (float) player.getAttributeValue(EntityAttributes.PLAYER_MINING_EFFICIENCY); - } - - if (StatusEffectUtil.hasHaste(player)) { - multiplier *= 1.0F + (StatusEffectUtil.getHasteAmplifier(player) + 1.0F) * 0.2F; - } - StatusEffectInstance effectInstance = player.getStatusEffect(StatusEffects.MINING_FATIGUE); - if (effectInstance != null) { - multiplier *= switch (effectInstance.getAmplifier()) { - case 0 -> 0.3F; - case 1 -> 0.09F; - case 2 -> 0.027F; - default -> 8.1e-4F; - }; - } - if (player.isSubmergedIn(FluidTags.WATER)) { - var attribute = player.getAttributeInstance(EntityAttributes.PLAYER_SUBMERGED_MINING_SPEED); - if (attribute != null) { - multiplier *= (float) attribute.getValue(); - } - } - if (!player.isOnGround()) { - multiplier /= 5.0F; - } - return multiplier; - } - - public static BlockPos vec3dToBlockPos(Vec3d position) { - return new BlockPos(MathHelper.floor(position.x), MathHelper.floor(position.y), MathHelper.floor(position.z)); - } - - public static BlockPos vec3dToBlockPos(double x, double y, double z) { - return new BlockPos(MathHelper.floor(x), MathHelper.floor(y), MathHelper.floor(z)); - } - - // public static boolean canSpawn(WorldView world, BlockPos pos, EntityType entityType) { - // SpawnLocation location = SpawnRestriction.getLocation(entityType); - // if (!SpawnHelper.canSpawn(location, world, pos, entityType)) { - // return false; - // } - // return world.isSpaceEmpty(entityType.createSimpleBoundingBox((double) pos.getX() + 0.5D, pos.getY(), (double) pos.getZ() + 0.5D)); - // } - - public static int getMaxChatLength(int fallback) { - if (CarpetClient.INSTANCE.isServerCarpet()) { - CarpetClientRule rule = CarpetClient.INSTANCE.getRule("maxChatLength"); - if (rule instanceof IntegerCarpetRule intRule) { - int maxLength = intRule.getValue(); - if (maxLength > 0) { - return maxLength; - } - } - if (rule instanceof StringCarpetRule stringRule) { - try { - int maxLength = Integer.parseInt(stringRule.getValue()); - if (maxLength >= 0) { - return maxLength; - } - } catch (NumberFormatException ignore) { - } - } - } - return fallback; - } - - @SuppressWarnings("unchecked") - public static V throwUnchecked(Throwable throwable) throws T { - throw (T) throwable; - } - - public static void throwAsUnchecked(ThrowableRunnable runnable) { - try { - runnable.run(); - } catch (Exception throwable) { - throwUnchecked(throwable); - } - } - - public static T throwAsUnchecked(ThrowableSupplier supplier) { - try { - return supplier.get(); - } catch (Exception throwable) { - return throwUnchecked(throwable); - } - } - - @FunctionalInterface - public interface ThrowableRunnable { - void run() throws Exception; - } - - @FunctionalInterface - public interface ThrowableSupplier { - T get() throws Exception; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/carpet/CarpetUtils.java b/src/main/java/me/senseiwells/essentialclient/utils/carpet/CarpetUtils.java deleted file mode 100644 index 88c5c121..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/carpet/CarpetUtils.java +++ /dev/null @@ -1,78 +0,0 @@ -package me.senseiwells.essentialclient.utils.carpet; - -import carpet.CarpetExtension; -import carpet.CarpetServer; -import carpet.api.settings.CarpetRule; -import carpet.api.settings.RuleHelper; -import carpet.api.settings.SettingsManager; -import net.minecraft.text.Text; -import org.jetbrains.annotations.Nullable; - -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; -import java.util.function.BiConsumer; - -public class CarpetUtils { - public static boolean isRuleCommand(CarpetRule rule) { - return rule.categories().contains("command"); - } - - public static String getRuleSettingsManagerId(CarpetRule rule) { - return rule.settingsManager().identifier(); - } - - public static String getRuleDescription(CarpetRule rule) { - return RuleHelper.translatedDescription(rule); - } - - public static String getRuleExtraInfo(CarpetRule rule) { - StringBuilder builder = new StringBuilder(); - if (rule.extraInfo() != null) { - for (Text info : rule.extraInfo()) { - builder.append(info.getString()).append(" "); - } - } - return builder.toString(); - } - - public static String getRuleValueAsString(CarpetRule rule) { - return RuleHelper.toRuleString(rule.value()); - } - - public static String getRuleDefaultValueAsString(CarpetRule rule) { - return RuleHelper.toRuleString(rule.defaultValue()); - } - - @Nullable - public static CarpetRule getCarpetRule(String name) { - for (SettingsManager manager : getAllCarpetSettingsManagers()) { - CarpetRule rule = manager.getCarpetRule(name); - if (rule != null) { - return rule; - } - } - return null; - } - - public static void forEachCarpetRule(BiConsumer, String> consumer) { - for (SettingsManager manager : getAllCarpetSettingsManagers()) { - for (CarpetRule rule : manager.getCarpetRules()) { - String id = manager.identifier(); - consumer.accept(rule, id); - } - } - } - - private static Collection getAllCarpetSettingsManagers() { - List managers = new LinkedList<>(); - managers.add(CarpetServer.settingsManager); - for (CarpetExtension extension : CarpetServer.extensions) { - SettingsManager manager = extension.extensionSettingsManager(); - if (manager != null) { - managers.add(manager); - } - } - return managers; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/ClientScriptUtils.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/ClientScriptUtils.java deleted file mode 100644 index ab9301d0..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/ClientScriptUtils.java +++ /dev/null @@ -1,761 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript; - -import com.mojang.brigadier.StringReader; -import com.mojang.brigadier.arguments.*; -import com.mojang.brigadier.builder.ArgumentBuilder; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import com.mojang.brigadier.builder.RequiredArgumentBuilder; -import com.mojang.brigadier.context.ParsedArgument; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; -import com.mojang.brigadier.suggestion.SuggestionProvider; -import com.mojang.brigadier.suggestion.Suggestions; -import kotlin.Pair; -import me.senseiwells.arucas.builtin.*; -import me.senseiwells.arucas.classes.ClassDefinition; -import me.senseiwells.arucas.classes.EnumDefinition; -import me.senseiwells.arucas.classes.PrimitiveDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.functions.ArucasFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.impl.ArucasCollection; -import me.senseiwells.arucas.utils.impl.ArucasList; -import me.senseiwells.arucas.utils.impl.ArucasMap; -import me.senseiwells.essentialclient.clientscript.definitions.EntityDef; -import me.senseiwells.essentialclient.clientscript.definitions.ItemStackDef; -import me.senseiwells.essentialclient.clientscript.definitions.TextDef; -import me.senseiwells.essentialclient.commands.CommandRegister; -import me.senseiwells.essentialclient.mixins.clientScript.KeyBindingAccessor; -import me.senseiwells.essentialclient.rule.client.*; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptItemStack; -import me.senseiwells.essentialclient.utils.command.*; -import me.senseiwells.essentialclient.utils.render.Texts; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.option.KeyBinding; -import net.minecraft.client.util.InputUtil; -import net.minecraft.command.CommandSource; -import net.minecraft.command.argument.*; -import net.minecraft.command.suggestion.SuggestionProviders; -import net.minecraft.entity.Entity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.*; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.registry.RegistryWrapper; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.screen.slot.SlotActionType; -import net.minecraft.server.command.CommandManager; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.text.ClickEvent; -import net.minecraft.text.HoverEvent; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.Hand; -import net.minecraft.util.Identifier; -import net.minecraft.util.InvalidIdentifierException; -import net.minecraft.util.math.Direction; -import net.minecraft.world.RaycastContext; -import org.lwjgl.glfw.GLFW; - -import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Future; -import java.util.function.Supplier; - -public class ClientScriptUtils { - private static final Set WARNED = ConcurrentHashMap.newKeySet(); - private static final Map HELD_KEYS = new ConcurrentHashMap<>(); - - static { - ClientTickEvents.END_CLIENT_TICK.register(client -> { - for (TickedKey key : HELD_KEYS.values()) { - key.tick(); - } - }); - } - - public static void load() { } - - public static void warnMainThread(String name, Interpreter interpreter) { - MinecraftClient client = EssentialUtils.getClient(); - if (!client.isOnThread() && !WARNED.contains(name)) { - WARNED.add(name); - interpreter.logDebug( - "'%s' was not called on the Minecraft main thread, this may lead to unexpected behavior".formatted(name) - ); - } - } - - public static Future ensureMainThread(String name, Interpreter interpreter, Runnable runnable) { - return ensureMainThread(name, interpreter, () -> { - runnable.run(); - return null; - }); - } - - public static Future ensureMainThread(String name, Interpreter interpreter, Supplier callable) { - MinecraftClient client = EssentialUtils.getClient(); - if (client.isOnThread()) { - return CompletableFuture.completedFuture(callable.get()); - } - if (!WARNED.contains(name)) { - WARNED.add(name); - interpreter.logDebug( - "'%s' was not called on the Minecraft main thread, this may lead to unexpected behavior".formatted(name) - ); - } - return client.submit(() -> interpreter.runSafe(callable)); - } - - public static void holdKey(Interpreter interpreter, KeyBinding key, int interval) { - if (interpreter.isRunning()) { - HELD_KEYS.put(key.getTranslationKey(), new TickedKey(key, interval)); - interpreter.addStopEvent(() -> releaseKey(key)); - } - } - - public static void releaseKey(KeyBinding key) { - HELD_KEYS.remove(key.getTranslationKey()); - key.setPressed(false); - } - - public static void modifyKey(Interpreter interpreter, boolean held, KeyBinding key) { - if (held) { - holdKey(interpreter, key, 0); - } else { - releaseKey(key); - } - } - - /** - * Default direction can be null, in which case a RuntimeError is thrown. - */ - public static Direction stringToDirection(String string, Direction defaultDirection) { - return switch (string.toLowerCase()) { - case "north", "n" -> Direction.NORTH; - case "east", "e" -> Direction.EAST; - case "south", "s" -> Direction.SOUTH; - case "west", "w" -> Direction.WEST; - case "up", "u" -> Direction.UP; - case "down", "d" -> Direction.DOWN; - default -> { - if (defaultDirection != null) { - yield defaultDirection; - } - throw new RuntimeError("Invalid direction '%s'".formatted(string)); - } - }; - } - - public static String mouseButtonToString(int number) { - return switch (number) { - case GLFW.GLFW_MOUSE_BUTTON_RIGHT -> "right"; - case GLFW.GLFW_MOUSE_BUTTON_LEFT -> "left"; - case GLFW.GLFW_MOUSE_BUTTON_MIDDLE -> "middle"; - default -> "unknown"; - }; - } - - public static Formatting stringToFormatting(String string) { - Formatting formatting = Formatting.byName(string); - if (formatting == null) { - throw new RuntimeError("Invalid formatting: %s".formatted(string)); - } - return formatting; - } - - public static ClickEvent stringToClickEvent(Interpreter interpreter, String string, ClassInstance object) { - return switch (string.toLowerCase()) { - case "function", "run_function" -> { - ArucasFunction function = object.getPrimitive(FunctionDef.class); - if (function == null) { - throw new RuntimeError("Invalid function value: %s".formatted(object.toString(interpreter))); - } - yield new FunctionClickEvent(interpreter, function); - } - default -> { - ClickEvent.Action action = Arrays.stream(ClickEvent.Action.values()) - .filter(a -> a.asString().equalsIgnoreCase(string)) - .findFirst() - .orElseThrow(() -> new RuntimeError("Invalid click event action: %s".formatted(string))); - String eventString = object.getPrimitive(StringDef.class); - if (eventString == null) { - throw new RuntimeError("Invalid event value: %s".formatted(object.toString(interpreter))); - } - yield new ClickEvent(action, eventString); - } - }; - } - - public static HoverEvent stringToHoverEvent(String string, ClassInstance object) { - return switch (string.toLowerCase()) { - case "show_text", "text" -> { - MutableText text = object.getPrimitive(TextDef.class); - if (text == null) { - throw new RuntimeError("Expected 'Text' for 'show_text' hover event"); - } - yield new HoverEvent(HoverEvent.Action.SHOW_TEXT, text); - } - case "show_item", "item" -> { - ScriptItemStack stack = object.getPrimitive(ItemStackDef.class); - if (stack == null) { - throw new RuntimeError("Expected 'ItemStack' for 'show_item' hover event"); - } - yield new HoverEvent(HoverEvent.Action.SHOW_ITEM, new HoverEvent.ItemStackContent(stack.stack)); - } - case "show_entity", "entity" -> { - Entity entity = object.getPrimitive(EntityDef.class); - if (entity == null) { - throw new RuntimeError("Expected 'Entity' for 'show_entity' hover event"); - } - yield new HoverEvent(HoverEvent.Action.SHOW_ENTITY, new HoverEvent.EntityContent(entity.getType(), entity.getUuid(), entity.getName())); - } - default -> throw new RuntimeError("Invalid action '%s'".formatted(string)); - }; - } - - public static Identifier stringToIdentifier(String string) { - try { - return Identifier.of(string); - } catch (InvalidIdentifierException e) { - throw new RuntimeError("Invalid id '%s'".formatted(string), e); - } - } - - public static RaycastContext.FluidHandling stringToFluidType(String string) { - return switch (string.toLowerCase()) { - case "none" -> RaycastContext.FluidHandling.NONE; - case "source", "sources", "sources_only" -> RaycastContext.FluidHandling.SOURCE_ONLY; - case "all", "any" -> RaycastContext.FluidHandling.ANY; - default -> throw new RuntimeError("'%s' is not a valid fluid type".formatted(string)); - }; - } - - public static Hand stringToHand(String string) { - return switch (string.toLowerCase()) { - case "main", "main_hand" -> Hand.MAIN_HAND; - case "off", "off_hand" -> Hand.OFF_HAND; - default -> throw new RuntimeError("'%s' is not a valid hand".formatted(string)); - }; - } - - public static SlotActionType stringToSlotActionType(String string) { - return switch (string.toLowerCase()) { - case "click", "pickup" -> SlotActionType.PICKUP; - case "shift_click", "quick_move" -> SlotActionType.QUICK_MOVE; - case "swap" -> SlotActionType.SWAP; - case "middle_click", "clone" -> SlotActionType.CLONE; - case "throw" -> SlotActionType.THROW; - case "drag", "quick_craft" -> SlotActionType.QUICK_CRAFT; - case "double_click", "pickup_all" -> SlotActionType.PICKUP_ALL; - default -> throw new RuntimeError("Invalid slotActionType, see Wiki"); - }; - } - - public static NbtElement stringToNbt(String string) { - try { - return new StringNbtReader(new StringReader(string)).parseElement(); - } catch (CommandSyntaxException cse) { - throw new RuntimeError("'%s' couldn't be parsed".formatted(string)); - } - } - - // public static ItemStack stringToItemStack(String string) { - // try { - // RegistryWrapper wrapper = CommandRegister.getRegistryAccess().createWrapper(RegistryKeys.ITEM); - // ItemStringReader.ItemResult reader = ItemStringReader.item(wrapper, new StringReader(string)); - // ItemStack itemStack = new ItemStack(reader.item()); - // itemStack.setNbt(reader.nbt()); - // return itemStack; - // } catch (CommandSyntaxException cse) { - // NbtElement element = stringToNbt(string); - // if (element instanceof NbtCompound nbtCompound) { - // return ItemStack.fromNbt(nbtCompound); - // } - // throw new RuntimeError("'%s' couldn't be parsed".formatted(string)); - // } - // } - - public static Text instanceToText(ClassInstance instance, Interpreter interpreter) { - Text text = instance.getPrimitive(TextDef.class); - return text != null ? text : Text.literal(instance.toString(interpreter)); - } - - public static ArucasMap nbtToMap(Interpreter interpreter, NbtCompound compound, int depth) { - ArucasMap nbtMap = new ArucasMap(); - depth--; - if (compound == null || depth < 0) { - return nbtMap; - } - for (String tagName : compound.getKeys()) { - NbtElement element = compound.get(tagName); - if (element == null) { - continue; - } - nbtMap.put(interpreter, interpreter.create(StringDef.class, tagName), nbtToValue(interpreter, element, depth)); - } - return nbtMap; - } - - public static ArucasList nbtToList(Interpreter interpreter, AbstractNbtList list, int depth) { - ArucasList nbtList = new ArucasList(); - depth--; - if (list == null || depth < 0) { - return nbtList; - } - for (NbtElement element : list) { - nbtList.add(nbtToValue(interpreter, element, depth)); - } - return nbtList; - } - - public static ClassInstance nbtToValue(Interpreter interpreter, NbtElement element, int depth) { - if (element instanceof NbtCompound inCompound) { - return interpreter.create(MapDef.class, nbtToMap(interpreter, inCompound, depth)); - } - if (element instanceof AbstractNbtList nbtList) { - return interpreter.create(ListDef.class, nbtToList(interpreter, nbtList, depth)); - } - if (element instanceof AbstractNbtNumber nbtNumber) { - return interpreter.create(NumberDef.class, nbtNumber.doubleValue()); - } - if (element == NbtEnd.INSTANCE) { - return interpreter.getNull(); - } - return interpreter.create(StringDef.class, element.asString()); - } - - public static NbtCompound mapToNbt(Interpreter interpreter, ArucasMap map, int depth) { - NbtCompound compound = new NbtCompound(); - if (map == null || depth < 0) { - return compound; - } - for (Pair values : map.pairSet()) { - compound.put(values.component1().toString(interpreter), valueToNbt(interpreter, values.component2(), depth)); - } - return compound; - } - - public static NbtList collectionToNbt(Interpreter interpreter, Collection collection, int depth) { - NbtList list = new NbtList(); - if (collection == null || depth < 0) { - return list; - } - for (ClassInstance instance : collection) { - NbtElement element = valueToNbt(interpreter, instance, depth); - // Doing it like this avoids the throwing of an error - list.addElement(list.size(), element); - } - return list; - } - - public static NbtElement valueToNbt(Interpreter interpreter, ClassInstance value, int depth) { - Object primitive = value.getPrimitive(MapDef.class); - if (primitive != null) { - return mapToNbt(interpreter, (ArucasMap) primitive, depth); - } - if ((primitive = value.getPrimitive(CollectionDef.class)) != null) { - return collectionToNbt(interpreter, ((ArucasCollection) primitive).asCollection(), depth); - } - if ((primitive = value.getPrimitive(NumberDef.class)) != null) { - return NbtDouble.of((double) primitive); - } - if (value == interpreter.getNull()) { - return NbtEnd.INSTANCE; - } - return NbtString.of(value.toString(interpreter)); - } - - public static ClassInstance mapToRule(ArucasMap map, Interpreter interpreter) { - String type = getFieldInMap(map, interpreter, "type", StringDef.class); - if (type == null) { - throw new RuntimeError("Config map must contain 'type' that is a string"); - } - String name = getFieldInMap(map, interpreter, "name", StringDef.class); - if (name == null) { - throw new RuntimeError("Config map must contain 'name' that is a string"); - } - - String description = getFieldInMap(map, interpreter, "description", StringDef.class); - String optionalInfo = getFieldInMap(map, interpreter, "optional_info", StringDef.class); - String currentValue = getFieldInMap(map, interpreter, "value", StringDef.class); - String category = getFieldInMap(map, interpreter, "category", StringDef.class); - ArucasFunction function = getFieldInMap(map, interpreter, "listener", FunctionDef.class); - int maxLength = Objects.requireNonNullElse(getFieldInMap(map, interpreter, "max_length", NumberDef.class), 32).intValue(); - - ClassInstance defaultValue = map.get(interpreter, interpreter.create(StringDef.class, "default_value")); - ClientRule clientRule = switch (type.toLowerCase()) { - case "boolean" -> { - Boolean bool = defaultValue == null ? null : defaultValue.getPrimitive(BooleanDef.class); - if (bool != null) { - yield new BooleanClientRule(name, description, bool, category); - } - yield new BooleanClientRule(name, description, category); - } - case "cycle" -> { - ArucasList list = getFieldInMap(map, interpreter, "cycle_values", ListDef.class); - if (list == null) { - throw new RuntimeError("'cycle' type must have 'cycle_values' as a list"); - } - - List cycles = new ArrayList<>(); - for (ClassInstance classInstance : list) { - cycles.add(classInstance.toString(interpreter)); - } - - String defaultCycle = defaultValue == null ? null : defaultValue.getPrimitive(StringDef.class); - if (defaultCycle != null) { - yield new CycleClientRule(name, description, cycles, defaultCycle, category, null); - } - yield new CycleClientRule(name, description, cycles, category); - } - case "double" -> { - Double defaultNumber = defaultValue == null ? null : defaultValue.getPrimitive(NumberDef.class); - if (defaultNumber != null) { - yield new DoubleClientRule(name, description, defaultNumber, category); - } - yield new DoubleClientRule(name, description, 0.0D, category); - } - case "double_slider" -> { - Double min = getFieldInMap(map, interpreter, "min", NumberDef.class); - if (min == null) { - throw new RuntimeError("'double_slider' type must have 'min' as a number"); - } - Double max = getFieldInMap(map, interpreter, "max", NumberDef.class); - if (max == null) { - throw new RuntimeError("'double_slider' type must have 'max' as a number"); - } - - Double defaultNumber = defaultValue == null ? null : defaultValue.getPrimitive(NumberDef.class); - if (defaultNumber != null) { - yield new DoubleSliderClientRule(name, description, defaultNumber, category, min, max); - } - yield new DoubleSliderClientRule(name, description, 0.0D, category, min, max); - } - case "integer" -> { - Double defaultNumber = defaultValue == null ? null : defaultValue.getPrimitive(NumberDef.class); - if (defaultNumber != null) { - yield new IntegerClientRule(name, description, defaultNumber.intValue(), category); - } - yield new IntegerClientRule(name, description, 0, category); - } - case "integer_slider" -> { - Double min = getFieldInMap(map, interpreter, "min", NumberDef.class); - if (min == null) { - throw new RuntimeError("'integer_slider' type must have 'min' as a number"); - } - Double max = getFieldInMap(map, interpreter, "max", NumberDef.class); - if (max == null) { - throw new RuntimeError("'integer_slider' type must have 'max' as a number"); - } - - Number defaultNumber = defaultValue == null ? null : defaultValue.getPrimitive(NumberDef.class); - if (defaultNumber != null) { - yield new IntegerSliderClientRule(name, description, defaultNumber.intValue(), category, min.intValue(), max.intValue()); - } - yield new IntegerSliderClientRule(name, description, 0, category, min.intValue(), max.intValue()); - } - case "list" -> { - List configData = new ArrayList<>(); - ArucasList defaultList = defaultValue == null ? null : defaultValue.getPrimitive(ListDef.class); - if (defaultList != null) { - for (ClassInstance listValue : defaultList) { - configData.add(listValue.toString(interpreter)); - } - } - ListClientRule listClientRule = new ListClientRule(name, description, configData, category); - listClientRule.setMaxLength(maxLength); - yield listClientRule; - } - case "string" -> { - StringClientRule stringClientRule = new StringClientRule(name, description, defaultValue == null ? "" : defaultValue.toString(interpreter), category); - stringClientRule.setMaxLength(maxLength); - yield stringClientRule; - } - default -> throw new RuntimeError("Invalid config type '%s'".formatted(type)); - }; - - ClassInstance instance = interpreter.convertValue(clientRule); - if (function != null) { - Interpreter parent = interpreter.branch(); - clientRule.addListener(object -> { - parent.runAsync(() -> { - function.invoke(parent.branch(), List.of(instance)); - return null; - }); - }); - } - if (currentValue != null) { - clientRule.setValueFromString(currentValue); - } - - clientRule.setOptionalInfo(optionalInfo); - return instance; - } - - public static ArgumentBuilder mapToCommand(ArucasMap arucasMap, Interpreter interpreter) { - return new CommandParser(arucasMap, interpreter).parse(); - } - - public static RequiredArgumentBuilder parseArgument( - String argumentName, - String typeName, - Collection suggests, - CommandParser.ArgumentGetter getter - ) { - SuggestionProvider extraSuggestion = null; - ArgumentType type = switch (typeName.toLowerCase()) { - case "word" -> StringArgumentType.word(); - case "string", "quote" -> StringArgumentType.word(); - case "boolean" -> BoolArgumentType.bool(); - case "itemstack" -> ItemStackArgumentType.itemStack(CommandRegister.getRegistryAccess()); - case "block" -> BlockStateArgumentType.blockState(CommandRegister.getRegistryAccess()); - case "greedystring" -> StringArgumentType.greedyString(); - case "entity" -> ClientEntityArgumentType.entity(); - case "entities" -> ClientEntityArgumentType.entities(); - case "blockpos" -> BlockPosArgumentType.blockPos(); - case "pos" -> Vec3ArgumentType.vec3(); - case "effect" -> RegistryEntryReferenceArgumentType.registryEntry(CommandRegister.getRegistryAccess(), RegistryKeys.STATUS_EFFECT); - case "particle" -> ParticleEffectArgumentType.particleEffect(CommandRegister.getRegistryAccess()); - case "enchantmentid" -> RegistryEntryReferenceArgumentType.registryEntry(CommandRegister.getRegistryAccess(), RegistryKeys.ENCHANTMENT); - case "entityid" -> { - extraSuggestion = SuggestionProviders.SUMMONABLE_ENTITIES; - yield RegistryEntryReferenceArgumentType.registryEntry(CommandRegister.getRegistryAccess(), RegistryKeys.ENTITY_TYPE); - } - case "recipeid" -> { - extraSuggestion = SuggestionProviders.ALL_RECIPES; - yield IdentifierArgumentType.identifier(); - } - case "biomeid" -> RegistryEntryReferenceArgumentType.registryEntry(CommandRegister.getRegistryAccess(), RegistryKeys.BIOME); - case "playername" -> { - extraSuggestion = (c, b) -> CommandHelper.suggestOnlinePlayers(b); - yield StringArgumentType.word(); - } - case "double" -> { - Double min = getter == null ? null : getter.get("min", NumberDef.class); - if (min != null) { - Double max = getter.get("max", NumberDef.class); - if (max != null) { - yield DoubleArgumentType.doubleArg(min, max); - } - yield DoubleArgumentType.doubleArg(min); - } - yield DoubleArgumentType.doubleArg(); - } - case "integer" -> { - Double min = getter == null ? null : getter.get("min", NumberDef.class); - if (min != null) { - Double max = getter.get("max", NumberDef.class); - if (max != null) { - yield IntegerArgumentType.integer(min.intValue(), max.intValue()); - } - yield IntegerArgumentType.integer(min.intValue()); - } - yield IntegerArgumentType.integer(); - } - case "enum" -> { - ClassDefinition definition = getter == null ? null : getter.get("enum", TypeDef.class); - if (definition instanceof EnumDefinition enumDefinition) { - yield DefinitionArgumentType.enumeration(enumDefinition); - } - throw new RuntimeError("Enum argument type must contain 'enum: '"); - } - default -> throw new RuntimeError("Invalid argument type"); - }; - - RequiredArgumentBuilder argumentBuilder = CommandManager.argument(argumentName, type); - if (extraSuggestion != null) { - argumentBuilder.suggests(extraSuggestion); - } - if (suggests != null) { - argumentBuilder.suggests((c, b) -> CommandSource.suggestMatching(suggests, b)); - } - return argumentBuilder; - } - - public static ClassInstance commandArgumentToValue(Object object, Interpreter interpreter) throws CommandSyntaxException { - // We check for these two here since they throw CommandSyntaxExceptions - if (object instanceof PosArgument posArgument) { - object = posArgument.toAbsolutePos(new FakeCommandSource(EssentialUtils.getPlayer())); - } - if (object instanceof ClientEntitySelector selector) { - FakeCommandSource source = new FakeCommandSource(EssentialUtils.getPlayer()); - object = selector.isSingleTarget() ? selector.getEntity(source) : selector.getEntities(source); - } - if (object instanceof RegistryEntry.Reference reference) { - return interpreter.convertValue(reference.value()); - } - return interpreter.convertValue(object); - } - - private static , V> V getFieldInMap(ArucasMap map, Interpreter interpreter, String field, Class type) { - ClassInstance instance = map.get(interpreter, interpreter.create(StringDef.class, field)); - return instance == null ? null : instance.getPrimitive(type); - } - - public static class TickedKey { - private final KeyBinding binding; - private final int interval; - private int tick = 0; - - public TickedKey(KeyBinding binding, int interval) { - this.binding = binding; - this.interval = interval; - } - - void tick() { - if (this.tick++ >= this.interval) { - this.binding.setPressed(true); - InputUtil.Key key = ((KeyBindingAccessor) this.binding).getBoundKey(); - KeyBinding.onKeyPressed(key); - this.tick = 0; - } - } - } - - public static class CommandParser { - public static final SimpleCommandExceptionType NO_ARGS = new SimpleCommandExceptionType(Texts.NO_ARGUMENTS); - - private final Interpreter interpreter; - private final String commandName; - private final ArucasMap subCommandMap; - private final ArucasMap argumentMap; - - CommandParser(ArucasMap commandMap, Interpreter interpreter) { - this.interpreter = interpreter.branch(); - - this.commandName = getFieldInMap(commandMap, interpreter, "name", StringDef.class); - if (this.commandName == null) { - throw new RuntimeError("Command map must contain 'name: '"); - } - - this.subCommandMap = getFieldInMap(commandMap, interpreter, "subcommands", MapDef.class); - this.argumentMap = getFieldInMap(commandMap, interpreter, "arguments", MapDef.class); - } - - ArgumentBuilder parse() { - LiteralArgumentBuilder baseCommand = CommandManager.literal(this.commandName); - if (this.subCommandMap == null) { - return baseCommand; - } - return this.command(baseCommand, this.subCommandMap); - } - - private ArgumentBuilder command(ArgumentBuilder parent, ArucasMap childMap) { - for (Pair pair : childMap.pairSet()) { - String key = pair.component1().getPrimitive(StringDef.class); - if (key == null) { - throw new RuntimeError("Expected string value in subcommand map"); - } - if (key.isBlank()) { - ArucasFunction function = pair.component2().getPrimitive(FunctionDef.class); - if (function == null) { - throw new RuntimeError("Expected function value"); - } - parent.executes(c -> { - Collection> arguments = CommandHelper.getArguments(c); - if (arguments == null) { - throw NO_ARGS.create(); - } - List list = new ArrayList<>(arguments.size()); - for (ParsedArgument argument : arguments) { - list.add(commandArgumentToValue(argument.getResult(), this.interpreter)); - } - this.interpreter.runAsync(() -> { - function.invoke(this.interpreter.branch(), list); - return null; - }); - return 1; - }); - continue; - } - ArucasMap value = pair.component2().getPrimitive(MapDef.class); - if (value == null) { - throw new RuntimeError("Expected map value for '%s'".formatted(key)); - } - String[] arguments = key.split(" "); - if (arguments.length > 1) { - ArgumentBuilder current = this.subCommand(arguments[arguments.length - 1], value); - for (int i = arguments.length - 2; i >= 0; i--) { - String name = arguments[i]; - current = this.connectedCommand(name).then(current); - } - parent.then(current); - continue; - } - parent.then(this.subCommand(key, value)); - } - return parent; - } - - private ArgumentBuilder subCommand(String string, ArucasMap childMap) { - return this.command(this.connectedCommand(string), childMap); - } - - private ArgumentBuilder connectedCommand(String string) { - if (string.charAt(0) != '<' || string.charAt(string.length() - 1) != '>') { - return CommandManager.literal(string); - } - string = string.substring(1, string.length() - 1); - if (this.argumentMap != null) { - ArucasMap subMap = getFieldInMap(this.argumentMap, this.interpreter, string, MapDef.class); - if (subMap != null) { - return this.getArgument(string, subMap); - } - } - throw new RuntimeError("Expected map value for argument '%s'".formatted(string)); - } - - private ArgumentBuilder getArgument(String name, ArucasMap arguments) { - String argument = getFieldInMap(arguments, this.interpreter, "type", StringDef.class); - if (argument == null) { - throw new RuntimeError("Expected string for 'type' for argument '%s'".formatted(name)); - } - - List suggestions = null; - ArucasList suggests = getFieldInMap(arguments, this.interpreter, "suggests", ListDef.class); - if (suggests != null) { - suggestions = suggests.stream().map(i -> i.toString(this.interpreter)).toList(); - } - RequiredArgumentBuilder argumentBuilder = parseArgument(name, argument, suggestions, new ArgumentGetter() { - @Override - public , V> V get(String fieldName, Class clazz) { - return getFieldInMap(arguments, CommandParser.this.interpreter, fieldName, clazz); - } - }); - - ArucasFunction suggester = getFieldInMap(arguments, this.interpreter, "suggester", FunctionDef.class); - if (suggester != null) { - argumentBuilder.suggests((c, b) -> { - Collection> commandArguments = CommandHelper.getArguments(c); - if (commandArguments == null) { - throw NO_ARGS.create(); - } - Interpreter branch = this.interpreter.branch(); - List list = new ArrayList<>(); - for (ParsedArgument arg : commandArguments) { - list.add(commandArgumentToValue(arg.getResult(), branch)); - } - return branch.runSafe(Suggestions.empty(), (Supplier>) () -> { - ArucasCollection collection = suggester.invoke(branch, list).getPrimitive(CollectionDef.class); - if (collection != null) { - List suggested = collection.asCollection().stream().map(i -> i.toString(branch)).toList(); - return CommandSource.suggestMatching(suggested, b); - } - throw new RuntimeError("Suggester did not return a list"); - }); - }); - } - return argumentBuilder; - } - - public interface ArgumentGetter { - , V> V get(String fieldName, Class clazz); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/ClientTickSyncer.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/ClientTickSyncer.java deleted file mode 100644 index af061b0f..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/ClientTickSyncer.java +++ /dev/null @@ -1,35 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript; - -import me.senseiwells.arucas.utils.impl.ArucasThread; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; - -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -public class ClientTickSyncer { - private static final Set FROZEN_THREADS = ConcurrentHashMap.newKeySet(); - - static { - ClientTickEvents.END_CLIENT_TICK.register(c -> ClientTickSyncer.triggerSync()); - } - - public static void load() { } - - public synchronized static void syncToTick() { - if (Thread.currentThread() instanceof ArucasThread arucasThread) { - FROZEN_THREADS.add(arucasThread); - arucasThread.freeze(); - return; - } - throw new RuntimeException("Tried to sync non Arucas Thread"); - } - - public synchronized static void triggerSync() { - if (!FROZEN_THREADS.isEmpty()) { - for (ArucasThread thread : FROZEN_THREADS) { - thread.thaw(); - } - FROZEN_THREADS.clear(); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/DocGenerator.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/DocGenerator.java deleted file mode 100644 index 80ae8ca0..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/DocGenerator.java +++ /dev/null @@ -1,81 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript; - -import joptsimple.OptionParser; -import joptsimple.OptionSet; -import joptsimple.OptionSpec; -import me.senseiwells.arucas.api.ArucasAPI; -import me.senseiwells.arucas.api.docs.visitor.ArucasDocParser; -import me.senseiwells.arucas.api.docs.visitor.impl.JsonDocVisitor; -import me.senseiwells.arucas.api.docs.visitor.impl.MarkdownDocVisitor; -import me.senseiwells.arucas.api.docs.visitor.impl.VSCSnippetDocVisitor; -import me.senseiwells.arucas.utils.FileUtils; -import me.senseiwells.arucas.utils.NetworkUtils; -import me.senseiwells.essentialclient.clientscript.core.ClientScriptInstance; -import me.senseiwells.essentialclient.utils.misc.WikiParser; -import net.fabricmc.api.ModInitializer; -import net.fabricmc.loader.api.FabricLoader; -import org.apache.logging.log4j.LogManager; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -// Ripped from carpet -public class DocGenerator implements ModInitializer { - @Override - public void onInitialize() { - String[] launchArgs = FabricLoader.getInstance().getLaunchArguments(true); - - // Prepare an OptionParser for our parameters - OptionParser parser = new OptionParser(); - OptionSpec pathSpec = parser.accepts("generate").withRequiredArg(); - - // Minecraft may need more stuff later that we don't want to special-case - parser.allowsUnrecognizedOptions(); - OptionSet options = parser.parse(launchArgs); - - // If our flag isn't set, continue regular launch - if (!options.has(pathSpec)) { - return; - } - - Path path = FileUtils.ensureExists(Path.of(options.valueOf(pathSpec))); - ArucasAPI api = ClientScriptInstance.getApi(); - Path libPath = FileUtils.ensureExists(path.resolve("libs")); - Path docPath = FileUtils.ensureExists(path.getParent().resolve("docs")); - Path jsonPath = FileUtils.ensureExists(path.resolve("json")); - Path mdPath = FileUtils.ensureExists(path.resolve("markdown")); - Path snippetPath = FileUtils.ensureExists(path.resolve("snippets")); - - JsonDocVisitor jsonVisitor = new JsonDocVisitor(); - MarkdownDocVisitor markdownVisitor = new MarkdownDocVisitor(); - VSCSnippetDocVisitor snippetVisitor = new VSCSnippetDocVisitor(); - - new ArucasDocParser(api).addVisitors(jsonVisitor, markdownVisitor, snippetVisitor).parse(); - - try { - Files.writeString(jsonPath.resolve("AllDocs.json"), jsonVisitor.getJson()); - api.generateNativeFiles(libPath); - - Files.writeString(snippetPath.resolve("arucas.json"), snippetVisitor.getJson()); - - String extensions = markdownVisitor.getExtensions(); - String classes = markdownVisitor.getClasses(); - String events = ScriptMarkdownHelper.parseEvents(); - Files.writeString(mdPath.resolve("Extensions.md"), extensions); - Files.writeString(mdPath.resolve("Classes.md"), classes); - Files.writeString(mdPath.resolve("Events.md"), events); - - Files.writeString(FileUtils.ensureParentExists(docPath.resolve("wiki/Home.md")), WikiParser.generateWiki()); - - String full = NetworkUtils.getStringFromUrl("https://raw.githubusercontent.com/senseiwells/Arucas/main/docs/FullLang.md"); - full += "\n\n" + extensions; - full += "\n\n" + classes; - full += "\n\n" + events; - Files.writeString(docPath.resolve("Full.md"), full); - } catch (IOException e) { - LogManager.getLogger("DocGenerator").info("Failed to generate docs", e); - } - System.exit(0); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/FunctionClickEvent.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/FunctionClickEvent.java deleted file mode 100644 index 7c0084c4..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/FunctionClickEvent.java +++ /dev/null @@ -1,24 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript; - -import me.senseiwells.arucas.functions.ArucasFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import net.minecraft.text.ClickEvent; - -import java.util.List; -import java.util.function.Supplier; - -public class FunctionClickEvent extends ClickEvent { - private final Interpreter interpreter; - private final ArucasFunction function; - - public FunctionClickEvent(Interpreter interpreter, ArucasFunction function) { - super(Action.RUN_COMMAND, ""); - this.interpreter = interpreter.branch(); - this.function = function; - } - - public void executeFunction() { - Interpreter branch = this.interpreter.branch(); - branch.runSafe((Supplier) () -> this.function.invoke(branch, List.of())); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/MinecraftDeobfuscator.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/MinecraftDeobfuscator.java deleted file mode 100644 index e429d9db..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/MinecraftDeobfuscator.java +++ /dev/null @@ -1,254 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript; - -import com.google.common.net.UrlEscapers; -import com.google.gson.Gson; -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import net.fabricmc.loader.impl.lib.mappingio.MappedElementKind; -import net.fabricmc.loader.impl.lib.mappingio.MappingVisitor; -import net.fabricmc.loader.impl.lib.mappingio.format.tiny.Tiny2FileReader; -import org.apache.commons.io.FileUtils; -import org.jetbrains.annotations.Nullable; - -import java.io.*; -import java.net.URL; -import java.net.URLConnection; -import java.nio.charset.StandardCharsets; -import java.nio.file.FileSystem; -import java.nio.file.*; -import java.util.*; - -/** - * Taken mostly from NotEnoughCrashes - *

- * Modified to map Yarn -> Intermediary - */ -public final class MinecraftDeobfuscator { - /** - * This map will only contain class deobfuscation mappings since - * we don't care about methods, fields, etc. We only deobfuscate - * when obfuscating method names, and we need the deobfuscated class - * name to do so (to ensure we have the correct method + declaring class) - */ - private static final Map CLASS_DEOBFUSCATION_MAPPINGS; - private static final Map OBFUSCATION_MAPPINGS; - private static final String MAPPINGS_JAR_LOCATION; - private static final Path MAPPINGS_DIRECTORY; - private static final Path CACHED_MAPPINGS; - - private static boolean triedLoadingMappings; - - static { - OBFUSCATION_MAPPINGS = new HashMap<>(); - CLASS_DEOBFUSCATION_MAPPINGS = new HashMap<>(); - MAPPINGS_JAR_LOCATION = "mappings/mappings.tiny"; - triedLoadingMappings = false; - - MAPPINGS_DIRECTORY = EssentialUtils.getEssentialConfigFile().resolve("Mappings"); - try { - if (!Files.exists(MAPPINGS_DIRECTORY)) { - Files.createDirectory(MAPPINGS_DIRECTORY); - } - } catch (IOException e) { - EssentialClient.LOGGER.error("Failed to create Mappings directory"); - } - - CACHED_MAPPINGS = MAPPINGS_DIRECTORY.resolve("mappings-" + EssentialUtils.getMinecraftVersion() + ".tiny"); - - if (!Files.exists(CACHED_MAPPINGS)) { - downloadAndCacheMappings(); - } - } - - public static void load() { } - - public static String obfuscate(String name) { - if (!triedLoadingMappings) { - loadMappings(); - } - - String mapped = OBFUSCATION_MAPPINGS.get(name); - if (ClientRules.CLIENTSCRIPT_DEBUGGER.getValue()) { - EssentialClient.LOGGER.info("Obfuscating {} -> {}", name, Objects.requireNonNullElse(mapped, name)); - } - return mapped == null ? name : mapped; - } - - public static String deobfuscateClass(String name) { - if (!triedLoadingMappings) { - loadMappings(); - } - - String mapped = CLASS_DEOBFUSCATION_MAPPINGS.get(name); - if (ClientRules.CLIENTSCRIPT_DEBUGGER.getValue()) { - EssentialClient.LOGGER.info("Deobfuscating {} -> {}", name, Objects.requireNonNullElse(mapped, name)); - } - return mapped == null ? name : mapped; - } - - private static void downloadAndCacheMappings() { - String yarnVersion; - try { - yarnVersion = Yarn.getLatestYarn(); - } catch (Exception e) { - EssentialClient.LOGGER.error("Could not get latest yarn build for version"); - return; - } - - EssentialClient.LOGGER.info("Downloading deobfuscation mappings: " + yarnVersion + " for the first launch"); - - String encodedYarnVersion = UrlEscapers.urlFragmentEscaper().escape(yarnVersion); - // Download V2 jar - String artifactUrl = "https://maven.fabricmc.net/net/fabricmc/yarn/" + encodedYarnVersion + "/yarn-" + encodedYarnVersion + "-v2.jar"; - - File jarFile = MAPPINGS_DIRECTORY.resolve("yarn-mappings.jar").toFile(); - jarFile.deleteOnExit(); - - try { - FileUtils.copyURLToFile(new URL(artifactUrl), jarFile); - } catch (IOException e) { - EssentialClient.LOGGER.error("Failed to downloads mappings!", e); - return; - } - - try (FileSystem jar = FileSystems.newFileSystem(jarFile.toPath(), (ClassLoader) null)) { - Files.copy(jar.getPath(MAPPINGS_JAR_LOCATION), CACHED_MAPPINGS, StandardCopyOption.REPLACE_EXISTING); - } catch (IOException e) { - EssentialClient.LOGGER.error("Failed to extract mappings!", e); - } - } - - private static void loadMappings() { - if (!Files.exists(CACHED_MAPPINGS)) { - EssentialClient.LOGGER.warn("Could not download mappings"); - return; - } - - triedLoadingMappings = true; - try (BufferedReader mappingReader = Files.newBufferedReader(CACHED_MAPPINGS)) { - Tiny2FileReader.read(mappingReader, new MappingVisitorImpl()); - } catch (IOException e) { - EssentialClient.LOGGER.error("Could not load mappings", e); - } - } - - /** - * This maps Intermediary -> Yarn (For classes only), - * and also maps Yarn -> Intermediary - */ - private static class MappingVisitorImpl implements MappingVisitor { - private String fromClass; - private String toClass; - private String intermediary; - - @Override - public void visitNamespaces(String s, List list) { - - } - - @Override - public boolean visitClass(String s) { - this.fromClass = s.replace('/', '.'); - return true; - } - - @Override - public boolean visitField(String s, @Nullable String s1) { - this.intermediary = s; - return true; - } - - @Override - public boolean visitMethod(String s, @Nullable String s1) { - this.intermediary = s; - return true; - } - - @Override - public boolean visitMethodArg(int i, int i1, @Nullable String s) { - return true; - } - - @Override - public boolean visitMethodVar(int i, int i1, int i2, int i3, @Nullable String s) { - return true; - } - - @Override - public void visitDstName(MappedElementKind mappedElementKind, int i, String s) { - if (s.equals("")) { - return; - } - - if (mappedElementKind == MappedElementKind.CLASS) { - this.toClass = s.replace('/', '.'); - CLASS_DEOBFUSCATION_MAPPINGS.put(this.fromClass, this.toClass); - OBFUSCATION_MAPPINGS.put(this.toClass, this.fromClass); - return; - } - - String from = this.fromClass + "#" + this.intermediary; - String to = this.toClass + "#" + s; - if (mappedElementKind == MappedElementKind.METHOD) { - from += "()"; - to += "()"; - } else if (mappedElementKind != MappedElementKind.FIELD) { - return; - } - - OBFUSCATION_MAPPINGS.put(to, from); - } - - @Override - public void visitComment(MappedElementKind mappedElementKind, String s) { - - } - } - - @SuppressWarnings("unused") - private static class Yarn { - private static final String YARN_API_ENTRYPOINT; - private static final Path YARN_VERSION; - private static String VERSION_CACHE; // Checkstyle ignore - - public String gameVersion; - public String separator; - public int build; - public String maven; - public String version; - public boolean stable; - - static { - YARN_API_ENTRYPOINT = "https://meta.fabricmc.net/v2/versions/yarn/" + EssentialUtils.getMinecraftVersion(); - YARN_VERSION = MAPPINGS_DIRECTORY.resolve("yarn-version.txt"); - } - - private static String getLatestYarn() throws IOException { - if (VERSION_CACHE == null) { - if (!Files.exists(YARN_VERSION)) { - URL url = new URL(YARN_API_ENTRYPOINT); - URLConnection request = url.openConnection(); - request.connect(); - - InputStream response = (InputStream) request.getContent(); - Yarn[] versions = new Gson().fromJson(new InputStreamReader(response), Yarn[].class); - if (versions.length == 0) { - throw new IllegalStateException("No yarn versions were received at the API endpoint. Received json: " + getString(response)); - } - String version = Arrays.stream(versions).max(Comparator.comparingInt(v -> v.build)).get().version; - Files.write(YARN_VERSION, version.getBytes()); - VERSION_CACHE = version; - } else { - VERSION_CACHE = new String(Files.readAllBytes(YARN_VERSION)); - } - } - - return VERSION_CACHE; - } - - private static String getString(InputStream inputStream) throws IOException { - return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/PosIterator.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/PosIterator.java deleted file mode 100644 index af2e758d..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/PosIterator.java +++ /dev/null @@ -1,47 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript; - -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.utils.impl.ArucasIterator; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptBlockState; -import net.minecraft.block.BlockState; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; - -import java.util.Iterator; -import java.util.function.Function; - -public class PosIterator implements ArucasIterator { - final Iterator blockPosIterator; - final Function converter; - - public PosIterator(Iterator posIterator, Function converter) { - this.blockPosIterator = posIterator; - this.converter = converter; - } - - @Override - public boolean hasNext() { - return this.blockPosIterator.hasNext(); - } - - @Override - public ClassInstance next() { - return this.converter.apply(this.blockPosIterator.next()); - } - - public static class Block extends PosIterator { - private final World world; - - public Block(World world, Iterator posIterator, Function converter) { - super(posIterator, converter); - this.world = world; - } - - @Override - public ClassInstance next() { - BlockPos pos = this.blockPosIterator.next(); - BlockState state = this.world.getBlockState(pos); - return this.converter.apply(new ScriptBlockState(state, pos)); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/ScreenRemapper.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/ScreenRemapper.java deleted file mode 100644 index 6c0836eb..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/ScreenRemapper.java +++ /dev/null @@ -1,89 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript; - -import net.minecraft.client.gui.screen.*; -import net.minecraft.client.gui.screen.advancement.AdvancementsScreen; -import net.minecraft.client.gui.screen.ingame.*; -import net.minecraft.client.gui.screen.multiplayer.SocialInteractionsScreen; -import net.minecraft.client.gui.screen.option.*; -import net.minecraft.client.gui.screen.pack.PackScreen; -import net.minecraft.client.gui.screen.world.EditGameRulesScreen; -import net.minecraft.client.gui.screen.world.EditWorldScreen; -import net.minecraft.client.gui.screen.world.PresetsScreen; -import net.minecraft.client.realms.gui.screen.DisconnectedRealmsScreen; -import net.minecraft.util.Util; - -import java.util.LinkedHashMap; -import java.util.Map; - -public class ScreenRemapper { - private static final Map, String> SCREEN_REMAPPER = Util.make(new LinkedHashMap<>(), map -> { - map.put(AccessibilityOptionsScreen.class, "AccessibilityOptions"); - map.put(AdvancementsScreen.class, "Advancement"); - map.put(AnvilScreen.class, "Anvil"); - map.put(BeaconScreen.class, "Beacon"); - map.put(BlastFurnaceScreen.class, "BlastFurnace"); - map.put(BookEditScreen.class, "BookEdit"); - map.put(BookScreen.class, "BookScreen"); - map.put(BrewingStandScreen.class, "BrewingStand"); - map.put(CartographyTableScreen.class, "CartographyTable"); - map.put(ChatOptionsScreen.class, "ChatOptions"); - map.put(ChatScreen.class, "Chat"); - map.put(CommandBlockScreen.class, "CommandBlock"); - map.put(ConfirmLinkScreen.class, "ConfirmChatLink"); - map.put(ConfirmScreen.class, "Confirm"); - map.put(ControlsOptionsScreen.class, "ControlOptions"); - map.put(CraftingScreen.class, "Crafting"); - map.put(CreativeInventoryScreen.class, "CreativeInventory"); - map.put(CreditsScreen.class, "Credits"); - map.put(DeathScreen.class, "Death"); - map.put(DialogScreen.class, "Dialog"); - map.put(DisconnectedRealmsScreen.class, "DisconnectedRealms"); - map.put(DisconnectedScreen.class, "Disconnected"); - map.put(EditGameRulesScreen.class, "EditGameRules"); - map.put(EditWorldScreen.class, "EditWorld"); - map.put(EnchantmentScreen.class, "Enchantment"); - map.put(ForgingScreen.class, "Forging"); - map.put(FurnaceScreen.class, "Furnace"); - map.put(GameMenuScreen.class, "GameMenu"); - map.put(GameModeSelectionScreen.class, "GameModeSelection"); - map.put(GameOptionsScreen.class, "GameOptions"); - map.put(Generic3x3ContainerScreen.class, "Generic3x3Container"); - map.put(GenericContainerScreen.class, "GenericContainer"); - map.put(GrindstoneScreen.class, "Grindstone"); - map.put(HopperScreen.class, "Hopper"); - map.put(HorseScreen.class, "Horse"); - map.put(InventoryScreen.class, "Inventory"); - map.put(JigsawBlockScreen.class, "JigsawBlock"); - map.put(LanguageOptionsScreen.class, "LanguageOptions"); - map.put(LecternScreen.class, "Lectern"); - map.put(LoomScreen.class, "LoomScreen"); - map.put(MerchantScreen.class, "Merchant"); - map.put(MinecartCommandBlockScreen.class, "MinecrartCommandBlock"); - map.put(MouseOptionsScreen.class, "MouseOptions"); - map.put(NoticeScreen.class, "Notice"); - map.put(OpenToLanScreen.class, "OpenToLan"); - map.put(OptionsScreen.class, "Options"); - map.put(OutOfMemoryScreen.class, "OutOfMemory"); - map.put(PackScreen.class, "Pack"); - map.put(PresetsScreen.class, "Presets"); - map.put(ProgressScreen.class, "Progress"); - map.put(MessageScreen.class, "SaveLevel"); - map.put(ShulkerBoxScreen.class, "ShulkerBox"); - map.put(SignEditScreen.class, "SignEdit"); - map.put(SkinOptionsScreen.class, "SkinOptions"); - map.put(SleepingChatScreen.class, "SleepingChat"); - map.put(SmithingScreen.class, "Smithing"); - map.put(SmokerScreen.class, "Smoker"); - map.put(SocialInteractionsScreen.class, "SocialInteractions"); - map.put(SoundOptionsScreen.class, "SoundOptions"); - map.put(StatsScreen.class, "Stats"); - map.put(StonecutterScreen.class, "Stonecutter"); - map.put(StructureBlockScreen.class, "StructureBlock"); - map.put(VideoOptionsScreen.class, "VideoOptions"); - }); - - public static String getScreenName(Class screen) { - String screenName = SCREEN_REMAPPER.get(screen); - return screenName != null ? screenName : screen.getSimpleName().replaceFirst("Screen$", ""); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/ScriptMarkdownHelper.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/ScriptMarkdownHelper.java deleted file mode 100644 index ff3d91fc..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/ScriptMarkdownHelper.java +++ /dev/null @@ -1,53 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript; - -import me.senseiwells.essentialclient.clientscript.events.MinecraftScriptEvents; - -public class ScriptMarkdownHelper { - public static String parseEvents() { - StringBuilder builder = new StringBuilder("# Events\n\n"); - builder.append(""" - Events are triggers for certain events that happen in the game. - ClientScript provides a way to hook into these triggers to be able to run your code. - You can register multiple functions to an event and they will all get called. - See [here]() on how to register and unregister events. - Each event will run async by default but you are able to run it on the main game thread. - """ - ); - MinecraftScriptEvents.forEachEvent(e -> { - builder.append("\n\n"); - builder.append("## `\"").append(e.getName()).append("\"`\n"); - builder.append("- ").append(e.getDescription()).append("\n"); - String[] parameters = e.getParameters(); - String params = ""; - if (parameters.length % 3 == 0 && parameters.length != 0) { - params = addParameters(builder, parameters); - } - builder.append("- Cancellable: ").append(e.canCancel()).append("\n"); - builder.append("```kotlin\n"); - builder.append("new GameEvent(\"").append(e.getName()).append("\", fun("); - builder.append(params).append(") {\n"); - builder.append(" // Code\n});"); - builder.append("\n```\n"); - }); - return builder.toString(); - } - - private static String addParameters(StringBuilder builder, String[] parameters) { - int i = 0; - StringBuilder params = new StringBuilder(); - while (i < parameters.length) { - String type = parameters[i++]; - String name = parameters[i++]; - String desc = parameters[i++]; - params.append(name); - builder.append("- Parameter - ").append(type); - builder.append(" (`").append(name).append("`): "); - builder.append(desc); - builder.append("\n"); - if (i < parameters.length) { - params.append(", "); - } - } - return params.toString(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/ScriptRepositoryManager.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/ScriptRepositoryManager.java deleted file mode 100644 index d0cbb809..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/ScriptRepositoryManager.java +++ /dev/null @@ -1,223 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript; - -import com.google.gson.*; -import me.senseiwells.arucas.utils.NetworkUtils; -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.clientscript.core.ClientScript; -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.utils.render.Texts; -import net.minecraft.text.Text; - -import java.io.BufferedWriter; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.*; - -public class ScriptRepositoryManager { - private static final Gson GSON = new GsonBuilder().create(); - - public static final ScriptRepositoryManager INSTANCE = new ScriptRepositoryManager(); - - private final Map> children; - - private ScriptRepositoryManager() { - this.children = new HashMap<>(); - - ClientRules.CLIENT_SCRIPT_REPOS.addListener(v -> { - Thread thread = new Thread(() -> { - for (Category category : Category.values()) { - this.clearChildren(category); - this.loadChildren(category); - } - }, "ClientScriptRepoLoader"); - thread.setDaemon(false); - thread.start(); - }); - } - - public String getScriptFromWeb(Category category, String name, boolean fromCache) { - ScriptFile scriptFile = this.getScriptFromName(category, name); - if (scriptFile == null) { - return null; - } - if (fromCache && scriptFile.content != null) { - return scriptFile.content; - } - String content = NetworkUtils.getStringFromUrl(scriptFile.downloadUrl); - if (content == null) { - return null; - } - return scriptFile.content = content; - } - - // Returns true if download failed - public boolean downloadScript(Category category, String name, boolean overwrite) { - Set scriptFileSet = this.getChildren(category); - if (!scriptFileSet.contains(new ScriptFile(name, null, null))) { - return true; - } - Path scriptDir = ClientScript.INSTANCE.getScriptDirectory(); - Path newScript = scriptDir.resolve(name + ".arucas"); - if (!overwrite && Files.exists(newScript)) { - for (int i = 1; ; i++) { - newScript = scriptDir.resolve(name + i + ".arucas"); - if (!Files.exists(newScript)) { - break; - } - } - } - String fileContent = this.getScriptFromWeb(category, name, false); - if (fileContent != null) { - try (BufferedWriter writer = Files.newBufferedWriter(newScript)) { - writer.write(fileContent); - return false; - } catch (IOException ignored) { - - } - } - return true; - } - - public String getViewableLink(Category category, String scriptName) { - ScriptFile scriptFile = this.getScriptFromName(category, scriptName); - if (scriptFile == null || scriptFile.viewableUrl == null) { - return "https://github.com/senseiwells/clientscript"; - } - return scriptFile.viewableUrl; - } - - public List getChildrenNames(Category category) { - return this.getChildren(category).stream().map(scriptFile -> scriptFile.name).toList(); - } - - private ScriptFile getScriptFromName(Category category, String name) { - return this.getChildren(category).stream().filter(s -> s.name.equals(name)).findAny().orElse(null); - } - - private Set getChildren(Category category) { - if (!this.children.containsKey(category) && !this.loadChildren(category)) { - return Set.of(); - } - return this.children.get(category); - } - - // Can accept senseiwells/clientscript/tree/main/scripts, senseiwells/clientscript/scripts, senseiwells/clientscript, https links - private String getApiAddress(String targetString) { - if (targetString.startsWith("https://api.github.com/repos/")) { - return targetString; - } - if (targetString.startsWith("https://github.com/")) { - targetString = targetString.substring(19); - } - String[] split = targetString.split("/"); - if (targetString.contains("/tree/") || targetString.contains("/blob/")) { - if (split.length < 4) { - return targetString; - } - String authorName = split[0]; - String repositoryName = split[1]; - String branchName = split[3]; - return "https://api.github.com/repos/" + authorName + "/" + repositoryName + "/contents/scripts?ref=" + branchName; - } else { - if (split.length < 2) { - return targetString; - } - String authorName = split[0]; - String repositoryName = split[1]; - return "https://api.github.com/repos/" + authorName + "/" + repositoryName + "/contents/scripts"; - } - } - - private void clearChildren(Category category) { - if (!this.children.containsKey(category)) { - return; - } - this.children.get(category).clear(); - } - - private boolean loadChildren(Category category) { - for (String repo : ClientRules.CLIENT_SCRIPT_REPOS.getValue()) { - repo = this.getApiAddress(repo); - String reference = ""; - if (repo.contains("?")) { - reference = repo.substring(repo.indexOf("?")); - repo = repo.substring(0, repo.indexOf("?")); - } - String response = NetworkUtils.getStringFromUrl(repo + "/" + category.toString() + reference); - if (response == null) { - EssentialClient.LOGGER.error("Couldn't request data from: " + repo + "/" + category); - continue; - } - try { - JsonArray childrenFiles = GSON.fromJson(response, JsonArray.class); - Set scriptFileSet = new HashSet<>(); - for (JsonElement element : childrenFiles) { - JsonObject object = element.getAsJsonObject(); - String childName = object.get("name").getAsString(); - if (!childName.endsWith(".arucas")) { - continue; - } - childName = childName.substring(0, childName.length() - 7); - String childDownload = object.get("download_url").getAsString(); - JsonObject links = object.get("_links").getAsJsonObject(); - String viewableUrl = links.get("html").getAsString(); - scriptFileSet.add(new ScriptFile(childName, childDownload, viewableUrl)); - } - Set files = this.children.computeIfAbsent(category, c -> new LinkedHashSet<>()); - files.addAll(scriptFileSet); - } catch (Exception e) { - EssentialClient.LOGGER.error("Failed to load scripts from: " + repo, e); - } - } - return this.children.containsKey(category); - } - - private static class ScriptFile { - private final String name; - private final String downloadUrl; - private final String viewableUrl; - private String content; - - ScriptFile(String name, String downloadUrl, String viewableUrl) { - this.name = name; - this.downloadUrl = downloadUrl; - this.viewableUrl = viewableUrl; - this.content = null; - } - - @Override - public int hashCode() { - return this.name.hashCode(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - return o instanceof ScriptFile scriptFile && scriptFile.name.equals(this.name); - } - } - - public enum Category { - AUTOMATION(Texts.AUTOMATION), - UTILITIES(Texts.UTILITIES), - MISCELLANEOUS(Texts.MISCELLANEOUS); - - private final Text prettyName; - - Category(Text prettyName) { - this.prettyName = prettyName; - } - - public Text getPrettyName() { - return this.prettyName; - } - - @Override - public String toString() { - return this.name().toLowerCase(); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/ThreadSafeUtils.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/ThreadSafeUtils.java deleted file mode 100644 index 1159cb2b..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/ThreadSafeUtils.java +++ /dev/null @@ -1,54 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript; - -import me.senseiwells.essentialclient.mixins.clientScript.ClientWorldAccessor; -import me.senseiwells.essentialclient.utils.interfaces.IEntityList; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.world.EntityList; -import net.minecraft.world.World; - -import java.util.UUID; - -/** - * Utility class that makes some Minecraft - * operations, that aren't usually Thread - * safe, Thread safe. - */ -public class ThreadSafeUtils { - public static Entity[] getEntitiesSafe(ClientWorld world) { - EntityList entityList = ((ClientWorldAccessor) world).getEntityList(); - return ((IEntityList) entityList).essentialclient$getAllEntities(); - } - - public static PlayerEntity[] getPlayersSafe(World world) { - return world.getPlayers().toArray(PlayerEntity[]::new); - } - - public static PlayerEntity getClosestPlayer(World world, Entity entity, double maxDistance) { - double d = -1.0; - double x = entity.getX(); - double y = entity.getY(); - double z = entity.getZ(); - PlayerEntity playerEntity = null; - - for (PlayerEntity player : getPlayersSafe(world)) { - double e = player.squaredDistanceTo(x, y, z); - if (playerEntity != entity && (maxDistance < 0.0 || e < maxDistance * maxDistance) && (d == -1.0 || e < d)) { - d = e; - playerEntity = player; - } - } - - return playerEntity; - } - - public static PlayerEntity getPlayerByUuid(World world, UUID uuid) { - for (PlayerEntity player : getPlayersSafe(world)) { - if (uuid.equals(player.getUuid())) { - return player; - } - } - return null; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptBlockState.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptBlockState.java deleted file mode 100644 index 26743922..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptBlockState.java +++ /dev/null @@ -1,47 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript.impl; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.registry.Registries; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.BlockPos; - -public class ScriptBlockState implements ScriptMaterial { - public final BlockState state; - public final BlockPos pos; - - public ScriptBlockState(BlockState state, BlockPos pos) { - this.state = state; - this.pos = pos == null ? null : pos.toImmutable(); - } - - @Override - public Identifier getId() { - return Registries.BLOCK.getId(this.asBlock()); - } - - @Override - public String getTranslationKey() { - return this.asBlock().getTranslationKey(); - } - - @Override - public Block asBlock() { - return this.state.getBlock(); - } - - @Override - public BlockState asBlockState() { - return this.state; - } - - @Override - public Object asDefault() { - return this.state; - } - - @Override - public String asString() { - return this.state.toString(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptBox.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptBox.java deleted file mode 100644 index 5bdb4459..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptBox.java +++ /dev/null @@ -1,45 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript.impl; - -import me.senseiwells.arucas.interpreter.Interpreter; -import net.minecraft.util.math.Vec3d; - -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; - -public class ScriptBox extends ScriptShape.Cornered { - private static final Map> REGULAR_BOXES = new ConcurrentHashMap<>(); - private static final Map> IGNORE_DEPTH_BOXES = new ConcurrentHashMap<>(); - - public ScriptBox(Interpreter interpreter, Vec3d cornerA, Vec3d cornerB) { - super(interpreter, cornerA, cornerB); - } - - @Override - protected Map> getRegularDepthMap() { - return REGULAR_BOXES; - } - - @Override - protected Map> getIgnoreDepthMap() { - return IGNORE_DEPTH_BOXES; - } - - public static boolean hasRegular() { - return REGULAR_BOXES.size() > 0; - } - - public static boolean hasIgnoreDepth() { - return IGNORE_DEPTH_BOXES.size() > 0; - } - - public static void forEachRegular(Consumer consumer) { - REGULAR_BOXES.values().forEach(set -> set.forEach(s -> consumer.accept((ScriptBox) s))); - } - - public static void forEachIgnoreDepth(Consumer consumer) { - IGNORE_DEPTH_BOXES.values().forEach(set -> set.forEach(s -> consumer.accept((ScriptBox) s))); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptConfigHandler.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptConfigHandler.java deleted file mode 100644 index 61675b20..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptConfigHandler.java +++ /dev/null @@ -1,221 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript.impl; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.impl.ArucasList; -import me.senseiwells.essentialclient.clientscript.definitions.ConfigDef; -import me.senseiwells.essentialclient.gui.RulesScreen; -import me.senseiwells.essentialclient.gui.entries.BaseListEntry; -import me.senseiwells.essentialclient.rule.client.*; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.config.Config; -import me.senseiwells.essentialclient.utils.interfaces.Rule; -import net.minecraft.text.Text; - -import java.nio.file.Path; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; - -public class ScriptConfigHandler implements Config.CList { - private final Map configs; - private final Interpreter interpreter; - private final String name; - private Path path; - private boolean save; - - public ScriptConfigHandler(Interpreter interpreter, String name, boolean read) { - this.configs = new ConcurrentHashMap<>(); - this.interpreter = interpreter; - this.name = name; - this.save = true; - - if (read) { - this.readConfig(); - } - - interpreter.addStopEvent(() -> { - if (this.save) { - this.saveConfig(); - } - }); - } - - public RulesScreen createScreen(Text title, boolean alphabetical) { - return new RulesScreen(title, EssentialUtils.getClient().currentScreen) { - @Override - public Collection> getRules(String filter) { - return ScriptConfigHandler.this.configs.values().stream().map(i -> i.getPrimitive(ConfigDef.class)).toList(); - } - - @Override - public Comparator> entryComparator() { - return alphabetical ? super.entryComparator() : (a, b) -> 0; - } - - @Override - public boolean shouldCategorise() { - return true; - } - }; - } - - public void addConfig(ClassInstance instance) { - ClientRule rule = instance.getPrimitive(ConfigDef.class); - if (rule != null) { - this.configs.put(rule.getName(), instance); - } - } - - public void resetAllToDefault() { - this.forEachConfig(Rule::resetToDefault); - } - - public void removeConfig(String name) { - this.configs.remove(name); - } - - public ClassInstance getConfig(String name) { - return this.configs.get(name); - } - - public ArucasList getAllConfigs() { - return new ArucasList(this.configs.values()); - } - - public void setSaveOnClose(boolean save) { - this.save = save; - } - - public boolean willSaveOnClose() { - return this.save; - } - - public void setSavePath(Path path) { - this.path = path; - } - - @Override - public String getConfigName() { - return this.name; - } - - @Override - public JsonElement getSaveData() { - JsonArray array = new JsonArray(); - for (ClassInstance instance : this.configs.values()) { - array.add(instance.asPrimitive(ConfigDef.class).serialise()); - } - return array; - } - - @Override - public void readConfig(JsonArray array) { - for (JsonElement element : array) { - this.parse(element.getAsJsonObject()); - } - } - - @Override - public Path getConfigRootPath() { - return this.path == null ? CList.super.getConfigRootPath() : this.path; - } - - private void forEachConfig(Consumer> consumer) { - this.configs.values().forEach(i -> { - ClientRule rule = i.getPrimitive(ConfigDef.class); - consumer.accept(rule); - }); - } - - @SuppressWarnings("unchecked") - private void parse(JsonObject object) { - String name = object.get("name").getAsString(); - JsonElement value = object.get("value"); - - ClassInstance instance = this.configs.get(name); - if (instance != null) { - ClientRule config = (ClientRule) this.configs.get(name).getPrimitive(ConfigDef.class); - if (config != null) { - config.setValueQuietly(config.fromJson(value)); - return; - } - } - - String type = object.get("type").getAsString(); - - JsonElement objectElement = object.get("description"); - String description = objectElement != null && objectElement.isJsonPrimitive() ? objectElement.getAsString() : null; - - objectElement = object.get("optional_info"); - String optionalInfo = objectElement != null && objectElement.isJsonPrimitive() ? objectElement.getAsString() : null; - - objectElement = object.get("max_length"); - int maxLength = objectElement != null && objectElement.isJsonPrimitive() ? objectElement.getAsInt() : 32; - - objectElement = object.get("category"); - String category = objectElement != null && objectElement.isJsonPrimitive() ? objectElement.getAsString() : null; - - objectElement = object.get("display"); - boolean display = objectElement == null || (objectElement.isJsonPrimitive() && objectElement.getAsBoolean()); - - JsonElement defaultValue = object.get("default_value"); - ClientRule rule = (ClientRule) switch (type) { - case "boolean" -> new BooleanClientRule(name, description, defaultValue != null && defaultValue.getAsBoolean(), category); - case "cycle" -> { - JsonArray cycleValues = object.getAsJsonArray("cycle_values"); - - List cycles = new ArrayList<>(); - for (JsonElement element : cycleValues) { - cycles.add(element.getAsString()); - } - - if (defaultValue != null) { - yield new CycleClientRule(name, description, cycles, defaultValue.getAsString(), category, null); - } - yield new CycleClientRule(name, description, cycles, category); - } - case "double" -> new DoubleClientRule(name, description, defaultValue == null ? 0.0D : defaultValue.getAsDouble(), category); - case "double_slider" -> { - double min = object.get("min").getAsDouble(); - double max = object.get("max").getAsDouble(); - yield new DoubleSliderClientRule(name, description, defaultValue == null ? 0.0D : defaultValue.getAsDouble(), category, min, max); - } - case "integer" -> new IntegerClientRule(name, description, defaultValue == null ? 0 : defaultValue.getAsInt(), category); - case "integer_slider" -> { - int min = object.get("min").getAsInt(); - int max = object.get("max").getAsInt(); - yield new IntegerSliderClientRule(name, description, defaultValue == null ? 0 : defaultValue.getAsInt(), category, min, max); - } - case "list" -> { - List configData = new ArrayList<>(); - if (defaultValue != null && defaultValue.isJsonArray()) { - for (JsonElement element : defaultValue.getAsJsonArray()) { - configData.add(element.getAsString()); - } - } - ListClientRule listClientRule = new ListClientRule(name, description, configData, category); - listClientRule.setMaxLength(maxLength); - yield listClientRule; - } - case "string" -> { - StringClientRule stringClientRule = new StringClientRule(name, description, defaultValue == null ? "" : defaultValue.getAsString(), category); - stringClientRule.setMaxLength(maxLength); - yield stringClientRule; - } - default -> throw new IllegalArgumentException("Invalid config type '%s'".formatted(type)); - }; - - if (value != null) { - rule.setValueQuietly(rule.fromJson(value)); - } - - rule.setOptionalInfo(optionalInfo); - rule.display(display); - - this.configs.put(name, this.interpreter.create(ConfigDef.class, rule)); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptEvent.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptEvent.java deleted file mode 100644 index 2bd521c3..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptEvent.java +++ /dev/null @@ -1,72 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript.impl; - -import me.senseiwells.arucas.builtin.FunctionDef; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.compiler.Trace; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.essentialclient.clientscript.events.CancelEvent; -import me.senseiwells.essentialclient.clientscript.events.MinecraftScriptEvent; -import me.senseiwells.essentialclient.utils.EssentialUtils; - -import java.util.List; -import java.util.UUID; -import java.util.function.Supplier; - -public class ScriptEvent { - private final Interpreter interpreter; - private final MinecraftScriptEvent event; - private final ClassInstance function; - private final boolean cancellable; - - public ScriptEvent(Interpreter interpreter, MinecraftScriptEvent event, ClassInstance function, boolean cancellable) { - this.interpreter = interpreter.branch(); - this.event = event; - this.function = function; - this.cancellable = cancellable; - } - - public UUID getId() { - return this.interpreter.getProperties().getId(); - } - - public Interpreter getInterpreter() { - return this.interpreter.branch(); - } - - public boolean isRegistered() { - return this.event.isEventRegistered(this); - } - - public void register() { - this.event.registerEvent(this); - } - - public boolean unregister() { - return this.event.unregisterEvent(this); - } - - public boolean invoke(List arguments) { - Interpreter branch = this.interpreter.branch(); - int count = this.function.asPrimitive(FunctionDef.class).getCount(); - List newArgs = count >= 0 && count < arguments.size() ? arguments.subList(0, count) : arguments; - - if (this.event.isThreadDefinable() && !this.cancellable && EssentialUtils.getClient().isOnThread()) { - branch.runAsync(() -> { - branch.call(this.function, newArgs, Trace.INTERNAL); - return null; - }); - return false; - } - return branch.runSafe(false, (Supplier) () -> { - try { - branch.call(this.function, newArgs, Trace.INTERNAL); - return Boolean.FALSE; - } catch (CancelEvent cancelEvent) { - if (this.event.canCancel() && EssentialUtils.getClient().isOnThread()) { - return Boolean.TRUE; - } - throw cancelEvent; - } - }); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptFakeBlock.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptFakeBlock.java deleted file mode 100644 index c22fe097..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptFakeBlock.java +++ /dev/null @@ -1,80 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript.impl; - -import me.senseiwells.arucas.interpreter.Interpreter; -import net.minecraft.block.BlockState; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.Vec3d; - -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; - -public class ScriptFakeBlock extends ScriptShape { - private static final Map> REGULAR_BLOCKS = new ConcurrentHashMap<>(); - private static final Map> IGNORE_DEPTH_BLOCKS = new ConcurrentHashMap<>(); - - private Vec3d position; - private BlockState state; - private Direction direction; - private boolean cull; - - public ScriptFakeBlock(Interpreter interpreter, Vec3d position, BlockState state) { - super(interpreter); - this.position = position; - this.state = state; - this.direction = Direction.NORTH; - this.cull = true; - } - - public void setPosition(Vec3d position) { - this.position = position; - } - - public void setState(BlockState state) { - this.state = state; - } - - public void setDirection(Direction direction) { - this.direction = direction; - } - - public void setCull(boolean cull) { - this.cull = cull; - } - - public Vec3d getPosition() { - return this.position; - } - - public BlockState getState() { - return this.state; - } - - public Direction getDirection() { - return this.direction; - } - - public boolean shouldCull() { - return this.cull; - } - - @Override - protected Map> getRegularDepthMap() { - return REGULAR_BLOCKS; - } - - @Override - protected Map> getIgnoreDepthMap() { - return IGNORE_DEPTH_BLOCKS; - } - - public static void forEachRegular(Consumer consumer) { - REGULAR_BLOCKS.values().forEach(set -> set.forEach(s -> consumer.accept((ScriptFakeBlock) s))); - } - - public static void forEachIgnoreDepth(Consumer consumer) { - IGNORE_DEPTH_BLOCKS.values().forEach(set -> set.forEach(s -> consumer.accept((ScriptFakeBlock) s))); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptFakeEntity.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptFakeEntity.java deleted file mode 100644 index 8f49e496..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptFakeEntity.java +++ /dev/null @@ -1,155 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript.impl; - -import it.unimi.dsi.fastutil.ints.IntOpenHashSet; -import it.unimi.dsi.fastutil.ints.IntSet; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.entity.Entity; -import net.minecraft.util.math.Vec3d; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicInteger; - -public class ScriptFakeEntity { - private static final Map FAKE_IDS = new HashMap<>(); - private static final AtomicInteger FAKE_ID_COUNTER = new AtomicInteger(Integer.MAX_VALUE); - - private final Entity entity; - private ClientWorld world; - private Vec3d pos; - private float bodyYaw; - private float yaw; - private float pitch; - - public ScriptFakeEntity(Interpreter interpreter, Entity entity, ClientWorld world) { - this.entity = entity.getType().create(world); - if (this.entity == null) { - throw new RuntimeError("Could not create fake entity"); - } - entity.setId(getNextFakeId(interpreter)); - this.world = world; - this.pos = Vec3d.ZERO; - this.bodyYaw = this.yaw = this.pitch = 0; - } - - public void setWorld(ClientWorld world) { - this.world = world; - } - - public ClientWorld getWorld() { - return this.world; - } - - public void setPos(Vec3d pos) { - this.setPos(pos, 0); - } - - public void setPos(Vec3d pos, int interpolation) { - this.pos = pos; - this.updatePosition(interpolation); - } - - public Vec3d getPos() { - return this.pos; - } - - public void setYaw(float yaw) { - this.setYaw(yaw, 0); - } - - public void setYaw(float yaw, int interpolation) { - this.yaw = yaw; - this.updatePosition(interpolation); - } - - public float getYaw() { - return this.yaw; - } - - public void setBodyYaw(float bodyYaw) { - this.setBodyYaw(bodyYaw, 0); - } - - public void setBodyYaw(float bodyYaw, int interpolation) { - this.bodyYaw = bodyYaw; - this.updatePosition(interpolation); - } - - public float getBodyYaw() { - return this.bodyYaw; - } - - public void setPitch(float pitch) { - this.setPitch(pitch, 0); - } - - public void setPitch(float pitch, int interpolation) { - this.pitch = pitch; - this.updatePosition(interpolation); - } - - public float getPitch() { - return this.pitch; - } - - public void updatePosAndRotation(Vec3d pos, float yaw, float pitch) { - this.updatePosAndRotation(pos, yaw, pitch, 0); - } - - public void updatePosAndRotation(Vec3d pos, float yaw, float pitch, int interpolation) { - this.pos = pos; - this.entity.setHeadYaw(yaw); - this.entity.setPitch(pitch); - this.updatePosition(interpolation); - } - - public void spawn() { - EssentialUtils.getClient().execute(() -> { - this.entity.refreshPositionAndAngles(this.pos.x, this.pos.y, this.pos.z, this.yaw, this.pitch); - this.entity.updateTrackedPositionAndAngles(this.pos.x, this.pos.y, this.pos.z, this.yaw, this.pitch, 3); - this.world.addEntity(this.entity); - }); - } - - public void despawn() { - this.world.removeEntity(this.entity.getId(), Entity.RemovalReason.DISCARDED); - } - - private void updatePosition(int interpolation) { - EssentialUtils.getClient().execute(() -> { - this.entity.setBodyYaw(this.bodyYaw); - this.entity.updateTrackedPositionAndAngles(this.pos.x, this.pos.y, this.pos.z, this.yaw, this.pitch, interpolation); - }); - } - - public synchronized static boolean isFakeEntity(int id) { - for (IntSet set : FAKE_IDS.values()) { - if (set.contains(id)) { - return true; - } - } - return false; - } - - private synchronized static int getNextFakeId(Interpreter interpreter) { - int id = FAKE_ID_COUNTER.getAndDecrement(); - IntSet fakeIds = FAKE_IDS.computeIfAbsent(interpreter.getProperties().getId(), uuid -> { - interpreter.addStopEvent(() -> { - IntSet ids = FAKE_IDS.get(uuid); - ClientWorld world = EssentialUtils.getWorld(); - if (ids != null && world != null) { - EssentialUtils.getClient().execute(() -> { - ids.forEach(i -> world.removeEntity(i, Entity.RemovalReason.DISCARDED)); - }); - } - }); - return new IntOpenHashSet(); - }); - fakeIds.add(id); - return id; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptItemStack.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptItemStack.java deleted file mode 100644 index 9c10bade..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptItemStack.java +++ /dev/null @@ -1,32 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript.impl; - -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; - -public class ScriptItemStack implements ScriptMaterial { - public final ItemStack stack; - - public ScriptItemStack(ItemStack itemStack) { - this.stack = itemStack; - } - - @Override - public Item asItem() { - return this.stack.getItem(); - } - - @Override - public ItemStack asItemStack() { - return this.stack; - } - - @Override - public Object asDefault() { - return this.stack; - } - - @Override - public String asString() { - return this.stack.toString(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptKeyBind.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptKeyBind.java deleted file mode 100644 index dd446439..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptKeyBind.java +++ /dev/null @@ -1,31 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript.impl; - -import me.senseiwells.arucas.functions.ArucasFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.essentialclient.feature.keybinds.ClientKeyBinds; -import me.senseiwells.essentialclient.feature.keybinds.MultiKeyBind; - -import java.util.List; -import java.util.function.Supplier; - -public class ScriptKeyBind { - private final MultiKeyBind keyBind; - private ArucasFunction function; - - public ScriptKeyBind(Interpreter interpreter, String name) { - Interpreter parent = interpreter.branch(); - this.keyBind = ClientKeyBinds.registerMulti(name, "Scripting Key Binds", client -> { - if (interpreter.isRunning() && this.function != null) { - interpreter.runSafe((Supplier) () -> this.function.invoke(parent.branch(), List.of())); - } - }); - } - - public MultiKeyBind getKeyBind() { - return this.keyBind; - } - - public void setFunction(ArucasFunction function) { - this.function = function; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptLine.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptLine.java deleted file mode 100644 index 3602d06b..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptLine.java +++ /dev/null @@ -1,46 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript.impl; - -import me.senseiwells.arucas.interpreter.Interpreter; -import net.minecraft.util.math.Vec3d; - -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; - -public class ScriptLine extends ScriptShape.Cornered { - private static final Map> REGULAR_LINES = new ConcurrentHashMap<>(); - private static final Map> IGNORE_DEPTH_LINES = new ConcurrentHashMap<>(); - - public ScriptLine(Interpreter interpreter, Vec3d cornerA, Vec3d cornerB) { - super(interpreter, cornerA, cornerB); - this.setOutlineWidth(5); - } - - @Override - protected Map> getRegularDepthMap() { - return REGULAR_LINES; - } - - @Override - protected Map> getIgnoreDepthMap() { - return IGNORE_DEPTH_LINES; - } - - public static boolean hasRegular() { - return REGULAR_LINES.size() > 0; - } - - public static boolean hasIgnoreDepth() { - return IGNORE_DEPTH_LINES.size() > 0; - } - - public static void forEachRegular(Consumer consumer) { - REGULAR_LINES.values().forEach(set -> set.forEach(s -> consumer.accept((ScriptLine) s))); - } - - public static void forEachIgnoreDepth(Consumer consumer) { - IGNORE_DEPTH_LINES.values().forEach(set -> set.forEach(s -> consumer.accept((ScriptLine) s))); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptMaterial.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptMaterial.java deleted file mode 100644 index b65a69ea..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptMaterial.java +++ /dev/null @@ -1,104 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript.impl; - -import me.senseiwells.arucas.exceptions.RuntimeError; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.item.BlockItem; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.registry.Registries; -import net.minecraft.util.Identifier; - -public interface ScriptMaterial { - default Identifier getId() { - return Registries.ITEM.getId(this.asItem()); - } - - default String getTranslationKey() { - return this.asItem().getTranslationKey(); - } - - default Item asItem() { - Item item = Item.BLOCK_ITEMS.get(this.asBlock()); - if (item != null) { - return item; - } - throw new RuntimeError("Material cannot be converted to an item"); - } - - default ItemStack asItemStack() { - return this.asItem().getDefaultStack(); - } - - default Block asBlock() { - Item item = this.asItem(); - if (item instanceof BlockItem blockItem) { - return blockItem.getBlock(); - } - throw new RuntimeError("Material cannot be converted into a block"); - } - - default BlockState asBlockState() { - return this.asBlock().getDefaultState(); - } - - Object asDefault(); - - String asString(); - - static ScriptMaterial materialOf(Block block) { - Item item = Item.BLOCK_ITEMS.get(block); - if (item == null) { - return new BlockMaterial(block); - } - return materialOf(item); - } - - static ScriptMaterial materialOf(Item item) { - return new ItemMaterial(item); - } - - record ItemMaterial(Item item) implements ScriptMaterial { - @Override - public Item asItem() { - return this.item; - } - - @Override - public Object asDefault() { - return this.item; - } - - @Override - public String asString() { - return this.item.toString(); - } - } - - record BlockMaterial(Block block) implements ScriptMaterial { - @Override - public Identifier getId() { - return Registries.BLOCK.getId(this.block); - } - - @Override - public String getTranslationKey() { - return this.block.getTranslationKey(); - } - - @Override - public Block asBlock() { - return this.block; - } - - @Override - public Object asDefault() { - return this.block; - } - - @Override - public String asString() { - return this.getId().getPath(); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptPos.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptPos.java deleted file mode 100644 index f00f2474..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptPos.java +++ /dev/null @@ -1,46 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript.impl; - -import me.senseiwells.essentialclient.utils.EssentialUtils; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; - -public class ScriptPos { - private final Vec3d pos; - private BlockPos blockPos; - - public ScriptPos(Vec3d pos) { - this.pos = pos; - } - - public ScriptPos(BlockPos blockPos) { - this(new Vec3d(blockPos.getX(), blockPos.getY(), blockPos.getZ())); - this.blockPos = blockPos.toImmutable(); - } - - public ScriptPos(double x, double y, double z) { - this(new Vec3d(x, y, z)); - } - - public Vec3d getVec3d() { - return this.pos; - } - - public BlockPos getBlockPos() { - if (this.blockPos == null) { - this.blockPos = EssentialUtils.vec3dToBlockPos(this.pos); - } - return this.blockPos; - } - - public double getX() { - return this.pos.getX(); - } - - public double getY() { - return this.pos.getY(); - } - - public double getZ() { - return this.pos.getZ(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptShape.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptShape.java deleted file mode 100644 index 4345af06..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptShape.java +++ /dev/null @@ -1,330 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript.impl; - -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.interpreter.Interpreter; -import net.minecraft.util.math.Vec3d; - -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; - -public abstract class ScriptShape { - private final Interpreter interpreter; - - private int red; - private int green; - private int blue; - private int alpha; - - private float xScale; - private float yScale; - private float zScale; - - private float xTilt; - private float yTilt; - private float zTilt; - - private boolean render; - private boolean ignoreDepth; - - ScriptShape(Interpreter interpreter) { - this.interpreter = interpreter; - this.red = 255; - this.green = 255; - this.blue = 255; - this.alpha = 255; - - this.xScale = 1; - this.yScale = 1; - this.zScale = 1; - - this.xTilt = 0; - this.yTilt = 0; - this.zTilt = 0; - - this.render = false; - this.ignoreDepth = false; - } - - public final void setColour(int colour) { - this.red = (colour >> 16) & 0xFF; - this.green = (colour >> 8) & 0xFF; - this.blue = colour & 0xFF; - } - - public final void setRed(int red) { - this.red = this.checkInBounds(red); - } - - public final void setGreen(int green) { - this.green = this.checkInBounds(green); - } - - public final void setBlue(int blue) { - this.blue = this.checkInBounds(blue); - } - - public final void setAlpha(int alpha) { - this.alpha = this.checkInBounds(alpha); - } - - public final int getColour() { - return (this.red << 16) | (this.green << 8) | this.blue; - } - - public final int getRed() { - return this.red; - } - - public final int getGreen() { - return this.green; - } - - public final int getBlue() { - return this.blue; - } - - public final int getAlpha() { - return this.alpha; - } - - public final void setXScale(float xScale) { - this.xScale = xScale; - } - - public final void setYScale(float yScale) { - this.yScale = yScale; - } - - public final void setZScale(float zScale) { - this.zScale = zScale; - } - - public final float getXScale() { - return this.xScale; - } - - public final float getYScale() { - return this.yScale; - } - - public final float getZScale() { - return this.zScale; - } - - public final void setXTilt(float xTilt) { - this.xTilt = xTilt; - } - - public final void setYTilt(float yTilt) { - this.yTilt = yTilt; - } - - public final void setZTilt(float zTilt) { - this.zTilt = zTilt; - } - - public final float getXTilt() { - return this.xTilt; - } - - public final float getYTilt() { - return this.yTilt; - } - - public final float getZTilt() { - return this.zTilt; - } - - public final void render(boolean render) { - this.render = render; - - if (render) { - this.addShape(); - return; - } - this.removeShape(); - } - - public final boolean getRender() { - return this.render; - } - - public final void setIgnoreDepth(boolean ignoreDepth) { - if (this.shouldIgnoreDepth() ^ ignoreDepth) { - if (this.getRender()) { - this.removeShape(); - this.ignoreDepth = ignoreDepth; - this.addShape(); - return; - } - this.ignoreDepth = ignoreDepth; - } - } - - public final boolean shouldIgnoreDepth() { - return this.ignoreDepth; - } - - protected final int compactRgb(int red, int green, int blue) { - return (red << 16) | (green << 8) | blue; - } - - protected final int checkInBounds(int colour) { - if (colour < 0 || colour > 255) { - throw new RuntimeError("Colour must be between 0 and 255"); - } - return colour; - } - - protected final int checkNonNegative(int value) { - if (value < 0) { - throw new RuntimeError("Value must be non-negative"); - } - return value; - } - - protected final float checkNonNegative(float value) { - if (value < 0) { - throw new RuntimeError("Value must be non-negative"); - } - return value; - } - - protected abstract Map> getRegularDepthMap(); - - protected abstract Map> getIgnoreDepthMap(); - - private Map> getMap() { - return this.shouldIgnoreDepth() ? this.getIgnoreDepthMap() : this.getRegularDepthMap(); - } - - private void addShape() { - Map> map = this.getMap(); - if (this.interpreter.isRunning()) { - Set shapes = map.computeIfAbsent(this.interpreter.getProperties().getId(), id -> { - this.interpreter.addStopEvent(() -> map.remove(id)); - return ConcurrentHashMap.newKeySet(); - }); - shapes.add(this); - } - } - - private void removeShape() { - Map> map = this.getMap(); - synchronized (map) { - Set shapes = map.get(this.interpreter.getProperties().getId()); - if (shapes != null) { - shapes.remove(this); - } - } - } - - public static abstract class Outlined extends ScriptShape { - private int outlineRed; - private int outlineGreen; - private int outlineBlue; - private int outlineWidth; - - Outlined(Interpreter interpreter) { - super(interpreter); - } - - public void setOutlineColour(int colour) { - this.outlineRed = (colour >> 16) & 0xFF; - this.outlineGreen = (colour >> 8) & 0xFF; - this.outlineBlue = colour & 0xFF; - } - - public void setOutlineRed(int red) { - this.outlineRed = this.checkInBounds(red); - } - - public void setOutlineGreen(int green) { - this.outlineGreen = this.checkInBounds(green); - } - - public void setOutlineBlue(int blue) { - this.outlineBlue = this.checkInBounds(blue); - } - - public void setOutlineWidth(int width) { - this.outlineWidth = this.checkNonNegative(width); - } - - public int getOutlineColour() { - return this.compactRgb(this.outlineRed, this.outlineGreen, this.outlineBlue); - } - - public int getOutlineRed() { - return this.outlineRed; - } - - public int getOutlineGreen() { - return this.outlineGreen; - } - - public int getOutlineBlue() { - return this.outlineBlue; - } - - public int getOutlineWidth() { - return this.outlineWidth; - } - } - - public static abstract class Centred extends Outlined { - private Vec3d position; - private float width; - - Centred(Interpreter interpreter, Vec3d position) { - super(interpreter); - this.position = position; - this.width = 5; - } - - public void setPosition(Vec3d position) { - this.position = position; - } - - public Vec3d getPosition() { - return this.position; - } - - public void setWidth(float width) { - this.width = this.checkNonNegative(width); - } - - public float getWidth() { - return this.width; - } - } - - public static abstract class Cornered extends Outlined { - private Vec3d cornerA; - private Vec3d cornerB; - - Cornered(Interpreter interpreter, Vec3d cornerA, Vec3d cornerB) { - super(interpreter); - this.cornerA = cornerA; - this.cornerB = cornerB; - } - - public void setCornerA(Vec3d cornerA) { - this.cornerA = cornerA; - } - - public void setCornerB(Vec3d cornerB) { - this.cornerB = cornerB; - } - - public Vec3d getCornerA() { - return this.cornerA; - } - - public Vec3d getCornerB() { - return this.cornerB; - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptSphere.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptSphere.java deleted file mode 100644 index b2b2f676..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptSphere.java +++ /dev/null @@ -1,55 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript.impl; - -import me.senseiwells.arucas.interpreter.Interpreter; -import net.minecraft.util.math.Vec3d; - -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; - -public class ScriptSphere extends ScriptShape.Centred { - private static final Map> REGULAR_SPHERES = new ConcurrentHashMap<>(); - private static final Map> IGNORE_DEPTH_SPHERES = new ConcurrentHashMap<>(); - - private float steps = 30; - - public ScriptSphere(Interpreter interpreter, Vec3d position) { - super(interpreter, position); - } - - public void setSteps(float steps) { - this.steps = steps; - } - - public float getSteps() { - return this.steps; - } - - @Override - protected Map> getRegularDepthMap() { - return REGULAR_SPHERES; - } - - @Override - protected Map> getIgnoreDepthMap() { - return IGNORE_DEPTH_SPHERES; - } - - public static boolean hasRegular() { - return REGULAR_SPHERES.size() > 0; - } - - public static boolean hasIgnoreDepth() { - return IGNORE_DEPTH_SPHERES.size() > 0; - } - - public static void forEachRegular(Consumer consumer) { - REGULAR_SPHERES.values().forEach(set -> set.forEach(s -> consumer.accept((ScriptSphere) s))); - } - - public static void forEachIgnoreDepth(Consumer consumer) { - IGNORE_DEPTH_SPHERES.values().forEach(set -> set.forEach(s -> consumer.accept((ScriptSphere) s))); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptTask.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptTask.java deleted file mode 100644 index d64e32e4..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/ScriptTask.java +++ /dev/null @@ -1,51 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript.impl; - -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.arucas.utils.impl.DelayedFunction; -import me.senseiwells.arucas.utils.impl.Task; -import me.senseiwells.essentialclient.utils.misc.Scheduler; -import org.jetbrains.annotations.NotNull; - -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Future; -import java.util.function.Supplier; - -public class ScriptTask extends Task { - public ScriptTask(Interpreter interpreter) { - super(interpreter); - } - - @NotNull - @Override - public Future run(Iterator tasks) { - int totalTicks = 0; - while (tasks.hasNext()) { - DelayedFunction next = tasks.next(); - if (!tasks.hasNext()) { - return Scheduler.schedule(totalTicks + next.getTime(), () -> { - Interpreter interpreter = this.getInterpreter(); - return interpreter.runSafe((Supplier) () -> { - if (interpreter.isRunning()) { - return next.getFunction().invoke(interpreter.branch(), List.of()); - } - return interpreter.getNull(); - }); - }); - } - totalTicks += next.getTime(); - Scheduler.schedule(totalTicks, () -> { - Interpreter interpreter = this.getInterpreter(); - interpreter.runSafe((Supplier) () -> { - if (interpreter.isRunning()) { - next.getFunction().invoke(interpreter.branch(), List.of()); - } - return null; - }); - }); - } - return CompletableFuture.completedFuture(this.getInterpreter().getNull()); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/WaitingEvent.java b/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/WaitingEvent.java deleted file mode 100644 index 25a61214..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/clientscript/impl/WaitingEvent.java +++ /dev/null @@ -1,8 +0,0 @@ -package me.senseiwells.essentialclient.utils.clientscript.impl; - -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.interpreter.Interpreter; - -import java.util.concurrent.CompletableFuture; - -public record WaitingEvent(Interpreter interpreter, CompletableFuture future) { } diff --git a/src/main/java/me/senseiwells/essentialclient/utils/command/ClientEntityArgumentType.java b/src/main/java/me/senseiwells/essentialclient/utils/command/ClientEntityArgumentType.java deleted file mode 100644 index 6cf79fc6..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/command/ClientEntityArgumentType.java +++ /dev/null @@ -1,636 +0,0 @@ -package me.senseiwells.essentialclient.utils.command; - -import com.mojang.brigadier.StringReader; -import com.mojang.brigadier.arguments.ArgumentType; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.suggestion.Suggestions; -import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import net.minecraft.command.CommandSource; -import net.minecraft.command.EntitySelectorOptions; -import net.minecraft.command.EntitySelectorReader; -import net.minecraft.command.FloatRangeArgument; -import net.minecraft.command.argument.EntityArgumentType; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.EquipmentSlot; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtHelper; -import net.minecraft.nbt.StringNbtReader; -import net.minecraft.predicate.NumberRange; -import net.minecraft.registry.Registries; -import net.minecraft.registry.Registry; -import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.registry.tag.TagKey; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.Vec3d; - -import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.BiPredicate; -import java.util.function.Consumer; -import java.util.regex.Pattern; - -// Taken from ClientCommands -public class ClientEntityArgumentType implements ArgumentType { - private static final Collection EXAMPLES = Arrays.asList("Player", "0123", "@e", "@e[type=foo]"); - - private final boolean singleTarget; - - private ClientEntityArgumentType(boolean singleTarget) { - this.singleTarget = singleTarget; - } - - public static ClientEntityArgumentType entity() { - return new ClientEntityArgumentType(true); - } - - @SuppressWarnings("unused") - public static ClientEntityArgumentType entities() { - return new ClientEntityArgumentType(false); - } - - @SuppressWarnings("unused") - public static ClientEntitySelector getEntitySelector(CommandContext context, String arg) { - return context.getArgument(arg, ClientEntitySelector.class); - } - - @SuppressWarnings("unused") - public static Entity getEntity(CommandContext context, String arg) throws CommandSyntaxException { - return context.getArgument(arg, ClientEntitySelector.class).getEntity(context.getSource()); - } - - @SuppressWarnings("unused") - public static List getEntities(CommandContext context, String arg) { - return context.getArgument(arg, ClientEntitySelector.class).getEntities(context.getSource()); - } - - @Override - public ClientEntitySelector parse(StringReader reader) throws CommandSyntaxException { - final int start = reader.getCursor(); - ClientEntitySelector ret = new Parser(reader).parse(); - ret.setSingleTarget(this.singleTarget); - - if (ret.getLimit() > 1 && this.singleTarget) { - reader.setCursor(start); - throw EntityArgumentType.TOO_MANY_ENTITIES_EXCEPTION.createWithContext(reader); - } - - return ret; - } - - @Override - public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { - if (context.getSource() instanceof CommandSource source) { - StringReader reader = new StringReader(builder.getInput()); - reader.setCursor(builder.getStart()); - Parser parser = new Parser(reader); - - try { - parser.parse(); - } catch (CommandSyntaxException ignore) { - } - - Collection suggestions = source.getPlayerNames(); - suggestions.addAll(source.getEntitySuggestions()); - - return parser.listSuggestions(builder, b -> CommandSource.suggestMatching(suggestions, b)); - } - return Suggestions.empty(); - } - - @Override - public Collection getExamples() { - return EXAMPLES; - } - - private static class Parser { - private static final BiConsumer> UNSORTED = (origin, list) -> { }; - private static final BiConsumer> NEAREST = (origin, list) -> list.sort(Comparator.comparingDouble(entity -> entity.squaredDistanceTo(origin))); - private static final BiConsumer> FURTHEST = (origin, list) -> list.sort(Comparator.comparingDouble(entity -> -entity.squaredDistanceTo(origin))); - private static final BiConsumer> RANDOM = (origin, list) -> Collections.shuffle(list); - - private final StringReader reader; - private BiFunction, CompletableFuture> suggestor; - private boolean playersOnly = false; - private boolean playersOnlyForced = false; - private BiPredicate filter = (origin, entity) -> true; - private BiConsumer> sorter = UNSORTED; - private int limit = Integer.MAX_VALUE; - private boolean senderOnly = false; - private Double originX = null; - private Double originY = null; - private Double originZ = null; - private Double boxX = null; - private Double boxY = null; - private Double boxZ = null; - - private boolean hasName = false; - private boolean hasDistance = false; - private boolean hasXRotation = false; - private boolean hasYRotation = false; - private boolean hasLimit = false; - private boolean hasSort = false; - private boolean hasType = false; - - Parser(StringReader reader) { - this.reader = reader; - } - - ClientEntitySelector parse() throws CommandSyntaxException { - this.suggestor = this::suggestStart; - - if (this.reader.canRead() && this.reader.peek() == '@') { - this.parseAtSelector(); - } else { - this.parsePlayerNameOrUuid(); - } - - if (this.boxX != null || this.boxY != null || this.boxZ != null) { - boolean xNeg = this.boxX != null && this.boxX < 0; - boolean yNeg = this.boxY != null && this.boxY < 0; - boolean zNeg = this.boxZ != null && this.boxZ < 0; - double xMin = xNeg ? this.boxX : 0; - double yMin = yNeg ? this.boxY : 0; - double zMin = zNeg ? this.boxZ : 0; - double xMax = (xNeg || this.boxX == null ? 0 : this.boxX) + 1; - double yMax = (yNeg || this.boxY == null ? 0 : this.boxY) + 1; - double zMax = (zNeg || this.boxZ == null ? 0 : this.boxZ) + 1; - this.addFilter((origin, entity) -> entity.getX() - origin.x >= xMin && entity.getX() - origin.x < xMax - && entity.getY() - origin.y >= yMin && entity.getY() - origin.y < yMax - && entity.getZ() - origin.z >= zMin && entity.getZ() - origin.z < zMax); - } - if (this.playersOnly || this.playersOnlyForced) { - this.addFilter((origin, entity) -> entity instanceof PlayerEntity); - } - return new ClientEntitySelector(this.filter, this.sorter, this.limit, this.senderOnly, this.originX, this.originY, this.originZ); - } - - void parsePlayerNameOrUuid() throws CommandSyntaxException { - if (this.reader.canRead()) { - int start = this.reader.getCursor(); - this.suggestor = (builder, playerNameSuggestor) -> { - SuggestionsBuilder newBuilder = builder.createOffset(start); - playerNameSuggestor.accept(newBuilder); - builder.add(newBuilder); - return builder.buildFuture(); - }; - } - - int start = this.reader.getCursor(); - String playerName = this.reader.readString(); - try { - UUID uuid = UUID.fromString(playerName); - this.filter = (origin, entity) -> entity.getUuid().equals(uuid); - this.limit = 1; - return; - } catch (IllegalArgumentException ignore) { - // we don't have an uuid, check player names - } - - if (playerName.isEmpty() || playerName.length() > 16) { - this.reader.setCursor(start); - throw EntitySelectorReader.INVALID_ENTITY_EXCEPTION.createWithContext(this.reader); - } - - this.playersOnlyForced = true; - this.filter = (origin, entity) -> ((PlayerEntity) entity).getGameProfile().getName().equals(playerName); - this.limit = 1; - } - - void parseAtSelector() throws CommandSyntaxException { - this.suggestor = (builder, playerNameSuggestor) -> this.suggestAtSelectors(builder.createOffset(builder.getStart() - 1), playerNameSuggestor); - this.reader.skip(); - if (!this.reader.canRead()) { - throw EntitySelectorReader.MISSING_EXCEPTION.createWithContext(this.reader); - } - char type = this.reader.read(); - switch (type) { - case 'p' -> { - this.playersOnly = true; - this.sorter = NEAREST; - this.limit = 1; - this.hasType = true; - } - case 'a' -> { - this.playersOnly = true; - this.sorter = UNSORTED; - this.limit = Integer.MAX_VALUE; - this.hasType = true; - } - case 'r' -> { - this.playersOnly = true; - this.sorter = RANDOM; - this.limit = 1; - } - case 'e' -> { - this.playersOnly = false; - this.sorter = UNSORTED; - this.limit = Integer.MAX_VALUE; - } - case 's' -> { - this.playersOnly = true; - this.sorter = UNSORTED; - this.limit = 1; - this.senderOnly = true; - this.addFilter((origin, entity) -> entity.isAlive()); - } - default -> throw EntitySelectorReader.UNKNOWN_SELECTOR_EXCEPTION.createWithContext(this.reader, "@" + type); - } - - this.suggestor = (builder, playerNameSuggest) -> { - builder.suggest("["); - return builder.buildFuture(); - }; - if (this.reader.canRead() && this.reader.peek() == '[') { - this.reader.skip(); - this.reader.skipWhitespace(); - this.parseOptions(); - } - } - - void parseOptions() throws CommandSyntaxException { - this.suggestor = this::suggestOption; - - while (true) { - int cursor = this.reader.getCursor(); - String optionName = this.reader.readString(); - Option option = Option.options.get(optionName); - if (option == null) { - this.reader.setCursor(cursor); - throw EntitySelectorOptions.UNKNOWN_OPTION_EXCEPTION.createWithContext(this.reader, optionName); - } - if (!option.applicable(this)) { - this.reader.setCursor(cursor); - throw EntitySelectorOptions.INAPPLICABLE_OPTION_EXCEPTION.createWithContext(this.reader, optionName); - } - - this.reader.skipWhitespace(); - if (!this.reader.canRead() || this.reader.read() != '=') { - this.reader.setCursor(cursor); - throw EntitySelectorReader.VALUELESS_EXCEPTION.createWithContext(this.reader, optionName); - } - this.reader.skipWhitespace(); - - this.suggestor = EntitySelectorReader.DEFAULT_SUGGESTION_PROVIDER; - option.apply(this); - - this.reader.skipWhitespace(); - - this.suggestor = (builder, playerNameSuggest) -> { - builder.suggest(","); - builder.suggest("]"); - return builder.buildFuture(); - }; - - if (!this.reader.canRead() || (this.reader.peek() != ',' && this.reader.peek() != ']')) { - throw EntitySelectorReader.UNTERMINATED_EXCEPTION.createWithContext(this.reader); - } - - char delimiter = this.reader.read(); - if (delimiter == ',') { - this.suggestor = this::suggestOption; - this.reader.skipWhitespace(); - } else { - this.suggestor = EntitySelectorReader.DEFAULT_SUGGESTION_PROVIDER; - break; - } - } - } - - boolean readNegationCharacter() { - if (this.reader.canRead() && this.reader.peek() == '!') { - this.reader.skip(); - this.reader.skipWhitespace(); - return true; - } - return false; - } - - boolean readTagCharacter() { - this.reader.skipWhitespace(); - if (this.reader.canRead() && this.reader.peek() == '#') { - this.reader.skip(); - this.reader.skipWhitespace(); - return true; - } - return false; - } - - void addFilter(BiPredicate filter) { - final var prevFilter = this.filter; - this.filter = (origin, entity) -> filter.test(origin, entity) && prevFilter.test(origin, entity); - } - - CompletableFuture listSuggestions(SuggestionsBuilder builder, Consumer playerNameSuggestor) { - return this.suggestor.apply(builder.createOffset(this.reader.getCursor()), playerNameSuggestor); - } - - private CompletableFuture suggestStart(SuggestionsBuilder builder, Consumer playerNameSuggestor) { - playerNameSuggestor.accept(builder); - this.suggestAtSelectors(builder, playerNameSuggestor); - return builder.buildFuture(); - } - - @SuppressWarnings("unused") - private CompletableFuture suggestAtSelectors(SuggestionsBuilder builder, Consumer playerNameSuggestor) { - builder.suggest("@p", Text.translatable("argument.entity.selector.nearestPlayer")); - builder.suggest("@a", Text.translatable("argument.entity.selector.allPlayers")); - builder.suggest("@r", Text.translatable("argument.entity.selector.randomPlayer")); - builder.suggest("@s", Text.translatable("argument.entity.selector.self")); - builder.suggest("@e", Text.translatable("argument.entity.selector.allEntities")); - return builder.buildFuture(); - } - - private CompletableFuture suggestOption(SuggestionsBuilder builder, Consumer playerNameSuggestor) { - String arg = builder.getRemaining().toLowerCase(Locale.ROOT); - Option.options.forEach((name, opt) -> { - if (opt.applicable(this) && name.toLowerCase(Locale.ROOT).startsWith(arg)) { - builder.suggest(name + "=", opt.desc); - } - }); - return builder.buildFuture(); - } - - private static abstract class Option { - static Map options = new HashMap<>(); - - static { - options.put("name", new Option("argument.entity.options.name.description") { - @Override - void apply(Parser parser) throws CommandSyntaxException { - boolean neg = parser.readNegationCharacter(); - if (parser.reader.canRead() && parser.reader.peek() == '/') { - Pattern regex = RegexArgumentType.parseSlashyRegex(parser.reader); - parser.addFilter((origin, entity) -> regex.matcher(entity.getName().getString()).matches() != neg); - } else { - String name = parser.reader.readString(); - parser.addFilter((origin, entity) -> entity.getName().getString().equals(name) != neg); - } - if (!neg) { - parser.hasName = true; - } - } - - @Override - boolean applicable(Parser parser) { - return !parser.hasName; - } - }); - options.put("distance", new Option("argument.entity.options.distance.description") { - @Override - void apply(Parser parser) throws CommandSyntaxException { - int cursor = parser.reader.getCursor(); - NumberRange.DoubleRange range = NumberRange.DoubleRange.parse(parser.reader); - if ((range.min().isPresent() && range.min().get() < 0) || (range.max().isPresent() && range.max().get() < 0)) { - parser.reader.setCursor(cursor); - throw EntitySelectorOptions.NEGATIVE_DISTANCE_EXCEPTION.createWithContext(parser.reader); - } - parser.hasDistance = true; - parser.addFilter((origin, entity) -> range.testSqrt(entity.squaredDistanceTo(origin))); - } - - @Override - boolean applicable(Parser parser) { - return !parser.hasDistance; - } - }); - options.put("x", new Option("argument.entity.options.x.description") { - @Override - void apply(Parser parser) throws CommandSyntaxException { - parser.originX = parser.reader.readDouble(); - } - - @Override - boolean applicable(Parser parser) { - return parser.originX == null; - } - }); - options.put("y", new Option("argument.entity.options.y.description") { - @Override - void apply(Parser parser) throws CommandSyntaxException { - parser.originY = parser.reader.readDouble(); - } - - @Override - boolean applicable(Parser parser) { - return parser.originY == null; - } - }); - options.put("z", new Option("argument.entity.options.z.description") { - @Override - void apply(Parser parser) throws CommandSyntaxException { - parser.originZ = parser.reader.readDouble(); - } - - @Override - boolean applicable(Parser parser) { - return parser.originZ == null; - } - }); - options.put("dx", new Option("argument.entity.options.dx.description") { - @Override - void apply(Parser parser) throws CommandSyntaxException { - parser.boxX = parser.reader.readDouble(); - } - - @Override - boolean applicable(Parser parser) { - return parser.boxX == null; - } - }); - options.put("dy", new Option("argument.entity.options.dy.description") { - @Override - void apply(Parser parser) throws CommandSyntaxException { - parser.boxY = parser.reader.readDouble(); - } - - @Override - boolean applicable(Parser parser) { - return parser.boxY == null; - } - }); - options.put("dz", new Option("argument.entity.options.dz.description") { - @Override - void apply(Parser parser) throws CommandSyntaxException { - parser.boxZ = parser.reader.readDouble(); - } - - @Override - boolean applicable(Parser parser) { - return parser.boxZ == null; - } - }); - options.put("x_rotation", new Option("argument.entity.options.x_rotation.description") { - @Override - void apply(Parser parser) throws CommandSyntaxException { - FloatRangeArgument range = FloatRangeArgument.parse(parser.reader, true, MathHelper::wrapDegrees); - float min = range.min() == null ? 0 : range.min(); - float max = range.max() == null ? 359 : range.max(); - if (max < min) { - parser.addFilter((origin, entity) -> entity.getPitch() >= min || entity.getPitch() <= max); - } else { - parser.addFilter((origin, entity) -> entity.getPitch() >= min && entity.getPitch() <= max); - } - parser.hasXRotation = true; - } - - @Override - boolean applicable(Parser parser) { - return !parser.hasXRotation; - } - }); - options.put("y_rotation", new Option("argument.entity.options.y_rotation.description") { - @Override - void apply(Parser parser) throws CommandSyntaxException { - FloatRangeArgument range = FloatRangeArgument.parse(parser.reader, true, MathHelper::wrapDegrees); - float min = range.min() == null ? 0 : range.min(); - float max = range.max() == null ? 359 : range.max(); - if (max < min) { - parser.addFilter((origin, entity) -> entity.getYaw() >= min || entity.getYaw() <= max); - } else { - parser.addFilter((origin, entity) -> entity.getYaw() >= min && entity.getYaw() <= max); - } - parser.hasYRotation = true; - } - - @Override - boolean applicable(Parser parser) { - return !parser.hasYRotation; - } - }); - options.put("limit", new Option("argument.entity.options.limit.description") { - @Override - void apply(Parser parser) throws CommandSyntaxException { - int cursor = parser.reader.getCursor(); - int limit = parser.reader.readInt(); - if (limit < 1) { - parser.reader.setCursor(cursor); - throw EntitySelectorOptions.TOO_SMALL_LEVEL_EXCEPTION.createWithContext(parser.reader); - } - parser.limit = limit; - parser.hasLimit = true; - } - - @Override - boolean applicable(Parser parser) { - return !parser.hasLimit; - } - }); - options.put("sort", new Option("argument.entity.options.sort.description") { - @Override - void apply(Parser parser) throws CommandSyntaxException { - int cursor = parser.reader.getCursor(); - String sort = parser.reader.readUnquotedString(); - parser.suggestor = (builder, playerNameSuggest) -> CommandSource.suggestMatching(Arrays.asList("nearest", "furthest", "random", "arbitrary"), builder); - switch (sort) { - case "nearest" -> parser.sorter = NEAREST; - case "furthest" -> parser.sorter = FURTHEST; - case "random" -> parser.sorter = RANDOM; - case "arbitrary" -> parser.sorter = UNSORTED; - default -> { - parser.reader.setCursor(cursor); - throw EntitySelectorOptions.IRREVERSIBLE_SORT_EXCEPTION.createWithContext(parser.reader, sort); - } - } - parser.hasSort = true; - } - - @Override - boolean applicable(Parser parser) { - return !parser.hasSort; - } - }); - options.put("type", new Option("argument.entity.options.type.description") { - @Override - void apply(Parser parser) throws CommandSyntaxException { - parser.suggestor = (builder, playerNameSuggest) -> { - Registry> entityTypes = Registries.ENTITY_TYPE; - - CommandSource.suggestIdentifiers(entityTypes.getIds(), builder, "!"); - - CommandSource.suggestIdentifiers(entityTypes.streamTags().map(TagKey::id), builder, "!#"); - - if (!parser.hasType) { - CommandSource.suggestIdentifiers(entityTypes.getIds(), builder); - CommandSource.suggestIdentifiers(entityTypes.streamTags().map(TagKey::id), builder, String.valueOf('#')); - } - return builder.buildFuture(); - }; - - int cursor = parser.reader.getCursor(); - boolean neg = parser.readNegationCharacter(); - - if (parser.readTagCharacter()) { - RegistryKey>> keyEntityTypes = RegistryKeys.ENTITY_TYPE; - - TagKey> tagKey = TagKey.of(keyEntityTypes, Identifier.fromCommandInput(parser.reader)); - parser.addFilter((origin, entity) -> entity.getType().isIn(tagKey) != neg); - } else { - Registry> entityTypes = Registries.ENTITY_TYPE; - - Identifier typeId = Identifier.fromCommandInput(parser.reader); - EntityType type = entityTypes.getOrEmpty(typeId).orElseThrow(() -> { - parser.reader.setCursor(cursor); - return EntitySelectorOptions.INVALID_TYPE_EXCEPTION.createWithContext(parser.reader, typeId); - }); - parser.playersOnly = false; - if (!neg) { - parser.hasType = true; - if (type == EntityType.PLAYER) { - parser.playersOnly = true; - } - } - parser.addFilter((origin, entity) -> (entity.getType() == type) != neg); - } - } - - @Override - boolean applicable(Parser parser) { - return !parser.hasType; - } - }); - options.put("nbt", new Option("argument.entity.options.nbt.description") { - @Override - void apply(Parser parser) throws CommandSyntaxException { - boolean neg = parser.readNegationCharacter(); - NbtCompound nbt = new StringNbtReader(parser.reader).parseCompound(); - parser.addFilter((origin, entity) -> { - NbtCompound entityNbt = entity.writeNbt(new NbtCompound()); - if (entity instanceof PlayerEntity) { - ItemStack heldItem = ((PlayerEntity) entity).getEquippedStack(EquipmentSlot.MAINHAND); - if (!heldItem.isEmpty()) { - // entityNbt.put("SelectedItem", heldItem.writeNbt(new NbtCompound())); - } - } - return NbtHelper.matches(nbt, entityNbt, true) != neg; - }); - } - - @Override - boolean applicable(Parser parser) { - return true; - } - }); - } - - final Text desc; - - private Option(String desc) { - this.desc = Text.translatable(desc); - } - - abstract void apply(Parser parser) throws CommandSyntaxException; - - abstract boolean applicable(Parser parser); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/command/ClientEntitySelector.java b/src/main/java/me/senseiwells/essentialclient/utils/command/ClientEntitySelector.java deleted file mode 100644 index b7c9183a..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/command/ClientEntitySelector.java +++ /dev/null @@ -1,85 +0,0 @@ -package me.senseiwells.essentialclient.utils.command; - -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.command.argument.EntityArgumentType; -import net.minecraft.entity.Entity; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.util.math.Vec3d; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.function.BiConsumer; -import java.util.function.BiPredicate; - -// Taken from ClientCommands -public class ClientEntitySelector { - private final BiPredicate filter; - private final BiConsumer> sorter; - private final int limit; - private final boolean senderOnly; - private final Double originX; - private final Double originY; - private final Double originZ; - private boolean isSingleTarget; - - public ClientEntitySelector(BiPredicate filter, BiConsumer> sorter, int limit, boolean senderOnly, Double originX, Double originY, Double originZ) { - this.filter = filter; - this.sorter = sorter; - this.limit = limit; - this.senderOnly = senderOnly; - this.originX = originX; - this.originY = originY; - this.originZ = originZ; - } - - public Entity getEntity(ServerCommandSource source) throws CommandSyntaxException { - List entities = this.getEntities(source); - if (entities.isEmpty()) { - throw EntityArgumentType.ENTITY_NOT_FOUND_EXCEPTION.create(); - } - if (entities.size() > 1) { - throw EntityArgumentType.TOO_MANY_ENTITIES_EXCEPTION.create(); - } - return entities.get(0); - } - - public List getEntities(ServerCommandSource source) { - Vec3d origin = source.getPosition(); - origin = new Vec3d(this.originX == null ? origin.x : this.originX, this.originY == null ? origin.y : this.originY, this.originZ == null ? origin.z : this.originZ); - - if (this.senderOnly) { - return this.filter.test(origin, source.getEntity()) ? Collections.singletonList(source.getEntity()) : Collections.emptyList(); - } - - List entities = new ArrayList<>(); - ClientWorld world = EssentialUtils.getWorld(); - if (world == null) { - return List.of(); - } - - for (Entity entity : world.getEntities()) { - if (this.filter.test(origin, entity)) { - entities.add(entity); - } - } - - this.sorter.accept(origin, entities); - - return entities.size() <= this.limit ? entities : entities.subList(0, this.limit); - } - - public int getLimit() { - return this.limit; - } - - public boolean isSingleTarget() { - return this.isSingleTarget; - } - - public void setSingleTarget(boolean isSingleTarget) { - this.isSingleTarget = isSingleTarget; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/command/CommandHelper.java b/src/main/java/me/senseiwells/essentialclient/utils/command/CommandHelper.java deleted file mode 100644 index 7a009c3d..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/command/CommandHelper.java +++ /dev/null @@ -1,160 +0,0 @@ -package me.senseiwells.essentialclient.utils.command; - -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.StringReader; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.context.ParsedArgument; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.suggestion.Suggestions; -import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import com.mojang.brigadier.tree.CommandNode; -import com.mojang.brigadier.tree.LiteralCommandNode; -import com.mojang.brigadier.tree.RootCommandNode; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.render.ChatColour; -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.command.CommandRegistryAccess; -import net.minecraft.command.CommandSource; -import net.minecraft.network.packet.s2c.play.CommandTreeS2CPacket; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.text.ClickEvent; -import net.minecraft.text.HoverEvent; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.reflect.Field; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; - -public class CommandHelper { - private static final Map>> FUNCTION_COMMAND_NODES = new ConcurrentHashMap<>(); - public static final Set CLIENT_COMMANDS = new HashSet<>(); - public static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.00", new DecimalFormatSymbols(Locale.UK)); - - private static CommandTreeS2CPacket fakeCommandPacket; - private static MethodHandle argumentHandle; - - static { - DECIMAL_FORMAT.setGroupingUsed(false); - } - - public static CompletableFuture suggestOnlinePlayers(SuggestionsBuilder builder) { - ClientPlayNetworkHandler networkHandler = EssentialUtils.getNetworkHandler(); - if (networkHandler == null || networkHandler.getPlayerList() == null) { - return CommandSource.suggestMatching(List.of(), builder); - } - List playerList = new ArrayList<>(); - networkHandler.getPlayerList().forEach(p -> playerList.add(p.getProfile().getName())); - return CommandSource.suggestMatching(playerList.toArray(String[]::new), builder); - } - - public static boolean isClientCommand(String command) { - if (CLIENT_COMMANDS.contains(command)) { - return true; - } - for (Set> commandNodes : FUNCTION_COMMAND_NODES.values()) { - for (LiteralCommandNode commandNode : commandNodes) { - if (commandNode.getLiteral().equals(command)) { - return true; - } - } - } - return false; - } - - public static void addComplexCommand(Interpreter interpreter, LiteralCommandNode commandNode) { - if (interpreter.isRunning()) { - Set> commandNodeSet = FUNCTION_COMMAND_NODES.computeIfAbsent(interpreter.getProperties().getId(), id -> { - interpreter.addStopEvent(() -> FUNCTION_COMMAND_NODES.remove(id)); - return ConcurrentHashMap.newKeySet(); - }); - commandNodeSet.add(commandNode); - } - } - - public static void registerFunctionCommands(CommandDispatcher dispatcher) { - for (Set> commandNodes : FUNCTION_COMMAND_NODES.values()) { - for (LiteralCommandNode commandNode : commandNodes) { - dispatcher.getRoot().addChild(commandNode); - } - } - } - - public static void clearClientCommands() { - CLIENT_COMMANDS.clear(); - } - - // TODO: Use fabric command source! - public static void executeCommand(StringReader reader, String command) { - ClientPlayerEntity player = EssentialUtils.getPlayer(); - try { - player.networkHandler.getCommandDispatcher().execute(reader, new FakeCommandSource(player)); - } catch (CommandSyntaxException e) { - EssentialUtils.sendMessage(ChatColour.RED + e.getMessage()); - if (e.getInput() != null && e.getCursor() >= 0) { - int cursor = Math.min(e.getCursor(), e.getInput().length()); - MutableText text = Text.literal("").formatted(Formatting.GRAY) - .styled(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command))); - if (cursor > 10) { - text.append("..."); - } - - text.append(e.getInput().substring(Math.max(0, cursor - 10), cursor)); - if (cursor < e.getInput().length()) { - text.append(Text.literal(e.getInput().substring(cursor)).formatted(Formatting.RED, Formatting.UNDERLINE)); - } - - text.append(Text.translatable("command.context.here").formatted(Formatting.RED, Formatting.ITALIC)); - EssentialUtils.sendMessage(text); - } - } catch (Exception e) { - Text error = Text.literal(e.getMessage() == null ? e.getClass().getName() : e.getMessage()); - EssentialUtils.getPlayer().sendMessage(Text.translatable("command.failed") - .styled(style -> style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, error))), false); - e.printStackTrace(); - } - } - - public static void setCommandPacket(CommandTreeS2CPacket packet, CommandRegistryAccess registryAccess) { - if (packet == null) { - return; - } - Collection> commandNodes = packet.getCommandTree(registryAccess).getChildren(); - - RootCommandNode newRootCommandNode = new RootCommandNode<>(); - for (CommandNode commandNode : commandNodes) { - newRootCommandNode.addChild(commandNode); - } - fakeCommandPacket = new CommandTreeS2CPacket(newRootCommandNode); - } - - public static CommandTreeS2CPacket getCommandPacket() { - return fakeCommandPacket; - } - - public static Collection> getArguments(CommandContext context) { - try { - if (argumentHandle == null) { - Field field = CommandContext.class.getDeclaredField("arguments"); - field.setAccessible(true); - MethodHandles.Lookup lookup = MethodHandles.lookup(); - argumentHandle = lookup.unreflectGetter(field); - } - @SuppressWarnings("unchecked") - Map> parsedArgumentMap = (Map>) argumentHandle.invokeExact(context); - return parsedArgumentMap.values(); - } catch (Throwable throwable) { - EssentialClient.LOGGER.error(throwable); - } - return null; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/command/DefinitionArgumentType.java b/src/main/java/me/senseiwells/essentialclient/utils/command/DefinitionArgumentType.java deleted file mode 100644 index e095e8be..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/command/DefinitionArgumentType.java +++ /dev/null @@ -1,48 +0,0 @@ -package me.senseiwells.essentialclient.utils.command; - -import com.mojang.brigadier.StringReader; -import com.mojang.brigadier.arguments.ArgumentType; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; -import com.mojang.brigadier.suggestion.Suggestions; -import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import me.senseiwells.arucas.classes.EnumDefinition; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.essentialclient.utils.render.Texts; -import net.minecraft.command.CommandSource; - -import java.util.concurrent.CompletableFuture; - -public class DefinitionArgumentType implements ArgumentType { - static { - INVALID_ENUM_EXCEPTION = new DynamicCommandExceptionType(Texts.ENUM_NOT_FOUND::generate); - } - - private static final DynamicCommandExceptionType INVALID_ENUM_EXCEPTION; - - private final EnumDefinition definition; - - private DefinitionArgumentType(EnumDefinition definition) { - this.definition = definition; - } - - public static DefinitionArgumentType enumeration(EnumDefinition enumDefinition) { - return new DefinitionArgumentType(enumDefinition); - } - - @Override - public ClassInstance parse(StringReader reader) throws CommandSyntaxException { - String enumName = reader.readString(); - ClassInstance enumValue = this.definition.getEnum(enumName); - if (enumValue == null) { - throw INVALID_ENUM_EXCEPTION.create(enumName); - } - return enumValue; - } - - @Override - public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { - return CommandSource.suggestMatching(this.definition.getNames(), builder); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/command/EnumArgumentType.java b/src/main/java/me/senseiwells/essentialclient/utils/command/EnumArgumentType.java deleted file mode 100644 index d8bd8468..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/command/EnumArgumentType.java +++ /dev/null @@ -1,57 +0,0 @@ -package me.senseiwells.essentialclient.utils.command; - -import com.mojang.brigadier.StringReader; -import com.mojang.brigadier.arguments.ArgumentType; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; -import com.mojang.brigadier.suggestion.Suggestions; -import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import me.senseiwells.essentialclient.utils.render.Texts; -import net.minecraft.command.CommandSource; -import net.minecraft.server.command.ServerCommandSource; - -import java.util.HashMap; -import java.util.concurrent.CompletableFuture; - -public class EnumArgumentType> implements ArgumentType { - static { - INVALID_ELEMENT_EXCEPTION = new DynamicCommandExceptionType(Texts.ENUM_NOT_FOUND::generate); - } - - private static final DynamicCommandExceptionType INVALID_ELEMENT_EXCEPTION; - private final HashMap values; - private final Class clazz; - - private EnumArgumentType(Class clazz) { - this.clazz = clazz; - Enum[] arrayOfEnum = clazz.getEnumConstants(); - this.values = new HashMap<>(arrayOfEnum.length); - for (Enum enumeration : arrayOfEnum) { - this.values.put(enumeration.name().toLowerCase(), clazz.cast(enumeration)); - } - } - - public static > EnumArgumentType enumeration(Class clazz) { - return new EnumArgumentType<>(clazz); - } - - public static > T getEnumeration(CommandContext commandContext, String string, Class clazz) { - return commandContext.getArgument(string, clazz); - } - - @Override - public T parse(StringReader reader) throws CommandSyntaxException { - String name = reader.readString(); - Enum enumeration = this.values.get(name); - if (enumeration != null) { - return this.clazz.cast(enumeration); - } - throw INVALID_ELEMENT_EXCEPTION.create(name); - } - - @Override - public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { - return CommandSource.suggestMatching(this.values.keySet(), builder); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/command/FakeCommandSource.java b/src/main/java/me/senseiwells/essentialclient/utils/command/FakeCommandSource.java deleted file mode 100644 index cb43b879..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/command/FakeCommandSource.java +++ /dev/null @@ -1,10 +0,0 @@ -package me.senseiwells.essentialclient.utils.command; - -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.server.command.ServerCommandSource; - -public class FakeCommandSource extends ServerCommandSource { - public FakeCommandSource(ClientPlayerEntity playerEntity) { - super(playerEntity, playerEntity.getPos(), playerEntity.getRotationClient(), null, 0, playerEntity.getNameForScoreboard(), playerEntity.getName(), null, playerEntity); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/command/PlayerData.java b/src/main/java/me/senseiwells/essentialclient/utils/command/PlayerData.java deleted file mode 100644 index 14e6f1d6..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/command/PlayerData.java +++ /dev/null @@ -1,7 +0,0 @@ -package me.senseiwells.essentialclient.utils.command; - -import net.minecraft.util.math.Vec2f; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.GameMode; - -public record PlayerData(Vec3d pos, Vec2f rotation, WorldEnum world, GameMode gamemode) { } diff --git a/src/main/java/me/senseiwells/essentialclient/utils/command/RegexArgumentType.java b/src/main/java/me/senseiwells/essentialclient/utils/command/RegexArgumentType.java deleted file mode 100644 index d6d9a496..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/command/RegexArgumentType.java +++ /dev/null @@ -1,136 +0,0 @@ -package me.senseiwells.essentialclient.utils.command; - -import com.mojang.brigadier.StringReader; -import com.mojang.brigadier.arguments.ArgumentType; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; -import net.minecraft.text.Text; - -import java.util.Arrays; -import java.util.Collection; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - -// Taken from ClientCommands -public class RegexArgumentType implements ArgumentType { - - private static final DynamicCommandExceptionType EXPECTED_REGEX_EXCEPTION = new DynamicCommandExceptionType(arg -> Text.translatable("Invalid regex %s", arg)); - - private final RegexType type; - - private RegexArgumentType(RegexType type) { - this.type = type; - } - - @SuppressWarnings("unused") - public static RegexArgumentType wordRegex() { - return new RegexArgumentType(RegexType.SINGLE_WORD); - } - - @SuppressWarnings("unused") - public static RegexArgumentType slashyRegex() { - return new RegexArgumentType(RegexType.SLASHY_PHRASE); - } - - @SuppressWarnings("unused") - public static RegexArgumentType greedyRegex() { - return new RegexArgumentType(RegexType.GREEDY_PHRASE); - } - - @SuppressWarnings("unused") - public static Pattern getRegex(CommandContext context, String name) { - return context.getArgument(name, Pattern.class); - } - - @Override - public Pattern parse(StringReader reader) throws CommandSyntaxException { - final int start = reader.getCursor(); - if (this.type == RegexType.GREEDY_PHRASE) { - String text = reader.getRemaining(); - try { - Pattern pattern = Pattern.compile(text); - reader.setCursor(reader.getTotalLength()); - return pattern; - } catch (PatternSyntaxException e) { - reader.setCursor(start); - throw EXPECTED_REGEX_EXCEPTION.createWithContext(reader, text); - } - } - if (this.type == RegexType.SINGLE_WORD) { - String text = reader.readUnquotedString(); - try { - return Pattern.compile(text); - } catch (PatternSyntaxException e) { - reader.setCursor(start); - throw EXPECTED_REGEX_EXCEPTION.createWithContext(reader, text); - } - } - return parseSlashyRegex(reader); - } - - public static Pattern parseSlashyRegex(StringReader reader) throws CommandSyntaxException { - final int start = reader.getCursor(); - - boolean slashy = reader.canRead() && reader.peek() == '/'; - if (!slashy) { - String text = reader.readUnquotedString(); - try { - return Pattern.compile(text); - } catch (PatternSyntaxException e) { - reader.setCursor(start); - throw EXPECTED_REGEX_EXCEPTION.createWithContext(reader, text); - } - } - - reader.skip(); // / - - StringBuilder regex = new StringBuilder(); - boolean escaped = false; - while (true) { - if (!reader.canRead()) { - reader.setCursor(start); - throw EXPECTED_REGEX_EXCEPTION.createWithContext(reader, reader.getString().substring(start)); - } - - if (reader.peek() == '/') { - if (!escaped) { - reader.skip(); - try { - return Pattern.compile(regex.toString()); - } catch (PatternSyntaxException e) { - int end = reader.getCursor(); - reader.setCursor(start); - throw EXPECTED_REGEX_EXCEPTION.createWithContext(reader, reader.getString().substring(start, end)); - } - } - regex.deleteCharAt(regex.length() - 1); // the backslash which escaped this slash - } - - escaped = reader.peek() == '\\' && !escaped; - regex.append(reader.peek()); - reader.skip(); - } - } - - @Override - public Collection getExamples() { - return this.type.getExamples(); - } - - public enum RegexType { - SINGLE_WORD("word", "\\w+"), - SLASHY_PHRASE("/\\w+/", "word", "//"), - GREEDY_PHRASE("word", "words with spaces", "/and symbols/"); - - private final Collection examples; - - RegexType(final String... examples) { - this.examples = Arrays.asList(examples); - } - - public Collection getExamples() { - return this.examples; - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/command/WorldEnum.java b/src/main/java/me/senseiwells/essentialclient/utils/command/WorldEnum.java deleted file mode 100644 index a518d0e0..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/command/WorldEnum.java +++ /dev/null @@ -1,25 +0,0 @@ -package me.senseiwells.essentialclient.utils.command; - -import net.minecraft.registry.RegistryKey; -import net.minecraft.world.World; - -public enum WorldEnum { - OVERWORLD(World.OVERWORLD), - THE_NETHER(World.NETHER), - THE_END(World.END); - - private final RegistryKey registryKey; - - WorldEnum(RegistryKey registryKey) { - this.registryKey = registryKey; - } - - public static WorldEnum fromRegistryKey(RegistryKey registryKey) { - for (WorldEnum worldEnum : WorldEnum.values()) { - if (worldEnum.registryKey.equals(registryKey)) { - return worldEnum; - } - } - return null; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/config/AbstractMappedConfig.java b/src/main/java/me/senseiwells/essentialclient/utils/config/AbstractMappedConfig.java deleted file mode 100644 index 817d409c..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/config/AbstractMappedConfig.java +++ /dev/null @@ -1,59 +0,0 @@ -package me.senseiwells.essentialclient.utils.config; - -import com.google.gson.JsonElement; - -import java.nio.file.Path; -import java.util.LinkedHashMap; -import java.util.Map; - -public abstract class AbstractMappedConfig implements Config { - protected final Map map; - - public AbstractMappedConfig() { - this.map = new LinkedHashMap<>(); - } - - public V get(K key) { - return this.map.get(key); - } - - public void set(K key, V value) { - this.map.put(key, value); - } - - public boolean has(K key) { - return this.map.containsKey(key); - } - - public V remove(K key) { - return this.map.remove(key); - } - - protected abstract JsonElement keyToJson(K key); - - protected abstract JsonElement valueToJson(V value); - - protected abstract K jsonToKey(JsonElement keyElement); - - protected abstract V jsonToValue(K key, JsonElement valueElement); - - @Override - public final void readConfig() { - Config.super.readConfig(); - } - - @Override - public final Path getConfigRootPath() { - return Config.super.getConfigRootPath(); - } - - @Override - public final T getConfigData() { - return Config.super.getConfigData(); - } - - @Override - public final void saveConfig() { - Config.super.saveConfig(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/config/Config.java b/src/main/java/me/senseiwells/essentialclient/utils/config/Config.java deleted file mode 100644 index 6bf04abe..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/config/Config.java +++ /dev/null @@ -1,127 +0,0 @@ -package me.senseiwells.essentialclient.utils.config; - -import com.google.gson.*; -import me.senseiwells.arucas.utils.FileUtils; -import me.senseiwells.essentialclient.EssentialClient; -import me.senseiwells.essentialclient.utils.EssentialUtils; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -public interface Config { - Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().serializeNulls().create(); - - /** - * This is used when displaying - * errors about the config - * - * @return the name of the config - */ - String getConfigName(); - - /** - * This gets the type of Json, we cannot cast - * to T as it will throw outside the catch - * - * @return the JsonElement type - */ - Class getJsonType(); - - /** - * This gets the data that will - * be saved to the config - * - * @return the data that should be saved - */ - JsonElement getSaveData(); - - /** - * This passes in the config - * data to be processed - * - * @param element the config data - */ - void readConfig(T element); - - /** - * This should be called when - * you want to read a config file - */ - default void readConfig() { - T element = this.getConfigData(); - if (element != null) { - this.readConfig(element); - } - } - - /** - * This is the path of the config, it's - * used to read and write the file - * - * @return the path of the config - */ - default Path getConfigPath() { - return this.getConfigRootPath().resolve(this.getConfigName() + ".json"); - } - - /** - * This gets the root config folder - * in this case in the EssentialClient - * folder located in .minecraft/config - * - * @return the root path of the config - */ - default Path getConfigRootPath() { - Path root = EssentialUtils.getEssentialConfigFile(); - FileUtils.ensureExists(root); - return root; - } - - /** - * This gets the config data - * from the specified file - * - * @return the config data - */ - default T getConfigData() { - Path configPath = this.getConfigPath(); - if (Files.isRegularFile(configPath)) { - try (BufferedReader reader = Files.newBufferedReader(configPath)) { - return this.GSON.fromJson(reader, this.getJsonType()); - } catch (IOException | JsonParseException e) { - EssentialClient.LOGGER.error("Failed to read '{}': {}", this.getConfigName(), e); - } - } - return null; - } - - /** - * This should be called when you - * want to save the config file - */ - default void saveConfig() { - Path configPath = this.getConfigPath(); - try (BufferedWriter writer = Files.newBufferedWriter(configPath)) { - this.GSON.toJson(this.getSaveData(), writer); - } catch (IOException e) { - EssentialClient.LOGGER.error("Failed to save '{}': {}", this.getConfigName(), e); - } - } - - interface CList extends Config { - @Override - default Class getJsonType() { - return JsonArray.class; - } - } - - interface CMap extends Config { - @Override - default Class getJsonType() { - return JsonObject.class; - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/config/ConfigClientNick.java b/src/main/java/me/senseiwells/essentialclient/utils/config/ConfigClientNick.java deleted file mode 100644 index 60e944de..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/config/ConfigClientNick.java +++ /dev/null @@ -1,34 +0,0 @@ -package me.senseiwells.essentialclient.utils.config; - -import com.google.gson.JsonElement; -import com.google.gson.JsonPrimitive; -import com.mojang.brigadier.suggestion.Suggestions; -import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import net.minecraft.command.CommandSource; - -import java.util.concurrent.CompletableFuture; - -public class ConfigClientNick extends MappedStringConfig { - public static final ConfigClientNick INSTANCE = new ConfigClientNick(); - - private ConfigClientNick() { } - - public CompletableFuture suggestPlayerRename(SuggestionsBuilder builder) { - return this.map.isEmpty() ? builder.buildFuture() : CommandSource.suggestMatching(this.map.keySet(), builder); - } - - @Override - public String getConfigName() { - return "ClientNick"; - } - - @Override - protected JsonElement valueToJson(String value) { - return new JsonPrimitive(value); - } - - @Override - protected String jsonToValue(String key, JsonElement valueElement) { - return valueElement.getAsString(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/config/ConfigPlayerClient.java b/src/main/java/me/senseiwells/essentialclient/utils/config/ConfigPlayerClient.java deleted file mode 100644 index c82b8e73..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/config/ConfigPlayerClient.java +++ /dev/null @@ -1,55 +0,0 @@ -package me.senseiwells.essentialclient.utils.config; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.mojang.brigadier.suggestion.Suggestions; -import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import me.senseiwells.essentialclient.utils.command.PlayerData; -import me.senseiwells.essentialclient.utils.command.WorldEnum; -import net.minecraft.command.CommandSource; -import net.minecraft.util.math.Vec2f; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.GameMode; - -import java.util.concurrent.CompletableFuture; - -public class ConfigPlayerClient extends MappedStringConfig { - public static final ConfigPlayerClient INSTANCE = new ConfigPlayerClient(); - - private ConfigPlayerClient() { } - - public CompletableFuture suggestPlayer(SuggestionsBuilder builder) { - return this.map.isEmpty() ? builder.buildFuture() : CommandSource.suggestMatching(this.map.keySet(), builder); - } - - @Override - public String getConfigName() { - return "PlayerClient"; - } - - @Override - protected JsonElement valueToJson(PlayerData value) { - JsonObject playerData = new JsonObject(); - playerData.addProperty("x", value.pos().x); - playerData.addProperty("y", value.pos().y); - playerData.addProperty("z", value.pos().z); - playerData.addProperty("yaw", value.rotation().x); - playerData.addProperty("pitch", value.rotation().y); - playerData.addProperty("dimension", value.world().name().toLowerCase()); - playerData.addProperty("gamemode", value.gamemode() == null ? "" : value.gamemode().getName()); - return playerData; - } - - @Override - protected PlayerData jsonToValue(String key, JsonElement valueElement) { - JsonObject playerData = valueElement.getAsJsonObject(); - double x = playerData.get("x").getAsDouble(); - double y = playerData.get("y").getAsDouble(); - double z = playerData.get("z").getAsDouble(); - float yaw = playerData.get("yaw").getAsFloat(); - float pitch = playerData.get("pitch").getAsFloat(); - WorldEnum world = WorldEnum.valueOf(playerData.get("dimension").getAsString().toUpperCase()); - GameMode gameMode = GameMode.byName(playerData.get("gamemode").getAsString(), null); - return new PlayerData(new Vec3d(x, y, z), new Vec2f(yaw, pitch), world, gameMode); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/config/ConfigPlayerList.java b/src/main/java/me/senseiwells/essentialclient/utils/config/ConfigPlayerList.java deleted file mode 100644 index 8525420a..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/config/ConfigPlayerList.java +++ /dev/null @@ -1,42 +0,0 @@ -package me.senseiwells.essentialclient.utils.config; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.mojang.brigadier.suggestion.Suggestions; -import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import net.minecraft.command.CommandSource; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -public class ConfigPlayerList extends MappedStringConfig> { - public static final ConfigPlayerList INSTANCE = new ConfigPlayerList(); - - private ConfigPlayerList() { } - - public CompletableFuture suggestList(SuggestionsBuilder builder) { - return this.map.isEmpty() ? builder.buildFuture() : CommandSource.suggestMatching(this.map.keySet(), builder); - } - - @Override - public String getConfigName() { - return "PlayerList"; - } - - @Override - protected JsonElement valueToJson(List value) { - JsonArray playerList = new JsonArray(); - value.forEach(playerList::add); - return playerList; - } - - @Override - protected List jsonToValue(String key, JsonElement valueElement) { - List playerList = new ArrayList<>(); - valueElement.getAsJsonArray().forEach(jsonElement -> { - playerList.add(jsonElement.getAsString()); - }); - return playerList; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/config/ListedConfig.java b/src/main/java/me/senseiwells/essentialclient/utils/config/ListedConfig.java deleted file mode 100644 index 3e6d21d3..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/config/ListedConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -package me.senseiwells.essentialclient.utils.config; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; - -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; - -@SuppressWarnings("unused") -public abstract class ListedConfig implements Config.CList { - protected final List list; - - public ListedConfig() { - this.list = new ArrayList<>(); - } - - public void add(E element) { - this.list.add(element); - } - - public E get(int index) { - return this.list.get(index); - } - - public E remove(int index) { - return this.list.remove(index); - } - - protected abstract JsonElement elementToJson(E element); - - protected abstract E jsonToElement(JsonElement element); - - @Override - public final JsonArray getSaveData() { - JsonArray configList = new JsonArray(); - this.list.forEach(e -> configList.add(this.elementToJson(e))); - return configList; - } - - @Override - public final void readConfig(JsonArray element) { - element.forEach(jsonElement -> this.list.add(this.jsonToElement(element))); - } - - @Override - public final void readConfig() { - Config.CList.super.readConfig(); - } - - @Override - public final Path getConfigRootPath() { - return Config.CList.super.getConfigRootPath(); - } - - @Override - public final JsonArray getConfigData() { - return Config.CList.super.getConfigData(); - } - - @Override - public final void saveConfig() { - Config.CList.super.saveConfig(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/config/MappedConfig.java b/src/main/java/me/senseiwells/essentialclient/utils/config/MappedConfig.java deleted file mode 100644 index 6e24f6e7..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/config/MappedConfig.java +++ /dev/null @@ -1,37 +0,0 @@ -package me.senseiwells.essentialclient.utils.config; - -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; - -@SuppressWarnings("unused") -public abstract class MappedConfig extends AbstractMappedConfig implements Config.CList { - public String getKeyName() { - return "key"; - } - - public String getValueName() { - return "value"; - } - - @Override - public final JsonArray getSaveData() { - JsonArray configArray = new JsonArray(); - this.map.forEach((k, v) -> { - JsonObject mapObject = new JsonObject(); - mapObject.add(this.getKeyName(), this.keyToJson(k)); - mapObject.add(this.getValueName(), this.valueToJson(v)); - configArray.add(mapObject); - }); - return configArray; - } - - @Override - public final void readConfig(JsonArray jsonElement) { - jsonElement.getAsJsonArray().forEach(element -> { - JsonObject mapObject = element.getAsJsonObject(); - K key = this.jsonToKey(mapObject.get(this.getKeyName())); - V value = this.jsonToValue(key, mapObject.get(this.getValueName())); - this.map.put(key, value); - }); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/config/MappedStringConfig.java b/src/main/java/me/senseiwells/essentialclient/utils/config/MappedStringConfig.java deleted file mode 100644 index 8fde5e9b..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/config/MappedStringConfig.java +++ /dev/null @@ -1,33 +0,0 @@ -package me.senseiwells.essentialclient.utils.config; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -public abstract class MappedStringConfig extends AbstractMappedConfig implements Config.CMap { - @Override - protected final JsonElement keyToJson(String key) { - throw new UnsupportedOperationException("Key should not be converted to json"); - } - - @Override - protected final String jsonToKey(JsonElement keyElement) { - throw new UnsupportedOperationException("Key should not be converted from json"); - } - - @Override - public JsonObject getSaveData() { - JsonObject jsonObject = new JsonObject(); - this.map.forEach((s, v) -> jsonObject.add(s, this.valueToJson(v))); - return jsonObject; - } - - @Override - public final void readConfig(JsonObject element) { - element.entrySet().forEach(entry -> { - V value = this.jsonToValue(entry.getKey(), entry.getValue()); - if (value != null) { - this.map.put(entry.getKey(), value); - } - }); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/interfaces/ChatHudAccessor.java b/src/main/java/me/senseiwells/essentialclient/utils/interfaces/ChatHudAccessor.java deleted file mode 100644 index 88bb11bd..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/interfaces/ChatHudAccessor.java +++ /dev/null @@ -1,9 +0,0 @@ -package me.senseiwells.essentialclient.utils.interfaces; - -import net.minecraft.client.gui.hud.ChatHudLine; - -import java.util.List; - -public interface ChatHudAccessor { - List essentialclient$getMessages(); -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/interfaces/IEntityList.java b/src/main/java/me/senseiwells/essentialclient/utils/interfaces/IEntityList.java deleted file mode 100644 index d4473239..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/interfaces/IEntityList.java +++ /dev/null @@ -1,10 +0,0 @@ -package me.senseiwells.essentialclient.utils.interfaces; - -import net.minecraft.entity.Entity; - -/** - * Thread safe accessor for Entities - */ -public interface IEntityList { - Entity[] essentialclient$getAllEntities(); -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/interfaces/IGameRule.java b/src/main/java/me/senseiwells/essentialclient/utils/interfaces/IGameRule.java deleted file mode 100644 index 555d2189..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/interfaces/IGameRule.java +++ /dev/null @@ -1,7 +0,0 @@ -package me.senseiwells.essentialclient.utils.interfaces; - -import net.minecraft.server.MinecraftServer; - -public interface IGameRule { - void essentialclient$ruleChanged(String ruleName, MinecraftServer server); -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/interfaces/IGhostRecipeBookWidget.java b/src/main/java/me/senseiwells/essentialclient/utils/interfaces/IGhostRecipeBookWidget.java deleted file mode 100644 index 4a9232d2..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/interfaces/IGhostRecipeBookWidget.java +++ /dev/null @@ -1,5 +0,0 @@ -package me.senseiwells.essentialclient.utils.interfaces; - -public interface IGhostRecipeBookWidget { - void essentialclient$clearGhostSlots(); -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/interfaces/IScreenInventory.java b/src/main/java/me/senseiwells/essentialclient/utils/interfaces/IScreenInventory.java deleted file mode 100644 index 540a251a..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/interfaces/IScreenInventory.java +++ /dev/null @@ -1,5 +0,0 @@ -package me.senseiwells.essentialclient.utils.interfaces; - -public interface IScreenInventory { - void essentialclient$setForced(); -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/interfaces/MinecraftClientInvoker.java b/src/main/java/me/senseiwells/essentialclient/utils/interfaces/MinecraftClientInvoker.java deleted file mode 100644 index 31762c80..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/interfaces/MinecraftClientInvoker.java +++ /dev/null @@ -1,7 +0,0 @@ -package me.senseiwells.essentialclient.utils.interfaces; - -public interface MinecraftClientInvoker { - void essentialclient$rightClick(); - - void essentialclient$leftClick(); -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/interfaces/Rule.java b/src/main/java/me/senseiwells/essentialclient/utils/interfaces/Rule.java deleted file mode 100644 index bce79d24..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/interfaces/Rule.java +++ /dev/null @@ -1,321 +0,0 @@ -package me.senseiwells.essentialclient.utils.interfaces; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonPrimitive; -import me.senseiwells.essentialclient.EssentialClient; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.function.Consumer; - -public interface Rule { - String getName(); - - Type getType(); - - String getDescription(); - - String getOptionalInfo(); - - T getDefaultValue(); - - T getValue(); - - T fromJson(JsonElement element); - - JsonElement toJson(T value); - - List> getListeners(); - - Rule shallowCopy(); - - void setValueQuietly(T value); - - void setValueFromString(String value); - - void setOptionalInfo(String optionalInfo); - - default String getCategory() { - return null; - } - - default boolean changeable() { - return true; - } - - default boolean isAvailable() { - return true; - } - - default boolean display() { - return true; - } - - default JsonElement getValueAsJson() { - return this.toJson(this.getValue()); - } - - default JsonElement getDefaultValueAsJson() { - return this.toJson(this.getDefaultValue()); - } - - default void addListener(RuleListener ruleListener) { - if (ruleListener != null) { - this.getListeners().add(ruleListener); - } - } - - default void setValue(T value) { - if (!Objects.equals(this.getValue(), value)) { - this.setValueQuietly(value); - this.onValueChange(); - } - } - - default void onValueChange() { - if (this.getListeners() != null) { - for (RuleListener ruleListener : this.getListeners()) { - ruleListener.accept(this); - } - } - } - - default void setValueFromJson(JsonElement element) { - this.setValue(this.fromJson(element)); - } - - default void resetToDefault() { - this.setValue(this.getDefaultValue()); - } - - default boolean isNotDefault() { - return !this.getValue().equals(this.getDefaultValue()); - } - - default void logCannotSet(Object value) { - EssentialClient.LOGGER.error("Cannot set the value '{}' for rule {}", value, this.getName()); - } - - interface Bool extends Rule { - default void invert() { - this.setValue(!this.getValue()); - } - - @Override - default Type getType() { - return Type.BOOLEAN; - } - - @Override - default Boolean fromJson(JsonElement element) { - return element.getAsBoolean(); - } - - @Override - default JsonElement toJson(Boolean value) { - return new JsonPrimitive(value); - } - - @Override - default void setValueFromString(String value) { - this.setValue("true".equals(value)); - } - } - - interface Num extends Rule { - @Override - Type getType(); - - @Override - default JsonElement toJson(T value) { - return new JsonPrimitive(value); - } - } - - interface Slider extends Num { - String getFormatted(); - - T getMin(); - - T getMax(); - - T getNewValue(double percent); - - double getPercentage(); - - default void setFromPercentage(double percentage) { - this.setValue(this.getNewValue(percentage)); - } - - @Override - default Type getType() { - return Type.SLIDER; - } - } - - interface Str extends Rule { - @Override - default Type getType() { - return Type.STRING; - } - - @Override - default String fromJson(JsonElement element) { - return element.getAsString(); - } - - @Override - default JsonElement toJson(String value) { - return new JsonPrimitive(value); - } - - @Override - default void setValueFromString(String value) { - this.setValue(value); - } - - int getMaxLength(); - - void setMaxLength(int maxLength); - } - - interface Cycle extends Rule { - List getCycleValues(); - - int getCurrentIndex(); - - void setCurrentIndex(int index); - - default int getMaxIndex() { - return this.getCycleValues().size() - 1; - } - - default void cycleValues() { - int currentIndex = this.getCurrentIndex(); - this.setCurrentIndex(currentIndex >= this.getMaxIndex() ? 0 : ++currentIndex); - this.setValue(this.getCycleValues().get(this.getCurrentIndex())); - } - - @Override - default Type getType() { - return Type.CYCLE; - } - - @Override - default JsonElement toJson(String value) { - return new JsonPrimitive(value); - } - - @Override - default String fromJson(JsonElement value) { - return value.getAsString(); - } - - @Override - default void setValueFromString(String value) { - this.setValue(value); - } - - @Override - default void setValue(String value) { - int index = this.getCycleValues().indexOf(value); - if (index == -1) { - this.logCannotSet(value); - return; - } - this.setCurrentIndex(index); - Rule.super.setValue(value); - } - - @Override - default void resetToDefault() { - Rule.super.resetToDefault(); - this.setCurrentIndex(0); - } - } - - interface ListRule extends Rule> { - @Override - default List fromJson(JsonElement value) { - JsonArray array = value.getAsJsonArray(); - - List configData = new ArrayList<>(); - for (JsonElement element : array) { - configData.add(element.getAsString()); - } - return configData; - } - - @Override - default JsonElement toJson(List value) { - JsonArray array = new JsonArray(); - for (String string : value) { - array.add(string); - } - return array; - } - - @Override - default Type getType() { - return Type.LIST; - } - - int getMaxLength(); - - void setMaxLength(int maxLength); - } - - @FunctionalInterface - interface RuleListener extends Consumer> { } - - enum Type { - BOOLEAN("Boolean", "boolean", Set.of(boolean.class, Boolean.class)), - INTEGER("Integer", "int", Set.of(int.class, Integer.class)), - DOUBLE("Double", "double", Set.of(double.class, Double.class)), - STRING("String", "string", Set.of(String.class)), - CYCLE("Cycle"), - SLIDER("Slider"), - LIST("List"), - NONE("None"); - - private final String name; - private final String alias; - private final Set> classAliases; - - Type(String string, String alias, Set> classAliases) { - this.name = string; - this.alias = alias; - this.classAliases = classAliases; - } - - Type(String string) { - this(string, string.toLowerCase(), Set.of()); - } - - public static Type fromClass(Class clazz) { - for (Type type : Type.values()) { - if (type.classAliases.contains(clazz)) { - return type; - } - } - return STRING; - } - - public static Type fromString(String name) { - for (Type type : Type.values()) { - if (type.name.equalsIgnoreCase(name) || type.alias.equals(name)) { - return type; - } - } - return STRING; - } - - @Override - public String toString() { - return this.name; - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/inventory/InventoryUtils.java b/src/main/java/me/senseiwells/essentialclient/utils/inventory/InventoryUtils.java deleted file mode 100644 index 1b1a67e4..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/inventory/InventoryUtils.java +++ /dev/null @@ -1,778 +0,0 @@ -package me.senseiwells.essentialclient.utils.inventory; - -import it.unimi.dsi.fastutil.ints.IntArrayList; -import it.unimi.dsi.fastutil.ints.IntList; -import me.senseiwells.arucas.builtin.BooleanDef; -import me.senseiwells.arucas.classes.instance.ClassInstance; -import me.senseiwells.arucas.exceptions.RuntimeError; -import me.senseiwells.arucas.functions.ArucasFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.essentialclient.clientscript.definitions.ItemStackDef; -import me.senseiwells.essentialclient.feature.CraftingSharedConstants; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptItemStack; -import me.senseiwells.essentialclient.utils.interfaces.IGhostRecipeBookWidget; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.ingame.CraftingScreen; -import net.minecraft.client.gui.screen.ingame.HandledScreen; -import net.minecraft.client.gui.screen.ingame.InventoryScreen; -import net.minecraft.client.gui.screen.ingame.MerchantScreen; -import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.network.ClientPlayerInteractionManager; -import net.minecraft.entity.EquipmentSlot; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.player.PlayerInventory; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.network.packet.c2s.play.RenameItemC2SPacket; -import net.minecraft.network.packet.c2s.play.SelectMerchantTradeC2SPacket; -import net.minecraft.recipe.*; -import net.minecraft.registry.DynamicRegistryManager; -import net.minecraft.screen.*; -import net.minecraft.screen.slot.Slot; -import net.minecraft.screen.slot.SlotActionType; -import net.minecraft.village.TradeOffer; -import net.minecraft.village.TradeOfferList; -import net.minecraft.village.TradedItem; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.function.Predicate; - -import static me.senseiwells.essentialclient.utils.EssentialUtils.*; - -public class InventoryUtils { - public static Slot getItemSlot(ClientPlayerEntity playerEntity, Item item) { - ScreenHandler containerPlayer = playerEntity.currentScreenHandler; - Predicate filterTotemStack = (s) -> s.getItem() == item; - Slot targetSlot = null; - for (Slot slot : containerPlayer.slots) { - ItemStack stack = slot.getStack(); - if (!stack.isEmpty() && filterTotemStack.test(stack)) { - targetSlot = slot; - break; - } - } - return targetSlot; - } - - public static void swapItemToEquipmentSlot(ClientPlayerEntity playerEntity, EquipmentSlot slotType, int sourceSlot) { - if (sourceSlot != -1 && playerEntity.currentScreenHandler == playerEntity.playerScreenHandler) { - ScreenHandler container = playerEntity.playerScreenHandler; - MinecraftClient client = EssentialUtils.getClient(); - if (client.interactionManager == null) { - return; - } - if (slotType == EquipmentSlot.MAINHAND) { - int currentHotbarSlot = playerEntity.getInventory().selectedSlot; - client.interactionManager.clickSlot(container.syncId, sourceSlot, currentHotbarSlot, SlotActionType.SWAP, client.player); - } else if (slotType == EquipmentSlot.OFFHAND) { - client.interactionManager.clickSlot(container.syncId, sourceSlot, 40, SlotActionType.SWAP, client.player); - } - } - } - - public static void dropAllItemType(Item item) { - PlayerEntity player = getPlayer(); - ClientPlayerInteractionManager interactionManager = getInteractionManager(); - ScreenHandler containerPlayer = player.currentScreenHandler; - for (Slot slot : containerPlayer.slots) { - ItemStack stack = slot.getStack(); - if (stack.getItem() == item) { - interactionManager.clickSlot(containerPlayer.syncId, slot.id, 1, SlotActionType.THROW, player); - } - } - } - - public static void dropAllItemExact(ItemStack test) { - PlayerEntity player = getPlayer(); - ClientPlayerInteractionManager interactionManager = getInteractionManager(); - ScreenHandler containerPlayer = player.currentScreenHandler; - for (Slot slot : containerPlayer.slots) { - ItemStack stack = slot.getStack(); - if (ItemStack.areItemsAndComponentsEqual(stack, test)) { - interactionManager.clickSlot(containerPlayer.syncId, slot.id, 1, SlotActionType.THROW, player); - } - } - } - - public static int isSlotInHotbar(ScreenHandler screenHandler, int slotNum) { - int totalSize = screenHandler.slots.size(); - if (screenHandler instanceof PlayerScreenHandler) { - return slotNum == 45 ? 40 : slotNum >= 36 ? slotNum - 36 : -1; - } - return slotNum >= totalSize - 10 ? slotNum - (totalSize - 9) : -1; - } - - private static boolean canMergeIntoMain(PlayerInventory inventory, ItemStack stack) { - int count = stack.getCount(); - for (int i = 0; i < inventory.main.size(); i++) { - ItemStack itemStack = inventory.main.get(i); - if (itemStack.isEmpty()) { - return true; - } - if (itemStack.getItem() == stack.getItem()) { - count -= itemStack.getMaxCount() - itemStack.getCount(); - if (count <= 0) { - return true; - } - } - } - return false; - } - - public static void tryMoveItemsToCraftingGridSlots(ItemStack[] itemStacks, ScreenHandler screenHandler) { - int numSlots = screenHandler.slots.size(); - if (9 < numSlots) { - clearCraftingGridOfItems(itemStacks, screenHandler); - - Slot slotGridFirst = screenHandler.getSlot(1); - Map> ingredientSlots = getSlotsPerItem(itemStacks); - for (Map.Entry> entry : ingredientSlots.entrySet()) { - ItemStack ingredientReference = entry.getKey().getDefaultStack(); - List recipeSlots = entry.getValue(); - List targetSlots = new ArrayList<>(); - for (int s : recipeSlots) { - targetSlots.add(s + 1); - } - fillCraftingGrid(screenHandler, slotGridFirst, ingredientReference, targetSlots); - } - } - } - - public static void clearCraftingGridOfItems(ItemStack[] recipe, ScreenHandler handler) { - final int invSlots = handler.slots.size(); - for (int i = 0, slotNum = 1; i < 9 && slotNum < invSlots; i++, slotNum++) { - EssentialUtils.throwAsUnchecked(() -> Thread.sleep(0, 1)); - Slot slotTmp = handler.getSlot(slotNum); - if (slotTmp != null && slotTmp.hasStack() && (!areStacksEqual(recipe[i], slotTmp.getStack()))) { - shiftClickSlot(handler, slotNum); - if (slotTmp.hasStack()) { - dropStack(handler, slotNum); - } - } - } - } - - private static void fillCraftingGrid( - ScreenHandler screenHandler, - Slot slotGridFirst, - ItemStack ingredientReference, - List targetSlots - ) { - PlayerEntity player = EssentialUtils.getPlayer(); - if (player == null) { - return; - } - int slotNum; - int slotReturn = -1; - int sizeOrig; - if (ingredientReference.isEmpty()) { - return; - } - while (true) { - slotNum = matchSlot(screenHandler, slotGridFirst, ingredientReference); - if (slotNum < 0) { - break; - } - if (slotReturn == -1) { - slotReturn = slotNum; - } - leftClickSlot(screenHandler, slotNum); - ItemStack stackCursor = getCursorStack(); - if (areStacksEqual(ingredientReference, stackCursor)) { - sizeOrig = stackCursor.getCount(); - dragSplitItemsIntoSlots(screenHandler, targetSlots); - stackCursor = getCursorStack(); - if (!stackCursor.isEmpty()) { - if (stackCursor.getCount() >= sizeOrig) { - break; - } - leftClickSlot(screenHandler, slotReturn); - if (!getCursorStack().isEmpty()) { - slotReturn = slotNum; - leftClickSlot(screenHandler, slotReturn); - } - } - } else { - break; - } - if (!getCursorStack().isEmpty()) { - break; - } - } - if (slotNum >= 0 && !getCursorStack().isEmpty()) { - leftClickSlot(screenHandler, slotNum); - } - } - - private static void dragSplitItemsIntoSlots(ScreenHandler handler, List targetSlots) { - ClientPlayerEntity player = getPlayer(); - if (player == null) { - return; - } - ItemStack stackInCursor = getCursorStack(); - if (stackInCursor.isEmpty()) { - return; - } - if (targetSlots.size() == 1) { - leftClickSlot(handler, targetSlots.get(0)); - return; - } - int numSlots = handler.slots.size(); - // Start to drag the items - craftClickSlot(handler, -999, 0); - for (int slotNum : targetSlots) { - if (slotNum >= numSlots) { - break; - } - // Dragging the items - craftClickSlot(handler, slotNum, 1); - } - // Finish dragging items - craftClickSlot(handler, -999, 2); - } - - public static boolean areStacksEqual(ItemStack stack1, ItemStack stack2) { - return !stack1.isEmpty() && stack1.getItem() == stack2.getItem(); - } - - public static boolean areStacksTotallyEqual(ItemStack stack1, ItemStack stack2) { - return !stack1.isEmpty() && ItemStack.areItemsAndComponentsEqual(stack1, stack2); - } - - private static int matchSlot(ScreenHandler container, Slot slotReference, ItemStack stackReference) { - int slotNum = -1; - int largest = 0; - for (Slot slot : container.slots) { - if (slot.inventory != slotReference.inventory && slot.hasStack() && areStacksEqual(stackReference, slot.getStack())) { - int stackSize = slot.getStack().getCount(); - if (stackSize > largest) { - slotNum = slot.id; - largest = stackSize; - } - } - } - return slotNum; - } - - /** - * @param stacks - this is the array of stacks that you want to craft - * @return - a map of the itemStack with a list of all the slots it is needed in - */ - private static Map> getSlotsPerItem(ItemStack[] stacks) { - Map> mapSlots = new HashMap<>(); - for (int i = 0; i < stacks.length; i++) { - Item item = stacks[i].getItem(); - if (item != Items.AIR) { - if (mapSlots.containsKey(item)) { - mapSlots.get(item).add(i); - } else { - List integerList = new ArrayList<>(); - integerList.add(i); - mapSlots.put(item, integerList); - } - } - } - return mapSlots; - } - - public static void swapSlot(ScreenHandler screenHandler, int index, int secondIndex) { - getInteractionManager().clickSlot(screenHandler.syncId, index, secondIndex, SlotActionType.SWAP, getPlayer()); - } - - public static void shiftClickSlot(ScreenHandler screen, int index) { - getInteractionManager().clickSlot(screen.syncId, index, 0, SlotActionType.QUICK_MOVE, getPlayer()); - } - - public static void leftClickSlot(ScreenHandler screen, int slotNum) { - getInteractionManager().clickSlot(screen.syncId, slotNum, 0, SlotActionType.PICKUP, getPlayer()); - } - - public static void craftClickSlot(ScreenHandler screen, int slotNum, int mouseButton) { - getInteractionManager().clickSlot(screen.syncId, slotNum, mouseButton, SlotActionType.QUICK_CRAFT, getPlayer()); - } - - public static void dropStack(ScreenHandler screen, int slotNum) { - getInteractionManager().clickSlot(screen.syncId, slotNum, 0, SlotActionType.THROW, getPlayer()); - } - - public static ItemStack getCursorStack() { - return getPlayer().currentScreenHandler.getCursorStack(); - } - - public static boolean setCursorStack(ItemStack stack) { - getPlayer().currentScreenHandler.setCursorStack(stack); - return true; - } - - public static ItemStack getStackAtSlot(ScreenHandler screenHandler, int slotId) { - return screenHandler.slots.get(slotId).getStack(); - } - - public static boolean areRecipesEqual(RecipeEntry recipe, RecipeEntry other) { - if (recipe == null || other == null) { - return false; - } - return recipe.id().equals(other.id()); - } - - public static boolean areTradesEqual(TradeOffer trade, TradeOffer other) { - return areStacksTotallyEqual(trade.getOriginalFirstBuyItem(), other.getOriginalFirstBuyItem()) - && areStacksTotallyEqual(trade.getSecondBuyItem().map(TradedItem::itemStack).orElse(ItemStack.EMPTY), other.getSecondBuyItem().map(TradedItem::itemStack).orElse(ItemStack.EMPTY)) - && areStacksTotallyEqual(trade.getSellItem(), other.getSellItem()); - } - - public static boolean isGridEmpty(ScreenHandler screenHandler, int gridLength) { - boolean isEmpty = true; - List slots = screenHandler.slots; - for (int i = 0; i < gridLength; i++) { - isEmpty &= !slots.get(i + 1).hasStack(); - } - return isEmpty; - } - - public static int getCraftingSlotLength(ScreenHandler handler) { - if (handler instanceof AbstractRecipeScreenHandler recipeScreen) { - return recipeScreen.getCraftingHeight() * recipeScreen.getCraftingWidth(); - } - return 0; - } - - public static void emptyCraftingGrid(ScreenHandler screenHandler, PlayerEntity player, int gridSize) { - List slots = player.currentScreenHandler.slots; - for (int i = 1; i < gridSize + 1; i++) { - shiftClickSlot(screenHandler, i); - if (slots.get(i).hasStack()) { - dropStack(screenHandler, i); - } - EssentialUtils.throwAsUnchecked(() -> Thread.sleep(0L, 1)); - } - } - - public static void dropStackScheduled(ScreenHandler screenHandler, boolean craftAll) { - CraftingSharedConstants.EXECUTOR.schedule(() -> { - int count = craftAll ? 64 : 1; - for (int i = 0; i < count; i++) { - getClient().execute(() -> dropStack(screenHandler, 0)); - EssentialUtils.throwAsUnchecked(() -> Thread.sleep(2L)); - } - }, 40L, TimeUnit.MILLISECONDS); - } - - @SuppressWarnings("unused") - public static void doCraftingSlotsFillAction(RecipeEntry recipe, HandledScreen handledScreen, boolean craftAll) { - doCraftingSlotsFillAction(recipe, null, handledScreen, craftAll); - } - - public static void doCraftingSlotsFillAction(RecipeEntry recipe, RecipeEntry lastRecipe, HandledScreen handledScreen, boolean craftAll) { - RecipeBookWidget widget; - if (handledScreen instanceof InventoryScreen playerScreen) { - widget = playerScreen.getRecipeBookWidget(); - } else if (handledScreen instanceof CraftingScreen craftingScreen) { - widget = craftingScreen.getRecipeBookWidget(); - } else { - // We not in correct screen. Should never happen really but just for the edge case - return; - } - - ScreenHandler handler = handledScreen.getScreenHandler(); - - PlayerEntity player = getPlayer(); - - int gridLength = getCraftingSlotLength(handler); - - // If chosen recipe is different or crafting grid has invalid recipe - if (!areRecipesEqual(recipe, lastRecipe) || (!isGridEmpty(handler, gridLength) && getStackAtSlot(handler, 0).isEmpty())) { - emptyCraftingGrid(handler, player, gridLength); - } - - RecipeMatcher matcher = new RecipeMatcher(); - // Populating the matcher - // Starting 1 to skip output slot. - handler.slots.stream().skip(1).map(Slot::getStack).forEachOrdered(matcher::addUnenchantedInput); - - IntList craftInputIds = new IntArrayList(); - int totalCraftOps = matcher.countCrafts(recipe, craftInputIds); - - if (totalCraftOps == 0 && isGridEmpty(handler, gridLength)) { - widget.showGhostRecipe(recipe, player.currentScreenHandler.slots); - } else { - ((IGhostRecipeBookWidget) widget).essentialclient$clearGhostSlots(); - parseRecipeAndCacheInventory(handler, gridLength, recipe.value(), craftInputIds, craftAll ? totalCraftOps : 1); - } - matcher.clear(); - } - - private static void parseRecipeAndCacheInventory(ScreenHandler screenHandler, int gridLength, Recipe recipe, IntList craftInputIds, int craftOps) { - if (recipe instanceof ShapedRecipe shapedRecipe) { - int gridSide = (int) Math.sqrt(gridLength); - int recipeWidth = shapedRecipe.getWidth(); - int recipeHeight = shapedRecipe.getHeight(); - - // Filling the recipe with AIR to convert 2x2 into 3x3 if player using 3x3 grid. otherwise, it does nothing - for (int i = 0; i < recipeHeight - 1; i++) { - for (int j = recipeWidth; j < gridSide; j++) { - craftInputIds.add(i * gridSide + j, 0); - } - } - } - cacheInventoryAndFillGrid(craftInputIds, screenHandler, craftOps); - } - - public static void cacheInventoryAndFillGrid(IntList craftInputIds, ScreenHandler screenHandler, int craftOps) { - Map inventoryCache = new HashMap<>(); - Map craftGridCache = new HashMap<>(); - List slots = screenHandler.slots; - - for (int i = 0, size = craftInputIds.size(); i < size; i++) { - int slotId = craftInputIds.getInt(i); - if (slotId != 0) { - craftGridCache.computeIfAbsent(slotId, IntArrayList::new).add(i + 1); // +1 to skip output slot - } - } - - for (Slot slot : slots) { - int id = RecipeMatcher.getItemId(slot.getStack()); - if (slot.inventory instanceof PlayerInventory && id != 0) { - inventoryCache.computeIfAbsent(id, IntArrayList::new).add(slot.id); - } - } - - fillCraftingGridWithItems(screenHandler, craftGridCache, inventoryCache, craftOps); - } - - public static void fillCraftingGridWithItems(ScreenHandler screenHandler, Map craftInputIds, Map inventoryCache, int craftOps) { - for (Integer itemId : craftInputIds.keySet()) { - IntList craftInputSlotIds = craftInputIds.get(itemId); - int recipeRequiredAmount = craftInputSlotIds.size(); - for (int i = 0; i < craftOps; i++) { - int startAt = 0; - int slotCounter = 0; - IntList slotsPerItem = inventoryCache.get(itemId); - if (slotsPerItem == null) { - continue; - } - do { - int slotId = slotsPerItem.getInt(slotCounter); - int count = getStackAtSlot(screenHandler, slotId).getCount(); - int endAt = Math.min(startAt + count, recipeRequiredAmount); - - leftClickSlot(screenHandler, slotId); - dragSplitItemsIntoGrid(screenHandler, craftInputSlotIds, startAt, endAt); - if (!getCursorStack().isEmpty()) { - leftClickSlot(screenHandler, slotId); - } - startAt = endAt; - } - while (startAt < recipeRequiredAmount && slotCounter++ < slotsPerItem.size()); - } - } - } - - public static void dragSplitItemsIntoGrid(ScreenHandler screenHandler, IntList craftingSlotIds, int startAt, int endAt) { - craftClickSlot(screenHandler, -999, 4); - for (int i = startAt; i < craftingSlotIds.size() && i < endAt; i++) { - int slotId = craftingSlotIds.getInt(i); - craftClickSlot(screenHandler, slotId, 5); - } - craftClickSlot(screenHandler, -999, 6); - } - - // ClientScript stuff - - public static void craftRecipe(RecipeEntry recipe, boolean shouldDrop, boolean craftAll) { - ScreenHandler handler = clickRecipe(recipe, craftAll); - if (shouldDrop) { - InventoryUtils.dropStackScheduled(handler, craftAll); - } else { - InventoryUtils.shiftClickSlot(handler, 0); - } - } - - public static ScreenHandler clickRecipe(RecipeEntry recipe, boolean craftAll) { - if (!(EssentialUtils.getClient().currentScreen instanceof HandledScreen handledScreen)) { - throw new RuntimeError("Must be in a crafting GUI"); - } - ScreenHandler handler = handledScreen.getScreenHandler(); - CraftingSharedConstants.IS_SCRIPT_CLICK.set(true); - EssentialUtils.getInteractionManager().clickRecipe(handler.syncId, recipe, craftAll); - return handler; - } - - public static Object anvil(Interpreter interpreter, ArucasFunction predicate1, ArucasFunction predicate2, boolean takeItems) { - ClientPlayerEntity player = getPlayer(); - if (!(player.currentScreenHandler instanceof AnvilScreenHandler anvilHandler)) { - throw new RuntimeError("Not in anvil gui"); - } - interpreter = interpreter.branch(); - ClientPlayerInteractionManager interactionManager = getInteractionManager(); - boolean firstValid = false; - boolean secondValid = false; - for (Slot slot : anvilHandler.slots) { - if (firstValid && secondValid) { - break; - } - List arguments = List.of(interpreter.create(ItemStackDef.class, new ScriptItemStack(slot.getStack()))); - if (!firstValid) { - Boolean returnValue = predicate1.invoke(interpreter.branch(), arguments).getPrimitive(BooleanDef.class); - if (returnValue != null && returnValue) { - firstValid = true; - interactionManager.clickSlot(anvilHandler.syncId, slot.id, 0, SlotActionType.PICKUP, player); - interactionManager.clickSlot(anvilHandler.syncId, 0, 0, SlotActionType.PICKUP, player); - continue; - } - } - if (!secondValid) { - Boolean returnValue = predicate2.invoke(interpreter.branch(), arguments).getPrimitive(BooleanDef.class); - if (returnValue != null && returnValue) { - secondValid = true; - interactionManager.clickSlot(anvilHandler.syncId, slot.id, 0, SlotActionType.PICKUP, player); - interactionManager.clickSlot(anvilHandler.syncId, 1, 0, SlotActionType.PICKUP, player); - } - } - } - anvilHandler.updateResult(); - if (anvilHandler.getLevelCost() > player.experienceLevel && !player.isCreative()) { - return anvilHandler.getLevelCost(); - } - boolean successful = firstValid && secondValid && anvilHandler.getSlot(2).hasStack(); - if (takeItems) { - shiftClickSlot(anvilHandler, 2); - } - return successful; - } - - public static Object anvilRename(Interpreter interpreter, String newName, ArucasFunction predicate) { - ClientPlayerEntity player = getPlayer(); - if (!(player.currentScreenHandler instanceof AnvilScreenHandler anvilHandler)) { - throw new RuntimeError("Not in anvil gui"); - } - interpreter = interpreter.branch(); - for (Slot slot : anvilHandler.slots) { - ItemStack itemStack = slot.getStack(); - if (!itemStack.getName().getString().equals(newName)) { - List args = List.of(interpreter.create(ItemStackDef.class, new ScriptItemStack(itemStack))); - Boolean returnValue = predicate.invoke(interpreter.branch(), args).getPrimitive(BooleanDef.class); - if (returnValue != null && returnValue) { - shiftClickSlot(anvilHandler, slot.id); - break; - } - } - } - anvilHandler.updateResult(); - anvilHandler.setNewItemName(newName); - getNetworkHandler().sendPacket(new RenameItemC2SPacket(newName)); - if (anvilHandler.getLevelCost() > player.experienceLevel && !player.isCreative()) { - return anvilHandler.getLevelCost(); - } - if (anvilHandler.getSlot(2).hasStack()) { - shiftClickSlot(anvilHandler, 2); - return true; - } - return false; - } - - public static boolean stonecutter(Item input, Item output) { - ClientPlayerEntity player = EssentialUtils.getPlayer(); - if (!(player.currentScreenHandler instanceof StonecutterScreenHandler cutterHandler)) { - throw new RuntimeError("Not in stonecutter gui"); - } - boolean valid = false; - for (Slot slot : cutterHandler.slots) { - if (slot.getStack().getItem() == input) { - shiftClickSlot(cutterHandler, slot.id); - valid = true; - break; - } - } - if (!valid) { - return false; - } - List> stonecuttingRecipes = cutterHandler.getAvailableRecipes(); - for (int i = 0; i < stonecuttingRecipes.size(); i++) { - ItemStack result = stonecuttingRecipes.get(i).value().getResult(EssentialUtils.getRegistryManager()); - if (result.getItem() == output) { - cutterHandler.onButtonClick(getPlayer(), i); - getInteractionManager().clickButton(cutterHandler.syncId, i); - if (cutterHandler.getSlot(1).hasStack()) { - shiftClickSlot(cutterHandler, 1); - return true; - } - } - } - return false; - } - - public static void tradeAllItems(int index, boolean dropItems) { - MerchantScreenHandler handler = checkScreen(); - Slot tradeSlot = handler.getSlot(2); - while (true) { - selectTrade(handler, index); - if (!tradeSlot.hasStack()) { - break; - } - ItemStack tradeStack = tradeSlot.getStack().copy(); - shiftClickSlot(handler, tradeSlot.id); - if (dropItems) { - dropAllItemType(tradeStack.getItem()); - } - if (tradeSlot.hasStack()) { - break; - } - } - clearTradeInputSlot(handler); - } - - private static void selectTrade(MerchantScreenHandler handler, int index) { - handler.setRecipeIndex(index); - handler.switchTo(index); - EssentialUtils.getNetworkHandler().sendPacket(new SelectMerchantTradeC2SPacket(index)); - } - - public static void selectTrade(int index) { - MerchantScreenHandler handler = checkScreen(); - handler.setRecipeIndex(index); - handler.switchTo(index); - EssentialUtils.getNetworkHandler().sendPacket(new SelectMerchantTradeC2SPacket(index)); - } - - public static void tradeSelectedRecipe(boolean drop) { - MerchantScreenHandler screenHandler = checkScreen(); - Slot tradeSlot = screenHandler.getSlot(2); - if (tradeSlot.getStack().getCount() == 0) { - return; - } - if (drop) { - getInteractionManager().clickSlot(screenHandler.syncId, 2, 1, SlotActionType.THROW, getPlayer()); - return; - } - shiftClickSlot(screenHandler, 2); - } - - public static void clearTradeInputSlot(MerchantScreenHandler handler) { - PlayerInventory inventory = EssentialUtils.getPlayer().getInventory(); - Slot slot = handler.getSlot(0); - if (slot.hasStack()) { - if (canMergeIntoMain(inventory, slot.getStack())) { - shiftClickSlot(handler, slot.id); - } else { - dropStack(handler, slot.id); - } - } - slot = handler.getSlot(1); - if (!slot.hasStack()) { - return; - } - if (canMergeIntoMain(inventory, slot.getStack())) { - shiftClickSlot(handler, slot.id); - return; - } - dropStack(handler, slot.id); - } - - public static boolean checkTradeDisabled(int index) { - TradeOfferList tradeOffers = checkScreen().getRecipes(); - if (index > tradeOffers.size() - 1) { - throwOutOfBounds(); - } - return tradeOffers.get(index).isDisabled(); - } - - public static int checkPriceForTrade(int index) { - TradeOfferList tradeOffers = checkScreen().getRecipes(); - if (index > tradeOffers.size() - 1) { - throwOutOfBounds(); - } - return tradeOffers.get(index).getDisplayedFirstBuyItem().getCount(); - } - - public static boolean checkHasTrade(Item item) { - for (TradeOffer offer : checkScreen().getRecipes()) { - if (offer.getSellItem().getItem() == item) { - return true; - } - } - return false; - } - - public static void clearTrade() { - clearTradeInputSlot(checkScreen()); - } - - public static boolean isTradeSelected() { - Slot tradeSlot = checkScreen().getSlot(2); - return tradeSlot.getStack().getCount() != 0; - } - - public static ItemStack getTrade(int index) { - TradeOfferList tradeOffers = checkScreen().getRecipes(); - if (index > tradeOffers.size() - 1) { - throwOutOfBounds(); - } - return tradeOffers.get(index).getSellItem(); - } - - public static int getIndexOfItemInMerchant(Item item) { - int i = 0; - for (TradeOffer offer : checkScreen().getRecipes()) { - if (offer.getSellItem().getItem() == item) { - return i; - } - i++; - } - throwOutOfBounds(); - return -1; - } - - private static MerchantScreenHandler checkScreen() { - if (EssentialUtils.getClient().currentScreen instanceof MerchantScreen merchantScreen) { - return merchantScreen.getScreenHandler(); - } - throw new RuntimeError("Not in merchant screen"); - } - - private static void throwOutOfBounds() { - throw new RuntimeError("That trade is out of bounds"); - } - - public static void clickCuttingRecipe(StonecuttingRecipe cuttingRecipe) { - if (!(EssentialUtils.getClient().currentScreen instanceof HandledScreen handledScreen)) { - throw new RuntimeError("Must be in a stonecutting GUI"); - } - ScreenHandler handler = handledScreen.getScreenHandler(); - if (!(handler instanceof StonecutterScreenHandler stonecutterScreenHandler)) { - throw new RuntimeError("Must be in a stonecutting GUI"); - } - CraftingSharedConstants.IS_SCRIPT_CLICK.set(true); - List> recipes = stonecutterScreenHandler.getAvailableRecipes(); - int id = recipes.stream().filter(recipe -> { - DynamicRegistryManager access = EssentialUtils.getRegistryManager(); - return recipe.value().getResult(access).getItem() == cuttingRecipe.getResult(access).getItem(); - }).findFirst().map(recipes::indexOf).orElse(-1); - stonecutterScreenHandler.onButtonClick(getPlayer(), id); - } - - public static void clickCuttingRecipe(Item inputItem, Item outputItem) { - if (!(EssentialUtils.getClient().currentScreen instanceof HandledScreen handledScreen)) { - throw new RuntimeError("Must be in a stonecutting GUI"); - } - ScreenHandler handler = handledScreen.getScreenHandler(); - if (!(handler instanceof StonecutterScreenHandler stonecutterScreenHandler)) { - throw new RuntimeError("Must be in a stonecutting GUI"); - } - CraftingSharedConstants.IS_SCRIPT_CLICK.set(true); - List> recipes = stonecutterScreenHandler.getAvailableRecipes(); - int id = recipes.stream().filter(recipe -> { - DynamicRegistryManager access = EssentialUtils.getRegistryManager(); - Item result = recipe.value().getResult(access).getItem(); - return result == outputItem && recipe.value().getIngredients().stream().anyMatch(ingredient -> ingredient.test(new ItemStack(inputItem))); - }).findFirst().map(recipes::indexOf).orElse(-1); - stonecutterScreenHandler.onButtonClick(getPlayer(), id); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/keyboard/KeyboardHelper.java b/src/main/java/me/senseiwells/essentialclient/utils/keyboard/KeyboardHelper.java deleted file mode 100644 index 6ac31095..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/keyboard/KeyboardHelper.java +++ /dev/null @@ -1,143 +0,0 @@ -package me.senseiwells.essentialclient.utils.keyboard; - -import net.minecraft.util.Util; -import org.lwjgl.glfw.GLFW; - -import java.util.HashMap; -import java.util.Map; - -public class KeyboardHelper { - - private static final Map STRING_TO_KEY = Util.make(new HashMap<>(), map -> { - map.put("a", GLFW.GLFW_KEY_A); - map.put("b", GLFW.GLFW_KEY_B); - map.put("c", GLFW.GLFW_KEY_C); - map.put("d", GLFW.GLFW_KEY_D); - map.put("e", GLFW.GLFW_KEY_E); - map.put("f", GLFW.GLFW_KEY_F); - map.put("g", GLFW.GLFW_KEY_G); - map.put("h", GLFW.GLFW_KEY_H); - map.put("i", GLFW.GLFW_KEY_I); - map.put("j", GLFW.GLFW_KEY_J); - map.put("k", GLFW.GLFW_KEY_K); - map.put("l", GLFW.GLFW_KEY_L); - map.put("m", GLFW.GLFW_KEY_M); - map.put("n", GLFW.GLFW_KEY_N); - map.put("o", GLFW.GLFW_KEY_O); - map.put("p", GLFW.GLFW_KEY_P); - map.put("q", GLFW.GLFW_KEY_Q); - map.put("r", GLFW.GLFW_KEY_R); - map.put("s", GLFW.GLFW_KEY_S); - map.put("t", GLFW.GLFW_KEY_T); - map.put("u", GLFW.GLFW_KEY_U); - map.put("v", GLFW.GLFW_KEY_V); - map.put("w", GLFW.GLFW_KEY_W); - map.put("x", GLFW.GLFW_KEY_X); - map.put("y", GLFW.GLFW_KEY_Y); - map.put("z", GLFW.GLFW_KEY_Z); - map.put("`", GLFW.GLFW_KEY_GRAVE_ACCENT); - map.put("1", GLFW.GLFW_KEY_1); - map.put("2", GLFW.GLFW_KEY_2); - map.put("3", GLFW.GLFW_KEY_3); - map.put("4", GLFW.GLFW_KEY_4); - map.put("5", GLFW.GLFW_KEY_5); - map.put("6", GLFW.GLFW_KEY_6); - map.put("7", GLFW.GLFW_KEY_7); - map.put("8", GLFW.GLFW_KEY_8); - map.put("9", GLFW.GLFW_KEY_9); - map.put("0", GLFW.GLFW_KEY_0); - map.put("-", GLFW.GLFW_KEY_MINUS); - map.put("=", GLFW.GLFW_KEY_EQUAL); - map.put("[", GLFW.GLFW_KEY_LEFT_BRACKET); - map.put("]", GLFW.GLFW_KEY_RIGHT_BRACKET); - map.put("\\", GLFW.GLFW_KEY_WORLD_2); - map.put(",", GLFW.GLFW_KEY_COMMA); - map.put(".", GLFW.GLFW_KEY_PERIOD); - map.put("/", GLFW.GLFW_KEY_SLASH); - map.put(";", GLFW.GLFW_KEY_SEMICOLON); - map.put("'", GLFW.GLFW_KEY_APOSTROPHE); - map.put("#", GLFW.GLFW_KEY_BACKSLASH); - map.put("backslash", GLFW.GLFW_KEY_BACKSLASH); - }); - - private static final Map KEY_TO_STRING = Util.make(new HashMap<>(), map -> { - map.put(GLFW.GLFW_KEY_SPACE, "space"); - map.put(GLFW.GLFW_KEY_LEFT_ALT, "left_alt"); - map.put(GLFW.GLFW_KEY_RIGHT_ALT, "right_alt"); - map.put(GLFW.GLFW_KEY_LEFT_SHIFT, "left_shift"); - map.put(GLFW.GLFW_KEY_RIGHT_SHIFT, "right_shift"); - map.put(GLFW.GLFW_KEY_LEFT_CONTROL, "left_control"); - map.put(GLFW.GLFW_KEY_RIGHT_CONTROL, "right_control"); - map.put(GLFW.GLFW_KEY_TAB, "tab"); - map.put(GLFW.GLFW_KEY_ESCAPE, "escape"); - map.put(GLFW.GLFW_KEY_BACKSPACE, "backspace"); - map.put(GLFW.GLFW_KEY_ENTER, "enter"); - map.put(GLFW.GLFW_KEY_NUM_LOCK, "num_lock"); - map.put(GLFW.GLFW_KEY_DELETE, "delete"); - map.put(GLFW.GLFW_KEY_INSERT, "insert"); - map.put(GLFW.GLFW_KEY_HOME, "home"); - map.put(GLFW.GLFW_KEY_END, "end"); - map.put(GLFW.GLFW_KEY_PAGE_UP, "page_up"); - map.put(GLFW.GLFW_KEY_PAGE_DOWN, "page_down"); - map.put(GLFW.GLFW_KEY_PRINT_SCREEN, "print_screen"); - map.put(GLFW.GLFW_KEY_SCROLL_LOCK, "scroll_lock"); - map.put(GLFW.GLFW_KEY_PAUSE, "pause"); - map.put(GLFW.GLFW_KEY_MENU, "menu"); - map.put(GLFW.GLFW_KEY_LEFT_SUPER, "left_windows"); - map.put(GLFW.GLFW_KEY_RIGHT_SUPER, "right_windows"); - map.put(GLFW.GLFW_KEY_CAPS_LOCK, "caps_lock"); - map.put(GLFW.GLFW_KEY_RIGHT, "right"); - map.put(GLFW.GLFW_KEY_LEFT, "left"); - map.put(GLFW.GLFW_KEY_UP, "up"); - map.put(GLFW.GLFW_KEY_DOWN, "down"); - map.put(GLFW.GLFW_KEY_KP_0, "keypad_0"); - map.put(GLFW.GLFW_KEY_KP_1, "keypad_1"); - map.put(GLFW.GLFW_KEY_KP_2, "keypad_2"); - map.put(GLFW.GLFW_KEY_KP_3, "keypad_3"); - map.put(GLFW.GLFW_KEY_KP_4, "keypad_4"); - map.put(GLFW.GLFW_KEY_KP_5, "keypad_5"); - map.put(GLFW.GLFW_KEY_KP_6, "keypad_6"); - map.put(GLFW.GLFW_KEY_KP_7, "keypad_7"); - map.put(GLFW.GLFW_KEY_KP_8, "keypad_8"); - map.put(GLFW.GLFW_KEY_KP_9, "keypad_9"); - map.put(GLFW.GLFW_KEY_KP_ADD, "keypad_+"); - map.put(GLFW.GLFW_KEY_KP_DECIMAL, "keypad_."); - map.put(GLFW.GLFW_KEY_KP_DIVIDE, "keypad_/"); - map.put(GLFW.GLFW_KEY_KP_ENTER, "keypad_enter"); - map.put(GLFW.GLFW_KEY_KP_EQUAL, "keypad_="); - map.put(GLFW.GLFW_KEY_KP_MULTIPLY, "keypad_*"); - map.put(GLFW.GLFW_KEY_KP_SUBTRACT, "keypad_-"); - map.put(GLFW.GLFW_KEY_F1, "f1"); - map.put(GLFW.GLFW_KEY_F2, "f2"); - map.put(GLFW.GLFW_KEY_F3, "f3"); - map.put(GLFW.GLFW_KEY_F4, "f4"); - map.put(GLFW.GLFW_KEY_F5, "f5"); - map.put(GLFW.GLFW_KEY_F6, "f6"); - map.put(GLFW.GLFW_KEY_F7, "f7"); - map.put(GLFW.GLFW_KEY_F8, "f8"); - map.put(GLFW.GLFW_KEY_F9, "f9"); - map.put(GLFW.GLFW_KEY_F10, "f10"); - map.put(GLFW.GLFW_KEY_F11, "f11"); - map.put(GLFW.GLFW_KEY_F12, "f12"); - map.put(GLFW.GLFW_KEY_F13, "f13"); - map.put(GLFW.GLFW_KEY_F14, "f14"); - map.put(GLFW.GLFW_KEY_F15, "f15"); - map.put(GLFW.GLFW_KEY_F16, "f16"); - }); - - static { - for (Map.Entry entry : KEY_TO_STRING.entrySet()) { - STRING_TO_KEY.put(entry.getValue(), entry.getKey()); - } - } - - public static String translateKeyToString(int code) { - String keyName = KEY_TO_STRING.get(code); - return keyName == null ? GLFW.glfwGetKeyName(code, 0) : keyName; - } - - public static int translateStringToKey(String string) { - Integer keyCode = STRING_TO_KEY.get(string); - return keyCode == null ? -1 : keyCode; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/misc/EssentialMixinConfig.java b/src/main/java/me/senseiwells/essentialclient/utils/misc/EssentialMixinConfig.java deleted file mode 100644 index 9b25c74c..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/misc/EssentialMixinConfig.java +++ /dev/null @@ -1,66 +0,0 @@ -package me.senseiwells.essentialclient.utils.misc; - -import net.fabricmc.loader.api.FabricLoader; -import org.objectweb.asm.tree.ClassNode; -import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; -import org.spongepowered.asm.mixin.extensibility.IMixinInfo; - -import java.util.List; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class EssentialMixinConfig implements IMixinConfigPlugin { - private final Pattern mixinPattern = Pattern.compile("([a-zA-Z]+\\.[a-zA-Z]+$)"); - - @Override - public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { - return switch (this.getSimpleMixinClass(mixinClassName)) { - case "keyboard.KeyboardMixin", "disableNarrator.KeyboardMixin", "disableHotbarScrolling.MouseMixin" -> !this.isModLoaded("rebind_all_the_keys"); - default -> true; - }; - } - - @Override - public List getMixins() { - return null; - } - - @Override - public String getRefMapperConfig() { - return null; - } - - @Override - public void onLoad(String mixinPackage) { - - } - - @Override - public void acceptTargets(Set myTargets, Set otherTargets) { - - } - - @Override - public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { - - } - - @Override - public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { - - } - - @SuppressWarnings("SameParameterValue") - private boolean isModLoaded(String modId) { - return FabricLoader.getInstance().isModLoaded(modId); - } - - private String getSimpleMixinClass(String mixinClassName) { - Matcher matcher = this.mixinPattern.matcher(mixinClassName); - if (matcher.find()) { - return matcher.group(); - } - return ""; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/misc/RecipeHelper.java b/src/main/java/me/senseiwells/essentialclient/utils/misc/RecipeHelper.java deleted file mode 100644 index 7bdb3a90..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/misc/RecipeHelper.java +++ /dev/null @@ -1,12 +0,0 @@ -package me.senseiwells.essentialclient.utils.misc; - -import me.senseiwells.essentialclient.utils.EssentialUtils; -import net.minecraft.item.ItemStack; -import net.minecraft.recipe.Recipe; - -public class RecipeHelper { - @Deprecated - public static ItemStack getOutput(Recipe recipe) { - return recipe.getResult(EssentialUtils.getRegistryManager()); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/misc/Scheduler.java b/src/main/java/me/senseiwells/essentialclient/utils/misc/Scheduler.java deleted file mode 100644 index f15048a3..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/misc/Scheduler.java +++ /dev/null @@ -1,63 +0,0 @@ -package me.senseiwells.essentialclient.utils.misc; - -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; - -import java.util.ArrayDeque; -import java.util.Queue; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.FutureTask; - -public class Scheduler { - private static final Int2ObjectOpenHashMap>> TASKS = new Int2ObjectOpenHashMap<>(); - private static final Object LOCK = new Object(); - private static int tickCount = 0; - - static { - ClientTickEvents.END_CLIENT_TICK.register(client -> { - synchronized (LOCK) { - Queue> queue = TASKS.remove(tickCount++); - if (queue != null) { - queue.forEach(Runnable::run); - queue.clear(); - } - } - }); - } - - public static void load() { } - - public static void schedule(int ticks, Runnable runnable) { - schedule(ticks, Executors.callable(runnable)); - } - - public static Future schedule(int ticks, Callable callable) { - synchronized (LOCK) { - if (ticks < 0) { - throw new IllegalArgumentException("Cannot schedule a task in the past"); - } - FutureTask task = new FutureTask<>(callable); - addTask(tickCount + ticks, task); - return task; - } - } - - public static void scheduleLoop(int delay, int interval, int until, Runnable runnable) { - synchronized (LOCK) { - if (delay < 0 || interval < 0 || until < 0) { - throw new IllegalArgumentException("Delay, interval or until ticks cannot be negative"); - } - for (int delayModifier = tickCount + delay; delayModifier <= tickCount + until; delayModifier += interval) { - addTask(delayModifier, new FutureTask<>(runnable, null)); - } - } - } - - private static void addTask(int ticks, FutureTask task) { - synchronized (LOCK) { - TASKS.computeIfAbsent(ticks, k -> new ArrayDeque<>()).add(task); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/misc/WikiParser.java b/src/main/java/me/senseiwells/essentialclient/utils/misc/WikiParser.java deleted file mode 100644 index 3453856f..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/misc/WikiParser.java +++ /dev/null @@ -1,34 +0,0 @@ -package me.senseiwells.essentialclient.utils.misc; - -import me.senseiwells.essentialclient.rule.ClientRules; -import me.senseiwells.essentialclient.rule.impl.SimpleRule; -import me.senseiwells.essentialclient.utils.EssentialUtils; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Comparator; - -public class WikiParser { - public static String generateWiki() { - StringBuilder builder = new StringBuilder(getWikiBase()); - addClientRules(builder); - return builder.toString(); - } - - private static String getWikiBase() { - Path wikiPath = Path.of("../docs/HomeBase.md"); - // We should only really be running this code in a dev environment (actions) - return Files.exists(wikiPath) ? EssentialUtils.throwAsUnchecked(() -> Files.readString(wikiPath)) : "# EssentialClient\n"; - } - - private static void addClientRules(StringBuilder builder) { - builder.append("\n## Client Rules:\n"); - ClientRules.getClientRules().stream().sorted(Comparator.comparing(SimpleRule::getName)).forEach(r -> { - builder.append("# ").append(r.getName()).append("\n"); - builder.append(r.getDescription()).append("\n"); - builder.append("- Category: ").append(r.getCategory()).append("\n"); - builder.append("- Type: ").append(r.getType().toString()).append("\n"); - builder.append("- Default Value: ").append(r.getDefaultValue()).append("\n\n"); - }); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/network/MojangAPI.java b/src/main/java/me/senseiwells/essentialclient/utils/network/MojangAPI.java deleted file mode 100644 index d249de2d..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/network/MojangAPI.java +++ /dev/null @@ -1,85 +0,0 @@ -package me.senseiwells.essentialclient.utils.network; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import me.senseiwells.arucas.utils.NetworkUtils; - -import java.util.*; - -public class MojangAPI { - private static final String NAME_TO_UUID_LINK = "https://api.mojang.com/users/profiles/minecraft/"; - private static final String UUID_TO_NAME_LINK = "https://api.mojang.com/user/profile/"; - private static final Gson GSON = new Gson(); - - private static Map nameToUuidCache; - private static Map uuidToNameCache; - private static Set invalidNames; - private static Set invalidUuids; - - public static UUID getUuidFromName(String name) { - if (invalidNames != null && invalidNames.contains(name)) { - return null; - } - UUID uuid; - if (nameToUuidCache != null && (uuid = nameToUuidCache.get(name)) != null) { - return uuid; - } - String response = NetworkUtils.getStringFromUrl(NAME_TO_UUID_LINK + name); - JsonObject object = GSON.fromJson(response, JsonObject.class); - if (object == null || object.has("error")) { - if (invalidNames == null) { - invalidNames = new HashSet<>(); - } - invalidNames.add(name); - return null; - } - uuid = UUID.fromString(addDashes(object.get("id").getAsString())); - if (nameToUuidCache == null) { - nameToUuidCache = new WeakHashMap<>(); - } - if (uuidToNameCache == null) { - uuidToNameCache = new WeakHashMap<>(); - } - nameToUuidCache.put(name, uuid); - uuidToNameCache.put(uuid, name); - return uuid; - } - - public static String getNameFromUuid(UUID uuid) { - if (invalidUuids != null && invalidUuids.contains(uuid)) { - return null; - } - String name; - if (uuidToNameCache != null && (name = uuidToNameCache.get(uuid)) != null) { - return name; - } - String response = NetworkUtils.getStringFromUrl(UUID_TO_NAME_LINK + uuid.toString()); - JsonObject object = GSON.fromJson(response, JsonObject.class); - if (object == null || object.has("error")) { - if (invalidUuids == null) { - invalidUuids = new HashSet<>(); - } - invalidUuids.add(uuid); - return null; - } - name = object.get("name").getAsString(); - if (nameToUuidCache == null) { - nameToUuidCache = new WeakHashMap<>(); - } - if (uuidToNameCache == null) { - uuidToNameCache = new WeakHashMap<>(); - } - nameToUuidCache.put(name, uuid); - uuidToNameCache.put(uuid, name); - return name; - } - - private static String addDashes(String uuid) { - StringBuilder builder = new StringBuilder(uuid); - builder.insert(20, '-'); - builder.insert(16, '-'); - builder.insert(12, '-'); - builder.insert(8, '-'); - return builder.toString(); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/network/NetworkHandler.java b/src/main/java/me/senseiwells/essentialclient/utils/network/NetworkHandler.java deleted file mode 100644 index 099defa5..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/network/NetworkHandler.java +++ /dev/null @@ -1,80 +0,0 @@ -package me.senseiwells.essentialclient.utils.network; - -import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.network.PacketByteBuf; -import net.minecraft.network.packet.CustomPayload; - -import java.util.function.Supplier; - -public abstract class NetworkHandler { - private boolean available; - private ClientPlayNetworkHandler networkHandler; - - public NetworkHandler() { - - } - - public final ClientPlayNetworkHandler getNetworkHandler() { - return this.networkHandler; - } - - public final void sendPayload(Supplier supplier) { - if (this.networkHandler != null) { - this.networkHandler.sendPacket(ClientPlayNetworking.createC2SPacket(supplier.get())); - } - } - - public final boolean isAvailable() { - return this.available; - } - - public final void onHello(ClientPlayNetworkHandler handler, HelloPayload payload) { - if (payload.version < this.getVersion()) { - this.onHelloFail(); - return; - } - this.onHelloSuccess(); - this.available = true; - this.networkHandler = handler; - this.sendPayload(() -> this.createHelloPayload("essential_client", this.getVersion())); - } - - public final void onHelloSinglePlayer() { - this.onHelloSuccess(); - this.available = true; - } - - public void onDisconnect() { - this.available = false; - } - - public abstract int getVersion(); - - public abstract void registerCustomPayloads(); - - protected abstract CustomPayload createHelloPayload(String brand, int version); - - protected void onHelloSuccess() { } - - protected void onHelloFail() { } - - public static abstract class HelloPayload implements CustomPayload { - public final String brand; - public final int version; - - public HelloPayload(String brand, int version) { - this.brand = brand; - this.version = version; - } - - public HelloPayload(PacketByteBuf buf) { - this(buf.readString(), buf.readInt()); - } - - public void write(PacketByteBuf buf) { - buf.writeString(this.brand); - buf.writeInt(this.version); - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/network/NetworkUtils.java b/src/main/java/me/senseiwells/essentialclient/utils/network/NetworkUtils.java deleted file mode 100644 index 708b64ac..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/network/NetworkUtils.java +++ /dev/null @@ -1,28 +0,0 @@ -package me.senseiwells.essentialclient.utils.network; - -public class NetworkUtils { - public static final int - HELLO = 0, - STOP = 14, - RELOAD = 15, - DATA = 16; - - public static final byte - BOOLEAN = -128, - BYTE = -127, - SHORT = -126, - INT = -125, - LONG = -124, - FLOAT = -123, - DOUBLE = -122, - BYTE_ARRAY = -121, - INT_ARRAY = -120, - LONG_ARRAY = -119, - STRING = -118, - TEXT = -117, - UUID = -116, - IDENTIFIER = -115, - ITEM_STACK = -114, - NBT = -113, - POS = -112; -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/network/PacketWriter.java b/src/main/java/me/senseiwells/essentialclient/utils/network/PacketWriter.java deleted file mode 100644 index ccf8579c..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/network/PacketWriter.java +++ /dev/null @@ -1,8 +0,0 @@ -package me.senseiwells.essentialclient.utils.network; - -import net.minecraft.network.PacketByteBuf; - -@FunctionalInterface -public interface PacketWriter { - void write(PacketByteBuf buf); -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/render/ChatColour.java b/src/main/java/me/senseiwells/essentialclient/utils/render/ChatColour.java deleted file mode 100644 index ed86f57c..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/render/ChatColour.java +++ /dev/null @@ -1,23 +0,0 @@ -package me.senseiwells.essentialclient.utils.render; - -@SuppressWarnings("unused") -public class ChatColour { - public static final String DARK_RED = "§4"; - public static final String RED = "§c"; - public static final String GOLD = "§6"; - public static final String YELLOW = "§e"; - public static final String DARK_GREEN = "§2"; - public static final String GREEN = "§a"; - public static final String AQUA = "§b"; - public static final String DARK_AQUA = "§3"; - public static final String DARK_BLUE = "§1"; - public static final String BLUE = "§9"; - public static final String LIGHT_PURPLE = "§d"; - public static final String DARK_PURPLE = "§5"; - public static final String WHITE = "§f"; - public static final String GRAY = "§7"; - public static final String DARK_GRAY = "§8"; - public static final String BLACK = "§0"; - public static final String BOLD = "§l"; - public static final String RESET = "§r"; -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/render/ChildScreen.java b/src/main/java/me/senseiwells/essentialclient/utils/render/ChildScreen.java deleted file mode 100644 index 710b2c86..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/render/ChildScreen.java +++ /dev/null @@ -1,42 +0,0 @@ -package me.senseiwells.essentialclient.utils.render; - -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.text.Text; - -public class ChildScreen extends Screen { - private final Screen parent; - - protected ChildScreen(Text title, Screen parent) { - super(title); - this.parent = parent; - } - - public Screen getParent() { - return this.parent; - } - - @Override - public void close() { - if (this.client != null) { - this.client.setScreen(this.parent); - } - } - - public static class Typed extends ChildScreen { - protected Typed(Text title, T parent) { - super(title, parent); - } - - @SuppressWarnings("unchecked") - public T getParent() { - return (T) super.getParent(); - } - - @Override - public void close() { - if (this.client != null) { - this.client.setScreen(this.getParent()); - } - } - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/render/FakeInventoryScreen.java b/src/main/java/me/senseiwells/essentialclient/utils/render/FakeInventoryScreen.java deleted file mode 100644 index 3a21827e..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/render/FakeInventoryScreen.java +++ /dev/null @@ -1,94 +0,0 @@ -package me.senseiwells.essentialclient.utils.render; - -import me.senseiwells.arucas.builtin.NumberDef; -import me.senseiwells.arucas.builtin.StringDef; -import me.senseiwells.arucas.functions.ArucasFunction; -import me.senseiwells.arucas.interpreter.Interpreter; -import me.senseiwells.essentialclient.clientscript.definitions.ItemStackDef; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.ClientScriptUtils; -import me.senseiwells.essentialclient.utils.clientscript.impl.ScriptItemStack; -import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; -import net.minecraft.entity.player.PlayerInventory; -import net.minecraft.inventory.Inventory; -import net.minecraft.item.ItemStack; -import net.minecraft.screen.GenericContainerScreenHandler; -import net.minecraft.screen.slot.Slot; -import net.minecraft.screen.slot.SlotActionType; -import net.minecraft.text.Text; - -import java.util.List; - -public class FakeInventoryScreen extends GenericContainerScreen { - private Interpreter interpreter; - private ArucasFunction function; - - public FakeInventoryScreen(Interpreter interpreter, PlayerInventory inventory, String title, int rows) { - super(getHandler(inventory, rows), inventory, Text.literal(title)); - super.init(EssentialUtils.getClient(), this.width, this.height); - this.interpreter = interpreter; - } - - public void setFunctionValue(Interpreter interpreter, ArucasFunction arucasFunction) { - this.interpreter = interpreter; - this.function = arucasFunction; - } - - public void setStack(int slot, ItemStack stack) { - Inventory handlerInventory = this.handler.getInventory(); - if (slot < handlerInventory.size() && slot >= 0) { - handlerInventory.setStack(slot, stack); - } - } - - public ItemStack getStack(int slot) { - Inventory handlerInventory = this.handler.getInventory(); - if (slot < handlerInventory.size() && slot >= 0) { - return handlerInventory.getStack(slot); - } - return null; - } - - public void fakeTick() { - if (this.interpreter == null || !this.interpreter.isRunning()) { - this.close(); - } - } - - @Override - public void close() { - EssentialUtils.getClient().setScreen(null); - } - - @Override - protected void onMouseClick(Slot slot, int slotId, int button, SlotActionType actionType) { - final int slotNumber = slot == null ? slotId : slot.id; - final String action = actionType.toString(); - if (this.interpreter != null && this.function != null && this.interpreter.isRunning()) { - List slots = this.handler.slots; - ItemStack stack = slotNumber < slots.size() && slotNumber >= 0 ? slots.get(slotNumber).getStack() : ItemStack.EMPTY; - Interpreter branch = this.interpreter.branch(); - branch.runAsync(() -> { - this.function.invoke(branch, List.of( - branch.create(ItemStackDef.class, new ScriptItemStack(stack.copy())), - branch.create(NumberDef.class, (double) slotNumber), - branch.create(StringDef.class, action), - branch.create(StringDef.class, ClientScriptUtils.mouseButtonToString(button)) - )); - return null; - }); - } - } - - private static GenericContainerScreenHandler getHandler(PlayerInventory inventory, int rows) { - return switch (rows) { - case 1 -> GenericContainerScreenHandler.createGeneric9x1(0, inventory); - case 2 -> GenericContainerScreenHandler.createGeneric9x2(0, inventory); - case 3 -> GenericContainerScreenHandler.createGeneric9x3(0, inventory); - case 4 -> GenericContainerScreenHandler.createGeneric9x4(0, inventory); - case 5 -> GenericContainerScreenHandler.createGeneric9x5(0, inventory); - case 6 -> GenericContainerScreenHandler.createGeneric9x6(0, inventory); - default -> throw new IllegalArgumentException("Invalid number of rows"); - }; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/render/RenderHelper.java b/src/main/java/me/senseiwells/essentialclient/utils/render/RenderHelper.java deleted file mode 100644 index 79c8120f..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/render/RenderHelper.java +++ /dev/null @@ -1,536 +0,0 @@ -package me.senseiwells.essentialclient.utils.render; - -import com.mojang.blaze3d.systems.RenderSystem; -import me.senseiwells.essentialclient.utils.EssentialUtils; -import me.senseiwells.essentialclient.utils.clientscript.impl.*; -import net.minecraft.block.BlockState; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.render.*; -import net.minecraft.client.render.block.BlockRenderManager; -import net.minecraft.client.render.model.BakedModel; -import net.minecraft.client.render.model.BakedQuad; -import net.minecraft.client.texture.SpriteAtlasTexture; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.*; -import net.minecraft.util.math.random.Random; -import net.minecraft.world.LightType; -import org.joml.Matrix4f; -import org.joml.Vector3f; - -import java.util.List; -import java.util.function.Consumer; - -public class RenderHelper { - @SuppressWarnings("deprecation") - public static final Identifier BLOCK_ATLAS_TEXTURE = SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE; - public static final RenderLayer CULL_BLOCK_LAYER = RenderLayer.getEntityTranslucentCull(BLOCK_ATLAS_TEXTURE); - public static final RenderLayer NO_CULL_BLOCK_LAYER = RenderLayer.getEntityTranslucent(BLOCK_ATLAS_TEXTURE); - - public static void drawScaledText(DrawContext context, Text text, int x, int y, float scale, boolean center) { - MinecraftClient client = EssentialUtils.getClient(); - MatrixStack matrices = context.getMatrices(); - matrices.push(); - matrices.translate(x, y, 0.0D); - matrices.scale(scale, scale, 0.0F); - if (center) { - context.drawCenteredTextWithShadow(client.textRenderer, text, 0, 0, 0xFFFFFF); - } else { - context.drawTextWithShadow(client.textRenderer, text, 0, 0, 0xFFFFFF); - } - matrices.pop(); - } - - public static void renderAllShapes(MatrixStack matrices) { - setupArucasRendering(); - - renderBoxes(matrices); - renderSpheres(matrices); - renderLines(matrices); - // renderBlocks(matrices); - - resetArucasRendering(); - } - - public static void setupArucasRendering() { - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - RenderSystem.depthMask(false); - RenderSystem.disableCull(); - } - - public static void resetArucasRendering() { - RenderSystem.lineWidth(1); - RenderSystem.enableCull(); - RenderSystem.depthMask(true); - RenderSystem.disableBlend(); - setPositionColourShader(); - } - - private static void renderBoxes(MatrixStack matrices) { - Tessellator tessellator = Tessellator.getInstance(); - Camera camera = MinecraftClient.getInstance().gameRenderer.getCamera(); - Vec3d cameraPos = camera.getPos(); - - if (ScriptBox.hasRegular()) { - drawBoxOutlines(tessellator, matrices, cameraPos, ScriptBox::forEachRegular); - drawBoxes(tessellator, matrices, cameraPos, ScriptBox::forEachRegular); - } - - if (ScriptBox.hasIgnoreDepth()) { - RenderSystem.disableDepthTest(); - drawBoxOutlines(tessellator, matrices, cameraPos, ScriptBox::forEachIgnoreDepth); - drawBoxes(tessellator, matrices, cameraPos, ScriptBox::forEachIgnoreDepth); - RenderSystem.enableDepthTest(); - } - } - - private static void drawBoxOutlines(Tessellator tessellator, MatrixStack matrices, Vec3d camera, Consumer> forEach) { - setLineShader(); - BufferBuilder bufferBuilder = startLines(tessellator); - forEach.accept(box -> { - if (box.getOutlineWidth() >= 1) { - RenderSystem.lineWidth(box.getOutlineWidth()); - addBoxToBuffer(bufferBuilder, matrices, camera, box, true); - } - }); - } - - private static void drawBoxes(Tessellator tessellator, MatrixStack matrices, Vec3d cameraPos, Consumer> forEach) { - setPositionColourShader(); - BufferBuilder bufferBuilder = startQuads(tessellator, VertexFormats.POSITION_COLOR); - forEach.accept(box -> { - addBoxToBuffer(bufferBuilder, matrices, cameraPos, box, false); - }); - } - - private static Vec3d getMinimumPos(Vec3d pos1, Vec3d pos2) { - return new Vec3d(Math.min(pos1.getX(), pos2.getX()), Math.min(pos1.getY(), pos2.getY()), Math.min(pos1.getZ(), pos2.getZ())); - } - - private static void addBoxToBuffer(BufferBuilder bufferBuilder, MatrixStack matrices, Vec3d cameraPos, ScriptBox box, boolean outline) { - Vec3d pos1 = box.getCornerA(); - Vec3d pos2 = box.getCornerB(); - - int red = box.getRed(), green = box.getGreen(), blue = box.getBlue(), alpha = box.getAlpha(); - if (outline) { - red = box.getOutlineRed(); - green = box.getOutlineGreen(); - blue = box.getOutlineBlue(); - alpha = 255; - } - - Vec3d posOrigin = getMinimumPos(pos1, pos2); - matrices.push(); - matrices.translate(posOrigin.getX() - cameraPos.getX(), posOrigin.getY() - cameraPos.getY(), posOrigin.getZ() - cameraPos.getZ()); - tilt(matrices, box); - scale(matrices, box); - addBoxVertices(bufferBuilder, matrices, pos1, pos2, red / 255.0F, green / 255.0F, blue / 255.0F, alpha / 255.0F, outline); - matrices.pop(); - } - - private static void addBoxVertices(BufferBuilder bufferBuilder, MatrixStack matrices, Vec3d pos1, Vec3d pos2, float red, float green, float blue, float alpha, boolean outline) { - float c0 = -0.002F; - float x1 = (float) (Math.abs(pos1.getX() - pos2.getX()) - c0 + 1); - float y1 = (float) (Math.abs(pos1.getY() - pos2.getY()) - c0 + 1); - float z1 = (float) (Math.abs(pos1.getZ() - pos2.getZ()) - c0 + 1); - - MatrixStack.Entry entry = matrices.peek(); - Matrix4f model = entry.getPositionMatrix(); - - if (outline) { - // idk man - bufferBuilder.vertex(model, c0, c0, c0).color(red, green, blue, alpha).normal(entry, 1.0F, 0.0F, 0.0F); - bufferBuilder.vertex(model, x1, c0, c0).color(red, green, blue, alpha).normal(entry, 1.0F, 0.0F, 0.0F); - bufferBuilder.vertex(model, c0, c0, c0).color(red, green, blue, alpha).normal(entry, 0.0F, 1.0F, 0.0F); - bufferBuilder.vertex(model, c0, y1, c0).color(red, green, blue, alpha).normal(entry, 0.0F, 1.0F, 0.0F); - bufferBuilder.vertex(model, c0, c0, c0).color(red, green, blue, alpha).normal(entry, 0.0F, 0.0F, 1.0F); - bufferBuilder.vertex(model, c0, c0, z1).color(red, green, blue, alpha).normal(entry, 0.0F, 0.0F, 1.0F); - bufferBuilder.vertex(model, x1, c0, c0).color(red, green, blue, alpha).normal(entry, 0.0F, 1.0F, 0.0F); - bufferBuilder.vertex(model, x1, y1, c0).color(red, green, blue, alpha).normal(entry, 0.0F, 1.0F, 0.0F); - bufferBuilder.vertex(model, x1, y1, c0).color(red, green, blue, alpha).normal(entry, -1.0F, 0.0F, 0.0F); - bufferBuilder.vertex(model, c0, y1, c0).color(red, green, blue, alpha).normal(entry, -1.0F, 0.0F, 0.0F); - bufferBuilder.vertex(model, c0, y1, c0).color(red, green, blue, alpha).normal(entry, 0.0F, 0.0F, 1.0F); - bufferBuilder.vertex(model, c0, y1, z1).color(red, green, blue, alpha).normal(entry, 0.0F, 0.0F, 1.0F); - bufferBuilder.vertex(model, c0, y1, z1).color(red, green, blue, alpha).normal(entry, 0.0F, -1.0F, 0.0F); - bufferBuilder.vertex(model, c0, c0, z1).color(red, green, blue, alpha).normal(entry, 0.0F, -1.0F, 0.0F); - bufferBuilder.vertex(model, c0, c0, z1).color(red, green, blue, alpha).normal(entry, 1.0F, 0.0F, 0.0F); - bufferBuilder.vertex(model, x1, c0, z1).color(red, green, blue, alpha).normal(entry, 1.0F, 0.0F, 0.0F); - bufferBuilder.vertex(model, x1, c0, z1).color(red, green, blue, alpha).normal(entry, 0.0F, 0.0F, -1.0F); - bufferBuilder.vertex(model, x1, c0, c0).color(red, green, blue, alpha).normal(entry, 0.0F, 0.0F, -1.0F); - bufferBuilder.vertex(model, c0, y1, z1).color(red, green, blue, alpha).normal(entry, 1.0F, 0.0F, 0.0F); - bufferBuilder.vertex(model, x1, y1, z1).color(red, green, blue, alpha).normal(entry, 1.0F, 0.0F, 0.0F); - bufferBuilder.vertex(model, x1, c0, z1).color(red, green, blue, alpha).normal(entry, 0.0F, 1.0F, 0.0F); - bufferBuilder.vertex(model, x1, y1, z1).color(red, green, blue, alpha).normal(entry, 0.0F, 1.0F, 0.0F); - bufferBuilder.vertex(model, x1, y1, c0).color(red, green, blue, alpha).normal(entry, 0.0F, 0.0F, 1.0F); - bufferBuilder.vertex(model, x1, y1, z1).color(red, green, blue, alpha).normal(entry, 0.0F, 0.0F, 1.0F); - return; - } - - // West Face - bufferBuilder.vertex(model, c0, c0, c0).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - bufferBuilder.vertex(model, c0, c0, z1).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - bufferBuilder.vertex(model, c0, y1, z1).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - bufferBuilder.vertex(model, c0, y1, c0).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - - // East Face - bufferBuilder.vertex(model, x1, c0, c0).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - bufferBuilder.vertex(model, x1, y1, c0).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - bufferBuilder.vertex(model, x1, y1, z1).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - bufferBuilder.vertex(model, x1, c0, z1).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - - - // North Face - bufferBuilder.vertex(model, c0, c0, c0).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - bufferBuilder.vertex(model, c0, y1, c0).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - bufferBuilder.vertex(model, x1, y1, c0).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - bufferBuilder.vertex(model, x1, c0, c0).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - - // South Face - bufferBuilder.vertex(model, c0, c0, z1).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - bufferBuilder.vertex(model, x1, c0, z1).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - bufferBuilder.vertex(model, x1, y1, z1).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - bufferBuilder.vertex(model, c0, y1, z1).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - - // Down Face - bufferBuilder.vertex(model, c0, c0, c0).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - bufferBuilder.vertex(model, x1, c0, c0).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - bufferBuilder.vertex(model, x1, c0, z1).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - bufferBuilder.vertex(model, c0, c0, z1).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - - // Up Face - bufferBuilder.vertex(model, c0, y1, c0).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - bufferBuilder.vertex(model, c0, y1, z1).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - bufferBuilder.vertex(model, x1, y1, z1).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - bufferBuilder.vertex(model, x1, y1, c0).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - } - - private static void renderSpheres(MatrixStack matrices) { - Tessellator tessellator = Tessellator.getInstance(); - Camera camera = MinecraftClient.getInstance().gameRenderer.getCamera(); - Vec3d cameraPos = camera.getPos(); - - if (ScriptSphere.hasRegular()) { - drawSpheresOutlines(tessellator, matrices, cameraPos, ScriptSphere::forEachRegular); - drawSpheres(tessellator, matrices, cameraPos, ScriptSphere::forEachRegular); - } - - if (ScriptSphere.hasIgnoreDepth()) { - RenderSystem.disableDepthTest(); - drawSpheresOutlines(tessellator, matrices, cameraPos, ScriptSphere::forEachIgnoreDepth); - drawSpheres(tessellator, matrices, cameraPos, ScriptSphere::forEachIgnoreDepth); - RenderSystem.enableDepthTest(); - } - } - - private static void drawSpheresOutlines(Tessellator tessellator, MatrixStack matrices, Vec3d camera, Consumer> forEach) { - setLineShader(); - BufferBuilder bufferBuilder = startLines(tessellator); - forEach.accept(sphere -> { - if (sphere.getOutlineWidth() >= 1) { - RenderSystem.lineWidth(sphere.getOutlineWidth()); - addSphereToBuffer(bufferBuilder, matrices, camera, sphere, true); - } - }); - } - - private static void drawSpheres(Tessellator tessellator, MatrixStack matrices, Vec3d cameraPos, Consumer> forEach) { - setPositionColourShader(); - BufferBuilder bufferBuilder = startQuads(tessellator, VertexFormats.POSITION_COLOR); - forEach.accept(sphere -> { - addSphereToBuffer(bufferBuilder, matrices, cameraPos, sphere, false); - }); - } - - private static void addSphereToBuffer(BufferBuilder bufferBuilder, MatrixStack matrices, Vec3d cameraPos, ScriptSphere sphere, boolean outline) { - Vec3d pos = sphere.getPosition(); - - int red = sphere.getRed(), green = sphere.getGreen(), blue = sphere.getBlue(), alpha = sphere.getAlpha(); - if (outline) { - red = sphere.getOutlineRed(); - green = sphere.getOutlineGreen(); - blue = sphere.getOutlineBlue(); - alpha = 255; - } - - matrices.push(); - matrices.translate(pos.getX() - cameraPos.getX(), pos.getY() - cameraPos.getY(), pos.getZ() - cameraPos.getZ()); - tilt(matrices, sphere); - scale(matrices, sphere); - addSphereVertices(bufferBuilder, matrices, sphere.getWidth(), sphere.getSteps(), red / 255.0F, green / 255.0F, blue / 255.0F, alpha / 255.0F, outline); - matrices.pop(); - } - - private static void addSphereVertices(BufferBuilder builder, MatrixStack matrices, float radius, float steps, float red, float green, float blue, float alpha, boolean outline) { - MatrixStack.Entry entry = matrices.peek(); - Matrix4f model = entry.getPositionMatrix(); - - float step = (float) (2 * Math.PI / steps); - int halfSteps = (int) (Math.PI / step) + 1; - int totalSteps = (int) (2 * Math.PI / step); - - if (outline) { - for (int i = 0; i <= totalSteps; i++) { - float theta = step * i; - for (int j = 0; j <= totalSteps; j++) { - float phi = step * j; - float x = radius * MathHelper.sin(phi) * MathHelper.cos(theta); - float z = radius * MathHelper.sin(phi) * MathHelper.sin(theta); - float y = radius * MathHelper.cos(phi); - Vector3f normalVector = new Vector3f(x, y, z); - normalVector.normalize(); - builder.vertex(model, x, y, z).color(red, green, blue, alpha).normal(entry, normalVector.x, normalVector.y, normalVector.z); - } - } - for (int j = 0; j <= totalSteps; j++) { - float phi = step * j; - for (int i = 0; i <= totalSteps; i++) { - float theta = step * i; - float x = radius * MathHelper.sin(phi) * MathHelper.cos(theta); - float z = radius * MathHelper.sin(phi) * MathHelper.sin(theta); - float y = radius * MathHelper.cos(phi); - Vector3f normalVector = new Vector3f(x, y, z); - normalVector.normalize(); - builder.vertex(model, x, y, z).color(red, green, blue, alpha).normal(entry, normalVector.x, normalVector.y, normalVector.z); - } - } - return; - } - - for (int i = 0; i <= totalSteps; i++) { - float theta = i * step; - float thetaPrime = theta + step; - float xb = 0; - float zb = 0; - float xbp = 0; - float zbp = 0; - float yp = radius; - for (int j = 0; j <= halfSteps; j++) { - float phi = j * step; - float x = radius * MathHelper.sin(phi) * MathHelper.cos(theta); - float z = radius * MathHelper.sin(phi) * MathHelper.sin(theta); - float y = radius * MathHelper.cos(phi); - float xp = radius * MathHelper.sin(phi) * MathHelper.cos(thetaPrime); - float zp = radius * MathHelper.sin(phi) * MathHelper.sin(thetaPrime); - builder.vertex(model, xb, yp, zb).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - builder.vertex(model, xbp, yp, zbp).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - builder.vertex(model, xp, y, zp).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - builder.vertex(model, x, y, z).color(red, green, blue, alpha).normal(entry, 0, 0, 0); - xb = x; - zb = z; - xbp = xp; - zbp = zp; - yp = y; - } - } - } - - private static void renderLines(MatrixStack matrices) { - Tessellator tessellator = Tessellator.getInstance(); - Camera camera = MinecraftClient.getInstance().gameRenderer.getCamera(); - Vec3d cameraPos = camera.getPos(); - - if (ScriptLine.hasRegular()) { - RenderSystem.enableDepthTest(); - drawLines(tessellator, matrices, cameraPos, ScriptLine::forEachRegular); - } - - if (ScriptLine.hasIgnoreDepth()) { - RenderSystem.disableDepthTest(); - drawLines(tessellator, matrices, cameraPos, ScriptLine::forEachIgnoreDepth); - RenderSystem.enableDepthTest(); - } - } - - private static void drawLines(Tessellator tessellator, MatrixStack matrices, Vec3d cameraPos, Consumer> forEach) { - setLineShader(); - BufferBuilder builder = startLines(tessellator); - forEach.accept(line -> { - if (line.getOutlineWidth() >= 1) { - RenderSystem.lineWidth(line.getOutlineWidth()); - addLineToBuffer(builder, matrices, cameraPos, line); - } - }); - } - - private static void addLineToBuffer(BufferBuilder builder, MatrixStack matrices, Vec3d cameraPos, ScriptLine line) { - Vec3d pos1 = line.getCornerA(); - Vec3d pos2 = line.getCornerB(); - int red = line.getRed(), green = line.getGreen(), blue = line.getBlue(), alpha = line.getAlpha(); - - matrices.push(); - matrices.translate(-cameraPos.getX(), -cameraPos.getY(), -cameraPos.getZ()); - tilt(matrices, line); - addLineVertices( - builder, matrices, - pos1.toVector3f(), pos2.toVector3f(), - red / 255.0F, - green / 255.0F, - blue / 255.0F, - alpha / 255.0F - ); - matrices.pop(); - } - - private static void addLineVertices(BufferBuilder builder, MatrixStack matrices, Vector3f pos1, Vector3f pos2, float red, float green, float blue, float alpha) { - float dx = pos1.x - pos2.x; - float dy = pos1.y - pos2.y; - float dz = pos1.z - pos2.z; - Vector3f normalVec = new Vector3f(dx, dy, dz); - normalVec.normalize(); - - MatrixStack.Entry entry = matrices.peek(); - Matrix4f model = entry.getPositionMatrix(); - builder.vertex(model, pos1.x, pos1.y, pos1.z).color(red, green, blue, alpha).normal(entry, normalVec.x, normalVec.y, normalVec.z); - builder.vertex(model, pos2.x, pos2.y, pos2.z).color(red, green, blue, alpha).normal(entry, normalVec.x, normalVec.y, normalVec.z); - } - - public static void renderBlocks(MatrixStack matrices) { - MinecraftClient client = EssentialUtils.getClient(); - VertexConsumerProvider.Immediate immediate = client.getBufferBuilders().getEntityVertexConsumers(); - - ScriptFakeBlock.forEachRegular(f -> renderFakeBlock(client, matrices, f, immediate)); - immediate.draw(NO_CULL_BLOCK_LAYER); - immediate.draw(CULL_BLOCK_LAYER); - - // TODO: Fix this :P - // RenderSystem.clear(GlConst.GL_DEPTH_BUFFER_BIT, MinecraftClient.IS_SYSTEM_MAC); - - ScriptFakeBlock.forEachIgnoreDepth(f -> renderFakeBlock(client, matrices, f, immediate)); - immediate.draw(NO_CULL_BLOCK_LAYER); - immediate.draw(CULL_BLOCK_LAYER); - } - - private static void renderFakeBlock(MinecraftClient client, MatrixStack matrices, ScriptFakeBlock fakeBlock, VertexConsumerProvider.Immediate immediate) { - if (client.world == null) { - return; - } - - Vec3d cameraPos = client.gameRenderer.getCamera().getPos(); - Vec3d pos = fakeBlock.getPosition(); - - matrices.push(); - matrices.translate(0.5D, 0.5D, 0.5D); - matrices.translate( - pos.getX() - cameraPos.x, - pos.getY() - cameraPos.y, - pos.getZ() - cameraPos.z - ); - if (fakeBlock.getDirection() == null) { - matrices.multiply(client.gameRenderer.getCamera().getRotation()); - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180)); - } else { - switch (fakeBlock.getDirection()) { - case SOUTH -> matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180)); - case EAST -> matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(270)); - case WEST -> matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(90)); - case UP -> matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90)); - case DOWN -> matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(-90)); - } - } - tilt(matrices, fakeBlock); - scale(matrices, fakeBlock); - - matrices.translate(-0.5, -0.5, -0.5); - - BlockPos blockPos = EssentialUtils.vec3dToBlockPos(pos); - int light = LightmapTextureManager.pack( - client.world.getLightLevel(LightType.BLOCK, blockPos), - client.world.getLightLevel(LightType.SKY, blockPos) - ); - - renderBlockAsEntity(fakeBlock.getState(), matrices, immediate, fakeBlock.getAlpha() / 255.0F, light, OverlayTexture.DEFAULT_UV, fakeBlock.shouldCull()); - - matrices.pop(); - } - - private static void tilt(MatrixStack matrices, ScriptShape tiltable) { - if (tiltable.getXTilt() != 0.0F) { - matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(tiltable.getXTilt())); - } - if (tiltable.getYTilt() != 0.0F) { - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(tiltable.getYTilt())); - } - if (tiltable.getZTilt() != 0.0F) { - matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(tiltable.getZTilt())); - } - } - - private static void scale(MatrixStack matrices, ScriptShape scalable) { - matrices.scale(scalable.getXScale(), scalable.getYScale(), scalable.getZScale()); - } - - public static void renderBlockAsEntity(BlockState state, MatrixStack matrices, VertexConsumerProvider vertexConsumer, float alpha, int light, int overlay, boolean cull) { - MinecraftClient client = EssentialUtils.getClient(); - BlockRenderManager manager = client.getBlockRenderManager(); - switch (state.getRenderType()) { - case MODEL -> { - BakedModel bakedModel = manager.getModel(state); - int i = client.getBlockColors().getColor(state, null, null, 0); - float red = (i >> 16 & 0xFF) / 255.0F; - float green = (i >> 8 & 0xFF) / 255.0F; - float blue = (i & 0xFF) / 255.0F; - RenderLayer layer = cull ? CULL_BLOCK_LAYER : NO_CULL_BLOCK_LAYER; - renderBlock(matrices.peek(), vertexConsumer.getBuffer(layer), state, bakedModel, red, green, blue, alpha, light, overlay); - } - // Not supported - case ENTITYBLOCK_ANIMATED -> manager.renderBlockAsEntity(state, matrices, vertexConsumer, light, overlay); - } - } - - public static void renderBlock(MatrixStack.Entry entry, VertexConsumer vertexConsumer, BlockState state, BakedModel bakedModel, float red, float green, float blue, float alpha, int light, int overlay) { - Random random = Random.create(); - long seed = 42L; - for (Direction direction : Direction.values()) { - random.setSeed(seed); - renderQuads(entry, vertexConsumer, red, green, blue, alpha, bakedModel.getQuads(state, direction, random), light, overlay); - } - random.setSeed(seed); - renderQuads(entry, vertexConsumer, red, green, blue, alpha, bakedModel.getQuads(state, null, random), light, overlay); - } - - private static void renderQuads(MatrixStack.Entry entry, VertexConsumer vertexConsumer, float red, float green, float blue, float alpha, List quads, int light, int overlay) { - for (BakedQuad bakedQuad : quads) { - float r = 1.0F; - float g = 1.0F; - float b = 1.0F; - float a = MathHelper.clamp(alpha, 0.0F, 1.0F); - if (bakedQuad.hasColor()) { - r = MathHelper.clamp(red, 0.0f, 1.0F); - g = MathHelper.clamp(green, 0.0f, 1.0F); - b = MathHelper.clamp(blue, 0.0f, 1.0F); - } - vertexConsumer.quad(entry, bakedQuad, r, g, b, a, light, overlay); - } - } - - public static BufferBuilder startLines(Tessellator tessellator) { - return tessellator.begin(VertexFormat.DrawMode.LINES, VertexFormats.LINES); - } - - public static BufferBuilder startDebugLines(Tessellator tessellator, VertexFormat format) { - return tessellator.begin(VertexFormat.DrawMode.DEBUG_LINES, format); - } - - public static BufferBuilder startQuads(Tessellator tessellator, VertexFormat format) { - return tessellator.begin(VertexFormat.DrawMode.QUADS, format); - } - - public static void setLineShader() { - RenderSystem.setShader(GameRenderer::getRenderTypeLinesProgram); - } - - public static void setPositionColourShader() { - RenderSystem.setShader(GameRenderer::getPositionColorProgram); - } - - public static void setPositionTextureColourShader() { - RenderSystem.setShader(GameRenderer::getPositionTexColorProgram); - } - - public static void bindTexture(Identifier texture) { - RenderSystem.setShaderTexture(0, texture); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/render/RuleWidget.java b/src/main/java/me/senseiwells/essentialclient/utils/render/RuleWidget.java deleted file mode 100644 index 546f21a4..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/render/RuleWidget.java +++ /dev/null @@ -1,49 +0,0 @@ -package me.senseiwells.essentialclient.utils.render; - -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.text.Text; - -public class RuleWidget { - private final String name; - private final int width; - private final int height; - private boolean isToggled; - private int x; - private int y; - - public RuleWidget(String name, int width, int height) { - this.name = name; - this.width = width; - this.height = height; - this.isToggled = false; - } - - public void toggle() { - this.isToggled = !this.isToggled; - } - - public void setPos(int x, int y) { - this.x = x; - this.y = y; - } - - public void drawRule(DrawContext context, TextRenderer font, float fontX, float fontY, int colour) { - context.drawTextWithShadow(font, Text.literal(getShortName(this.name)), (int) fontX, (int) fontY, colour); - } - - public boolean isHovered(int mouseX, int mouseY) { - return mouseX >= this.x && mouseX < this.x + this.width && mouseY >= this.y && mouseY < this.y + this.height; - } - - public boolean isToggled() { - return this.isToggled; - } - - public static String getShortName(String string) { - if (string.length() > 34) { - return string.substring(0, 31) + "..."; - } - return string; - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/render/Texts.java b/src/main/java/me/senseiwells/essentialclient/utils/render/Texts.java deleted file mode 100644 index bdae8993..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/render/Texts.java +++ /dev/null @@ -1,166 +0,0 @@ -package me.senseiwells.essentialclient.utils.render; - -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.text.TranslatableTextContent; -import net.minecraft.util.Formatting; -import net.minecraft.util.Identifier; - -import static net.minecraft.text.Text.literal; -import static net.minecraft.text.Text.translatable; - -public class Texts { - public static final Text EMPTY = literal(""); - public static final Text ESSENTIAL_CLIENT = translatable("essentialclient"); - public static final Text CLIENT_MENU = translatable("essentialclient.menu"); - public static final Text CLIENT_SCREEN = translatable("essentialclient.options"); - public static final Text SERVER_SCREEN = translatable("essentialclient.carpetOptions"); - public static final Text GAME_RULE_SCREEN = translatable("essentialclient.gameOptions"); - public static final Text SCRIPT_SCREEN = translatable("essentialclient.scriptOptions"); - public static final Text CHUNK_SCREEN = translatable("essentialclient.chunkDebugMap"); - public static final Text CHUNK_CLUSTER_SCREEN = translatable("essentialclient.chunkClusters"); - public static final Text CONTROLS_SCREEN = translatable("essentialclient.controls"); - public static final Text TOP_SECRET = translatable("essentialclient.topSecret"); - public static final TextGenerator VERSION = o -> translatable("essentialclient.version", o); - - public static final Text RESET = translatable("essentialclient.ui.reset"); - public static final Text SELECTED = translatable("essentialclient.ui.selected"); - public static final Text REFRESH = translatable("essentialclient.ui.refresh"); - public static final Text DONE = translatable("essentialclient.ui.done"); - public static final Text DOCUMENTATION = translatable("essentialclient.ui.documentation"); - public static final Text CONFIG = translatable("essentialclient.ui.config"); - public static final Text REMOVE = translatable("essentialclient.ui.remove"); - public static final Text CREATE = translatable("essentialclient.ui.create"); - public static final Text NEW = translatable("essentialclient.ui.new"); - public static final Text DOWNLOAD = translatable("essentialclient.ui.download"); - public static final Text TRUE = translatable("essentialclient.ui.true").formatted(Formatting.DARK_GREEN); - public static final Text FALSE = translatable("essentialclient.ui.false").formatted(Formatting.DARK_RED); - public static final Text START = translatable("essentialclient.ui.start").formatted(Formatting.DARK_GREEN); - public static final Text STOP = translatable("essentialclient.ui.stop").formatted(Formatting.DARK_RED); - public static final Text CANCEL = translatable("essentialclient.ui.cancel"); - public static final Text UNKNOWN = translatable("essentialclient.ui.unknown"); - - public static final TextGenerator ARUCAS_VERSION = o -> translatable("essentialclient.script.arucasVersion", o); - public static final TextGenerator DOWNLOAD_SUCCESS = o -> translatable("essentialclient.script.downloadSuccess", o); - public static final TextGenerator NO_SCRIPT = o -> translatable("essentialclient.script.noScript", o); - public static final TextGenerator SCRIPT_CONFIG = o -> translatable("essentialclient.script.config", o); - public static final Text SCRIPT_NAME = translatable("essentialclient.script.name"); - public static final Text OPEN_SCRIPT = translatable("essentialclient.script.open"); - public static final Text DELETE_SCRIPT = translatable("essentialclient.script.delete"); - public static final Text CREATE_NEW_SCRIPT = translatable("essentialclient.script.createNew"); - public static final Text DOWNLOAD_SCRIPT = translatable("essentialclient.script.download"); - public static final Text AUTOMATION = translatable("essentialclient.script.automation"); - public static final Text UTILITIES = translatable("essentialclient.script.utilities"); - public static final Text MISCELLANEOUS = translatable("essentialclient.script.miscellaneous"); - public static final Text VIEW = translatable("essentialclient.script.view"); - public static final Text DOWNLOAD_FAILED = translatable("essentialclient.script.downloadFailed"); - public static final Text DOWNLOAD_SUCCESSFUL = translatable("essentialclient.script.downloadSuccessful"); - public static final Text FINISHED = translatable("essentialclient.script.finished").formatted(Formatting.RED); - public static final Text STARTED = translatable("essentialclient.script.started").formatted(Formatting.GREEN); - public static final TextGenerator SCRIPT_STATUS = o -> translatable("essentialclient.script.scriptStatus", o); - public static final TextGenerator READ_ERROR = o -> translatable("essentialclient.script.readError", o); - public static final TextGenerator FATAL_ERROR = o -> translatable("essentialclient.script.fatalError", o); - public static final TextGenerator CRASH_REPORT = o -> translatable("essentialclient.script.crashReport", o); - public static final Text CRASH_BUG = translatable("essentialclient.script.crashBug").formatted(Formatting.RED); - - public static final Text X = literal("X"); - public static final Text Z = literal("Z"); - public static final Text OVERWORLD = translatable("essentialclient.chunkDebug.overworld"); - public static final Text NETHER = translatable("essentialclient.chunkDebug.nether"); - public static final Text END = translatable("essentialclient.chunkDebug.end"); - public static final Text MINIMAP_NONE = translatable("essentialclient.chunkDebug.minimapNone"); - public static final Text MINIMAP_STATIC = translatable("essentialclient.chunkDebug.minimapStatic"); - public static final Text MINIMAP_FOLLOW = translatable("essentialclient.chunkDebug.minimapFollow"); - public static final Text RETURN_TO_PLAYER = translatable("essentialclient.chunkDebug.returnToPlayer"); - public static final TextGenerator SELECTED_CHUNK = o -> translatable("essentialclient.chunkDebug.selectedChunk", o); - public static final TextGenerator CHUNK_STATUS = o -> translatable("essentialclient.chunkDebug.status", o); - public static final TextGenerator CHUNK_TICKET = o -> translatable("essentialclient.chunkDebug.ticket", o); - public static final TextGenerator CHUNK_STAGE = o -> translatable("essentialclient.chunkDebug.stage", o); - public static final Text UNLOADED = translatable("essentialclient.chunkDebug.type.unloaded"); - public static final Text BORDER = translatable("essentialclient.chunkDebug.type.border"); - public static final Text LAZY = translatable("essentialclient.chunkDebug.type.lazy"); - public static final Text ENTITY_TICKING = translatable("essentialclient.chunkDebug.type.entity"); - public static final Text EMPTY_STATUS = translatable("essentialclient.chunkDebug.status.empty"); - public static final Text STRUCTURE_STARTS = translatable("essentialclient.chunkDebug.status.structureStarts"); - public static final Text STRUCTURE_REFERENCES = translatable("essentialclient.chunkDebug.status.structureReferences"); - public static final Text BIOMES = translatable("essentialclient.chunkDebug.status.biomes"); - public static final Text NOISE = translatable("essentialclient.chunkDebug.status.noise"); - public static final Text SURFACE = translatable("essentialclient.chunkDebug.status.surface"); - public static final Text CARVERS = translatable("essentialclient.chunkDebug.status.carvers"); - public static final Text LIQUID_CARVERS = translatable("essentialclient.chunkDebug.status.liquidCarvers"); - public static final Text FEATURES = translatable("essentialclient.chunkDebug.status.features"); - public static final Text LIGHT = translatable("essentialclient.chunkDebug.status.light"); - public static final Text SPAWN = translatable("essentialclient.chunkDebug.status.spawn"); - public static final Text HEIGHTMAPS = translatable("essentialclient.chunkDebug.status.heightmaps"); - public static final Text FULL = translatable("essentialclient.chunkDebug.status.full"); - public static final Text TICKET_SPAWN = translatable("essentialclient.chunkDebug.ticket.spawn"); - public static final Text DRAGON = translatable("essentialclient.chunkDebug.ticket.dragon"); - public static final Text PLAYER = translatable("essentialclient.chunkDebug.ticket.player"); - public static final Text FORCED = translatable("essentialclient.chunkDebug.ticket.forced"); - public static final Text TICKET_LIGHT = translatable("essentialclient.chunkDebug.ticket.light"); - public static final Text PORTAL = translatable("essentialclient.chunkDebug.ticket.portal"); - public static final Text TELEPORT = translatable("essentialclient.chunkDebug.ticket.teleport"); - public static final Text CHONK = translatable("essentialclient.chunkDebug.ticket.chonk"); - public static final Text TICKET_UNKNOWN = translatable("essentialclient.chunkDebug.ticket.unknown"); - - public static final TextGenerator NO_CONFIG = o -> translatable("essentialclient.configs.noConfig", o); - public static final TextGenerator REMOVED_CONFIG = o -> translatable("essentialclient.configs.removeConfig", o); - public static final Text KEYBIND = translatable("essentialclient.configs.keyBind"); - public static final Text NO_KEYBINDING = translatable("essentialclient.configs.noKeyBinding"); - public static final Text EDIT_LIST = translatable("essentialclient.configs.editList"); - public static final TextGenerator EDITING_LIST = o -> translatable("essentialclient.configs.editingList", o); - public static final Text WIKI_PAGE = translatable("essentialclient.configs.wiki"); - public static final Text CONFIG_FOLDER = translatable("essentialclient.configs.configFolder"); - - public static final Text INVALID_DIMENSION = translatable("essentialclient.alternateDimension.invalid"); - public static final TextGenerator COORDINATES = o -> translatable("essentialclient.alternateDimension.coordinates", o); - - public static final TextGenerator WRONG_GAMEMODE = o -> translatable("essentialclient.playerClient.wrongGamemode", o); - - public static final TextGenerator LIST_EXISTS = o -> translatable("essentialclient.playerList.exists", o); - public static final TextGenerator LIST_NOT_EXISTS = o -> translatable("essentialclient.playerList.notExists", o); - public static final TextGenerator LIST_EMPTY = o -> translatable("essentialclient.playerList.empty", o); - public static final TextGenerator LIST_HAS_PLAYER = o -> translatable("essentialclient.playerList.hasPlayer", o); - public static final TextGenerator LIST_CREATED = o -> translatable("essentialclient.playerList.created", o); - public static final TextGenerator LIST_DELETED = o -> translatable("essentialclient.playerList.deleted", o); - public static final TextGenerator LIST_PLAYER_ADDED = o -> translatable("essentialclient.playerList.playerAdded", o); - - public static final Text AFK = translatable("essentialclient.afkLogout.message"); - - public static final Text SWAP_INVENTORY = translatable("essentialclient.swapInventories.name"); - - public static final TextGenerator SET_GAME_RULE = o -> translatable("essentialclient.gameRule.set", o); - - public static final Text NO_ARGUMENTS = translatable("essentialclient.command.noArguments"); - public static final TextGenerator ENUM_NOT_FOUND = o -> translatable("essentialclient.command.enumNotFound", o); - - public static final Text UNKNOWN_UPDATE = translatable("essentialclient.clientUpdater.unknown"); - public static final Text UP_TO_DATE = translatable("essentialclient.clientUpdater.upToDate"); - public static final Text NO_VERSIONS = translatable("essentialclient.clientUpdater.noVersions"); - public static final TextGenerator SUCCESSFULLY_DOWNLOADED = o -> translatable("essentialclient.clientUpdater.successfullyDownloaded", o); - public static final TextGenerator FAILED_TO_DOWNLOAD = o -> translatable("essentialclient.clientUpdater.failedToDownload", o); - public static final Text OPEN_MODS_FOLDER = translatable("essentialclient.clientUpdater.openModsFolder"); - - public static final TextGenerator NEW_DISPLAY = o -> translatable("essentialclient.clientNick.newDisplay", o); - public static final TextGenerator NOT_RENAMED = o -> translatable("essentialclient.clientNick.newDisplay", o); - public static final TextGenerator NO_LONGER_RENAMED = o -> translatable("essentialclient.clientNick.newDisplay", o); - public static final TextGenerator IS_NOT_RENAMED = o -> translatable("essentialclient.clientNick.newDisplay", o); - public static final TextGenerator IS_RENAMED_TO = o -> translatable("essentialclient.clientNick.newDisplay", o); - - public static final TextGenerator CURRENT_REGION = o -> translatable("essentialclient.region.currentRegion", o); - public static final TextGenerator DISTANT_REGION = o -> translatable("essentialclient.region.distantRegion", o); - - public static final Identifier JETBRAINS_MONO = Identifier.of("essentialclient", "jetbrainsmono"); - public static final Identifier MINECRAFT_MONO = Identifier.of("essentialclient", "monocraft"); - - public static String getTranslatableKey(Text text) { - if (text.getContent() instanceof TranslatableTextContent translatableText) { - return translatableText.getKey(); - } - return null; - } - - public interface TextGenerator { - MutableText generate(Object... first); - } -} diff --git a/src/main/java/me/senseiwells/essentialclient/utils/render/WidgetHelper.java b/src/main/java/me/senseiwells/essentialclient/utils/render/WidgetHelper.java deleted file mode 100644 index 40ba9640..00000000 --- a/src/main/java/me/senseiwells/essentialclient/utils/render/WidgetHelper.java +++ /dev/null @@ -1,16 +0,0 @@ -package me.senseiwells.essentialclient.utils.render; - -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.ClickableWidget; -import net.minecraft.text.Text; - -public class WidgetHelper { - public static ButtonWidget newButton(int x, int y, int width, int height, Text message, ButtonWidget.PressAction onPress) { - return ButtonWidget.builder(message, onPress).dimensions(x, y, width, height).build(); - } - - @Deprecated - public static void setPosition(ClickableWidget widget, int x, int y) { - widget.setPosition(x, y); - } -} diff --git a/src/main/kotlin/me/senseiwells/essential_client/EssentialClient.kt b/src/main/kotlin/me/senseiwells/essential_client/EssentialClient.kt new file mode 100644 index 00000000..f6a8c4af --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/EssentialClient.kt @@ -0,0 +1,73 @@ +package me.senseiwells.essential_client + +import me.senseiwells.essential_client.features.* +import me.senseiwells.essential_client.features.carpet_client.* +import me.senseiwells.essential_client.features.carpet_client.database.CarpetRulesDatabase +import me.senseiwells.essential_client.gui.EssentialClientScreen +import me.senseiwells.keybinds.api.KeybindListener +import net.fabricmc.api.ModInitializer +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents +import net.minecraft.client.Minecraft +import net.minecraft.client.multiplayer.ClientPacketListener +import net.minecraft.nbt.CompoundTag +import net.minecraft.resources.ResourceLocation +import org.jetbrains.annotations.ApiStatus.Internal +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +object EssentialClient: ModInitializer { + const val MOD_ID = "essential-client" + + private var carpet: CarpetClient = EmptyCarpetClient + + val logger: Logger = LoggerFactory.getLogger("EssentialClient") + + override fun onInitialize() { + EssentialClientConfig.load() + CarpetRulesDatabase.load() + SpoofedCarpetClientNetworkHandler.load() + + AfkTracker.load() + BetterAccurateBlockPlacement.load() + DisplayStartTime.load() + HighlightLiquids.load() + + this.loadKeybinds() + this.loadEvents() + } + + fun id(path: String): ResourceLocation { + return ResourceLocation.fromNamespaceAndPath(MOD_ID, path.removePrefix("${MOD_ID}:")) + } + + fun getCarpetClient(): CarpetClient { + return this.carpet + } + + @Internal + fun synchronizeCarpetRules(tag: CompoundTag) { + this.carpet.synchronizeRuleData(Minecraft.getInstance(), tag) + } + + @Internal + fun setMultiplayerCarpet(connection: ClientPacketListener) { + this.carpet = MultiplayerCarpetClient(connection) + } + + private fun loadKeybinds() { + EssentialClientConfig.essentialMenuKeybind.addListener(KeybindListener.onPress { + Minecraft.getInstance().setScreen(EssentialClientScreen()) + }) + } + + private fun loadEvents() { + ClientPlayConnectionEvents.JOIN.register { _, _, client -> + if (client.isLocalServer && CarpetClient.hasLocalCarpet) { + this.carpet = SingleplayerCarpetClient + } + } + ClientPlayConnectionEvents.DISCONNECT.register { _, _ -> + this.carpet = EmptyCarpetClient + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/EssentialClientConfig.kt b/src/main/kotlin/me/senseiwells/essential_client/EssentialClientConfig.kt new file mode 100644 index 00000000..1746b948 --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/EssentialClientConfig.kt @@ -0,0 +1,208 @@ +package me.senseiwells.essential_client + +import com.mojang.blaze3d.platform.InputConstants +import dev.isxander.yacl3.config.v2.api.ConfigClassHandler +import dev.isxander.yacl3.config.v2.api.SerialEntry +import dev.isxander.yacl3.config.v2.api.autogen.* +import dev.isxander.yacl3.config.v2.api.serializer.GsonConfigSerializerBuilder +import me.senseiwells.essential_client.EssentialClient.id +import me.senseiwells.essential_client.utils.yacl.ReloadChunks +import me.senseiwells.keybinds.api.InputKeys +import me.senseiwells.keybinds.api.Keybind +import me.senseiwells.keybinds.api.KeybindManager +import me.senseiwells.keybinds.api.yacl.Keybinding +import net.fabricmc.loader.api.FabricLoader +import net.minecraft.client.gui.screens.Screen +import java.nio.file.Path +import kotlin.Boolean +import dev.isxander.yacl3.config.v2.api.autogen.Boolean as Bool + +class EssentialClientConfig { + @IntField + @AutoGen(category = "gameplay") + @SerialEntry var autoWalk: Int = 0 + + @Bool(colored = true) + @AutoGen(category = "gameplay") + @CustomDescription + @SerialEntry var betterAccurateBlockPlacement: Boolean = false + + @FloatSlider(min = 0.0F, max = 10.0F, step = 0.5F) + @AutoGen(category = "gameplay") + @SerialEntry var spectatorScrollMaxSpeed: Float = 1.0F + + @FloatSlider(min = 0.0F, max = 10.0F, step = 0.5F) + @AutoGen(category = "gameplay") + @SerialEntry var spectatorScrollSensitivity: Float = 1.0F + + @IntField + @AutoGen(category = "technical") + @SerialEntry var announceAfk: Int = 0 + + @StringField + @AutoGen(category = "technical") + @SerialEntry var announceAfkMessage: String = "I am now AFK" + + @StringField + @AutoGen(category = "technical") + @SerialEntry var announceBackMessage: String = "" + + @Bool(colored = true) + @AutoGen(category = "technical") + @SerialEntry var carpetAlwaysSetDefault: Boolean = false + + @FloatSlider(min = 0.0F, max = 10.0F, step = 0.5F, format = "%.2f") + @AutoGen(category = "technical") + @SerialEntry var creativeWalkSpeed: Float = 1.0F + + @Bool(colored = true) + @AutoGen(category = "technical") + @SerialEntry var disableHotbarScrolling: Boolean = false + + @Bool(colored = true) + @AutoGen(category = "rendering") + @SerialEntry var disableArmorRendering: Boolean = false + + @Bool(colored = true) + @AutoGen(category = "rendering") + @SerialEntry var disableDamageTilt: Boolean = false + + @Bool(colored = true) + @AutoGen(category = "rendering") + @SerialEntry var disableBossbarRendering: Boolean = false + + @Bool(colored = true) + @AutoGen(category = "rendering") + @SerialEntry var disableMapRendering: Boolean = false + + @Bool(colored = true) + @AutoGen(category = "rendering") + @SerialEntry var disableNametagRendering: Boolean = false + + @Bool(colored = true) + @AutoGen(category = "rendering") + @SerialEntry var disableNightVisionFlashing: Boolean = false + + @Bool(colored = true) + @AutoGen(category = "rendering") + @SerialEntry var disableRecipeToasts: Boolean = false + + @Bool(colored = true) + @AutoGen(category = "rendering") + @SerialEntry var disableAdvancementToasts: Boolean = false + + @Bool(colored = true) + @AutoGen(category = "rendering") + @SerialEntry var disableTutorialToasts: Boolean = false + + @Bool(colored = true) + @AutoGen(category = "rendering") + @SerialEntry var disableJoinLeaveMessages: Boolean = false + + @Bool(colored = true) + @AutoGen(category = "rendering") + @SerialEntry var disableScreenshotMessages: Boolean = false + + @Bool(colored = true) + @AutoGen(category = "rendering") + @SerialEntry var displayPlayTime: Boolean = false + + @Bool(colored = true) + @AutoGen(category = "rendering") + @SerialEntry var essentialClientButton: Boolean = false + + @ReloadChunks + @FloatSlider(min = 0.0F, max = 1.0F, step = 0.05F, format = "%.2f") + @AutoGen(category = "rendering") + @SerialEntry var lavaOpacity: Float = 1.0F + + @ReloadChunks + @Bool(colored = true) + @AutoGen(category = "rendering") + @SerialEntry var highlightLavaSources: Boolean = false + + @ReloadChunks + @Bool(colored = true) + @AutoGen(category = "rendering") + @SerialEntry var highlightWaterSources: Boolean = false + + @Bool(colored = true) + @AutoGen(category = "rendering") + @SerialEntry var persistentChatHistory: Boolean = false + + @Bool(colored = true) + @AutoGen(category = "rendering") + @SerialEntry var toggleTab: Boolean = false + + @Keybinding(id = ESSENTIAL_MENU_KEYBIND) + @AutoGen(category = "keybinds") + @SerialEntry var essentialClientMenuKeys: InputKeys = InputKeys.of(InputConstants.KEY_F7) + + @Keybinding(id = ACCURATE_REVERSE_KEYBIND) + @AutoGen(category = "keybinds") + @SerialEntry var accurateReverseKeys: InputKeys = InputKeys.EMPTY + + @Keybinding(id = ACCURATE_INTO_KEYBIND) + @AutoGen(category = "keybinds") + @SerialEntry var accurateIntoKeys: InputKeys = InputKeys.EMPTY + + companion object { + private const val ESSENTIAL_CATEGORY = "key.categories.essential-client" + private const val ESSENTIAL_MENU_KEYBIND = "${EssentialClient.MOD_ID}:open_menu" + private const val ACCURATE_REVERSE_KEYBIND = "${EssentialClient.MOD_ID}:accurate_reverse" + private const val ACCURATE_INTO_KEYBIND = "${EssentialClient.MOD_ID}:accurate_into" + + private val directory: Path = FabricLoader.getInstance().configDir.resolve("EssentialClient") + private val handler: ConfigClassHandler = createHandler() + + @JvmStatic + val instance: EssentialClientConfig + get() = this.handler.instance() + + val essentialMenuKeybind: Keybind + val accurateReverseKeybind: Keybind + val accurateIntoKeybind: Keybind + + init { + this.handler.load() + + val config = this.instance + this.essentialMenuKeybind = register(ESSENTIAL_MENU_KEYBIND, config.essentialClientMenuKeys) + this.accurateReverseKeybind = register(ACCURATE_REVERSE_KEYBIND, config.accurateReverseKeys) + this.accurateIntoKeybind = register(ACCURATE_INTO_KEYBIND, config.accurateIntoKeys) + } + + fun screen(parent: Screen? = null): Screen { + return this.handler.generateGui().generateScreen(parent) + } + + fun resolve(path: String): Path { + return this.directory.resolve(path) + } + + internal fun load() { + + } + + private fun register(id: String, keys: InputKeys): Keybind { + val keybind = KeybindManager.register(id(id), keys) + KeybindManager.addToControlsScreen(ESSENTIAL_CATEGORY, keybind) + return keybind + } + + private fun createHandler(): ConfigClassHandler { + return ConfigClassHandler.createBuilder(EssentialClientConfig::class.java) + .id(id("config")) + .serializer { config -> + GsonConfigSerializerBuilder.create(config) + .setPath(this.directory.resolve("config.json")) + .appendGsonBuilder { obj -> + obj.setPrettyPrinting() + obj.registerTypeAdapter(InputKeys::class.java, InputKeys.Serializer.INSTANCE) + } + .build() + } + .build() + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/compat/EssentialClientMixinConfigPlugin.kt b/src/main/kotlin/me/senseiwells/essential_client/compat/EssentialClientMixinConfigPlugin.kt new file mode 100644 index 00000000..1b2c4d15 --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/compat/EssentialClientMixinConfigPlugin.kt @@ -0,0 +1,49 @@ +package me.senseiwells.essential_client.compat + +import me.senseiwells.essential_client.features.carpet_client.CarpetClient +import org.objectweb.asm.tree.ClassNode +import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin +import org.spongepowered.asm.mixin.extensibility.IMixinInfo + +class EssentialClientMixinConfigPlugin: IMixinConfigPlugin { + override fun onLoad(mixinPackage: String) { + + } + + override fun getRefMapperConfig(): String? { + return null + } + + override fun shouldApplyMixin(targetClassName: String, mixinClassName: String): Boolean { + if (mixinClassName == "me.senseiwells.essential_client.mixins.carpet_client.ClientNetworkHandlerMixin") { + return CarpetClient.hasLocalCarpet + } + return true + } + + override fun acceptTargets(myTargets: Set, otherTargets: Set) { + + } + + override fun getMixins(): List? { + return null + } + + override fun preApply( + targetClassName: String, + targetClass: ClassNode, + mixinClassName: String, + mixinInfo: IMixinInfo + ) { + + } + + override fun postApply( + targetClassName: String, + targetClass: ClassNode, + mixinClassName: String, + mixinInfo: IMixinInfo + ) { + + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/compat/ModMenuEssentialClientImpl.kt b/src/main/kotlin/me/senseiwells/essential_client/compat/ModMenuEssentialClientImpl.kt new file mode 100644 index 00000000..551522ba --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/compat/ModMenuEssentialClientImpl.kt @@ -0,0 +1,12 @@ +package me.senseiwells.essential_client.compat + +import com.terraformersmc.modmenu.api.ConfigScreenFactory +import com.terraformersmc.modmenu.api.ModMenuApi +import me.senseiwells.essential_client.EssentialClientConfig +import me.senseiwells.essential_client.gui.EssentialClientScreen + +object ModMenuEssentialClientImpl: ModMenuApi { + override fun getModConfigScreenFactory(): ConfigScreenFactory<*> { + return ConfigScreenFactory(::EssentialClientScreen) + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/features/AfkTracker.kt b/src/main/kotlin/me/senseiwells/essential_client/features/AfkTracker.kt new file mode 100644 index 00000000..d0561a4e --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/features/AfkTracker.kt @@ -0,0 +1,47 @@ +package me.senseiwells.essential_client.features + +import me.senseiwells.essential_client.EssentialClientConfig +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents +import net.minecraft.client.Minecraft +import net.minecraft.world.phys.Vec3 + +object AfkTracker { + private const val MINIMUM_TIMEOUT = 200 + + private var prevPosition = Vec3.ZERO + private var prevMouseX = 0.0 + private var prevMouseY = 0.0 + private var afkTicks = 0 + + internal fun load() { + ClientTickEvents.END_CLIENT_TICK.register(::tick) + } + + private fun tick(minecraft: Minecraft) { + val player = minecraft.player ?: return + val timeout = EssentialClientConfig.instance.announceAfk + if (timeout < MINIMUM_TIMEOUT) { + return + } + + val position = player.position() + val mouseX = minecraft.mouseHandler.xpos() + val mouseY = minecraft.mouseHandler.ypos() + if (this.prevPosition == position && this.prevMouseX == mouseX && this.prevMouseY == mouseX) { + if (++this.afkTicks == timeout) { + player.connection.sendChat(EssentialClientConfig.instance.announceAfkMessage) + } + return + } + + if (this.afkTicks >= timeout) { + player.connection.sendChat(EssentialClientConfig.instance.announceBackMessage) + } + + this.prevPosition = position + this.prevMouseX = mouseX + this.prevMouseY = mouseY + + this.afkTicks = 0 + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/features/AutoWalk.kt b/src/main/kotlin/me/senseiwells/essential_client/features/AutoWalk.kt new file mode 100644 index 00000000..0af90a96 --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/features/AutoWalk.kt @@ -0,0 +1,46 @@ +package me.senseiwells.essential_client.features + +import me.senseiwells.essential_client.EssentialClientConfig +import net.minecraft.ChatFormatting +import net.minecraft.client.Minecraft +import net.minecraft.client.Options +import net.minecraft.client.player.Input +import net.minecraft.network.chat.Component +import org.jetbrains.annotations.ApiStatus.Internal + +object AutoWalk { + private var holdUp = false + private var heldTicks = 0 + + @Internal + @JvmStatic + fun tick(input: Input, options: Options) { + val wasHoldingUp = this.holdUp + if (options.keyUp.isDown) { + val required = EssentialClientConfig.instance.autoWalk + this.holdUp = required > 0 && required <= ++this.heldTicks + if (this.holdUp && !wasHoldingUp) { + this.onActivated() + } + } else { + this.heldTicks = 0 + if (this.holdUp) { + input.up = true + } + } + + if (options.keyDown.isDown) { + this.heldTicks = 0 + this.holdUp = false + } + } + + private fun onActivated() { + val minecraft = Minecraft.getInstance() + val player = minecraft.player ?: return + player.displayClientMessage( + Component.translatable("essential-client.autoWalk.activated").withStyle(ChatFormatting.GREEN), + true + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/features/BetterAccurateBlockPlacement.kt b/src/main/kotlin/me/senseiwells/essential_client/features/BetterAccurateBlockPlacement.kt new file mode 100644 index 00000000..a062e102 --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/features/BetterAccurateBlockPlacement.kt @@ -0,0 +1,65 @@ +package me.senseiwells.essential_client.features + +import me.senseiwells.essential_client.EssentialClientConfig +import me.senseiwells.essential_client.utils.MathUtils.angles +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents +import net.minecraft.client.Minecraft +import net.minecraft.core.Direction +import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket +import net.minecraft.util.Mth +import net.minecraft.world.phys.BlockHitResult +import net.minecraft.world.phys.Vec2 +import org.jetbrains.annotations.ApiStatus.Internal + +object BetterAccurateBlockPlacement { + private var rotation: Vec2? = null + private var direction: Direction? = null + + @Internal + @JvmStatic + fun getFakeRotation(): Vec2? { + return this.rotation + } + + @Internal + @JvmStatic + fun getFakeDirection(): Direction? { + return this.direction + } + + internal fun load() { + ClientTickEvents.END_CLIENT_TICK.register(::tick) + } + + private fun tick(minecraft: Minecraft) { + if (!EssentialClientConfig.instance.betterAccurateBlockPlacement) { + this.rotation = null + this.direction = null + return + } + + val player = minecraft.player ?: return + var facing = Direction.orderedByNearest(player).first() + + var rotation = player.rotationVector + if (EssentialClientConfig.accurateIntoKeybind.isHeld) { + val hit = minecraft.hitResult + if (hit is BlockHitResult) { + rotation = hit.direction.angles + facing = hit.direction + } + } + + if (EssentialClientConfig.accurateReverseKeybind.isHeld) { + val (x, y) = if (facing.axis.isHorizontal) 0 to 180 else 180 to 0 + rotation = Vec2(Mth.wrapDegrees(rotation.x + x), Mth.wrapDegrees(rotation.y + y)) + facing = facing.opposite + } + + if (this.rotation != rotation) { + this.rotation = rotation + player.connection.send(ServerboundMovePlayerPacket.Rot(rotation.y, rotation.x, player.onGround())) + } + this.direction = facing + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/features/DisplayStartTime.kt b/src/main/kotlin/me/senseiwells/essential_client/features/DisplayStartTime.kt new file mode 100644 index 00000000..a88f36ef --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/features/DisplayStartTime.kt @@ -0,0 +1,24 @@ +package me.senseiwells.essential_client.features + +import kotlinx.datetime.Clock +import me.senseiwells.essential_client.EssentialClientConfig +import net.minecraft.client.gui.Font +import net.minecraft.client.gui.GuiGraphics +import org.apache.commons.lang3.time.DurationFormatUtils + +object DisplayStartTime { + private val start = Clock.System.now() + + @JvmStatic + fun render(graphics: GuiGraphics, font: Font) { + if (EssentialClientConfig.instance.displayPlayTime) { + val duration = Clock.System.now().minus(this.start).inWholeMilliseconds + val formatted = DurationFormatUtils.formatDuration(duration, "H:mm:ss", true) + graphics.drawString(font, formatted, 8, 8, 0xFFFFFF) + } + } + + internal fun load() { + + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/features/HighlightLiquids.kt b/src/main/kotlin/me/senseiwells/essential_client/features/HighlightLiquids.kt new file mode 100644 index 00000000..cf4efa1c --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/features/HighlightLiquids.kt @@ -0,0 +1,41 @@ +package me.senseiwells.essential_client.features + +import me.senseiwells.essential_client.EssentialClient +import net.fabricmc.fabric.api.resource.ResourceManagerHelper +import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener +import net.minecraft.client.model.geom.builders.UVPair +import net.minecraft.client.renderer.texture.TextureAtlasSprite +import net.minecraft.client.resources.model.Material +import net.minecraft.resources.ResourceLocation +import net.minecraft.server.packs.PackType +import net.minecraft.server.packs.resources.ResourceManager +import net.minecraft.world.inventory.InventoryMenu +import org.jetbrains.annotations.ApiStatus.Internal + +object HighlightLiquids: SimpleSynchronousResourceReloadListener { + private val highlight = Material(InventoryMenu.BLOCK_ATLAS, EssentialClient.id("block/liquid_highlight")) + + private lateinit var sprite: TextureAtlasSprite + + @Internal + @JvmStatic + lateinit var spriteUVs: List + + override fun getFabricId(): ResourceLocation { + return EssentialClient.id("highlight_liquids") + } + + override fun onResourceManagerReload(manager: ResourceManager) { + this.sprite = this.highlight.sprite() + this.spriteUVs = listOf( + UVPair(this.sprite.u0, this.sprite.v0), + UVPair(this.sprite.u0, this.sprite.v1), + UVPair(this.sprite.u1, this.sprite.v1), + UVPair(this.sprite.u1, this.sprite.v0) + ) + } + + internal fun load() { + ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(this) + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/CarpetClient.kt b/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/CarpetClient.kt new file mode 100644 index 00000000..11c0f465 --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/CarpetClient.kt @@ -0,0 +1,97 @@ +package me.senseiwells.essential_client.features.carpet_client + +import dev.isxander.yacl3.api.ConfigCategory +import dev.isxander.yacl3.api.OptionDescription +import dev.isxander.yacl3.api.YetAnotherConfigLib +import me.senseiwells.essential_client.features.carpet_client.database.CarpetRuleData +import me.senseiwells.essential_client.features.carpet_client.yacl.* +import me.senseiwells.essential_client.utils.yacl.SimpleBinding +import net.fabricmc.loader.api.FabricLoader +import net.minecraft.client.Minecraft +import net.minecraft.nbt.CompoundTag +import net.minecraft.network.chat.Component + +sealed class CarpetClient { + fun createConfig(minecraft: Minecraft): YetAnotherConfigLib { + val builder = YetAnotherConfigLib.createBuilder() + this.createCategories(minecraft, builder::category) + builder.title(Component.literal("Carpet Settings")) + val config = builder.build() + return config + } + + abstract fun isValidRule(name: String, manager: String): Boolean + + internal abstract fun synchronizeRuleData(minecraft: Minecraft, tag: CompoundTag) + + protected abstract fun createCategories(minecraft: Minecraft, consumer: (ConfigCategory) -> Unit) + + protected fun createUnboundOption(data: CarpetRuleData): CarpetOption.Builder { + return this.createUnboundOption( + Component.literal(data.name), + Component.literal(data.description), + data.extras.map(Component::literal), + data.validators.map(Component::literal) + ) + } + + protected fun createUnboundOption( + name: Component, + description: Component, + extra: List, + validators: List, + ): CarpetOption.Builder { + val builder = CarpetOption.Builder() + builder.name(name) + builder.description( + OptionDescription.createBuilder() + .text(description) + .text(extra) + .text(validators) + .build() + ) + return builder + } + + @Suppress("UNCHECKED_CAST") + protected fun bindOption( + builder: CarpetOption.Builder, + data: CarpetRuleData + ): CarpetOption.Builder? { + val type = data.type as CarpetOptionType + + builder.type(type) + val defaultValue = data.defaultValue as? T + val value = data.value as? T + if (value != null && defaultValue != null) { + builder.binding(SimpleBinding(value, defaultValue)) + } else { + val nonNullValue = value ?: defaultValue ?: return null + builder.binding(SimpleBinding(nonNullValue)) + } + type.controller(builder, data.options, data.strict) + return builder + } + + protected fun bindOption( + builder: CarpetOption.Builder, + clazz: Class, + value: T, + defaultValue: T, + categories: Collection, + suggestions: Collection, + strict: Boolean + ): CarpetOption.Builder { + val type = CarpetOptionType.resolve(clazz, categories) + builder.type(type) + builder.binding(SimpleBinding(value, defaultValue)) + type.controller(builder, suggestions, strict) + return builder + } + + companion object { + @JvmField + val hasLocalCarpet = FabricLoader.getInstance().isModLoaded("carpet") + } +} + diff --git a/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/EmptyCarpetClient.kt b/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/EmptyCarpetClient.kt new file mode 100644 index 00000000..d08d8bdd --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/EmptyCarpetClient.kt @@ -0,0 +1,31 @@ +package me.senseiwells.essential_client.features.carpet_client + +import dev.isxander.yacl3.api.ConfigCategory +import me.senseiwells.essential_client.features.carpet_client.database.CarpetRulesDatabase +import net.minecraft.client.Minecraft +import net.minecraft.nbt.CompoundTag +import net.minecraft.network.chat.Component + +data object EmptyCarpetClient: CarpetClient() { + override fun isValidRule(name: String, manager: String): Boolean { + // We have no carpet installed... + return false + } + + override fun synchronizeRuleData(minecraft: Minecraft, tag: CompoundTag) { + // This will never be called + } + + override fun createCategories(minecraft: Minecraft, consumer: (ConfigCategory) -> Unit) { + for ((mod, registry) in CarpetRulesDatabase.registries.entries) { + val builder = ConfigCategory.createBuilder() + builder.name(Component.literal(mod)) + for (data in registry.values()) { + val option = this.bindOption(this.createUnboundOption(data), data) ?: continue + option.available(false) + builder.option(option.build()) + } + consumer.invoke(builder.build()) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/MultiplayerCarpetClient.kt b/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/MultiplayerCarpetClient.kt new file mode 100644 index 00000000..e95d9fba --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/MultiplayerCarpetClient.kt @@ -0,0 +1,111 @@ +package me.senseiwells.essential_client.features.carpet_client + +import dev.isxander.yacl3.api.ConfigCategory +import dev.isxander.yacl3.api.utils.OptionUtils +import dev.isxander.yacl3.gui.YACLScreen +import it.unimi.dsi.fastutil.objects.Object2ObjectAVLTreeMap +import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap +import me.senseiwells.essential_client.features.carpet_client.database.CarpetRuleData +import me.senseiwells.essential_client.features.carpet_client.database.CarpetRuleDataRegistry +import me.senseiwells.essential_client.features.carpet_client.database.CarpetRulesDatabase +import me.senseiwells.essential_client.features.carpet_client.yacl.CarpetOption +import net.minecraft.client.Minecraft +import net.minecraft.client.multiplayer.ClientPacketListener +import net.minecraft.nbt.CompoundTag +import net.minecraft.network.chat.Component + +class MultiplayerCarpetClient( + private val connection: ClientPacketListener +): CarpetClient() { + private lateinit var registries: Map + + override fun isValidRule(name: String, manager: String): Boolean { + for (registry in this.registries.values) { + val rule = registry.get(name) ?: continue + if (rule.settingManagers.contains(manager)) { + return true + } + } + return false + } + + override fun synchronizeRuleData(minecraft: Minecraft, tag: CompoundTag) { + if (!this::registries.isInitialized) { + this.initializeRuleData(tag) + return + } + + val screen = minecraft.screen + this.forEachRule(tag) { ruleName, ruleValue, manager -> + for (registry in this.registries.values) { + val rule = registry.get(ruleName) ?: continue + if (rule.settingManagers.contains(manager)) { + rule.value = rule.type.mapFromString(ruleValue) + break + } + } + if (screen is YACLScreen) { + OptionUtils.forEachOptions(screen.config) { option -> + if (option is CarpetOption && option.name().string == ruleName) { + option.setValueFromString(ruleValue) + } + } + } + } + } + + override fun createCategories(minecraft: Minecraft, consumer: (ConfigCategory) -> Unit) { + val initialized = this::registries.isInitialized + val registries = if (initialized) this.registries else CarpetRulesDatabase.registries + + for ((mod, rules) in registries) { + val category = ConfigCategory.createBuilder() + category.name(Component.literal(mod)) + + for (rule in rules.values()) { + val builder = this.bindOption(this.createUnboundOption(rule), rule) ?: continue + builder.applier { option -> + this.connection.sendCommand( + "${rule.defaultManager} ${rule.name} ${option.getPendingValueAsString()}" + ) + } + val connection = minecraft.connection + if (connection != null && initialized) { + val hasCommand = connection.commands.root.getChild(rule.defaultManager) != null + builder.available(hasCommand) + } else { + builder.available(false) + } + category.option(builder.build()) + } + + consumer.invoke(category.build()) + } + } + + private fun initializeRuleData(tag: CompoundTag) { + val map = Object2ObjectAVLTreeMap(String::compareTo) + this.forEachRule(tag) { ruleName, ruleValue, manager -> + val original = CarpetRulesDatabase.getDataForRule(ruleName, manager) + val rule = original?.copy(value = original.type.mapFromString(ruleValue)) + ?: CarpetRuleData.createDefault(ruleName, ruleValue, manager) + map.getOrPut(rule.modName, CarpetRuleDataRegistry::Builder).add(rule) + } + + val registries = Object2ObjectLinkedOpenHashMap() + for ((mod, builder) in map) { + registries[mod] = builder.build() + } + this.registries = registries + } + + private inline fun forEachRule(tag: CompoundTag, consumer: (String, String, String) -> Unit) { + for (key in tag.allKeys) { + val outline = tag.getCompound(key) + val ruleName = outline.getString("Rule") + val ruleValue = outline.getString("Value") + val manager = outline.getString("Manager").ifBlank { "carpet" } + consumer.invoke(ruleName, ruleValue, manager) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/SingleplayerCarpetClient.kt b/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/SingleplayerCarpetClient.kt new file mode 100644 index 00000000..22bd59a5 --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/SingleplayerCarpetClient.kt @@ -0,0 +1,100 @@ +package me.senseiwells.essential_client.features.carpet_client + +import carpet.api.settings.CarpetRule +import carpet.api.settings.InvalidRuleValueException +import carpet.api.settings.RuleHelper +import com.google.common.collect.TreeMultimap +import dev.isxander.yacl3.api.ConfigCategory +import dev.isxander.yacl3.api.Option +import me.senseiwells.essential_client.EssentialClient +import me.senseiwells.essential_client.features.carpet_client.database.CarpetRuleData +import me.senseiwells.essential_client.features.carpet_client.database.CarpetRulesDatabase +import me.senseiwells.essential_client.features.carpet_client.yacl.CarpetOption +import me.senseiwells.essential_client.utils.CarpetUtils +import net.minecraft.client.Minecraft +import net.minecraft.nbt.CompoundTag +import net.minecraft.network.chat.Component + +data object SingleplayerCarpetClient: CarpetClient() { + override fun isValidRule(name: String, manager: String): Boolean { + if (!hasLocalCarpet) { + return false + } + for (rule in CarpetUtils.rules()) { + if (rule.name() == name && rule.settingsManager().identifier() == manager) { + return true + } + } + return false + } + + override fun synchronizeRuleData(minecraft: Minecraft, tag: CompoundTag) { + // In singleplayer we have access to the server, + // carpet doesn't synchronize rules + } + + override fun createCategories(minecraft: Minecraft, consumer: (ConfigCategory) -> Unit) { + if (!hasLocalCarpet) { + EssentialClient.logger.error("Tried loading singleplayer carpet rules without carpet installed!") + return + } + + val sorted = TreeMultimap.create>( + String::compareTo, + Comparator.comparing { option -> option.name().string } + ) + for (rule in CarpetUtils.rules()) { + val data = CarpetRulesDatabase.getDataForRule(rule) + if (data == null) { + sorted.put("Carpet", this.createOption(rule)) + continue + } + sorted.put(data.modName, this.createOption(rule, data)) + } + + for ((mod, options) in sorted.asMap()) { + val category = ConfigCategory.createBuilder() + category.name(Component.literal(mod)) + category.options(options) + consumer.invoke(category.build()) + } + } + + private fun bindOption(builder: CarpetOption.Builder, rule: CarpetRule): CarpetOption.Builder { + return this.bindOption( + builder, + rule.type(), + rule.value(), + rule.defaultValue(), + rule.categories(), + rule.suggestions(), + rule.strict() + ).applier { option -> + try { + rule.set(null, option.pendingValue()) + option.setValue(option.pendingValue()) + } catch (_: InvalidRuleValueException) { + + } + } + } + + private fun createOption(rule: CarpetRule): CarpetOption { + return this.bindOption(this.createUnboundOption(rule), rule).build() + } + + private fun createOption(rule: CarpetRule, data: CarpetRuleData): CarpetOption { + return this.bindOption(this.createUnboundOption(data), rule).build() + } + + private fun createUnboundOption(rule: CarpetRule): CarpetOption.Builder { + val builder = this.createUnboundOption( + Component.literal(rule.name()), + Component.literal(RuleHelper.translatedDescription(rule)), + rule.extraInfo(), + listOf() + ) + builder.available(!rule.settingsManager().locked()) + return builder + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/SpoofedCarpetClientNetworkHandler.kt b/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/SpoofedCarpetClientNetworkHandler.kt new file mode 100644 index 00000000..cfb42436 --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/SpoofedCarpetClientNetworkHandler.kt @@ -0,0 +1,53 @@ +package me.senseiwells.essential_client.features.carpet_client + +import io.netty.buffer.ByteBuf +import me.senseiwells.essential_client.EssentialClient +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking +import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry +import net.minecraft.nbt.CompoundTag +import net.minecraft.network.codec.ByteBufCodecs +import net.minecraft.network.codec.StreamCodec +import net.minecraft.network.protocol.common.custom.CustomPacketPayload +import net.minecraft.resources.ResourceLocation + +object SpoofedCarpetClientNetworkHandler { + internal fun load() { + if (!CarpetClient.hasLocalCarpet) { + PayloadTypeRegistry.playC2S().register(CarpetPayload.TYPE, CarpetPayload.STREAM_CODEC) + PayloadTypeRegistry.playS2C().register(CarpetPayload.TYPE, CarpetPayload.STREAM_CODEC) + ClientPlayNetworking.registerGlobalReceiver(CarpetPayload.TYPE, ::handleCarpetPacket) + } + } + + private fun handleCarpetPacket(payload: CarpetPayload, context: ClientPlayNetworking.Context) { + for (key in payload.data.allKeys) { + when (key) { + "69" -> this.handleCarpetHello(context) + "Rules" -> this.handleCarpetRules(payload.data.getCompound(key)) + } + } + } + + private fun handleCarpetHello(context: ClientPlayNetworking.Context) { + val data = CompoundTag() + data.putString("420", "essential-client-spoofed") + context.responseSender().sendPacket(CarpetPayload(data)) + EssentialClient.setMultiplayerCarpet(context.player().connection) + } + + private fun handleCarpetRules(tag: CompoundTag) { + EssentialClient.synchronizeCarpetRules(tag) + } + + private class CarpetPayload(val data: CompoundTag): CustomPacketPayload { + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + val TYPE = CustomPacketPayload.Type(ResourceLocation.parse("carpet:hello")) + + val STREAM_CODEC: StreamCodec = ByteBufCodecs.COMPOUND_TAG.map(::CarpetPayload, CarpetPayload::data) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/database/CarpetRuleData.kt b/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/database/CarpetRuleData.kt new file mode 100644 index 00000000..a3d42279 --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/database/CarpetRuleData.kt @@ -0,0 +1,78 @@ +package me.senseiwells.essential_client.features.carpet_client.database + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.Transient +import me.senseiwells.essential_client.features.carpet_client.yacl.CarpetOptionType +import me.senseiwells.essential_client.utils.VersionUtils.getMajorVersion +import net.minecraft.SharedConstants + +@Serializable +data class CarpetRuleData( + val name: String, + val description: String, + @SerialName("type") + val typeAsString: String, + @SerialName("value") + val defaultValueAsString: String, + val strict: Boolean, + val categories: List, + val options: List, + val extras: List = listOf(), + val validators: List = listOf(), + @SerialName("config_files") + val settingManagers: List = listOf(), + @SerialName("mod_name") + val modName: String, + @SerialName("mod_slug") + val modSlug: String, + @SerialName("mod_url") + val modUrl: String, + @SerialName("minecraft_versions") + val minecraftVersions: List, + @Transient + val type: CarpetOptionType<*> = CarpetOptionType.resolve(typeAsString, categories), + @Transient + val defaultValue: Any? = type.mapFromString(defaultValueAsString), + @Transient + var value: Any? = defaultValue +) { + val defaultManager: String + get() = this.settingManagers.firstOrNull() ?: "carpet" + + fun compareMinecraftVersions(other: CarpetRuleData): Int { + val versionA = this.minecraftVersions.lastOrNull() + val versionB = other.minecraftVersions.lastOrNull() + if (versionA == null) { + if (versionB == null) { + return 0 + } + return -1 + } + if (versionB == null) { + return 1 + } + return versionA.compareTo(versionB) + } + + companion object { + fun createDefault(name: String, value: String, manager: String): CarpetRuleData { + return CarpetRuleData( + name, + "", + "String", + value, + false, + listOf(), + listOf(), + listOf(), + listOf(), + listOf(manager), + "Unknown", + "", + "", + listOf(SharedConstants.getCurrentVersion().getMajorVersion()) + ) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/database/CarpetRuleDataRegistry.kt b/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/database/CarpetRuleDataRegistry.kt new file mode 100644 index 00000000..6438cb76 --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/database/CarpetRuleDataRegistry.kt @@ -0,0 +1,40 @@ +package me.senseiwells.essential_client.features.carpet_client.database + +import com.google.common.collect.TreeMultimap +import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap +import java.util.* + +class CarpetRuleDataRegistry private constructor( + private val map: SortedMap +) { + fun get(name: String): CarpetRuleData? { + return this.map[name] + } + + fun values(): SequencedCollection { + return this.map.sequencedValues() + } + + class Builder { + private val map = TreeMultimap.create( + String::compareTo, + CarpetRuleData::compareMinecraftVersions + ) + + fun add(rule: CarpetRuleData) { + this.map.put(rule.name, rule) + } + + fun build(version: String? = null): CarpetRuleDataRegistry { + val map = Object2ObjectLinkedOpenHashMap() + for ((key, rules) in this.map.asMap()) { + var rule: CarpetRuleData? = null + if (version != null) { + rule = rules.find { it.minecraftVersions.contains(version) } + } + map[key] = rule ?: rules.last() + } + return CarpetRuleDataRegistry(map) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/database/CarpetRulesDatabase.kt b/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/database/CarpetRulesDatabase.kt new file mode 100644 index 00000000..e6c1e86a --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/database/CarpetRulesDatabase.kt @@ -0,0 +1,178 @@ +package me.senseiwells.essential_client.features.carpet_client.database + +import carpet.api.settings.CarpetRule +import it.unimi.dsi.fastutil.objects.Object2ObjectAVLTreeMap +import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap +import it.unimi.dsi.fastutil.objects.ObjectArrayList +import kotlinx.datetime.Clock +import kotlinx.datetime.toKotlinInstant +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.decodeFromStream +import kotlinx.serialization.json.encodeToStream +import me.senseiwells.essential_client.EssentialClient +import me.senseiwells.essential_client.EssentialClientConfig +import me.senseiwells.essential_client.features.carpet_client.CarpetClient +import me.senseiwells.essential_client.features.carpet_client.yacl.CarpetOptionType +import me.senseiwells.essential_client.utils.CarpetUtils +import me.senseiwells.essential_client.utils.CarpetUtils.matches +import me.senseiwells.essential_client.utils.VersionUtils.getMajorVersion +import net.minecraft.SharedConstants +import net.minecraft.Util +import java.io.IOException +import java.net.HttpURLConnection +import java.net.URI +import java.util.concurrent.CompletableFuture +import kotlin.io.path.getLastModifiedTime +import kotlin.io.path.inputStream +import kotlin.io.path.outputStream + +object CarpetRulesDatabase { + private val cache = EssentialClientConfig.resolve("carpet_rules.json") + + private val json = Json { + ignoreUnknownKeys = true + } + + private val rules = CompletableFuture.supplyAsync( + this::getCarpetRulesByMod, Util.backgroundExecutor() + ) + + val registries: Map + get() = rules.join() + + fun getDataForRule(name: String, manager: String): CarpetRuleData? { + for (rules in registries.values) { + val data = rules.get(name) ?: continue + if (data.settingManagers.contains(manager)) { + return data + } + } + return null + } + + fun getDataForRule(original: CarpetRule<*>): CarpetRuleData? { + for (rules in registries.values) { + val data = rules.get(original.name()) ?: continue + if (original.matches(data)) { + return data + } + } + return null + } + + internal fun load() { + + } + + private fun getCarpetRulesByMod(): Map { + val map = Object2ObjectAVLTreeMap>(String::compareTo) + for (rule in getCarpetRules()) { + map.getOrPut(rule.modName, ::ObjectArrayList).add(rule) + } + + val version = SharedConstants.getCurrentVersion() + val majorVersion = version.getMajorVersion() + val rulesByMod = Object2ObjectLinkedOpenHashMap() + for ((mod, rules) in map) { + val builder = CarpetRuleDataRegistry.Builder() + rules.forEach(builder::add) + rulesByMod[mod] = builder.build(majorVersion) + } + return rulesByMod + } + + private fun getCarpetRules(): List { + try { + val lastModified = this.cache.getLastModifiedTime().toInstant().toKotlinInstant() + val duration = lastModified.minus(Clock.System.now()) + if (duration.inWholeHours < 10) { + val result = this.readCarpetRules() + if (result.isSuccess) { + return result.getOrThrow() + } + } + } catch (_: IOException) { + + } + + var result = this.downloadCarpetRules() + if (result.isFailure) { + val error = result.exceptionOrNull() + result = this.readCarpetRules() + if (result.isFailure) { + EssentialClient.logger.error("Failed to retrieve carpet rules from database", error) + } + } else { + this.writeCarpetRules(result.getOrThrow()) + } + return result.getOrNull() ?: listOf() + } + + @OptIn(ExperimentalSerializationApi::class) + private fun downloadCarpetRules(): Result> { + return runCatching { + val url = URI("https://data.carpet.rubixdev.de/data/combined.json").toURL() + val connection = url.openConnection() as HttpURLConnection + connection.requestMethod = "GET" + connection.connectTimeout = 5000 + connection.readTimeout = 5000 + + resolveDataWithLocalCarpet( + cleanupData(json.decodeFromStream>(connection.inputStream)) + ) + } + } + + @OptIn(ExperimentalSerializationApi::class) + private fun writeCarpetRules(rules: List) { + runCatching { + cache.outputStream().use { stream -> + json.encodeToStream(rules, stream) + } + } + } + + @OptIn(ExperimentalSerializationApi::class) + private fun readCarpetRules(): Result> { + return runCatching { + cache.inputStream().use { stream -> + resolveDataWithLocalCarpet(json.decodeFromStream>(stream)) + } + } + } + + private fun cleanupData(rules: List): List { + return rules.map(::cleanupData) + } + + private fun cleanupData(data: CarpetRuleData): CarpetRuleData { + val index = data.options.indexOfFirst { data.defaultValueAsString.equals(it, true) } + if (index != -1 && data.options[index] != data.defaultValueAsString) { + val defaultValueAsString = data.options[index] + return data.copy( + defaultValueAsString = defaultValueAsString, + defaultValue = data.type.mapFromString(defaultValueAsString) + ) + } + return data + } + + private fun resolveDataWithLocalCarpet(rules: List): List { + if (!CarpetClient.hasLocalCarpet) { + return rules + } + return rules.map(::resolveDataWithLocalCarpet) + } + + private fun resolveDataWithLocalCarpet(data: CarpetRuleData): CarpetRuleData { + val rule = CarpetUtils.rules().find { it.matches(data) } + if (rule != null) { + return data.copy( + type = CarpetOptionType.resolve(rule.type(), rule.categories()), + defaultValue = rule.defaultValue() + ) + } + return data + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/yacl/CarpetOption.kt b/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/yacl/CarpetOption.kt new file mode 100644 index 00000000..49a5cd1d --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/yacl/CarpetOption.kt @@ -0,0 +1,238 @@ +package me.senseiwells.essential_client.features.carpet_client.yacl + +import com.google.common.collect.ImmutableSet +import dev.isxander.yacl3.api.* +import dev.isxander.yacl3.api.controller.ControllerBuilder +import dev.isxander.yacl3.impl.SafeBinding +import net.minecraft.network.chat.Component +import java.util.function.BiConsumer +import java.util.function.Consumer +import java.util.function.Function +import java.util.function.Supplier + +class CarpetOption( + private val name: Component, + private val descriptionProvider: (T) -> OptionDescription, + private val binding: Binding, + private val type: CarpetOptionType, + private val applier: (CarpetOption) -> Unit, + private val listeners: MutableList, T>>, + private var available: Boolean, + controllerProvider: (Option) -> Controller +): Option { + private val controller: Controller = controllerProvider.invoke(this) + private var description: OptionDescription + + private var pending = this.binding.value + + private var setting: Boolean = false + + init { + this.description = this.descriptionProvider.invoke(this.pending) + this.triggerListeners() + + this.addListener { _, pending -> + this.description = this.descriptionProvider.invoke(pending) + } + } + + fun getPendingValueAsString(): String { + return this.type.mapToString(this.pending) + } + + fun setValueFromString(value: String) { + val mapped = this.type.mapFromString(value) + if (mapped != null && this.binding.value != mapped) { + this.setValue(mapped) + } + } + + fun setValue(value: T) { + this.setting = false + this.binding.value = value + } + + override fun name(): Component { + return this.name + } + + override fun description(): OptionDescription { + return this.description + } + + @Deprecated("Use description") + override fun tooltip(): Component { + return this.description.text() + } + + override fun controller(): Controller { + return this.controller + } + + override fun binding(): Binding { + return this.binding + } + + override fun available(): Boolean { + return this.available + } + + override fun setAvailable(available: Boolean) { + val changed = this.available != available + this.available = available + if (changed) { + if (!available) { + this.pending = this.binding.value + } + this.triggerListeners() + } + } + + override fun flags(): ImmutableSet { + return ImmutableSet.of() + } + + override fun changed(): Boolean { + if (this.setting) { + return false + } + return this.binding.value != this.pending + } + + override fun pendingValue(): T { + return this.pending + } + + override fun requestSet(value: T) { + this.pending = value + this.triggerListeners() + } + + override fun applyValue(): Boolean { + if (this.changed()) { + this.setting = true + this.applier.invoke(this) + return true + } + return false + } + + override fun forgetPendingValue() { + this.requestSet(this.binding.value) + } + + override fun requestSetDefault() { + this.requestSet(this.binding.defaultValue()) + } + + override fun isPendingValueDefault(): Boolean { + return this.binding.defaultValue() == this.pending + } + + override fun addListener(listener: BiConsumer, T>) { + this.listeners.add(listener) + } + + private fun triggerListeners() { + for (listener in this.listeners) { + listener.accept(this, this.pending) + } + } + + class Builder: Option.Builder { + private var name: Component? = null + private var description: ((T) -> OptionDescription) = { OptionDescription.EMPTY } + private var binding: Binding? = null + private var type: CarpetOptionType? = null + private var applier: (CarpetOption) -> Unit = { } + private val listeners = ArrayList, T>>() + private var controller: ((Option) -> Controller)? = null + private var available: Boolean = true + + override fun name(name: Component): Builder { + this.name = name + return this + } + + override fun description(description: OptionDescription): Builder { + this.description = { description } + return this + } + + override fun available(available: Boolean): Builder { + this.available = available + return this + } + + override fun flag(vararg flag: OptionFlag): Builder { + return this + } + + override fun flags(flags: MutableCollection): Builder { + return this + } + + override fun instant(instant: Boolean): Builder { + return this + } + + override fun listeners(listeners: MutableCollection, T>>): Builder { + this.listeners.addAll(listeners) + return this + } + + override fun listener(listener: BiConsumer, T>): Builder { + this.listeners.add(listener) + return this + } + + override fun binding(def: T, getter: Supplier, setter: Consumer): Builder { + this.binding = Binding.generic(def, getter, setter) + return this + } + + override fun binding(binding: Binding): Builder { + this.binding = binding + return this + } + + fun type(type: CarpetOptionType): Builder { + this.type = type + return this + } + + fun applier(applier: (CarpetOption) -> Unit): Builder { + this.applier = applier + return this + } + + override fun customController(control: Function, Controller>): Builder { + this.controller = control::apply + return this + } + + override fun controller(controllerBuilder: Function, ControllerBuilder>): Builder { + @Suppress("UnstableApiUsage") + this.controller = { controllerBuilder.apply(it).build() } + return this + } + + override fun description(descriptionFunction: Function): Builder { + this.description = descriptionFunction::apply + return this + } + + override fun build(): CarpetOption { + return CarpetOption( + requireNotNull(this.name) { "CarpetOption name must be specified" }, + this.description, + SafeBinding(requireNotNull(this.binding) { "CarpetOption binding must be specified" }), + requireNotNull(this.type) { "CarpetOption mapper must be specified" } , + this.applier, + ArrayList(this.listeners), + this.available, + requireNotNull(this.controller) { "CarpetOption controller must be specified" } + ) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/yacl/CarpetOptionTypes.kt b/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/yacl/CarpetOptionTypes.kt new file mode 100644 index 00000000..4323399f --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/features/carpet_client/yacl/CarpetOptionTypes.kt @@ -0,0 +1,334 @@ +package me.senseiwells.essential_client.features.carpet_client.yacl + +import dev.isxander.yacl3.api.Option +import dev.isxander.yacl3.api.controller.* +import dev.isxander.yacl3.gui.controllers.BooleanController.TRUE_FALSE_FORMATTER +import dev.isxander.yacl3.gui.controllers.slider.DoubleSliderController +import dev.isxander.yacl3.gui.controllers.slider.FloatSliderController +import dev.isxander.yacl3.gui.controllers.slider.IntegerSliderController +import dev.isxander.yacl3.gui.controllers.slider.LongSliderController +import net.minecraft.ChatFormatting +import net.minecraft.network.chat.Component + +sealed interface CarpetOptionType { + fun controller( + builder: Option.Builder, + suggestions: Collection, + strict: Boolean + ) + + fun clazz(): Class + + fun mapToString(value: T): String + + fun mapFromString(value: String): T? + + companion object { + private const val COMMAND_CATEGORY = "command" + + fun resolve(type: String, categories: Iterable): CarpetOptionType<*> { + return when (type) { + "boolean" -> BooleanCarpetOptionType + "int" -> IntCarpetOptionType + "long" -> LongCarpetOptionType + "float" -> FloatCarpetOptionType + "double" -> DoubleCarpetOptionType + else -> when { + categories.any { it.equals(COMMAND_CATEGORY, true) } -> CommandCarpetOptionType + else -> StringCarpetOptionType + } + } + } + + fun resolve(type: Class, categories: Iterable): CarpetOptionType { + @Suppress("UNCHECKED_CAST") + return when (type) { + Boolean::class.javaObjectType -> BooleanCarpetOptionType + Int::class.javaObjectType -> IntCarpetOptionType + Float::class.javaObjectType -> FloatCarpetOptionType + Double::class.javaObjectType -> DoubleCarpetOptionType + Enum::class.java -> EnumCarpetOptionType(type) + String::class.java -> when { + categories.any { it.equals(COMMAND_CATEGORY, true) } -> CommandCarpetOptionType + else -> StringCarpetOptionType + } + else -> when { + type.isEnum -> EnumCarpetOptionType(type as Class>) + else -> throw IllegalArgumentException("Unsupported type: $type") + } + } as CarpetOptionType + } + } +} + +data object BooleanCarpetOptionType: CarpetOptionType { + override fun controller( + builder: Option.Builder, + suggestions: Collection, + strict: Boolean + ) { + builder.controller { option -> + BooleanControllerBuilder.create(option) + .trueFalseFormatter() + .coloured(true) + } + } + + override fun mapToString(value: Boolean): String { + return value.toString() + } + + override fun clazz(): Class { + return Boolean::class.javaObjectType + } + + override fun mapFromString(value: String): Boolean? { + return value.toBooleanStrictOrNull() + } +} + +data object IntCarpetOptionType: CarpetOptionType { + override fun controller( + builder: Option.Builder, + suggestions: Collection, + strict: Boolean + ) { + addSuggestionsControllerOr( + builder, + suggestions, + strict, + String::toIntOrNull, + IntegerSliderController.DEFAULT_FORMATTER::apply + ) { option -> + IntegerFieldControllerBuilder.create(option) + } + } + + override fun mapToString(value: Int): String { + return value.toString() + } + + override fun clazz(): Class { + return Int::class.javaObjectType + } + + override fun mapFromString(value: String): Int? { + return value.toIntOrNull() + } +} + +data object LongCarpetOptionType: CarpetOptionType { + override fun controller( + builder: Option.Builder, + suggestions: Collection, + strict: Boolean + ) { + addSuggestionsControllerOr( + builder, + suggestions, + strict, + String::toLongOrNull, + LongSliderController.DEFAULT_FORMATTER::apply + ) { option -> + LongFieldControllerBuilder.create(option) + } + } + + override fun mapToString(value: Long): String { + return value.toString() + } + + override fun clazz(): Class { + return Long::class.javaObjectType + } + + override fun mapFromString(value: String): Long? { + return value.toLongOrNull() + } +} + +data object FloatCarpetOptionType: CarpetOptionType { + override fun controller( + builder: Option.Builder, + suggestions: Collection, + strict: Boolean + ) { + addSuggestionsControllerOr( + builder, + suggestions, + strict, + String::toFloatOrNull, + FloatSliderController.DEFAULT_FORMATTER::apply + ) { option -> + FloatFieldControllerBuilder.create(option) + .min(-Float.MAX_VALUE) // TODO: Remove once YACL fixes this + } + } + + override fun mapToString(value: Float): String { + return value.toString() + } + + override fun clazz(): Class { + return Float::class.javaObjectType + } + + override fun mapFromString(value: String): Float? { + return value.toFloatOrNull() + } +} + +data object DoubleCarpetOptionType: CarpetOptionType { + override fun controller( + builder: Option.Builder, + suggestions: Collection, + strict: Boolean + ) { + addSuggestionsControllerOr( + builder, + suggestions, + strict, + String::toDoubleOrNull, + DoubleSliderController.DEFAULT_FORMATTER::apply + ) { option -> + DoubleFieldControllerBuilder.create(option) + .min(-Double.MAX_VALUE) // TODO: Remove once YACL fixes this + } + } + + override fun mapToString(value: Double): String { + return value.toString() + } + + override fun clazz(): Class { + return Double::class.javaObjectType + } + + override fun mapFromString(value: String): Double? { + return value.toDoubleOrNull() + } +} + +class EnumCarpetOptionType( + private val type: Class> +): CarpetOptionType> { + override fun controller( + builder: Option.Builder>, + suggestions: Collection, + strict: Boolean + ) { + builder.controller { option -> + CyclingListControllerBuilder.create(option) + .values(this.type.enumConstants.toList()) + .formatValue { + formatAsBoolean(it.name) { Component.literal(it.name.lowercase()) } + } + } + } + + override fun mapToString(value: Enum<*>): String { + return value.name + } + + override fun clazz(): Class> { + return this.type + } + + override fun mapFromString(value: String): Enum<*>? { + return this.type.enumConstants.firstOrNull { + it.name.equals(value, true) + } + } +} + +data object StringCarpetOptionType: CarpetOptionType { + override fun controller( + builder: Option.Builder, + suggestions: Collection, + strict: Boolean + ) { + addSuggestionsControllerOr(builder, suggestions, strict, { it }) { option -> + StringControllerBuilder.create(option) + } + } + + override fun mapToString(value: String): String { + return value + } + + override fun clazz(): Class { + return String::class.java + } + + override fun mapFromString(value: String): String { + return value + } +} + +data object CommandCarpetOptionType: CarpetOptionType { + private val COMMAND_LEVELS = listOf("true", "false", "ops", "0", "1", "2", "3", "4") + + override fun controller( + builder: Option.Builder, + suggestions: Collection, + strict: Boolean + ) { + builder.controller { option -> + CyclingListControllerBuilder.create(option) + .values(COMMAND_LEVELS) + .formatValue { + formatAsBoolean(it) + } + } + } + + override fun mapToString(value: String): String { + return value + } + + override fun clazz(): Class { + return String::class.java + } + + override fun mapFromString(value: String): String? { + if (COMMAND_LEVELS.any { it.equals(value, true) }) { + return value + } + return null + } +} + +private inline fun formatAsBoolean( + value: String, + formatter: () -> Component = { Component.literal(value) } +): Component { + val boolean = value.lowercase().toBooleanStrictOrNull() + if (boolean != null) { + return Component.empty() + .append(TRUE_FALSE_FORMATTER.apply(boolean)) + .withStyle(if (boolean) ChatFormatting.GREEN else ChatFormatting.RED) + } + return formatter.invoke() +} + +private fun addSuggestionsControllerOr( + builder: Option.Builder, + suggestions: Collection, + strict: Boolean, + mapper: (String) -> T?, + formatter: ValueFormatter = ValueFormatter { Component.literal(it.toString()) }, + otherwise: (Option) -> ControllerBuilder +) { + if (strict) { + val options = suggestions.mapNotNull(mapper) + if (options.isNotEmpty()) { + builder.controller { option -> + CyclingListControllerBuilder.create(option) + .values(options) + .formatValue { value -> formatAsBoolean(value.toString()) { formatter.format(value) } } + } + return + } + } + builder.controller(otherwise) +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/gui/EssentialClientScreen.kt b/src/main/kotlin/me/senseiwells/essential_client/gui/EssentialClientScreen.kt new file mode 100644 index 00000000..18383fed --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/gui/EssentialClientScreen.kt @@ -0,0 +1,73 @@ +package me.senseiwells.essential_client.gui + +import me.senseiwells.chunkdebug.client.ChunkDebugClient +import me.senseiwells.chunkdebug.client.gui.ChunkDebugScreen +import me.senseiwells.essential_client.EssentialClient +import me.senseiwells.essential_client.EssentialClientConfig +import net.fabricmc.loader.api.FabricLoader +import net.minecraft.client.gui.components.Button +import net.minecraft.client.gui.components.StringWidget +import net.minecraft.client.gui.components.Tooltip +import net.minecraft.client.gui.layouts.* +import net.minecraft.client.gui.screens.Screen +import net.minecraft.network.chat.CommonComponents +import net.minecraft.network.chat.Component + +class EssentialClientScreen( + private val parent: Screen? = null +): Screen(Component.translatable("essential-client.menu")) { + private val layout = HeaderAndFooterLayout(this, 32, 64) + + override fun init() { + val minecraft = this.minecraft!! + + val width = 204 + val grid = GridLayout() + grid.defaultCellSetting().padding(4, 4, 4, 0) + val rows = grid.createRowHelper(1) + rows.addChild(Button.builder(Component.translatable("essential-client.menu.config")) { + minecraft.setScreen(EssentialClientConfig.screen(this)) + }.width(width).build()) + rows.addChild(Button.builder(Component.translatable("essential-client.menu.carpetConfig")) { + minecraft.setScreen(EssentialClient.getCarpetClient().createConfig(minecraft).generateScreen(this)) + }.width(width).tooltip(Tooltip.create(Component.translatable("essential-client.menu.carpetConfig.tooltip"))).build()) + val chunks = rows.addChild(Button.builder(Component.translatable("essential-client.menu.chunkDebugMap")) { + minecraft.setScreen(createChunkDebugScreen(this)) + }.width(width).tooltip(Tooltip.create(Component.translatable("essential-client.menu.chunkDebugMap.tooltip"))).build()) + chunks.active = hasChunkDebug && canUseChunkDebug() + + val scripting = rows.addChild(Button.builder(Component.translatable("essential-client.menu.clientScript")) { + + }.width(width).tooltip(Tooltip.create(Component.translatable("essential-client.menu.clientScript.tooltip"))).build()) + scripting.active = false + + this.layout.addToHeader(StringWidget(this.title, this.font)) { settings -> settings.alignVerticallyBottom() } + this.layout.addToContents(grid) { settings -> settings.alignVerticallyTop() } + this.layout.addToFooter(Button.builder(CommonComponents.GUI_DONE) { + this.onClose() + }.build()) + + this.layout.visitWidgets(this::addRenderableWidget) + this.repositionElements() + } + + override fun repositionElements() { + this.layout.arrangeElements() + } + + override fun onClose() { + this.minecraft!!.setScreen(this.parent) + } + + companion object { + private val hasChunkDebug = FabricLoader.getInstance().isModLoaded("chunk-debug") + + private fun canUseChunkDebug(): Boolean { + return this.createChunkDebugScreen() != null + } + + private fun createChunkDebugScreen(parent: Screen? = null): ChunkDebugScreen? { + return ChunkDebugClient.getInstance().createChunkDebugScreen(parent) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/utils/CarpetUtils.kt b/src/main/kotlin/me/senseiwells/essential_client/utils/CarpetUtils.kt new file mode 100644 index 00000000..758dd21b --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/utils/CarpetUtils.kt @@ -0,0 +1,24 @@ +package me.senseiwells.essential_client.utils + +import carpet.CarpetExtension +import carpet.CarpetServer +import carpet.api.settings.CarpetRule +import carpet.api.settings.SettingsManager +import me.senseiwells.essential_client.features.carpet_client.database.CarpetRuleData + +object CarpetUtils { + fun rules(): List> { + val managers = arrayListOf(CarpetServer.settingsManager) + CarpetServer.extensions.mapTo(managers, CarpetExtension::extensionSettingsManager) + return managers.flatMap { it.carpetRules } + } + + fun CarpetRule<*>.matches(data: CarpetRuleData): Boolean { + if (data.settingManagers.contains(this.settingsManager().identifier())) { + if (this.name() == data.name && this.type() == data.type.clazz()) { + return true + } + } + return false + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/utils/MathUtils.kt b/src/main/kotlin/me/senseiwells/essential_client/utils/MathUtils.kt new file mode 100644 index 00000000..132d4e95 --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/utils/MathUtils.kt @@ -0,0 +1,16 @@ +package me.senseiwells.essential_client.utils + +import net.minecraft.core.Direction +import net.minecraft.world.phys.Vec2 + +object MathUtils { + val Direction.angles: Vec2 + get() = when (this) { + Direction.UP -> Vec2(0.0F, -90.0F) + Direction.DOWN -> Vec2(0.0F, 90.0F) + Direction.NORTH -> Vec2(180.0F, 0.0F) + Direction.EAST -> Vec2(-90.0F, 0.0F) + Direction.SOUTH -> Vec2(0.0F, 0.0F) + Direction.WEST -> Vec2(90.0F, 0.0F) + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/utils/VersionUtils.kt b/src/main/kotlin/me/senseiwells/essential_client/utils/VersionUtils.kt new file mode 100644 index 00000000..c4c8fa00 --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/utils/VersionUtils.kt @@ -0,0 +1,9 @@ +package me.senseiwells.essential_client.utils + +import net.minecraft.WorldVersion + +object VersionUtils { + fun WorldVersion.getMajorVersion(): String { + return this.name.replaceAfterLast('.', "") + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/senseiwells/essential_client/utils/yacl/ReloadChunks.kt b/src/main/kotlin/me/senseiwells/essential_client/utils/yacl/ReloadChunks.kt new file mode 100644 index 00000000..250fc5d4 --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/utils/yacl/ReloadChunks.kt @@ -0,0 +1,5 @@ +package me.senseiwells.essential_client.utils.yacl + +@Target(AnnotationTarget.FIELD) +@Retention(AnnotationRetention.RUNTIME) +annotation class ReloadChunks diff --git a/src/main/kotlin/me/senseiwells/essential_client/utils/yacl/ReloadResources.kt b/src/main/kotlin/me/senseiwells/essential_client/utils/yacl/ReloadResources.kt new file mode 100644 index 00000000..3e80e8c9 --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/utils/yacl/ReloadResources.kt @@ -0,0 +1,5 @@ +package me.senseiwells.essential_client.utils.yacl + +@Target(AnnotationTarget.FIELD) +@Retention(AnnotationRetention.RUNTIME) +annotation class ReloadResources diff --git a/src/main/kotlin/me/senseiwells/essential_client/utils/yacl/SimpleBinding.kt b/src/main/kotlin/me/senseiwells/essential_client/utils/yacl/SimpleBinding.kt new file mode 100644 index 00000000..b8b72345 --- /dev/null +++ b/src/main/kotlin/me/senseiwells/essential_client/utils/yacl/SimpleBinding.kt @@ -0,0 +1,20 @@ +package me.senseiwells.essential_client.utils.yacl + +import dev.isxander.yacl3.api.Binding + +class SimpleBinding( + private var value: T, + private val defaultValue: T = value +): Binding { + override fun setValue(value: T) { + this.value = value + } + + override fun getValue(): T { + return this.value + } + + override fun defaultValue(): T { + return this.defaultValue + } +} \ No newline at end of file diff --git a/src/main/resources/assets/essentialclient/icon.png b/src/main/resources/assets/essential-client/icon.png similarity index 100% rename from src/main/resources/assets/essentialclient/icon.png rename to src/main/resources/assets/essential-client/icon.png diff --git a/src/main/resources/assets/essential-client/lang/en_us.json b/src/main/resources/assets/essential-client/lang/en_us.json new file mode 100644 index 00000000..323a270c --- /dev/null +++ b/src/main/resources/assets/essential-client/lang/en_us.json @@ -0,0 +1,92 @@ +{ + "yacl3.config.essential-client:config.category.gameplay": "Gameplay", + "yacl3.config.essential-client:config.autoWalk": "Auto Walk", + "yacl3.config.essential-client:config.autoWalk.desc.1": "This will hold your forward key after you have held it for the set amount of ticks", + "yacl3.config.essential-client:config.betterAccurateBlockPlacement": "Better Accurate Block Placement", + "yacl3.config.essential-client:config.betterAccurateBlockPlacement.desc.1": "This is the same as accurate block placement for tweakeroo but without the need for any server-side mods", + "yacl3.config.essential-client:config.betterAccurateBlockPlacement.desc.2": "This uses some packet hacking, which may flag anti-cheat on some servers", + "yacl3.config.essential-client:config.spectatorScrollMaxSpeed": "Increase Spectator Scroll Speed", + "yacl3.config.essential-client:config.spectatorScrollMaxSpeed.desc.1": "Increases the limit at which you can scroll to go faster in spectator", + "yacl3.config.essential-client:config.spectatorScrollSensitivity": "Increase Spectator Scroll Sensitivity", + "yacl3.config.essential-client:config.spectatorScrollSensitivity.desc.1": "Increases the sensitivity at which you can scroll to go faster in spectator", + "yacl3.config.essential-client:config.switchToTotem": "Switch To Totem", + "yacl3.config.essential-client:config.switchToTotem.desc.1": "This will switch to a totem (if you have one) under a set amount of health", + "yacl3.config.essential-client:config.announceAfk": "Announce AFK", + "yacl3.config.essential-client:config.announceAfk.desc.1": "This announces when you become AFK after a set amount of time (in ticks)", + "yacl3.config.essential-client:config.announceAfkMessage": "Announce AFK Message", + "yacl3.config.essential-client:config.announceAfkMessage.desc.1": "This is the message you announce after you are AFK", + "yacl3.config.essential-client:config.announceAfkMessage.desc.2": "Requires 'Announce AFK' to be enabled", + "yacl3.config.essential-client:config.announceBackMessage": "Announce Back Message", + "yacl3.config.essential-client:config.announceBackMessage.desc.1": "This is the message you announce after you are back from being AFK", + "yacl3.config.essential-client:config.announceBackMessage.desc.2": "Requires 'Announce AFK' to be enabled", + + "yacl3.config.essential-client:config.category.technical": "Technical", + "yacl3.config.essential-client:config.carpetAlwaysSetDefault": "Carpet Always Set Default", + "yacl3.config.essential-client:config.carpetAlwaysSetDefault.desc.1": "This makes it so whenever you set a carpet rule, it automatically sets it to default", + "yacl3.config.essential-client:config.creativeWalkSpeed": "Creative Walk Speed", + "yacl3.config.essential-client:config.creativeWalkSpeed.desc.1": "This allows you to override the vanilla walk speed in creative mode", + "yacl3.config.essential-client:config.disableHotbarScrolling": "Disable Hotbar Scrolling", + "yacl3.config.essential-client:config.disableHotbarScrolling.desc.1": "Prevents you from scrolling to use your hotbar, learn your keybinds!", + + "yacl3.config.essential-client:config.category.rendering": "Rendering", + "yacl3.config.essential-client:config.disableArmorRendering": "Disable Armor Rendering", + "yacl3.config.essential-client:config.disableArmorRendering.desc.1": "This allows you to disable armor rendering for the specified entities", + "yacl3.config.essential-client:config.disableDamageTilt": "Disable Damage Tilt", + "yacl3.config.essential-client:config.disableDamageTilt.desc.1": "Disables the camera tilt effect when taking damage", + "yacl3.config.essential-client:config.disableBossbarRendering": "Disable Bossbar Rendering", + "yacl3.config.essential-client:config.disableBossbarRendering.desc.1": "This will disable any bossbars from rendering", + "yacl3.config.essential-client:config.disableMapRendering": "Disable Map Rendering", + "yacl3.config.essential-client:config.disableMapRendering.desc.1": "Disables maps in item frames from rendering", + "yacl3.config.essential-client:config.disableNametagRendering": "Disable Nametag Rendering", + "yacl3.config.essential-client:config.disableNametagRendering.desc.1": "This disables all name tags from rendering", + "yacl3.config.essential-client:config.disableNightVisionFlashing": "Disable Night Vision Flashing", + "yacl3.config.essential-client:config.disableNightVisionFlashing.desc.1": "Disables the flash that occurs when night vision is about to run out", + "yacl3.config.essential-client:config.disableRecipeToasts": "Disable Recipe Toasts", + "yacl3.config.essential-client:config.disableRecipeToasts.desc.1": "Disables the recipe toast notifications from showing", + "yacl3.config.essential-client:config.disableAdvancementToasts": "Disable Advancement Toasts", + "yacl3.config.essential-client:config.disableAdvancementToasts.desc.1": "Disables the advancement toast notifications from showing", + "yacl3.config.essential-client:config.disableTutorialToasts": "Disable Tutorial Toasts", + "yacl3.config.essential-client:config.disableTutorialToasts.desc.1": "Disables the tutorial toast notifications from showing", + "yacl3.config.essential-client:config.disableJoinLeaveMessages": "Disable Join/Leave Messages", + "yacl3.config.essential-client:config.disableJoinLeaveMessages.desc.1": "This will prevent player join/leave messages from displaying", + "yacl3.config.essential-client:config.disableScreenshotMessages": "Disable Screenshot Messages", + "yacl3.config.essential-client:config.disableScreenshotMessages.desc.1": "Removes the message that pops up when you take a screenshot", + "yacl3.config.essential-client:config.displayPlayTime": "Display Play Time", + "yacl3.config.essential-client:config.displayPlayTime.desc.1": "Displays the amount of time your client has been running in the corner of the pause menu", + "yacl3.config.essential-client:config.essentialClientButton": "EssentialClient Button", + "yacl3.config.essential-client:config.essentialClientButton.desc.1": "This renders the EssentialClient Menu on the main menu screen and pause screen", + "yacl3.config.essential-client:config.lavaOpacity": "Lava Opacity", + "yacl3.config.essential-client:config.lavaOpacity.desc.1": "Changes the opacity of lava", + "yacl3.config.essential-client:config.highlightLavaSources": "Highlight Lava Sources", + "yacl3.config.essential-client:config.highlightLavaSources.desc.1": "Changes the texture for lava sources to make them more visible", + "yacl3.config.essential-client:config.highlightWaterSources": "Highlight Water Sources", + "yacl3.config.essential-client:config.highlightWaterSources.desc.1": "Changes the texture for water sources to make them more visible", + "yacl3.config.essential-client:config.persistentChatHistory": "Persistent Chat History", + "yacl3.config.essential-client:config.persistentChatHistory.desc.1": "This prevents the chat from being cleared, also applies when changing worlds/servers", + "yacl3.config.essential-client:config.toggleTab": "Toggle Tab", + "yacl3.config.essential-client:config.toggleTab.desc.1": "This allows you to toggle tab instead of holding it to see the tab menu", + + "yacl3.config.essential-client:config.category.keybinds": "Keybinds", + "yacl3.config.essential-client:config.essentialClientMenuKeys": "EssentialClient Menu Keybind", + "yacl3.config.essential-client:config.essentialClientMenuKeys.desc.1": "This is the keybind to open the EssentialClient Menu", + "yacl3.config.essential-client:config.accurateReverseKeys": "Accurate Reverse Keybind", + "yacl3.config.essential-client:config.accurateReverseKeys.desc.1": "This is the keybind to activate reverse accurate block placement", + "yacl3.config.essential-client:config.accurateIntoKeys": "Accurate Into keybind", + "yacl3.config.essential-client:config.accurateIntoKeys.desc.1": "This is the keybind to activate into accurate block placement", + + "key.categories.essential-client": "EssentialClient", + "key.essential-client.open_menu": "EssentialClient Menu", + "key.essential-client.accurate_into": "Accurate Into", + "key.essential-client.accurate_reverse": "Accurate Reverse", + + "essential-client.menu": "EssentialClient Menu", + "essential-client.menu.config": "EssentialClient Settings", + "essential-client.menu.carpetConfig": "Carpet Server Settings", + "essential-client.menu.carpetConfig.tooltip": "View and modify the server's Carpet settings through a gui", + "essential-client.menu.chunkDebugMap": "ChunkDebug Map", + "essential-client.menu.chunkDebugMap.tooltip": "Opens the ChunkDebug Map\nRequires ChunkDebug to be installed separately", + "essential-client.menu.clientScript": "ClientScript Options", + "essential-client.menu.clientScript.tooltip": "ClientScripts are no longer being supported\nA new scripting system is being worked on, but is not quite ready yet", + + "essential-client.autoWalk.activated": "You are now auto-walking" +} \ No newline at end of file diff --git a/src/main/resources/assets/essentialclient/lang/en_us.json b/src/main/resources/assets/essential-client/lang/en_us.old.json similarity index 100% rename from src/main/resources/assets/essentialclient/lang/en_us.json rename to src/main/resources/assets/essential-client/lang/en_us.old.json diff --git a/src/main/resources/assets/essentialclient/lang/zh_cn.json b/src/main/resources/assets/essential-client/lang/zh_cn.old.json similarity index 100% rename from src/main/resources/assets/essentialclient/lang/zh_cn.json rename to src/main/resources/assets/essential-client/lang/zh_cn.old.json diff --git a/src/main/resources/assets/essential-client/textures/block/liquid_highlight.png b/src/main/resources/assets/essential-client/textures/block/liquid_highlight.png new file mode 100644 index 00000000..d8b3ca8c Binary files /dev/null and b/src/main/resources/assets/essential-client/textures/block/liquid_highlight.png differ diff --git a/src/main/resources/assets/essentialclient/font/jetbrainsmono.json b/src/main/resources/assets/essentialclient/font/jetbrainsmono.json deleted file mode 100644 index 8144e5db..00000000 --- a/src/main/resources/assets/essentialclient/font/jetbrainsmono.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "providers": [ - { - "type": "ttf", - "file": "essentialclient:jetbrainsmono.ttf", - "shift": [ - -0.5, - 1.2 - ], - "size": 9, - "oversample": 4.0, - "skip": "", - "legal": "https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL" - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/essentialclient/font/jetbrainsmono.ttf b/src/main/resources/assets/essentialclient/font/jetbrainsmono.ttf deleted file mode 100644 index 8da8aa40..00000000 Binary files a/src/main/resources/assets/essentialclient/font/jetbrainsmono.ttf and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/font/monocraft.json b/src/main/resources/assets/essentialclient/font/monocraft.json deleted file mode 100644 index 815fec3b..00000000 --- a/src/main/resources/assets/essentialclient/font/monocraft.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "providers": [ - { - "type": "ttf", - "file": "essentialclient:monocraft.ttf", - "shift": [ - -0.5, - 1.2 - ], - "size": 9, - "oversample": 4.0, - "skip": "", - "legal": "https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL" - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/essentialclient/font/monocraft.ttf b/src/main/resources/assets/essentialclient/font/monocraft.ttf deleted file mode 100644 index de3c39c5..00000000 Binary files a/src/main/resources/assets/essentialclient/font/monocraft.ttf and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/block/lava_flow.png b/src/main/resources/assets/essentialclient/textures/block/lava_flow.png deleted file mode 100644 index 83353614..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/block/lava_flow.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/block/lava_flow.png.mcmeta b/src/main/resources/assets/essentialclient/textures/block/lava_flow.png.mcmeta deleted file mode 100644 index 8e55e43b..00000000 --- a/src/main/resources/assets/essentialclient/textures/block/lava_flow.png.mcmeta +++ /dev/null @@ -1,5 +0,0 @@ -{ - "animation": { - "frametime": 3 - } -} diff --git a/src/main/resources/assets/essentialclient/textures/block/lava_still.png b/src/main/resources/assets/essentialclient/textures/block/lava_still.png deleted file mode 100644 index 4a31035e..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/block/lava_still.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/block/lava_still.png.mcmeta b/src/main/resources/assets/essentialclient/textures/block/lava_still.png.mcmeta deleted file mode 100644 index 7ceb3639..00000000 --- a/src/main/resources/assets/essentialclient/textures/block/lava_still.png.mcmeta +++ /dev/null @@ -1,45 +0,0 @@ -{ - "animation": { - "frametime": 2, - "frames": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 18, - 17, - 16, - 15, - 14, - 13, - 12, - 11, - 10, - 9, - 8, - 7, - 6, - 5, - 4, - 3, - 2, - 1 - ] - } -} \ No newline at end of file diff --git a/src/main/resources/assets/essentialclient/textures/block/water_flow.png b/src/main/resources/assets/essentialclient/textures/block/water_flow.png deleted file mode 100644 index bfe71c42..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/block/water_flow.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/block/water_flow.png.mcmeta b/src/main/resources/assets/essentialclient/textures/block/water_flow.png.mcmeta deleted file mode 100644 index 4f0718ac..00000000 --- a/src/main/resources/assets/essentialclient/textures/block/water_flow.png.mcmeta +++ /dev/null @@ -1,3 +0,0 @@ -{ - "animation": {} -} \ No newline at end of file diff --git a/src/main/resources/assets/essentialclient/textures/block/water_still.png b/src/main/resources/assets/essentialclient/textures/block/water_still.png deleted file mode 100644 index 7c12aedf..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/block/water_still.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/block/water_still.png.mcmeta b/src/main/resources/assets/essentialclient/textures/block/water_still.png.mcmeta deleted file mode 100644 index 0645f48c..00000000 --- a/src/main/resources/assets/essentialclient/textures/block/water_still.png.mcmeta +++ /dev/null @@ -1,5 +0,0 @@ -{ - "animation": { - "frametime": 2 - } -} diff --git a/src/main/resources/assets/essentialclient/textures/capes/bacon.png b/src/main/resources/assets/essentialclient/textures/capes/bacon.png deleted file mode 100644 index 0239c290..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/bacon.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/birthday.png b/src/main/resources/assets/essentialclient/textures/capes/birthday.png deleted file mode 100644 index bfae0352..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/birthday.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/cheapsh0t.png b/src/main/resources/assets/essentialclient/textures/capes/cheapsh0t.png deleted file mode 100644 index 875713fa..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/cheapsh0t.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/christmas2010.png b/src/main/resources/assets/essentialclient/textures/capes/christmas2010.png deleted file mode 100644 index bc89c981..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/christmas2010.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/cobalt.png b/src/main/resources/assets/essentialclient/textures/capes/cobalt.png deleted file mode 100644 index e92565ab..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/cobalt.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/dannyb.png b/src/main/resources/assets/essentialclient/textures/capes/dannyb.png deleted file mode 100644 index 6e5a0c51..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/dannyb.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/julian.png b/src/main/resources/assets/essentialclient/textures/capes/julian.png deleted file mode 100644 index 19cb8d00..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/julian.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/migrator.png b/src/main/resources/assets/essentialclient/textures/capes/migrator.png deleted file mode 100644 index 282e1d65..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/migrator.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/millionth.png b/src/main/resources/assets/essentialclient/textures/capes/millionth.png deleted file mode 100644 index 281fa419..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/millionth.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/minecon2011.png b/src/main/resources/assets/essentialclient/textures/capes/minecon2011.png deleted file mode 100644 index d52a84c4..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/minecon2011.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/minecon2012.png b/src/main/resources/assets/essentialclient/textures/capes/minecon2012.png deleted file mode 100644 index f72175cd..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/minecon2012.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/minecon2013.png b/src/main/resources/assets/essentialclient/textures/capes/minecon2013.png deleted file mode 100644 index e4388aca..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/minecon2013.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/minecon2015.png b/src/main/resources/assets/essentialclient/textures/capes/minecon2015.png deleted file mode 100644 index 3cfc33f9..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/minecon2015.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/minecon2016.png b/src/main/resources/assets/essentialclient/textures/capes/minecon2016.png deleted file mode 100644 index e4df64fa..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/minecon2016.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/mojangcape.png b/src/main/resources/assets/essentialclient/textures/capes/mojangcape.png deleted file mode 100644 index b8316388..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/mojangcape.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/mojangclassic.png b/src/main/resources/assets/essentialclient/textures/capes/mojangclassic.png deleted file mode 100644 index 8102a75b..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/mojangclassic.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/mojangstudios.png b/src/main/resources/assets/essentialclient/textures/capes/mojangstudios.png deleted file mode 100644 index 44cfe56f..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/mojangstudios.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/mojira.png b/src/main/resources/assets/essentialclient/textures/capes/mojira.png deleted file mode 100644 index a922a16d..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/mojira.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/mrmessiah.png b/src/main/resources/assets/essentialclient/textures/capes/mrmessiah.png deleted file mode 100644 index b406daf6..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/mrmessiah.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/newyear2011.png b/src/main/resources/assets/essentialclient/textures/capes/newyear2011.png deleted file mode 100644 index 2a06e2a1..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/newyear2011.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/prismarine.png b/src/main/resources/assets/essentialclient/textures/capes/prismarine.png deleted file mode 100644 index 7408590a..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/prismarine.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/realms.png b/src/main/resources/assets/essentialclient/textures/capes/realms.png deleted file mode 100644 index a68ce46c..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/realms.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/scrolls.png b/src/main/resources/assets/essentialclient/textures/capes/scrolls.png deleted file mode 100644 index bcc532e8..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/scrolls.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/translator.png b/src/main/resources/assets/essentialclient/textures/capes/translator.png deleted file mode 100644 index 4b4e3c86..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/translator.png and /dev/null differ diff --git a/src/main/resources/assets/essentialclient/textures/capes/turtle.png b/src/main/resources/assets/essentialclient/textures/capes/turtle.png deleted file mode 100644 index e4098a87..00000000 Binary files a/src/main/resources/assets/essentialclient/textures/capes/turtle.png and /dev/null differ diff --git a/src/main/resources/essential-client.mixins.json b/src/main/resources/essential-client.mixins.json new file mode 100644 index 00000000..a74251bb --- /dev/null +++ b/src/main/resources/essential-client.mixins.json @@ -0,0 +1,39 @@ +{ + "required": true, + "package": "me.senseiwells.essential_client.mixins", + "compatibilityLevel": "JAVA_17", + "plugin": "me.senseiwells.essential_client.compat.EssentialClientMixinConfigPlugin", + "client": [ + "auto_walk.KeyboardInputMixin", + "better_accurate_block_placement.BlockPlaceContextMixin", + "better_accurate_block_placement.LocalPlayerMixin", + "carpet_always_set_default.ClientPacketListenerMixin", + "carpet_client.ClientNetworkHandlerMixin", + "disable_armor_rendering.HumanoidArmorLayerMixin", + "disable_bossbar_rendering.GuiMixin", + "disable_damage_tilt.GameRendererMixin", + "disable_hotbar_scrolling.MouseHandlerMixin", + "disable_join_leave_messages.ChatListenerMixin", + "disable_map_rendering.ItemFrameRendererMixin", + "disable_nametag_rendering.EntityRendererMixin", + "disable_night_vision_flashing.GameRendererMixin", + "disable_screenshot_message.ScreenshotMixin", + "disable_toasts.ToastComponentMixin", + "display_time_played.PauseScreenMixin", + "essential_client_button.PauseScreenMixin", + "highlight_liquids.LiquidBlockRendererMixin", + "lava_opacity.BlockRenderDispatcherMixin", + "lava_opacity.LiquidBlockRendererMixin", + "lava_opacity.SectionCompilerMixin", + "persistent_chat_history.GuiMixin", + "spectator_scrolling.MouseHandlerMixin", + "toggle_tab.GuiMixin" + ], + "injectors": { + "defaultRequire": 1 + }, + "mixins": [ + "creative_walk_speed.PlayerMixin", + "yacl.SimpleOptionFactoryMixin" + ] +} diff --git a/src/main/resources/essentialclient.mixins.json b/src/main/resources/essentialclient.mixins.json deleted file mode 100644 index 39a482b2..00000000 --- a/src/main/resources/essentialclient.mixins.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "required": true, - "package": "me.senseiwells.essentialclient.mixins", - "compatibilityLevel": "JAVA_17", - "plugin": "me.senseiwells.essentialclient.utils.misc.EssentialMixinConfig", - "client": [ - "autoWalk.KeyboardInputMixin", - "betterAccurateBlockPlacement.ClientPlayerEntityMixin", - "betterAccurateBlockPlacement.ItemPlacementContextMixin", - "betterAccurateBlockPlacement.ItemUsageContextMixin", - "carpet.ClientNetworkHandlerMixin", - "chunkDebug.InGameHudMixin", - "cleanConfirmScreen.ConfirmScreenMixin", - "clientNick.MessageHandlerMixin", - "clientNick.PlayerEntityRendererMixin", - "clientNick.PlayerListHudMixin", - "clientScript.AnvilScreenHandlerMixin", - "clientScript.BlockItemMixin", - "clientScript.ChatHudMixin", - "clientScript.ClientPlayerEntityMixin", - "clientScript.ClientPlayerInteractionManagerMixin", - "clientScript.ClientPlayNetworkHandlerMixin", - "clientScript.ClientWorldAccessor", - "clientScript.DebugHudMixin", - "clientScript.EntityListMixin", - "clientScript.EntityMixin", - "clientScript.FishingBobberEntityMixin", - "clientScript.HandledScreenMixin", - "clientScript.ItemEntityAccessor", - "clientScript.KeyBindingAccessor", - "clientScript.KeyboardMixin", - "clientScript.LivingEntityMixin", - "clientScript.MerchantScreenMixin", - "clientScript.MinecraftClientAccessor", - "clientScript.MinecraftClientMixin", - "clientScript.MouseMixin", - "clientScript.NbtListMixin", - "clientScript.ScreenMixin", - "clientScript.StonecutterScreenHandlerMixin", - "clientScript.WorldRendererMixin", - "commandSuggestorIgnoresSpaces.ChatInputSuggestorMixin", - "core.ClientPlayNetworkHandlerMixin", - "core.GameMenuScreenMixin", - "core.KeyboardMixin", - "core.MinecraftClientMixin", - "core.TitleScreenMixin", - "craftingHax.ClientPlayerInteractionManagerMixin", - "customClientCape.AbstractClientPlayerEntityMixin", - "daylightCycleSlowdownMultiplier.ClientPlayNetworkHandlerMixin", - "daylightCycleSlowdownMultiplier.ClientWorldMixin", - "disableArmourRendering.ArmorFeatureRendererMixin", - "disableBobViewWhenHurt.GameRendererMixin", - "disableBossBar.BossBarHudMixin", - "disableHotbarScrolling.MouseMixin", - "disableMapRendering.ItemFrameEntityRendererMixin", - "disableMessages.MessageHandlerMixin", - "disableNameTags.EntityRendererMixin", - "disableNarrator.KeyboardMixin", - "disableNightVisionFlash.GameRendererMixin", - "disableRecipeNotifications.RecipeToastMixin", - "disableScreenshotMessage.ScreenshotRecorderMixin", - "disableTutorialNotifications.TutorialToastMixin", - "displayTimePlayed.GameMenuScreenMixin", - "gameRuleSync.GameRuleAccessor", - "gameRuleSync.RuleInvoker", - "gameRuleSync.RuleMixin", - "keyboard.KeyboardMixin", - "longChatMessages.ChatScreenMixin", - "longChatMessages.GenericChatMessageC2SPacketMixin", - "longChatMessages.StringHelperMixin", - "mouseScrollRules.MouseMixin", - "openScreenshotDirectory.ScreenshotRecorderMixin", - "overrideCreativeWalkSpeed.LivingEntityMixin", - "permanentChatHud.ChatHudMixin", - "quickLockRecipe.AnimatedResultButtonMixin", - "quickLockRecipe.RecipeBookResultsMixin", - "quickLockRecipe.RecipeBookWidgetMixin", - "removeWarnReceivedPassengers.ClientPlayNetworkHandlerMixin", - "soulBlocksEffectOnFov.AbstractClientPlayerEntityMixin", - "stackableShulkers.HopperBlockEntityMixin", - "stackableShulkers.ItemStackMixin", - "survivalInventoryInCreative.CreativeInventoryScreenMixin", - "survivalInventoryInCreative.InventoryScreenMixin", - "switchToTotem.ClientPlayerEntityMixin", - "toggleTab.InGameHudMixin", - "unlockAllRecipes.ClientPlayerInteractionManagerMixin", - "unlockAllRecipes.ClientPlayNetworkHandlerMixin", - "unlockAllRecipes.GhostSlotClearInvoker", - "unlockAllRecipes.RecipeBookWidgetMixin", - "waterFovMultiplier.GameRendererMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 4e06fbc2..48e52eff 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -2,8 +2,8 @@ "schemaVersion": 1, "id": "essential-client", "version": "${version}", - "name": "Essential Client", - "description": "A client mod that provides utilities and client support for carpet rules", + "name": "EssentialClient", + "description": "EssentialClient is a client-side mod that adds many client utilities as well as providing a gui to modify carpet rules!", "authors": [ "Sensei" ], @@ -11,7 +11,7 @@ "AngelBottomless", "BvngeeCord", "Crec0", - "EarthComputer", + "Earthcomputer", "HardCoded", "lhmddws", "Pixeils", @@ -19,29 +19,37 @@ "SuperSanta" ], "contact": { - "homepage": "https://github.com/senseiwells/EssentialClient" + "source": "https://github.com/senseiwells/EssentialClient", + "issues": "https://github.com/senseiwells/EssentialClient/issues" }, "license": "MIT", - "icon": "assets/essentialclient/icon.png", + "icon": "assets/essential-client/icon.png", "environment": "client", "entrypoints": { - "preLaunch": [ - "me.senseiwells.essentialclient.feature.MixinExtraSupport::load" - ], "main": [ - "me.senseiwells.essentialclient.EssentialClient", - "me.senseiwells.essentialclient.utils.clientscript.DocGenerator" + { + "adapter": "kotlin", + "value": "me.senseiwells.essential_client.EssentialClient" + } ], "modmenu": [ - "me.senseiwells.essentialclient.gui.modmenu.ModMenuImpl" + { + "adapter": "kotlin", + "value": "me.senseiwells.essential_client.compat.ModMenuEssentialClientImpl" + } ] }, "mixins": [ - "essentialclient.mixins.json" + "essential-client.mixins.json" ], "depends": { - "fabricloader": ">=0.13.1", "fabric": "*", + "fabricloader": ">=${fabric_loader_dependency}", + "yet_another_config_lib_v3": ">=${yacl_dependency}", "minecraft": "${minecraft_dependency}" + }, + "suggests": { + "carpet": "*", + "chunk-debug": "*" } }